summaryrefslogtreecommitdiffstats
path: root/src/modules
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 02:13:59 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 02:13:59 +0000
commita6d58bb6052ac8cb01805a48c4ad2f129126116f (patch)
treedd867a099fcbb263a8009a9fb22695b87855dad6 /src/modules
downloadkvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.tar.gz
kvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.zip
Added KDE3 version of kvirc
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kvirc@1095341 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/Makefile.am61
-rw-r--r--src/modules/about/ENTRIES259
-rw-r--r--src/modules/about/Makefile.am27
-rw-r--r--src/modules/about/aboutdialog.cpp166
-rw-r--r--src/modules/about/aboutdialog.h39
-rw-r--r--src/modules/about/abouttext.inc768
-rw-r--r--src/modules/about/libkviabout.cpp100
-rw-r--r--src/modules/about/mkabouttext.pl172
-rw-r--r--src/modules/action/Makefile.am17
-rw-r--r--src/modules/action/libkviaction.cpp533
-rw-r--r--src/modules/actioneditor/Makefile.am21
-rw-r--r--src/modules/actioneditor/actioneditor.cpp1009
-rw-r--r--src/modules/actioneditor/actioneditor.h210
-rw-r--r--src/modules/actioneditor/libkviactioneditor.cpp86
-rw-r--r--src/modules/addon/Makefile.am22
-rw-r--r--src/modules/addon/libkviaddon.cpp659
-rw-r--r--src/modules/addon/managementdialog.cpp403
-rw-r--r--src/modules/addon/managementdialog.h114
-rw-r--r--src/modules/addon/pics/Makefile.am9
-rw-r--r--src/modules/addon/pics/kvi_dialog_addons.pngbin0 -> 191267 bytes
-rw-r--r--src/modules/aliaseditor/Makefile.am21
-rw-r--r--src/modules/aliaseditor/aliaseditor.cpp1408
-rw-r--r--src/modules/aliaseditor/aliaseditor.h197
-rw-r--r--src/modules/aliaseditor/libkvialiaseditor.cpp90
-rw-r--r--src/modules/avatar/Makefile.am20
-rw-r--r--src/modules/avatar/libkviavatar.cpp585
-rw-r--r--src/modules/avatar/libkviavatar.h54
-rw-r--r--src/modules/chan/Makefile.am18
-rw-r--r--src/modules/chan/libkvichan.cpp1635
-rw-r--r--src/modules/channelsjoin/Makefile.am20
-rw-r--r--src/modules/channelsjoin/channelsjoinwindow.cpp301
-rw-r--r--src/modules/channelsjoin/channelsjoinwindow.h70
-rw-r--r--src/modules/channelsjoin/libkvichannelsjoin.cpp108
-rw-r--r--src/modules/clock/Makefile.am20
-rw-r--r--src/modules/clock/libkviclock.cpp257
-rw-r--r--src/modules/clock/libkviclock.h46
-rw-r--r--src/modules/codetester/Makefile.am17
-rw-r--r--src/modules/codetester/codetester.cpp157
-rw-r--r--src/modules/codetester/codetester.h67
-rw-r--r--src/modules/codetester/libkvicodetester.cpp89
-rw-r--r--src/modules/config/Makefile.am18
-rw-r--r--src/modules/config/libkviconfig.cpp877
-rw-r--r--src/modules/context/Makefile.am18
-rw-r--r--src/modules/context/libkvicontext.cpp401
-rw-r--r--src/modules/dcc/Makefile.am66
-rw-r--r--src/modules/dcc/adpcmcodec.cpp294
-rw-r--r--src/modules/dcc/adpcmcodec.h59
-rw-r--r--src/modules/dcc/broker.cpp898
-rw-r--r--src/modules/dcc/broker.h124
-rw-r--r--src/modules/dcc/canvas.cpp301
-rw-r--r--src/modules/dcc/canvas.h74
-rw-r--r--src/modules/dcc/canvaswidget.cpp1601
-rw-r--r--src/modules/dcc/canvaswidget.h322
-rw-r--r--src/modules/dcc/chat.cpp842
-rw-r--r--src/modules/dcc/chat.h101
-rw-r--r--src/modules/dcc/codec.cpp88
-rw-r--r--src/modules/dcc/codec.h57
-rw-r--r--src/modules/dcc/descriptor.cpp224
-rw-r--r--src/modules/dcc/descriptor.h163
-rw-r--r--src/modules/dcc/dialogs.cpp206
-rw-r--r--src/modules/dcc/dialogs.h82
-rw-r--r--src/modules/dcc/gsmcodec.cpp149
-rw-r--r--src/modules/dcc/gsmcodec.h54
-rw-r--r--src/modules/dcc/kvi_dccfiletransfericons.pngbin0 -> 25192 bytes
-rw-r--r--src/modules/dcc/libkvidcc.cpp2766
-rw-r--r--src/modules/dcc/marshal.cpp647
-rw-r--r--src/modules/dcc/marshal.h112
-rw-r--r--src/modules/dcc/requests.cpp1154
-rw-r--r--src/modules/dcc/send.cpp1898
-rw-r--r--src/modules/dcc/send.h260
-rw-r--r--src/modules/dcc/thread.cpp111
-rw-r--r--src/modules/dcc/thread.h79
-rw-r--r--src/modules/dcc/utils.cpp169
-rw-r--r--src/modules/dcc/utils.h34
-rw-r--r--src/modules/dcc/voice.cpp1041
-rw-r--r--src/modules/dcc/voice.h440
-rw-r--r--src/modules/dcc/window.cpp53
-rw-r--r--src/modules/dcc/window.h49
-rw-r--r--src/modules/dialog/Makefile.am21
-rw-r--r--src/modules/dialog/libkvidialog.cpp920
-rw-r--r--src/modules/dialog/libkvidialog.h133
-rw-r--r--src/modules/dockwidget/Makefile.am33
-rw-r--r--src/modules/dockwidget/kvi_dock.pngbin0 -> 1959 bytes
-rw-r--r--src/modules/dockwidget/kvi_dock_part-0.pngbin0 -> 1477 bytes
-rw-r--r--src/modules/dockwidget/kvi_dock_part-1.pngbin0 -> 1027 bytes
-rw-r--r--src/modules/dockwidget/kvi_dock_part-2.pngbin0 -> 1034 bytes
-rw-r--r--src/modules/dockwidget/libkvidockwidget.h34
-rw-r--r--src/modules/dockwidget/libkvidockwidget_qt3.cpp858
-rw-r--r--src/modules/dockwidget/libkvidockwidget_qt3.h95
-rw-r--r--src/modules/dockwidget/libkvidockwidget_qt4.cpp691
-rw-r--r--src/modules/dockwidget/libkvidockwidget_qt4.h81
-rw-r--r--src/modules/editor/Makefile.am20
-rw-r--r--src/modules/editor/libkvieditor.cpp94
-rw-r--r--src/modules/editor/scripteditor.cpp1224
-rw-r--r--src/modules/editor/scripteditor.h200
-rw-r--r--src/modules/eventeditor/Makefile.am21
-rw-r--r--src/modules/eventeditor/eventeditor.cpp536
-rw-r--r--src/modules/eventeditor/eventeditor.h120
-rw-r--r--src/modules/eventeditor/libkvieventeditor.cpp88
-rw-r--r--src/modules/file/Makefile.am18
-rw-r--r--src/modules/file/libkvifile.cpp1260
-rw-r--r--src/modules/filetransferwindow/Makefile.am22
-rw-r--r--src/modules/filetransferwindow/caps/Makefile.am9
-rw-r--r--src/modules/filetransferwindow/caps/filetransferwindow0
-rw-r--r--src/modules/filetransferwindow/filetransferwindow.cpp768
-rw-r--r--src/modules/filetransferwindow/filetransferwindow.h111
-rw-r--r--src/modules/filetransferwindow/libkvifiletransferwindow.cpp161
-rw-r--r--src/modules/help/Makefile.am22
-rw-r--r--src/modules/help/helpwidget.cpp154
-rw-r--r--src/modules/help/helpwidget.h61
-rw-r--r--src/modules/help/helpwindow.cpp329
-rw-r--r--src/modules/help/helpwindow.h75
-rwxr-xr-xsrc/modules/help/index.cpp854
-rwxr-xr-xsrc/modules/help/index.h124
-rw-r--r--src/modules/help/libkvihelp.cpp236
-rw-r--r--src/modules/http/Makefile.am26
-rw-r--r--src/modules/http/httpfiletransfer.cpp489
-rw-r--r--src/modules/http/httpfiletransfer.h104
-rw-r--r--src/modules/http/kvi_httpicons.pngbin0 -> 19630 bytes
-rw-r--r--src/modules/http/libkvihttp.cpp324
-rw-r--r--src/modules/ident/Makefile.am20
-rw-r--r--src/modules/ident/libkviident.cpp615
-rw-r--r--src/modules/ident/libkviident.h86
-rw-r--r--src/modules/iograph/Makefile.am20
-rw-r--r--src/modules/iograph/libkviiograph.cpp297
-rw-r--r--src/modules/iograph/libkviiograph.h55
-rw-r--r--src/modules/lamerizer/Makefile.am27
-rw-r--r--src/modules/lamerizer/lamerizer1
-rw-r--r--src/modules/lamerizer/libkvilamerizer.cpp279
-rw-r--r--src/modules/lamerizer/libkvilamerizer.h47
-rw-r--r--src/modules/links/Makefile.am20
-rw-r--r--src/modules/links/libkvilinks.cpp116
-rw-r--r--src/modules/links/linkswindow.cpp472
-rw-r--r--src/modules/links/linkswindow.h89
-rw-r--r--src/modules/list/Makefile.am20
-rw-r--r--src/modules/list/libkvilist.cpp101
-rw-r--r--src/modules/list/listwindow.cpp535
-rw-r--r--src/modules/list/listwindow.h122
-rw-r--r--src/modules/log/Makefile.am18
-rw-r--r--src/modules/log/libkvilog.cpp309
-rw-r--r--src/modules/logview/Makefile.am23
-rw-r--r--src/modules/logview/caps/Makefile.am9
-rw-r--r--src/modules/logview/caps/logview0
-rw-r--r--src/modules/logview/libkvilogview.cpp170
-rw-r--r--src/modules/logview/logviewmdiwindow.cpp477
-rw-r--r--src/modules/logview/logviewmdiwindow.h125
-rw-r--r--src/modules/logview/logviewwidget.cpp76
-rw-r--r--src/modules/logview/logviewwidget.h86
-rw-r--r--src/modules/mask/Makefile.am18
-rw-r--r--src/modules/mask/libkvimask.cpp201
-rw-r--r--src/modules/math/Makefile.am18
-rw-r--r--src/modules/math/libkvimath.cpp475
-rw-r--r--src/modules/mediaplayer/Makefile.am36
-rw-r--r--src/modules/mediaplayer/libkvimediaplayer.cpp1751
-rw-r--r--src/modules/mediaplayer/mp_amarokinterface.cpp189
-rw-r--r--src/modules/mediaplayer/mp_amarokinterface.h76
-rw-r--r--src/modules/mediaplayer/mp_amipinterface.cpp400
-rw-r--r--src/modules/mediaplayer/mp_amipinterface.h58
-rw-r--r--src/modules/mediaplayer/mp_dcopinterface.cpp224
-rw-r--r--src/modules/mediaplayer/mp_dcopinterface.h57
-rw-r--r--src/modules/mediaplayer/mp_interface.cpp277
-rw-r--r--src/modules/mediaplayer/mp_interface.h238
-rw-r--r--src/modules/mediaplayer/mp_jukinterface.cpp185
-rw-r--r--src/modules/mediaplayer/mp_jukinterface.h77
-rw-r--r--src/modules/mediaplayer/mp_mp3.cpp468
-rw-r--r--src/modules/mediaplayer/mp_mp3.h137
-rw-r--r--src/modules/mediaplayer/mp_winampinterface.cpp566
-rw-r--r--src/modules/mediaplayer/mp_winampinterface.h76
-rw-r--r--src/modules/mediaplayer/mp_xmmsinterface.cpp355
-rw-r--r--src/modules/mediaplayer/mp_xmmsinterface.h84
-rw-r--r--src/modules/mircimport/Makefile.am22
-rw-r--r--src/modules/mircimport/caps/Makefile.am9
-rw-r--r--src/modules/mircimport/caps/mircimport1
-rw-r--r--src/modules/mircimport/libkvimircimport.cpp385
-rw-r--r--src/modules/mircimport/libkvimircimport.h82
-rw-r--r--src/modules/mircimport/pics/Makefile.am9
-rw-r--r--src/modules/mircimport/pics/kvi_mircimport.pngbin0 -> 733 bytes
-rw-r--r--src/modules/my/Makefile.am20
-rw-r--r--src/modules/my/idle.cpp133
-rw-r--r--src/modules/my/idle.h84
-rw-r--r--src/modules/my/idle_mac.cpp162
-rw-r--r--src/modules/my/idle_x11.cpp113
-rw-r--r--src/modules/my/libkvimy.cpp430
-rw-r--r--src/modules/notifier/Makefile.am44
-rw-r--r--src/modules/notifier/libkvinotifier.cpp323
-rw-r--r--src/modules/notifier/libkvinotifier.kvc28
-rw-r--r--src/modules/notifier/notifiermessage.cpp107
-rw-r--r--src/modules/notifier/notifiermessage.h97
-rw-r--r--src/modules/notifier/notifiersettings.h66
-rw-r--r--src/modules/notifier/notifierwindow.cpp1427
-rw-r--r--src/modules/notifier/notifierwindow.h194
-rw-r--r--src/modules/notifier/notifierwindowbody.cpp232
-rw-r--r--src/modules/notifier/notifierwindowbody.h147
-rw-r--r--src/modules/notifier/notifierwindowborder.cpp220
-rw-r--r--src/modules/notifier/notifierwindowborder.h154
-rw-r--r--src/modules/notifier/notifierwindowprogressbar.cpp51
-rw-r--r--src/modules/notifier/notifierwindowprogressbar.h67
-rw-r--r--src/modules/notifier/notifierwindowtabs.cpp705
-rw-r--r--src/modules/notifier/notifierwindowtabs.h263
-rwxr-xr-xsrc/modules/notifier/pics/Makefile.am9
-rwxr-xr-xsrc/modules/notifier/pics/notifier_background.pngbin0 -> 4306 bytes
-rw-r--r--src/modules/notifier/pics/notifier_close.pngbin0 -> 311 bytes
-rw-r--r--src/modules/notifier/pics/notifier_down.pngbin0 -> 491 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_body_next_clicked.pngbin0 -> 630 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_body_next_off.pngbin0 -> 561 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_body_next_on.pngbin0 -> 568 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_body_prev_clicked.pngbin0 -> 599 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_body_prev_off.pngbin0 -> 520 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_body_prev_on.pngbin0 -> 535 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_body_write_clicked.pngbin0 -> 166 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_body_write_off.pngbin0 -> 171 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_body_write_on.pngbin0 -> 160 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_close_clicked.pngbin0 -> 1087 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_close_clicked_hl.pngbin0 -> 1064 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_close_out.pngbin0 -> 1248 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_close_out_hl.pngbin0 -> 1214 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_close_over.pngbin0 -> 1374 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_close_over_hl.pngbin0 -> 1338 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_tab_close_clicked.pngbin0 -> 518 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_tab_close_off.pngbin0 -> 428 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_tab_close_on.pngbin0 -> 517 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_tab_next_clicked.pngbin0 -> 809 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_tab_next_out.pngbin0 -> 828 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_tab_next_over.pngbin0 -> 870 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_tab_prev_clicked.pngbin0 -> 773 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_tab_prev_out.pngbin0 -> 827 bytes
-rw-r--r--src/modules/notifier/pics/notifier_icon_tab_prev_over.pngbin0 -> 843 bytes
-rw-r--r--src/modules/notifier/pics/notifier_left.pngbin0 -> 442 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pen.pngbin0 -> 712 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_body_dwn.pngbin0 -> 138 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_body_dwndx.pngbin0 -> 162 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_body_dwnsx.pngbin0 -> 162 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_body_dx.pngbin0 -> 136 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_body_kvirc.pngbin0 -> 2599 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_body_kvirc_dwn.pngbin0 -> 249 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_body_kvirc_sx.pngbin0 -> 172 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_body_sx.pngbin0 -> 136 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_caption_bkg.pngbin0 -> 154 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_caption_bkg_hl.pngbin0 -> 154 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_caption_dx.pngbin0 -> 196 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_caption_dx_hl.pngbin0 -> 196 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_caption_sx.pngbin0 -> 195 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_caption_sx_hl.pngbin0 -> 195 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_tab_bkg.pngbin0 -> 150 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_tab_dx.pngbin0 -> 157 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_tab_focused_bkg.pngbin0 -> 156 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_tab_focused_dx.pngbin0 -> 187 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_tab_focused_sx.pngbin0 -> 184 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_tab_sx.pngbin0 -> 157 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_tab_unfocused_bkg.pngbin0 -> 175 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_tab_unfocused_dx.pngbin0 -> 210 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_tab_unfocused_sx.pngbin0 -> 204 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_dwn.pngbin0 -> 156 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_dwn_hl.pngbin0 -> 156 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_dwndx.pngbin0 -> 193 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_dwndx_hl.pngbin0 -> 193 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_dwnsx.pngbin0 -> 196 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_dwnsx_hl.pngbin0 -> 196 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_dx.pngbin0 -> 150 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_dx_hl.pngbin0 -> 150 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_sx.pngbin0 -> 150 bytes
-rw-r--r--src/modules/notifier/pics/notifier_pix_wnd_sx_hl.pngbin0 -> 150 bytes
-rw-r--r--src/modules/notifier/pics/notifier_right.pngbin0 -> 443 bytes
-rw-r--r--src/modules/notifier/pics/notifier_up.pngbin0 -> 488 bytes
-rw-r--r--src/modules/objects/Makefile.am143
-rw-r--r--src/modules/objects/class_button.cpp178
-rw-r--r--src/modules/objects/class_button.h58
-rw-r--r--src/modules/objects/class_buttongroup.cpp87
-rw-r--r--src/modules/objects/class_buttongroup.h44
-rw-r--r--src/modules/objects/class_checkbox.cpp128
-rw-r--r--src/modules/objects/class_checkbox.h48
-rw-r--r--src/modules/objects/class_combobox.cpp368
-rw-r--r--src/modules/objects/class_combobox.h71
-rw-r--r--src/modules/objects/class_dialog.cpp89
-rw-r--r--src/modules/objects/class_dialog.h44
-rw-r--r--src/modules/objects/class_dockwindow.cpp276
-rw-r--r--src/modules/objects/class_dockwindow.h49
-rw-r--r--src/modules/objects/class_file.cpp488
-rw-r--r--src/modules/objects/class_file.h113
-rw-r--r--src/modules/objects/class_groupbox.cpp376
-rw-r--r--src/modules/objects/class_groupbox.h64
-rw-r--r--src/modules/objects/class_hbox.cpp128
-rw-r--r--src/modules/objects/class_hbox.h47
-rw-r--r--src/modules/objects/class_label.cpp409
-rw-r--r--src/modules/objects/class_label.h54
-rw-r--r--src/modules/objects/class_layout.cpp274
-rw-r--r--src/modules/objects/class_layout.h52
-rw-r--r--src/modules/objects/class_lcd.cpp180
-rw-r--r--src/modules/objects/class_lcd.h51
-rw-r--r--src/modules/objects/class_lineedit.cpp461
-rw-r--r--src/modules/objects/class_lineedit.h81
-rw-r--r--src/modules/objects/class_list.cpp392
-rw-r--r--src/modules/objects/class_list.h64
-rw-r--r--src/modules/objects/class_listbox.cpp390
-rw-r--r--src/modules/objects/class_listbox.h70
-rw-r--r--src/modules/objects/class_listview.cpp557
-rw-r--r--src/modules/objects/class_listview.h102
-rw-r--r--src/modules/objects/class_listviewitem.cpp421
-rw-r--r--src/modules/objects/class_listviewitem.h88
-rw-r--r--src/modules/objects/class_mainwindow.cpp158
-rw-r--r--src/modules/objects/class_mainwindow.h47
-rw-r--r--src/modules/objects/class_menubar.cpp76
-rw-r--r--src/modules/objects/class_menubar.h40
-rw-r--r--src/modules/objects/class_multilineedit.cpp1217
-rw-r--r--src/modules/objects/class_multilineedit.h110
-rw-r--r--src/modules/objects/class_painter.cpp1007
-rw-r--r--src/modules/objects/class_painter.h96
-rw-r--r--src/modules/objects/class_pixmap.cpp317
-rw-r--r--src/modules/objects/class_pixmap.h72
-rw-r--r--src/modules/objects/class_popupmenu.cpp361
-rw-r--r--src/modules/objects/class_popupmenu.h58
-rw-r--r--src/modules/objects/class_process.cpp317
-rw-r--r--src/modules/objects/class_process.h74
-rw-r--r--src/modules/objects/class_progressbar.cpp162
-rw-r--r--src/modules/objects/class_progressbar.h51
-rw-r--r--src/modules/objects/class_radiobutton.cpp138
-rw-r--r--src/modules/objects/class_radiobutton.h51
-rw-r--r--src/modules/objects/class_slider.cpp287
-rw-r--r--src/modules/objects/class_slider.h64
-rw-r--r--src/modules/objects/class_socket.cpp1331
-rw-r--r--src/modules/objects/class_socket.h185
-rw-r--r--src/modules/objects/class_spinbox.cpp265
-rw-r--r--src/modules/objects/class_spinbox.h64
-rw-r--r--src/modules/objects/class_tabwidget.cpp541
-rw-r--r--src/modules/objects/class_tabwidget.h61
-rw-r--r--src/modules/objects/class_tbrowser.cpp143
-rw-r--r--src/modules/objects/class_tbrowser.h52
-rw-r--r--src/modules/objects/class_toolbar.cpp156
-rw-r--r--src/modules/objects/class_toolbar.h50
-rw-r--r--src/modules/objects/class_toolbutton.cpp341
-rw-r--r--src/modules/objects/class_toolbutton.h69
-rw-r--r--src/modules/objects/class_urllabel.cpp330
-rw-r--r--src/modules/objects/class_urllabel.h64
-rw-r--r--src/modules/objects/class_vbox.cpp128
-rw-r--r--src/modules/objects/class_vbox.h45
-rw-r--r--src/modules/objects/class_widget.cpp1745
-rw-r--r--src/modules/objects/class_widget.h113
-rw-r--r--src/modules/objects/class_window.cpp158
-rw-r--r--src/modules/objects/class_window.h64
-rw-r--r--src/modules/objects/class_wizard.cpp371
-rw-r--r--src/modules/objects/class_wizard.h79
-rw-r--r--src/modules/objects/class_workspace.cpp262
-rw-r--r--src/modules/objects/class_workspace.h53
-rw-r--r--src/modules/objects/class_wrapper.cpp269
-rw-r--r--src/modules/objects/class_wrapper.h53
-rw-r--r--src/modules/objects/class_xmlreader.cpp343
-rw-r--r--src/modules/objects/class_xmlreader.h46
-rw-r--r--src/modules/objects/libkviobjects.cpp1066
-rw-r--r--src/modules/objects/object_macros.h90
-rw-r--r--src/modules/options/Makefile.am157
-rw-r--r--src/modules/options/container.cpp123
-rw-r--r--src/modules/options/container.h53
-rw-r--r--src/modules/options/dialog.cpp675
-rw-r--r--src/modules/options/dialog.h104
-rw-r--r--src/modules/options/instances.cpp3590
-rw-r--r--src/modules/options/instances.h83
-rw-r--r--src/modules/options/libkvioptions.cpp324
-rwxr-xr-xsrc/modules/options/mkcreateinstanceproc.sh441
-rw-r--r--src/modules/options/optw_antispam.cpp64
-rw-r--r--src/modules/options/optw_antispam.h47
-rw-r--r--src/modules/options/optw_avatar.cpp131
-rw-r--r--src/modules/options/optw_avatar.h45
-rw-r--r--src/modules/options/optw_away.cpp71
-rw-r--r--src/modules/options/optw_away.h46
-rw-r--r--src/modules/options/optw_connection.cpp321
-rw-r--r--src/modules/options/optw_connection.h116
-rw-r--r--src/modules/options/optw_ctcp.cpp90
-rw-r--r--src/modules/options/optw_ctcp.h41
-rw-r--r--src/modules/options/optw_ctcpfloodprotection.cpp116
-rw-r--r--src/modules/options/optw_ctcpfloodprotection.h41
-rw-r--r--src/modules/options/optw_dcc.cpp393
-rw-r--r--src/modules/options/optw_dcc.h139
-rw-r--r--src/modules/options/optw_generalopt.cpp51
-rw-r--r--src/modules/options/optw_generalopt.h39
-rw-r--r--src/modules/options/optw_highlighting.cpp128
-rw-r--r--src/modules/options/optw_highlighting.h67
-rw-r--r--src/modules/options/optw_ident.cpp37
-rw-r--r--src/modules/options/optw_ident.h28
-rw-r--r--src/modules/options/optw_identity.cpp729
-rw-r--r--src/modules/options/optw_identity.h192
-rw-r--r--src/modules/options/optw_ignore.cpp62
-rw-r--r--src/modules/options/optw_ignore.h47
-rw-r--r--src/modules/options/optw_input.cpp156
-rw-r--r--src/modules/options/optw_input.h61
-rw-r--r--src/modules/options/optw_interfacefeatures.cpp88
-rw-r--r--src/modules/options/optw_interfacefeatures.h48
-rw-r--r--src/modules/options/optw_interfacelookglobal.cpp215
-rw-r--r--src/modules/options/optw_interfacelookglobal.h113
-rw-r--r--src/modules/options/optw_irc.cpp220
-rw-r--r--src/modules/options/optw_irc.h116
-rw-r--r--src/modules/options/optw_ircoutput.cpp94
-rw-r--r--src/modules/options/optw_ircoutput.h49
-rw-r--r--src/modules/options/optw_ircview.cpp168
-rw-r--r--src/modules/options/optw_ircview.h83
-rw-r--r--src/modules/options/optw_lag.cpp85
-rw-r--r--src/modules/options/optw_lag.h40
-rw-r--r--src/modules/options/optw_logging.cpp64
-rw-r--r--src/modules/options/optw_logging.h42
-rw-r--r--src/modules/options/optw_mediatypes.cpp262
-rw-r--r--src/modules/options/optw_mediatypes.h83
-rw-r--r--src/modules/options/optw_messages.cpp693
-rw-r--r--src/modules/options/optw_messages.h186
-rw-r--r--src/modules/options/optw_nickserv.cpp368
-rw-r--r--src/modules/options/optw_nickserv.h89
-rw-r--r--src/modules/options/optw_notify.cpp134
-rw-r--r--src/modules/options/optw_notify.h54
-rw-r--r--src/modules/options/optw_protection.cpp50
-rw-r--r--src/modules/options/optw_protection.h48
-rw-r--r--src/modules/options/optw_proxy.cpp367
-rw-r--r--src/modules/options/optw_proxy.h94
-rw-r--r--src/modules/options/optw_query.cpp115
-rw-r--r--src/modules/options/optw_query.h43
-rw-r--r--src/modules/options/optw_servers.cpp1712
-rw-r--r--src/modules/options/optw_servers.h210
-rw-r--r--src/modules/options/optw_sound.cpp310
-rw-r--r--src/modules/options/optw_sound.h94
-rw-r--r--src/modules/options/optw_ssl.cpp35
-rw-r--r--src/modules/options/optw_ssl.h29
-rw-r--r--src/modules/options/optw_taskbar.cpp255
-rw-r--r--src/modules/options/optw_taskbar.h125
-rw-r--r--src/modules/options/optw_textencoding.cpp139
-rw-r--r--src/modules/options/optw_textencoding.h50
-rw-r--r--src/modules/options/optw_texticons.cpp244
-rw-r--r--src/modules/options/optw_texticons.h105
-rw-r--r--src/modules/options/optw_theme.cpp26
-rw-r--r--src/modules/options/optw_theme.h30
-rw-r--r--src/modules/options/optw_tools.cpp50
-rw-r--r--src/modules/options/optw_tools.h46
-rw-r--r--src/modules/options/optw_topiclabel.cpp43
-rw-r--r--src/modules/options/optw_topiclabel.h41
-rw-r--r--src/modules/options/optw_transport.cpp33
-rw-r--r--src/modules/options/optw_transport.h29
-rw-r--r--src/modules/options/optw_tray.cpp91
-rw-r--r--src/modules/options/optw_tray.h50
-rw-r--r--src/modules/options/optw_uparser.cpp62
-rw-r--r--src/modules/options/optw_uparser.h40
-rw-r--r--src/modules/options/optw_urlhandlers.cpp127
-rw-r--r--src/modules/options/optw_urlhandlers.h52
-rw-r--r--src/modules/options/optw_userlist.cpp245
-rw-r--r--src/modules/options/optw_userlist.h114
-rw-r--r--src/modules/perl/Makefile.am18
-rw-r--r--src/modules/perl/libkviperl.cpp600
-rw-r--r--src/modules/perlcore/KVIrc.xs139
-rw-r--r--src/modules/perlcore/Makefile.am23
-rw-r--r--src/modules/perlcore/libkviperlcore.cpp414
-rw-r--r--src/modules/perlcore/perlcoreinterface.h59
-rw-r--r--src/modules/perlcore/ppport.h540
-rw-r--r--src/modules/perlcore/typemap313
-rw-r--r--src/modules/perlcore/xs.inc277
-rw-r--r--src/modules/popupeditor/Makefile.am17
-rw-r--r--src/modules/popupeditor/libkvipopupeditor.cpp88
-rw-r--r--src/modules/popupeditor/popupeditor.cpp1433
-rw-r--r--src/modules/popupeditor/popupeditor.h206
-rw-r--r--src/modules/raweditor/Makefile.am17
-rw-r--r--src/modules/raweditor/libkviraweditor.cpp87
-rw-r--r--src/modules/raweditor/raweditor.cpp563
-rw-r--r--src/modules/raweditor/raweditor.h118
-rw-r--r--src/modules/regchan/Makefile.am18
-rw-r--r--src/modules/regchan/libkviregchan.cpp426
-rw-r--r--src/modules/reguser/Makefile.am25
-rw-r--r--src/modules/reguser/dialog.cpp903
-rw-r--r--src/modules/reguser/dialog.h148
-rw-r--r--src/modules/reguser/edituser.cpp781
-rw-r--r--src/modules/reguser/edituser.h152
-rw-r--r--src/modules/reguser/libkvireguser.cpp1239
-rw-r--r--src/modules/reguser/wizard.cpp464
-rw-r--r--src/modules/reguser/wizard.h89
-rw-r--r--src/modules/rijndael/Makefile.am23
-rw-r--r--src/modules/rijndael/ablowfish.cpp632
-rw-r--r--src/modules/rijndael/ablowfish.h141
-rw-r--r--src/modules/rijndael/caps/Makefile.am9
-rw-r--r--src/modules/rijndael/caps/rijndael1
-rw-r--r--src/modules/rijndael/libkvirijndael.cpp853
-rw-r--r--src/modules/rijndael/libkvirijndael.h169
-rw-r--r--src/modules/rijndael/rijndael.cpp1626
-rw-r--r--src/modules/rijndael/rijndael.h153
-rw-r--r--src/modules/setup/Makefile.am26
-rw-r--r--src/modules/setup/libkvisetup.cpp158
-rw-r--r--src/modules/setup/setupwizard.cpp1132
-rw-r--r--src/modules/setup/setupwizard.h164
-rw-r--r--src/modules/sharedfile/Makefile.am18
-rw-r--r--src/modules/sharedfile/libkvisharedfile.cpp281
-rw-r--r--src/modules/sharedfileswindow/Makefile.am22
-rw-r--r--src/modules/sharedfileswindow/caps/Makefile.am9
-rw-r--r--src/modules/sharedfileswindow/caps/sharedfileswindow0
-rw-r--r--src/modules/sharedfileswindow/libkvisharedfileswindow.cpp158
-rw-r--r--src/modules/sharedfileswindow/sharedfileswindow.cpp742
-rw-r--r--src/modules/sharedfileswindow/sharedfileswindow.h114
-rw-r--r--src/modules/snd/Makefile.am22
-rw-r--r--src/modules/snd/libkvisnd.cpp744
-rw-r--r--src/modules/snd/libkvisnd.h213
-rw-r--r--src/modules/socketspy/Makefile.am20
-rw-r--r--src/modules/socketspy/libkvisocketspy.cpp92
-rw-r--r--src/modules/socketspy/socketspywindow.cpp125
-rw-r--r--src/modules/socketspy/socketspywindow.h53
-rw-r--r--src/modules/spaste/Makefile.am24
-rw-r--r--src/modules/spaste/controller.cpp121
-rw-r--r--src/modules/spaste/controller.h59
-rw-r--r--src/modules/spaste/libkvispaste.cpp346
-rw-r--r--src/modules/spaste/libkvispaste.h13
-rw-r--r--src/modules/str/Makefile.am18
-rw-r--r--src/modules/str/libkvistr.cpp2330
-rw-r--r--src/modules/system/Makefile.am18
-rw-r--r--src/modules/system/libkvisystem.cpp749
-rw-r--r--src/modules/system/plugin.cpp427
-rw-r--r--src/modules/system/plugin.h80
-rw-r--r--src/modules/term/Makefile.am21
-rw-r--r--src/modules/term/libkviterm.cpp167
-rw-r--r--src/modules/term/termwidget.cpp179
-rw-r--r--src/modules/term/termwidget.h72
-rw-r--r--src/modules/term/termwindow.cpp84
-rw-r--r--src/modules/term/termwindow.h54
-rw-r--r--src/modules/texticons/Makefile.am18
-rw-r--r--src/modules/texticons/libkvitexticons.cpp161
-rw-r--r--src/modules/theme/Makefile.am36
-rw-r--r--src/modules/theme/libkvitheme.cpp193
-rw-r--r--src/modules/theme/managementdialog.cpp459
-rw-r--r--src/modules/theme/managementdialog.h109
-rw-r--r--src/modules/theme/packthemedialog.cpp489
-rw-r--r--src/modules/theme/packthemedialog.h66
-rw-r--r--src/modules/theme/savethemedialog.cpp301
-rw-r--r--src/modules/theme/savethemedialog.h71
-rw-r--r--src/modules/theme/themefunctions.cpp396
-rw-r--r--src/modules/theme/themefunctions.h54
-rw-r--r--src/modules/tip/Makefile.am30
-rw-r--r--src/modules/tip/kvi_tip.pngbin0 -> 2590 bytes
-rw-r--r--src/modules/tip/libkvitip.cpp309
-rw-r--r--src/modules/tip/libkvitip.h71
-rw-r--r--src/modules/tip/libkvitip.kvc28
-rw-r--r--src/modules/tip/libkvitip_cs.kvc29
-rw-r--r--src/modules/tip/libkvitip_it.kvc28
-rw-r--r--src/modules/tip/libkvitip_ru.kvc29
-rw-r--r--src/modules/tmphighlight/Makefile.am22
-rw-r--r--src/modules/tmphighlight/libkvitmphighlight.cpp174
-rw-r--r--src/modules/toolbar/Makefile.am18
-rw-r--r--src/modules/toolbar/libkvitoolbar.cpp602
-rw-r--r--src/modules/toolbareditor/Makefile.am20
-rw-r--r--src/modules/toolbareditor/libkvitoolbareditor.cpp96
-rw-r--r--src/modules/toolbareditor/toolbareditor.cpp537
-rw-r--r--src/modules/toolbareditor/toolbareditor.h119
-rw-r--r--src/modules/torrent/Makefile.am30
-rw-r--r--src/modules/torrent/libkvitorrent.cpp904
-rw-r--r--src/modules/torrent/tc_interface.cpp31
-rw-r--r--src/modules/torrent/tc_interface.h164
-rw-r--r--src/modules/torrent/tc_ktorrentdcopinterface.cpp500
-rw-r--r--src/modules/torrent/tc_ktorrentdcopinterface.h131
-rw-r--r--src/modules/torrent/tc_statusbarapplet.cpp69
-rw-r--r--src/modules/torrent/tc_statusbarapplet.h26
-rw-r--r--src/modules/url/Makefile.am23
-rw-r--r--src/modules/url/caps/Makefile.am9
-rw-r--r--src/modules/url/caps/url0
-rw-r--r--src/modules/url/icons.h554
-rw-r--r--src/modules/url/libkviurl.cpp910
-rw-r--r--src/modules/url/libkviurl.h144
-rw-r--r--src/modules/window/Makefile.am21
-rw-r--r--src/modules/window/libkviwindow.cpp1547
-rw-r--r--src/modules/window/userwindow.cpp107
-rw-r--r--src/modules/window/userwindow.h48
558 files changed, 119961 insertions, 0 deletions
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
new file mode 100644
index 00000000..267a89ef
--- /dev/null
+++ b/src/modules/Makefile.am
@@ -0,0 +1,61 @@
+SUBDIRS = about \
+ action \
+ actioneditor \
+ addon \
+ aliaseditor \
+ avatar \
+ chan \
+ channelsjoin \
+ clock \
+ codetester \
+ config \
+ context \
+ dcc \
+ dialog \
+ editor \
+ eventeditor \
+ file \
+ filetransferwindow \
+ dockwidget \
+ help \
+ http \
+ ident \
+ iograph \
+ lamerizer \
+ links \
+ list \
+ log \
+ logview \
+ mask \
+ math \
+ mediaplayer \
+ mircimport \
+ my \
+ notifier \
+ objects \
+ options \
+ perl \
+ perlcore \
+ popupeditor \
+ raweditor \
+ regchan \
+ reguser \
+ rijndael \
+ setup \
+ sharedfile \
+ sharedfileswindow \
+ snd \
+ socketspy \
+ spaste \
+ str \
+ system \
+ term \
+ texticons \
+ theme \
+ tip \
+ tmphighlight \
+ toolbar \
+ toolbareditor \
+ torrent \
+ url \
+ window
diff --git a/src/modules/about/ENTRIES b/src/modules/about/ENTRIES
new file mode 100644
index 00000000..0e53b3da
--- /dev/null
+++ b/src/modules/about/ENTRIES
@@ -0,0 +1,259 @@
+NAME: Szymon Stefanek
+NICK: Pragma
+MAIL: pragma at kvirc dot net
+ROLE: The "Creator" of KVIrc
+ROLE: Mental work, hand work,
+ROLE: eyes consuming and coffee drinking
+TEXT: I'll check... lemme check...
+TEXT: I'll fix it tomorrow...
+TEXT: KVIrc: the client that can't make coffee
+
+NAME: Jan Wagner
+NICK: Istari
+NICK: spion
+ROLE: Webmaster, bughunter, snapshot mantainer
+ROLE: support gay^Wguy :o) and the man that gives
+ROLE: you KVIrc through IPv6.
+
+NAME: Luk De Ketelaere
+NICK: Balboy
+MAIL: balboy at kvirc dot net
+ROLE: Documentation, bug searching, public relations
+TEXT: No idea of what you're talking about... or why you need it :)
+
+NAME: Andrea Parrella
+NICK: YaP
+MAIL: yap at kvirc dot net
+ROLE: Bug hunting, plugin development, bug fixes,
+ROLE: windows porting and snapshots
+TEXT: why you haven't implemented a class like DoEverythingByYourself ? :)
+TEXT: <Pragma> a wonderful recursive function :)
+TEXT: <YaP> Damn...I knew it eheheheheh
+
+NAME: Christian Strommen
+NICK: Number1
+MAIL: number1 at realityx dot net
+ROLE: Makes sure that nobody is lazy, bug-hunter, a LOT of suggestions and maker of RealityX IRC
+TEXT: Skydiving is almost as exciting as KVIrc scripting!
+TEXT: Pragma: could you add these functions: $rubmyback() and $makecoffe() ?
+
+NAME: Olle Hällnäs
+NICK: Crocodile
+MAIL: olle at xmms dot org
+ROLE: The "open hand" for the KVIrc project.
+ROLE: Provider of the CVS service, www & ftp mirroring, bandwidth,
+ROLE: great ideas and fun while coding.
+
+NAME: Juanjo Alvarez
+NICK: Kane
+MAIL: juanjux at yahoo dot es
+ROLE: Away system, colored nicks, general programming, spanish translantation
+TEXT: Pragma: think of KVIrc as a tool for scripters... we have to left them something to do :)
+
+NAME: Krzysztof Godlewski
+NICK: Kristoff
+MAIL: kristoff at proczta dot wprost dot pl
+ROLE: Official polish beer provider
+ROLE: and plugin developer
+TEXT: echo "STOP IT" > /dev/neighbour
+TEXT: cd ./neighbour && make clean
+TEXT: Pragma...erm...bugs ? WHICH bugs ? ;))
+
+NAME: Christopher R. Gabriel
+NICK: CGabriel
+MAIL: cgabriel at linux dot it
+ROLE: The 'light' inside the GNU clouds
+ROLE: Generic (??!) official project supporter :)
+TEXT: Pragma: seems that kvirc with all its plugins is becoming a desktop environment
+TEXT: echo espresso > /dev/coffee
+TEXT: Pragma: you reached the user limit. WTF!
+
+NAME: Andrew Frolov
+NICK: Drosha@Undernet
+ROLE: Beta testing
+ROLE: Ideator of www.kvirc.org
+TEXT: This free project is better that shareware
+TEXT: mIrc for windows even in alpha stage
+
+NAME: Ted Podgurski
+NICK: alch3m1st
+MAIL: tedp at toocool dot com
+ROLE: Test scripter, bug hunting
+ROLE: ideator & creator of the first www.kvirc.net
+TEXT: whassup ?
+
+NAME: RAD Kade 1
+NICK: RADKade1
+ROLE: Debugging an improvements
+TEXT: I'm just *really* good at doing things
+TEXT: when I have no idea of what I'm actually doing
+
+NAME: Fritz Elfert
+NICK: KNFritz@OpenProjects
+ROLE: Improvements of KVIrc code and of my linux knowledge
+ROLE: I like to think him as a 'spiritual guide'... :D
+
+NAME: Charles Samuels
+NICK: Njaard
+MAIL: charles at altair dot dhs dot org
+ROLE: The KDE man! Making sure that KVirc has a reason to have a K in the beginning
+TEXT: Could I please make KVirc a pure KDE application today?? Pleeease...
+
+NAME: BuTi
+NICK: BuTi@OpenProjects
+MAIL: buti at geocities dot com
+ROLE: Some "tiny" pieces of code
+
+NAME: Nick Betcher
+NICK: Error403
+MAIL: nbetcher at real-time dot com
+TEXT: &lt;Error403&gt; Number1: I imagined you looking crazy :)
+TEXT: "&lt;NumeroUno&gt; I was drunk
+
+NAME: Orn E. Hansen
+NICK: oehansen
+MAIL: oe.hansen at gamma dot telenordia dot se
+ROLE: The official C++ manual and plugin developer
+TEXT: prepare yourselves..
+TEXT: #include <iostream.h>
+TEXT: class testing {...
+TEXT: <oehansen> I must admit, I'm getting confused :-)
+TEXT: <Pragma> Me too , at this point :)
+
+NAME: Giovanni Ferri
+NICK: marl
+MAIL: giovanni at fonderiadigitale dot it
+ROLE: Bug hunter, ideas source :)
+TEXT: buy a pigeon traveller and pass dcc transfers to him
+
+NAME: Anodine
+NICK: [Anodine]
+ROLE: Various funky improvements
+TEXT: I can program anything I set my mind to!
+
+NAME: Paul Boehm
+NICK: infected
+ROLE: Beta testing, language structure improvements
+TEXT: ...it's enough for 100 IPs per meter
+TEXT: on earth, so every lightswitch can have
+TEXT: its own IP...then you telnet to your lightswitch
+TEXT: and turn it off!
+
+NAME: munehiro
+NICK: munehiro
+ROLE: Italian translations, code improvements and many useful suggestions
+
+NAME: Eva Schaller
+NICK: Penny
+ROLE: Italian translation, bug hunting, moral support :))))
+TEXT: KVirc ? Ah! Il dinosauro...
+
+NAME: Christoph Thielecke
+NICK: Crissi
+ROLE: German translation, bug hunting, new ideas
+ROLE: Some scripting, Code improvements + new code ;)
+TEXT: Pragma: Short question...
+
+NAME: Triskelios
+NICK: Triskelios
+MAIL: trisk-kvirc at quasarnet dot org
+ROLE: Breaking everything, and correcting grammar when there isn't anything left to break
+ROLE: Also, listening to Aeri's requests and getting about half of them done...
+TEXT: Hey, it's not my responsibility to find a funny quote of myself ^_~
+
+NAME: Du&#353;an Hok&#367;v
+NICK: Hunterz
+MAIL: dusan at mirc dot cz
+ROLE: Czech translation
+
+NAME: Thilo Shulz
+NICK: Thilo
+ROLE: Bugtracking and constant user support on #kvirc
+
+NAME: Iacopo Palazzi
+NICK: Iakko@IrcNet
+MAIL: iakko at omnikron dot net
+ROLE: Various code patches, ideas and bug hunting
+
+NAME: Thomas Kalla
+NICK: |Tom|@IrcNet
+ROLE: MacOSX porting
+
+NAME: Valeriy Girchenko
+ROLE: Russian translation
+
+NAME: José Melo
+NICK: Ze_M
+ROLE: Portuguese translation, default script patches and Mandriva (MDE) packager.
+
+NAME: Adilson Gonçalves Soares Junior
+NICK: CaBiDe
+MAIL: cabide at brfree dot com dot br
+ROLE: Portuguese Brasilian translation
+
+NAME: Alessandro Carbone
+NICK: Noldor
+MAIL: noldor at barmes dot org
+ROLE: Betatesting, bugfixing, exotic scripting,
+ROLE: code improvements, documentation....To be continued :-)
+TEXT: <Grifisx>...damned brackets  ...there are always too many...
+TEXT: <Noldor>....or too few..
+
+NAME: Tonino Imbesi
+NICK: Grifisx
+MAIL: grifisx at barmes dot org
+ROLE: Betatesting, bugfixing, exotic scripting,
+ROLE: code improvements, documentation....To be continued :-)
+TEXT: <Grifisx> The difference between me and you is just that
+TEXT: <Grifisx> You see things and you say "Why?" But I dream things
+TEXT: <Grifisx> that never were and I say..."Why not?"
+
+NAME: Alexey Uzhva
+NICK: Alexey
+MAIL: wizard at opendoor dot ru
+ROLE: Bugfixing, code improvements, localization improvements
+ROLE: To be continued :-)
+
+NAME: Ahinu
+NICK: Ahinu
+MAIL: ahinu at wanadoo dot fr
+ROLE: French translation, code fixes, betatesting and heavy bughunting
+
+NAME: Cle'
+NICK: Etherea
+MAIL: badgirl at virg0 dot org
+ROLE: Artist :)
+TEXT: Time makes no sense ;)
+
+NAME: Andidas
+NICK: Andidas
+ROLE: Splash screen Artist :)
+MAIL: http://www.andidas.com
+
+NAME: TheXception
+NICK: TheXception
+MAIL: kvirc@thexception.net
+ROLE: bugfixes, german tutorials
+TEXT: everything is possible, it only needs its time.
+
+NAME: Elvio Basello
+NICK: HelLViS69
+MAIL: hellvis69 at netsons dot org
+ROLE: Site (re)creator, Italian translation, scripting,
+ROLE: bughunting, Slackware packages, new ideas...
+TEXT: <HelLViS69> Blessed gdb, in the name of ritchie,
+TEXT: kermingham and rms
+
+NAME: Massimiliano Leone
+NICK: k0sm|k0
+MAIL: k0smik0 at logorroici dot org
+ROLE: Debian packages, moral support
+TEXT: One must make one's self superior to humanity, in power,
+TEXT: in loftiness of soul, in contempt. - Friedrich Nietzsche
+
+NAME: Lorenzo Marcon
+NICK: LoSko
+MAIL: http://losko.altervista.org/nglfserv/
+ROLE: Bug hunting and fixing, doc fixes, scripting (NGL File Server)
+TEXT: I don't know what I want, but I know how to get it.
+
diff --git a/src/modules/about/Makefile.am b/src/modules/about/Makefile.am
new file mode 100644
index 00000000..4192c119
--- /dev/null
+++ b/src/modules/about/Makefile.am
@@ -0,0 +1,27 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviabout.la
+
+libkviabout_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviabout_la_SOURCES = libkviabout.cpp aboutdialog.cpp
+
+libkviabout_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= aboutdialog.h
+
+EXTRA_DIST = mkabouttext.pl abouttext.inc ENTRIES
+
+abouttext:
+ perl mkabouttext.pl
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+#libkviabout.cpp: libkviabout.moc
+aboutdialog.cpp: aboutdialog.moc
diff --git a/src/modules/about/aboutdialog.cpp b/src/modules/about/aboutdialog.cpp
new file mode 100644
index 00000000..4d13d98f
--- /dev/null
+++ b/src/modules/about/aboutdialog.cpp
@@ -0,0 +1,166 @@
+//=============================================================================
+//
+// 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) 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 "aboutdialog.h"
+
+#include "kvi_defaults.h"
+
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_fileutils.h"
+#include "kvi_sourcesdate.h"
+
+#include <qwidget.h>
+#include <qlayout.h>
+#include <kvi_tal_textedit.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qevent.h>
+
+extern KviAboutDialog * g_pAboutDialog;
+/*
+"<font color=\"#FFFF00\"><b>KVIrc public releases :</b></font><br>\n" \
+"<br>\n" \
+"<font color=\"#FF0000\">0.9.0</font><br>\n" \
+"<font size=\"2\" color=\"#808080\">Release date: 25.01.1999</font><br>\n" \
+"<br>\n" \
+"<font color=\"#FF0000\">1.0.0 'Millennium'</font><br>\n" \
+"<font size=\"2\">\"The net in your hands\"</font><br>\n" \
+"<font size=\"2\" color=\"#808080\">Release date: 21.12.1999</font><br>\n" \
+"<br>\n" \
+"<font color=\"#FF0000\">2.0.0 'Phoenix'</font><br>\n" \
+"<font size=\"2\">\"The client that can't make coffee\"</font><br>\n" \
+"<font size=\"2\" color=\"#808080\">Release date: 30.05.2000</font><br>\n" \
+"<br>\n" \
+"<font color=\"#FF0000\">2.1.0 'Dark Star'</font><br>\n" \
+"<font size=\"2\">\"The client that can't make coffee\"</font><br>\n" \
+"<font size=\"2\" color=\"#808080\">Release date: 30.01.2001</font><br>\n" \
+"<br>\n" \
+"<font color=\"#FF0000\">2.1.1 'Monolith'</font><br>\n" \
+"<font size=\"2\">\"A breath of fresh net\"</font><br>\n" \
+"<font size=\"2\" color=\"#808080\">Release date: 01.05.2001</font><br>\n" \
+"<br> 3.0.0-xmas build: 24-12-2001\n" \
+"3.0.0-beta1: 24-06-2002\n "
+"<font color=\"#FF0000\">3.0.0 'Avatar'</font><br>\n" \
+"<font size=\"2\">\"No slogan yet\"</font><br>\n" \
+"<font size=\"2\" color=\"#808080\">Release date: Still unknown</font><br>\n" \
+*/
+
+#include "abouttext.inc"
+
+KviAboutDialog::KviAboutDialog()
+: KviTalTabDialog(0)
+{
+ setCaption(__tr2qs_ctx("About KVIrc...","about"));
+ setOkButton(__tr2qs_ctx("Close","about"));
+
+ KviStr buffer;
+ g_pApp->findImage(buffer,"kvi_splash.png");
+
+ QPixmap pix(buffer.ptr());
+
+ QWidget * w = new QWidget(this);
+ QGridLayout * g = new QGridLayout(w,2,1,4,8);
+
+ QLabel * l = new QLabel(w);
+ l->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
+ l->setBackgroundColor(Qt::black);
+ l->setAlignment(Qt::AlignCenter);
+ l->setPixmap(pix);
+
+ g->addWidget(l,0,0);
+
+ QString aboutString= "KVIrc <b>" KVI_VERSION " '" KVI_RELEASE_NAME "'</b><br>";
+ aboutString += __tr2qs_ctx("Forged by the <b>KVIrc Development Team</b>","about");
+ aboutString += "<br>";
+ aboutString += __tr2qs_ctx("Sources date","about");
+ aboutString += ": ";
+ aboutString += KVI_SOURCES_DATE;
+
+ l = new QLabel(aboutString,w);
+ l->setAlignment(Qt::AlignCenter);
+ g->addWidget(l,1,0);
+
+ addTab(w,__tr2qs_ctx("About","about"));
+
+
+
+ w = new QWidget(this);
+ g = new QGridLayout(w,1,1,4,8);
+
+ KviTalTextEdit * v = new KviTalTextEdit(w);
+ v->setReadOnly(true);
+ g->addWidget(v,0,0);
+
+ v->setText(g_szAboutText);
+
+ addTab(w,__tr2qs_ctx("Honor && Glory","about"));
+
+
+
+ w = new QWidget(this);
+ g = new QGridLayout(w,1,1,4,8);
+
+ v = new KviTalTextEdit(w);
+ v->setReadOnly(true);
+ v->setWordWrap(KviTalTextEdit::NoWrap);
+ g->addWidget(v,0,0);
+
+ QString szLicense;
+
+ QString szLicensePath;
+ g_pApp->getGlobalKvircDirectory(szLicensePath,KviApp::License,"EULA");
+
+ 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 <pragma at kvirc dot net>","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;
+}
+
+#include "aboutdialog.moc"
diff --git a/src/modules/about/aboutdialog.h b/src/modules/about/aboutdialog.h
new file mode 100644
index 00000000..da543a19
--- /dev/null
+++ b/src/modules/about/aboutdialog.h
@@ -0,0 +1,39 @@
+#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 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_tal_tabdialog.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/abouttext.inc b/src/modules/about/abouttext.inc
new file mode 100644
index 00000000..c35fc173
--- /dev/null
+++ b/src/modules/about/abouttext.inc
@@ -0,0 +1,768 @@
+static char * g_szAboutText = "" \
+"<html>" \
+"<head>" \
+"<title>Honor and glory</title>" \
+"</head>" \
+"<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#FF0000\"><center>" \
+"<h4>" \
+"This is a partial list of the people that have " \
+"contributed in some way to the KVIrc project.<br><br>" \
+"Honor and glory to:<br>" \
+"</h4><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Szymon Stefanek</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Pragma" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"pragma at kvirc dot net" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"The \"Creator\" of KVIrc" \
+"<br>" \
+"Mental work, hand work," \
+"<br>" \
+"eyes consuming and coffee drinking" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"I'll check... lemme check...\"" \
+"<br>" \
+"\"I'll fix it tomorrow...\"" \
+"<br>" \
+"\"KVIrc: the client that can't make coffee\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Jan Wagner</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Istari" \
+", " \
+"spion" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Webmaster, bughunter, snapshot mantainer" \
+"<br>" \
+"support gay^Wguy :o) and the man that gives" \
+"<br>" \
+"you KVIrc through IPv6." \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Luk De Ketelaere</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Balboy" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"balboy at kvirc dot net" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Documentation, bug searching, public relations" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"No idea of what you're talking about... or why you need it :)\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Andrea Parrella</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"YaP" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"yap at kvirc dot net" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Bug hunting, plugin development, bug fixes," \
+"<br>" \
+"windows porting and snapshots" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"why you haven't implemented a class like DoEverythingByYourself ? :)\"" \
+"<br>" \
+"\"&lt;Pragma&gt; a wonderful recursive function :)\"" \
+"<br>" \
+"\"&lt;YaP&gt; Damn...I knew it eheheheheh\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Christian Strommen</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Number1" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"number1 at realityx dot net" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Makes sure that nobody is lazy, bug-hunter, a LOT of suggestions and maker of RealityX IRC" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"Skydiving is almost as exciting as KVIrc scripting!\"" \
+"<br>" \
+"\"Pragma: could you add these functions: $rubmyback() and $makecoffe() ?\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Olle Hällnäs</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Crocodile" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"olle at xmms dot org" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"The \"open hand\" for the KVIrc project." \
+"<br>" \
+"Provider of the CVS service, www & ftp mirroring, bandwidth," \
+"<br>" \
+"great ideas and fun while coding." \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Juanjo Alvarez</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Kane" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"juanjux at yahoo dot es" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Away system, colored nicks, general programming, spanish translantation" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"Pragma: think of KVIrc as a tool for scripters... we have to left them something to do :)\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Krzysztof Godlewski</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Kristoff" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"kristoff at proczta dot wprost dot pl" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Official polish beer provider" \
+"<br>" \
+"and plugin developer" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"echo \"STOP IT\" &gt; /dev/neighbour\"" \
+"<br>" \
+"\"cd ./neighbour && make clean\"" \
+"<br>" \
+"\"Pragma...erm...bugs ? WHICH bugs ? ;))\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Christopher R. Gabriel</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"CGabriel" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"cgabriel at linux dot it" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"The 'light' inside the GNU clouds" \
+"<br>" \
+"Generic (??!) official project supporter :)" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"Pragma: seems that kvirc with all its plugins is becoming a desktop environment\"" \
+"<br>" \
+"\"echo espresso &gt; /dev/coffee\"" \
+"<br>" \
+"\"Pragma: you reached the user limit. WTF!\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Andrew Frolov</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Drosha@Undernet" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Beta testing" \
+"<br>" \
+"Ideator of www.kvirc.org" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"This free project is better that shareware\"" \
+"<br>" \
+"\"mIrc for windows even in alpha stage\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Ted Podgurski</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"alch3m1st" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"tedp at toocool dot com" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Test scripter, bug hunting" \
+"<br>" \
+"ideator & creator of the first www.kvirc.net" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"whassup ?\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>RAD Kade 1</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"RADKade1" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Debugging an improvements" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"I'm just *really* good at doing things\"" \
+"<br>" \
+"\"when I have no idea of what I'm actually doing\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Fritz Elfert</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"KNFritz@OpenProjects" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Improvements of KVIrc code and of my linux knowledge" \
+"<br>" \
+"I like to think him as a 'spiritual guide'... :D" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Charles Samuels</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Njaard" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"charles at altair dot dhs dot org" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"The KDE man! Making sure that KVirc has a reason to have a K in the beginning" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"Could I please make KVirc a pure KDE application today?? Pleeease...\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>BuTi</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"BuTi@OpenProjects" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"buti at geocities dot com" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Some \"tiny\" pieces of code" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Nick Betcher</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Error403" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"nbetcher at real-time dot com" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"&lt;Error403&gt; Number1: I imagined you looking crazy :)\"" \
+"<br>" \
+"\"\"&lt;NumeroUno&gt; I was drunk\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Orn E. Hansen</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"oehansen" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"oe.hansen at gamma dot telenordia dot se" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"The official C++ manual and plugin developer" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"prepare yourselves..\"" \
+"<br>" \
+"\"#include &lt;iostream.h&gt;\"" \
+"<br>" \
+"\"class testing {...\"" \
+"<br>" \
+"\"&lt;oehansen&gt; I must admit, I'm getting confused :-)\"" \
+"<br>" \
+"\"&lt;Pragma&gt; Me too , at this point :)\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Giovanni Ferri</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"marl" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"giovanni at fonderiadigitale dot it" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Bug hunter, ideas source :)" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"buy a pigeon traveller and pass dcc transfers to him\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Anodine</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"[Anodine]" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Various funky improvements" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"I can program anything I set my mind to!\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Paul Boehm</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"infected" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Beta testing, language structure improvements" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"...it's enough for 100 IPs per meter\"" \
+"<br>" \
+"\"on earth, so every lightswitch can have\"" \
+"<br>" \
+"\"its own IP...then you telnet to your lightswitch\"" \
+"<br>" \
+"\"and turn it off!\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>munehiro</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"munehiro" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Italian translations, code improvements and many useful suggestions" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Eva Schaller</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Penny" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Italian translation, bug hunting, moral support :))))" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"KVirc ? Ah! Il dinosauro...\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Christoph Thielecke</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Crissi" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"German translation, bug hunting, new ideas" \
+"<br>" \
+"Some scripting, Code improvements + new code ;)" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"Pragma: Short question...\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Triskelios</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Triskelios" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"trisk-kvirc at quasarnet dot org" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Breaking everything, and correcting grammar when there isn't anything left to break" \
+"<br>" \
+"Also, listening to Aeri's requests and getting about half of them done..." \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"Hey, it's not my responsibility to find a funny quote of myself ^_~\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Du&#353;an Hok&#367;v</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Hunterz" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"dusan at mirc dot cz" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Czech translation" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Thilo Shulz</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Thilo" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Bugtracking and constant user support on #kvirc" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Iacopo Palazzi</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Iakko@IrcNet" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"iakko at omnikron dot net" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Various code patches, ideas and bug hunting" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Thomas Kalla</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"|Tom|@IrcNet" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"MacOSX porting" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Valeriy Girchenko</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Russian translation" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>José Melo</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Ze_M" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Portuguese translation, default script patches and Mandriva (MDE) packager." \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Adilson Gonçalves Soares Junior</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"CaBiDe" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"cabide at brfree dot com dot br" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Portuguese Brasilian translation" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Alessandro Carbone</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Noldor" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"noldor at barmes dot org" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Betatesting, bugfixing, exotic scripting," \
+"<br>" \
+"code improvements, documentation....To be continued :-)" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"&lt;Grifisx&gt;...damned brackets  ...there are always too many...\"" \
+"<br>" \
+"\"&lt;Noldor&gt;....or too few..\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Tonino Imbesi</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Grifisx" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"grifisx at barmes dot org" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Betatesting, bugfixing, exotic scripting," \
+"<br>" \
+"code improvements, documentation....To be continued :-)" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"&lt;Grifisx&gt; The difference between me and you is just that\"" \
+"<br>" \
+"\"&lt;Grifisx&gt; You see things and you say \"Why?\" But I dream things \"" \
+"<br>" \
+"\"&lt;Grifisx&gt; that never were and I say...\"Why not?\"\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Alexey Uzhva</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Alexey" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"wizard at opendoor dot ru" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Bugfixing, code improvements, localization improvements" \
+"<br>" \
+"To be continued :-)" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Ahinu</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Ahinu" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"ahinu at wanadoo dot fr " \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"French translation, code fixes, betatesting and heavy bughunting" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Cle'</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Etherea" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"badgirl at virg0 dot org" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Artist :)" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"Time makes no sense ;)\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Andidas</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"Andidas" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"http://www.andidas.com" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Splash screen Artist :)" \
+"</font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>TheXception</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"TheXception" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"kvirc@thexception.net" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"bugfixes, german tutorials" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"everything is possible, it only needs its time.\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Elvio Basello</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"HelLViS69" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"hellvis69 at netsons dot org" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Site (re)creator, Italian translation, scripting," \
+"<br>" \
+"bughunting, Slackware packages, new ideas..." \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"&lt;HelLViS69&gt; Blessed gdb, in the name of ritchie,\"" \
+"<br>" \
+"\"kermingham and rms\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Massimiliano Leone</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"k0sm|k0" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"k0smik0 at logorroici dot org" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Debian packages, moral support" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"One must make one's self superior to humanity, in power,\"" \
+"<br>" \
+"\"in loftiness of soul, in contempt. - Friedrich Nietzsche\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" \
+"<tr><td align=\"center\">" \
+"<font color=\"#000000\" size=\"+2\"><b>Lorenzo Marcon</b></font>" \
+"</td></tr>" \
+"<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (" \
+"LoSko" \
+")</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">" \
+"[" \
+"http://losko.altervista.org/nglfserv/" \
+"]" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#303030\">" \
+"Bug hunting and fixing, doc fixes, scripting (NGL File Server)" \
+"</font></td></tr>" \
+"<tr><td align=\"center\"><font color=\"#606060\"><i>" \
+"\"I don't know what I want, but I know how to get it.\"" \
+"</i></font></td></tr>" \
+"</table><br><br>" \
+"<br>" \
+"This list is far from being complete.<br>" \
+"A lot of more or less \"anonymous\" people have wasted their time, " \
+"eyes, bandwidth and brain resources on this project.<br>" \
+"If you're one of those, then well, this dialog is also for you :)<br>" \
+"</center><body>" \
+"</html>" \
+"";
diff --git a/src/modules/about/libkviabout.cpp b/src/modules/about/libkviabout.cpp
new file mode 100644
index 00000000..c7cb899c
--- /dev/null
+++ b/src/modules/about/libkviabout.cpp
@@ -0,0 +1,100 @@
+//=============================================================================
+//
+// File : kvi_about.cpp
+// Creation date : Tue Jul 6 1999 03:54:25 by Szymon Stefanek
+// Last major modification : Tue Dec 05 2000 06:00:00 by Christian Strmmen
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Till Bush (buti at geocities dot com)
+// Copyright (C) 1999-2005 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_module.h"
+#include "kvi_locale.h"
+
+
+#include "aboutdialog.h"
+
+KviAboutDialog * g_pAboutDialog = 0;
+
+/*
+ @doc: about.kvirc
+ @type:
+ command
+ @title:
+ about.kvirc
+ @short:
+ Shows the "about kvirc" dialog
+ @syntax:
+ about.kvirc
+ @description:
+ Shows the KVIrc "about dialog".
+ This command is exported by the "about" module.
+*/
+
+
+static bool about_kvs_command_kvirc(KviKvsModuleCommandCall *)
+{
+ if(!g_pAboutDialog)
+ {
+ g_pAboutDialog = new KviAboutDialog();
+ g_pAboutDialog->show();
+ } else {
+ g_pAboutDialog->raise();
+ }
+ return true;
+}
+
+
+// =======================================
+// init routine
+// =======================================
+
+static bool about_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"kvirc",about_kvs_command_kvirc)
+ return true;
+}
+
+static bool about_module_cleanup(KviModule *m)
+{
+ if(g_pAboutDialog)delete g_pAboutDialog;
+ g_pAboutDialog = 0;
+ return true;
+}
+
+static bool about_module_can_unload(KviModule * m)
+{
+ return (!g_pAboutDialog);
+}
+
+// =======================================
+// plugin definition structure
+// =======================================
+
+KVIRC_MODULE(
+ "KVIrc about dialog",
+ "2.0.0",
+ "Till Bush <buti@geocities.com>\n" \
+ "Szymon Stefanek <pragma at kvirc dot net>" ,
+ "Exports the /about.kvirc command\n",
+ about_module_init ,
+ about_module_can_unload,
+ 0,
+ about_module_cleanup
+)
diff --git a/src/modules/about/mkabouttext.pl b/src/modules/about/mkabouttext.pl
new file mode 100644
index 00000000..0b58a42c
--- /dev/null
+++ b/src/modules/about/mkabouttext.pl
@@ -0,0 +1,172 @@
+#!/usr/bin/perl
+
+open(TEMPLATE,"ENTRIES") or die "Can't open the ENTRIES file";
+
+$cnt = -1;
+
+while(<TEMPLATE>)
+{
+ $_ =~ s/\n//g;
+ $_ =~ s/</&lt;/g;
+ $_ =~ s/>/&gt;/g;
+
+ if(/^NAME:[ ]*/)
+ {
+ $_ =~ s/^NAME:[ ]*//;
+ $cnt++;
+ $g_names[$cnt]=$_;
+ } elsif(/^MAIL:[ ]*/)
+ {
+ $_ =~ s/^MAIL:[ ]*//;
+ $tmp = $g_mails[$cnt];
+ if($tmp ne "")
+ {
+ $tmp = "$tmp<!!!>";
+ }
+ $tmp = "$tmp$_";
+ $g_mails[$cnt] = $tmp;
+ } elsif(/^ROLE:[ ]*/)
+ {
+ $_ =~ s/^ROLE:[ ]*//;
+ $tmp = $g_roles[$cnt];
+ if($tmp ne "")
+ {
+ $tmp = "$tmp<!!!>";
+ }
+ $tmp = "$tmp$_";
+ $g_roles[$cnt] = $tmp;
+ } elsif(/^TEXT:[ ]*/)
+ {
+ $_ =~ s/^TEXT:[ ]*//;
+ $tmp = $g_texts[$cnt];
+ if($tmp ne "")
+ {
+ $tmp = "$tmp<!!!>";
+ }
+ $tmp = "$tmp$_";
+ $g_texts[$cnt] = $tmp;
+ } elsif(/^NICK:[ ]*/)
+ {
+ $_ =~ s/^NICK:[ ]*//;
+ $tmp = $g_nicks[$cnt];
+ if($tmp ne "")
+ {
+ $tmp = "$tmp<!!!>";
+ }
+ $tmp = "$tmp$_";
+ $g_nicks[$cnt] = $tmp;
+ }
+}
+
+close(TEMPLATE);
+
+sub p
+{
+ $t = $_[0];
+ $t =~ s/\"/\\\"/g;
+ $t =~ s/^[ ]*//g;
+ print OUT "\"$t\" \\\n";
+}
+
+open(OUT,">abouttext.inc") or die "Can't open abouttext.inc";
+
+print OUT "static char * g_szAboutText = \"\" \\\n";
+
+p "<html>";
+p " <head>";
+p " <title>Honor and glory</title>";
+p " </head>";
+p " <body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#FF0000\"><center>";
+
+
+p " <h4>";
+p "This is a partial list of the people that have ";
+p "contributed in some way to the KVIrc project.<br><br>";
+p "Honor and glory to:<br>";
+p " </h4><br><br>";
+
+$i = 0;
+$cnt++;
+while($i < $cnt)
+{
+ p "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">";
+ p "<tr><td align=\"center\">";
+ p "<font color=\"#000000\" size=\"+2\"><b>$g_names[$i]</b></font>";
+ p "</td></tr>";
+
+ if($g_nicks[$i] ne "")
+ {
+
+ p "<tr><td align=\"center\"><font color=\"#800020\" size=\"+2\"> (";
+ @n = split(/<!!!>/,$g_nicks[$i]);
+ $j = 0;
+ while($n[$j] ne "")
+ {
+ if($j > 0){ p ", "; }
+ p $n[$j];
+ $j++;
+ }
+ p ")</font></td></tr>";
+
+ }
+
+ if($g_mails[$i] ne "")
+ {
+ p "<tr><td align=\"center\"><font color=\"#0000FF\" size=\"+1\">";
+ @n = split(/<!!!>/,$g_mails[$i]);
+ $j = 0;
+ while($n[$j] ne "")
+ {
+ if($j > 0){ p "<br>"; }
+ p "[";
+ p $n[$j];
+ p "]";
+ $j++;
+ }
+ p "</font></td></tr>";
+ }
+
+ if($g_roles[$i] ne "")
+ {
+ p "<tr><td align=\"center\"><font color=\"#303030\">";
+ @n = split(/<!!!>/,$g_roles[$i]);
+ $j = 0;
+ while($n[$j] ne "")
+ {
+ if($j > 0){ p "<br>"; }
+ p $n[$j];
+ $j++;
+ }
+ p "</font></td></tr>";
+ }
+
+ if($g_texts[$i] ne "")
+ {
+ p "<tr><td align=\"center\"><font color=\"#606060\"><i>";
+ @n = split(/<!!!>/,$g_texts[$i]);
+ $j = 0;
+ while($n[$j] ne "")
+ {
+ if($j > 0){ p "<br>" ; }
+ p "\"$n[$j]\"";
+ $j++;
+ }
+ p "</i></font></td></tr>";
+ }
+
+ p "</table><br><br>";
+ $i++;
+}
+
+p "<br>";
+p "This list is far from being complete.<br>";
+p "A lot of more or less \"anonymous\" people have wasted their time, ";
+p "eyes, bandwidth and brain resources on this project.<br>";
+p "If you're one of those, then well, this dialog is also for you :)<br>";
+
+p " </center><body>";
+p "</html>";
+
+print OUT "\"\";\n";
+
+close(OUT);
diff --git a/src/modules/action/Makefile.am b/src/modules/action/Makefile.am
new file mode 100644
index 00000000..2015e908
--- /dev/null
+++ b/src/modules/action/Makefile.am
@@ -0,0 +1,17 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviaction.la
+
+libkviaction_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviaction_la_SOURCES = libkviaction.cpp
+
+libkviaction_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+#noinst_HEADERS= actiondialog.h
+
diff --git a/src/modules/action/libkviaction.cpp b/src/modules/action/libkviaction.cpp
new file mode 100644
index 00000000..daf84699
--- /dev/null
+++ b/src/modules/action/libkviaction.cpp
@@ -0,0 +1,533 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// File : libkviaction.cpp
+// Creation date : Tue 7 Dec 00:05:59 2002 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2004-2005 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_module.h"
+#include "kvi_action.h"
+#include "kvi_actionmanager.h"
+#include "kvi_locale.h"
+#include "kvi_qstring.h"
+#include "kvi_parameterlist.h"
+#include "kvi_cmdformatter.h"
+#include "kvi_qstring.h"
+#include "kvi_error.h"
+#include "kvi_out.h"
+#include "kvi_iconmanager.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_kvs_useraction.h"
+#include "kvi_kvs_script.h"
+
+/*
+ @doc: action.list
+ @type:
+ command
+ @title:
+ action.list
+ @short:
+ Lists the available actions
+ @syntax:
+ action.list
+ @description:
+ Lists the currently defined actions: nothing more, nothing less.
+*/
+
+static bool action_kvs_cmd_list(KviKvsModuleCommandCall * c)
+{
+ KviWindow * pOut = c->window();
+
+ KviPointerHashTableIterator<QString,KviAction> it(*(KviActionManager::instance()->actions()));
+ while(KviAction * a = it.current())
+ {
+ if(a->isKviUserActionNeverOverrideThis())
+ pOut->output(KVI_OUT_VERBOSE,__tr2qs("%cCore action: %Q"),KVI_TEXT_BOLD,&(a->name()));
+ else
+ pOut->output(KVI_OUT_VERBOSE,__tr2qs("%cUser action: %Q"),KVI_TEXT_BOLD,&(a->name()));
+ pOut->output(KVI_OUT_VERBOSE,__tr2qs("Label: %Q"),&(a->visibleName()));
+ pOut->output(KVI_OUT_VERBOSE,__tr2qs("Category: %Q"),&(a->category()->visibleName()));
+ pOut->output(KVI_OUT_VERBOSE,__tr2qs("Description: %Q"),&(a->description()));
+ pOut->output(KVI_OUT_VERBOSE," "); // spacer
+ ++it;
+ }
+ return true;
+}
+
+/*
+ @doc: action.trigger
+ @type:
+ command
+ @title:
+ action.trigger
+ @short:
+ Triggers an action
+ @syntax:
+ action.trigger [-q] <name:string>
+ @switches:
+ !sw: -q | --quiet
+ Run in quiet mode (do not print any warnings)
+ @description:
+ Triggers the action specified by <name>, if that action exists and is enabled.
+ If the -q switch is specified the command runs in quiet mode and
+ does not print warnings if the action is not defined or disabled.
+ @examples:
+ [example]
+ action.trigger connect
+ [/example]
+*/
+
+static bool action_kvs_cmd_trigger(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviAction * a = KviActionManager::instance()->getAction(szName);
+ if(a)
+ {
+ if(a->isEnabled())
+ {
+ a->activate();
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The action \"%1\" is disabled").arg(szName));
+ }
+ } else {
+ c->warning(__tr2qs("The action \"%1\" does not exist").arg(szName));
+ }
+
+ return true;
+}
+
+/*
+ @doc: action.enable
+ @type:
+ command
+ @title:
+ action.enable
+ @short:
+ Enables an action
+ @syntax:
+ action.enable [-q] <name:string>
+ @switches:
+ !sw: -q | --quiet
+ Run quietly, do not print any warnings
+ @description:
+ Enables the action specified by <name>, if that action exists.
+ If the action was previously enabled then this command does nothing.
+ otherwise all the toolbar buttons and menu items belonging to this
+ action will get enabled.[br]
+ Since [cmd]action.create[/cmd] command allows specifying contexts
+ for actions and the action engine is able to enable/disable the actions
+ automatically on certain events you will probably never need to use this command.
+ If the -q switch is specified the command runs in quiet mode and
+ does not print warnings if the action is not defined.
+ @seealso:
+ [cmd]action.disable[/cmd]
+*/
+
+static bool action_kvs_cmd_enable(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviAction * a = KviActionManager::instance()->getAction(szName);
+ if(a)
+ {
+ if(!a->isEnabled())a->setEnabled(true);
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The action \"%1\" does not exist").arg(szName));
+ }
+
+ return true;
+}
+
+/*
+ @doc: action.disable
+ @type:
+ command
+ @title:
+ action.disable
+ @short:
+ Disables an action
+ @syntax:
+ action.disable [-q] [-f] <name:string>
+ @switches:
+ !sw: -q | --quiet
+ Run quietly, do not print any warnings
+ @description:
+ Disables the action specified by <name>, if that action exists.
+ If the action was previously disabled then this command does nothing.
+ otherwise all the toolbar buttons and menu items belonging to this
+ action will get disabled.[br]
+ Since [cmd]action.create[/cmd] command allows specifying contexts
+ for actions and the action engine is able to enable/disable the actions
+ automatically on certain events you will probably never need to use this command.
+ For the same reason the action may get automatically re-enabled when
+ one of the enabling events specified at [cmd]action.create[/cmd] time happens.
+ If the -q switch is specified the command runs in quiet mode and
+ does not print warnings if the action is not defined.
+ @seealso:
+ [cmd]action.enable[/cmd]
+*/
+
+static bool action_kvs_cmd_disable(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviAction * a = KviActionManager::instance()->getAction(szName);
+ if(a)
+ {
+ if(a->isEnabled())a->setEnabled(false);
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The action \"%1\" does not exist").arg(szName));
+ }
+
+ return true;
+}
+
+/*
+ @doc: action.destroy
+ @type:
+ command
+ @title:
+ action.destroy
+ @short:
+ Destroy an action
+ @syntax:
+ action.destroy [-q] <name:string>
+ @switches:
+ !sw: -q | --quiet
+ Run quietly, do not print any warnings
+ @description:
+ Destroys the action specified by <name>, if that action exists.[br]
+ Destroying an action will remove it from any toolbar or popup.[br]
+ If the -q switch is specified the command runs in quiet mode and
+ does not print warnings if the action is not defined.
+ Please note that you CAN'T destroy core actions, you can destroy
+ only script actions that have been defined by the user (or other scripts).
+ @seealso:
+ # this will trigger a warning and NOT work
+ action.destroy connect
+*/
+
+static bool action_kvs_cmd_destroy(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviAction * a = KviActionManager::instance()->getAction(szName);
+ if(a)
+ {
+ if(a->isKviUserActionNeverOverrideThis())
+ {
+ a->suicide();
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The action \"%1\" is a core action and cannot be destroyed").arg(szName));
+ }
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The action \"%1\" does not exist").arg(szName));
+ }
+
+ return true;
+}
+
+/*
+ @doc: action.create
+ @type:
+ command
+ @title:
+ action.create
+ @short:
+ Defines a new action
+ @syntax:
+ action.create [-i] [-c] [-l] [-w=<window_types:string>] [-s] [-t=<category:string>] (<name:string>,<visible label:string>,<description:string>,<big_icon_id:string>[,<small_icon_id:string>])
+ {
+ <action body>
+ }
+ @switches:
+ !sw: -i | --bind-to-context
+ Specifies that the action needs an IRC context to be executed.
+ When the current window does not belong to an IRC context
+ the action is automatically disabled
+
+ !sw: -c | --bind-to-connection
+ Specifies that the action needs an IRC connection to be executed.
+ When the current window has no associated IRC connection
+ the action is automatically disabled.
+ This switch implies -i.
+
+ !sw: -l | --enable-at-login
+ Specifies that the action needs to be enabled at login time, that is
+ when a link to the server has been estabilished but the login
+ operations haven't been carried out yet (and thus there is no real IRC connection).
+ This switch requires -c to work.
+
+ !sw: -w=<window_types> | --window-types=<window_type>
+ Causes the action to be enabled only when the active window
+ is one of the specified types. <window_types> may be any combination
+ of the letters 'q' (query), 'c' (channel), 'x' (console), 'd' (dccchat).
+ If this switch is omitted then the action is enabled in all the windows.[br]
+
+ !sw: -s | --selected-only
+ Specifies that the action will be activated only if the active window
+ has selected users in the userlist. This switch requires -w with a combination
+ of flags 'q','c' and 'x' (it doesn't work for dcc chat).
+
+ !sw: -t=<category> | --category=<category>
+ Causes the action to belong to the specified category.
+ <category> can be one of "irc","scripting","settings","gui","channel","tools" and "generic".
+ If this switch is omitted the "generic" category is automatically assumed.
+ The actions failing in the "tools" category will appear in the "Tools" KVIrc menu too.
+
+ !sw: -k=<key sequence> | --key-sequence=<key sequence>
+ Specifies that the action will be activated also by the <key sequence>
+ which is a string formed from up to four keyboard codes separated by
+ commas optionally combined with the modifiers "Alt","Ctrl","Shift" and "Meta".[br]
+ Examples of such sequences are: "Ctrl+X", "Ctrl+Alt+F" or "Ctrl+X,Alt+Space".
+ @description:
+ [p]
+ Defines a new script action.
+ [/p]
+ [p]
+ Each action has an unique <name> that must not collide with any core action
+ (i.e. don't use the "kvirc." prefix).
+ At any time you can check [cmd]action.list[/cmd] to verify that no core action
+ is already using your <name>. If the <name> was already used for a script action
+ then this action is simply replaced by the new one.
+ [/p]
+ [p]
+ Each action has an associated <visible label> that is the name meant to be presented to the user,
+ possibly even translated. This label will appear on the toolbar buttons, in the tooltips and
+ in the popup menu items. The string will be evaluated just before the actions is displayed
+ so the eventual runtime translation will fetch from the correct language catalogue.
+ [/p]
+ [p]
+ <description> is the descriptive text that will be displayed in the action choice dialog
+ (and maybe in other places).
+ The string will be evaluated just before the actions is displayed
+ so the eventual runtime translation will fetch from the correct language catalogue.
+ [/p]
+ [p]
+ <big_icon_id> is the [doc:image_id]image identifier[/doc] of the icon that will
+ appear on the toolbar buttons and in the action choice dialog.
+ [/p]
+ [p]
+ <small_icon_id> is optional and is the [doc:image_id]image identifier[/doc] of the icon
+ that will appear in the menu items. Since menu items can be also iconless then
+ this parameter is optional.
+ [/p]
+ [p]
+ <action body> is the callback code snippet that will be triggered when this action is activated
+ either by the means of [cmd]action.trigger[/cmd], a toolbar button or a menu item selection.
+ An empty <action body> causes this command to behave like [cmd]action.destoy[/cmd] <name>.
+ [/p]
+ @seealso:
+ [cmd]action.destroy[/cmd], [cmd]action.trigger[/cmd]
+ @examples:
+ [example]
+
+ [/example]
+*/
+
+static bool action_kvs_cmd_create(KviKvsModuleCallbackCommandCall * c)
+{
+ QString szName,szVisibleText,szDescription,szBigIconId,szSmallIconId;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETER_IGNORED("visible_label")
+ KVSM_PARAMETER_IGNORED("description")
+ KVSM_PARAMETER("big_icon_id",KVS_PT_NONEMPTYSTRING,0,szBigIconId)
+ KVSM_PARAMETER("small_icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szSmallIconId)
+ KVSM_PARAMETERS_END(c)
+
+ if(!(c->getParameterCode(1,szVisibleText) && c->getParameterCode(2,szDescription)))
+ {
+ c->error(__tr2qs("Internal error: call a head-shrinker"));
+ return false;
+ }
+
+ QString szCategory,szWindows,szKeySequence;
+
+ int iFlags = 0;
+
+ if(c->switches()->find('i',"bind-to-context"))iFlags |= KviAction::NeedsContext;
+ if(c->switches()->find('c',"bind-to-connection"))iFlags |= KviAction::NeedsConnection | KviAction::NeedsContext;
+ if(c->switches()->find('l',"enable-at-login"))
+ {
+ if(iFlags & KviAction::NeedsConnection)
+ iFlags |= KviAction::EnableAtLogin;
+ else
+ c->warning(__tr2qs("The switch -l requires -c"));
+ }
+ c->switches()->getAsStringIfExisting('t',"category",szCategory);
+ if(szCategory.isEmpty())szCategory = "generic";
+ c->switches()->getAsStringIfExisting('w',"window-types",szWindows);
+ if(!szWindows.isEmpty())
+ {
+ if(szWindows.find('c') != -1)iFlags |= KviAction::WindowChannel;
+ if(szWindows.find('x') != -1)iFlags |= KviAction::WindowConsole;
+ if(szWindows.find('d') != -1)iFlags |= KviAction::WindowDccChat;
+ if(szWindows.find('q') != -1)iFlags |= KviAction::WindowQuery;
+ }
+ if(c->switches()->find('s',"enable-on-selected"))
+ {
+ if(iFlags & (KviAction::WindowChannel | KviAction::WindowConsole | KviAction::WindowQuery))
+ iFlags |= KviAction::WindowOnlyIfUsersSelected;
+ else
+ c->warning(__tr2qs("The switch -s requires -w with a combination of flags 'c','x' and 'q'"));
+ }
+ c->switches()->getAsStringIfExisting('k',"key-sequence",szKeySequence);
+
+
+ KviAction * old = KviActionManager::instance()->getAction(szName);
+ if(old)
+ {
+ if(old->isKviUserActionNeverOverrideThis())
+ old->suicide();
+ else {
+ c->warning(__tr2qs("The action \"%1\" is already defined as core action and cannot be overridden").arg(szName));
+ return false;
+ }
+ }
+
+ QString szCmd = c->callback()->code();
+
+ if(szCmd.isEmpty())
+ {
+ // just killed it :)
+ return true;
+ }
+
+ int iOldFlags = iFlags;
+ iFlags = KviAction::validateFlags(iFlags);
+ if(iFlags != iOldFlags)
+ debug("action.validate has provided invalid flags: %d fixed to %d",iOldFlags,iFlags);
+
+ KviKvsUserAction * a = KviKvsUserAction::createInstance(KviActionManager::instance(),
+ szName,szCmd,szVisibleText,
+ szDescription,szCategory,szBigIconId,
+ szSmallIconId,iFlags,szKeySequence);
+
+ KviActionManager::instance()->registerAction(a);
+
+ return true;
+}
+
+/*
+ @doc: action.exists
+ @type:
+ function
+ @title:
+ $action.exists
+ @short:
+ Checks if an action is currently defined
+ @syntax:
+ <boolean> $action.exists(<name:string>)
+ @description:
+ Returns 1 if the action with the specified <name> is currently defined
+ and 0 otherwise.
+*/
+
+static bool action_kvs_fnc_exists(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("action_name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setBoolean(KviActionManager::instance()->getAction(szName) ? true : false);
+ return true;
+}
+
+/*
+ @doc: action.isEnabled
+ @type:
+ function
+ @title:
+ $action.isEnabled
+ @short:
+ Checks if an action is currently enabled.
+ @syntax:
+ <boolean> $action.isEnabled(<name:string>)
+ @description:
+ Returns 1 if the action with the specified <name> is currently enabled
+ and 0 otherwise. If the action does not exist the function returns 0.
+*/
+
+static bool action_kvs_fnc_isEnabled(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("action_name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ KviAction * a = KviActionManager::instance()->getAction(szName);
+ if(a)
+ c->returnValue()->setBoolean(a->isEnabled());
+ else
+ c->returnValue()->setBoolean(false);
+ return true;
+}
+
+
+static bool action_module_init(KviModule *m)
+{
+ // setlabel , $label , $position , move , $itempos , $itemexists , $itemtype
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"list",action_kvs_cmd_list);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"trigger",action_kvs_cmd_trigger);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"enable",action_kvs_cmd_enable);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"disable",action_kvs_cmd_disable);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"destroy",action_kvs_cmd_destroy);
+
+ KVSM_REGISTER_CALLBACK_COMMAND(m,"create",action_kvs_cmd_create);
+
+ KVSM_REGISTER_FUNCTION(m,"exists",action_kvs_fnc_exists);
+ KVSM_REGISTER_FUNCTION(m,"isEnabled",action_kvs_fnc_isEnabled);
+ return true;
+}
+
+static bool action_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "action", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Interface to the system actions",
+ action_module_init,
+ 0,
+ 0,
+ action_module_cleanup
+)
diff --git a/src/modules/actioneditor/Makefile.am b/src/modules/actioneditor/Makefile.am
new file mode 100644
index 00000000..84ce9dd7
--- /dev/null
+++ b/src/modules/actioneditor/Makefile.am
@@ -0,0 +1,21 @@
+###############################################################################
+# KVirc IRC client module Makefile - Szymon Stefanek <pragma at kvirc dot net>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviactioneditor.la
+
+libkviactioneditor_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviactioneditor_la_SOURCES = libkviactioneditor.cpp actioneditor.cpp
+nodist_libkviactioneditor_la_SOURCES = moc_actioneditor.cpp
+
+noinst_HEADERS = actioneditor.h
+libkviactioneditor_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+moc_actioneditor.cpp: actioneditor.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/actioneditor/actioneditor.cpp b/src/modules/actioneditor/actioneditor.cpp
new file mode 100644
index 00000000..cfc12932
--- /dev/null
+++ b/src/modules/actioneditor/actioneditor.cpp
@@ -0,0 +1,1009 @@
+//=============================================================================
+//
+// 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 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 "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_imagedialog.h"
+#include "kvi_config.h"
+#include "kvi_filedialog.h"
+#include "kvi_fileutils.h"
+#include "kvi_scripteditor.h"
+#include "kvi_debug.h"
+#include "kvi_app.h"
+#include "kvi_qstring.h"
+#include "kvi_kvs_aliasmanager.h"
+#include "kvi_filedialog.h"
+#include "kvi_actionmanager.h"
+#include "kvi_action.h"
+#include "kvi_kvs_useraction.h"
+#include "kvi_customtoolbarmanager.h"
+
+#include <qsplitter.h>
+#include <qlayout.h>
+#include "kvi_tal_vbox.h"
+#include <qtooltip.h>
+#include <qpushbutton.h>
+#include <qdir.h>
+#include <qmessagebox.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qtoolbutton.h>
+#include <qcheckbox.h>
+#include <qtooltip.h>
+#include <qpainter.h>
+#ifdef COMPILE_USE_QT4
+ #include <q3header.h>
+#else
+ #include <qheader.h>
+#endif
+#include <qtabwidget.h>
+#include <kvi_tal_groupbox.h>
+#include "kvi_valuelist.h"
+#include <qlabel.h>
+
+extern KviActionEditorWindow * g_pActionEditorWindow;
+
+static QString g_szLastEditedAction;
+
+#define LVI_ICON_SIZE 32
+#define LVI_BORDER 4
+#define LVI_SPACING 8
+#define LVI_MINIMUM_TEXT_WIDTH 150
+#define LVI_MINIMUM_CELL_WIDTH (LVI_MINIMUM_TEXT_WIDTH + LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER)
+
+KviActionEditorListViewItem::KviActionEditorListViewItem(KviTalListView * v,KviActionData * a)
+: KviTalListViewItem(v,"")
+{
+ m_pActionData = a;
+ m_pListView = v;
+ m_pIcon = 0;
+ setupForActionData();
+}
+
+KviActionEditorListViewItem::~KviActionEditorListViewItem()
+{
+ if(m_pIcon)delete m_pIcon;
+ delete m_pActionData;
+}
+
+void KviActionEditorListViewItem::setupForActionData()
+{
+ QString t = "<b>" + m_pActionData->m_szName + "</b>";
+ t += "<br><font color=\"#808080\" size=\"-1\">" + m_pActionData->m_szVisibleName + "</font>";
+ m_szKey = m_pActionData->m_szName.upper();
+ m_pText = new QSimpleRichText(t,m_pListView->font());
+ if(m_pIcon)delete m_pIcon;
+ QPixmap * p = g_pIconManager->getBigIcon(m_pActionData->m_szBigIcon);
+ if(p)m_pIcon = new QPixmap(*p);
+ else {
+ p = g_pIconManager->getImage("kvi_bigicon_unknown.png");
+ if(p)m_pIcon = new QPixmap(*p);
+ else m_pIcon = new QPixmap(LVI_ICON_SIZE,LVI_ICON_SIZE);
+ }
+ setup();
+}
+
+QString KviActionEditorListViewItem::key(int,bool) const
+{
+ return m_szKey;
+}
+
+void KviActionEditorListViewItem::setup()
+{
+ KviTalListViewItem::setup();
+ int iWidth = m_pListView->visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ iWidth -= LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER;
+ m_pText->setWidth(iWidth);
+ int iHeight = m_pText->height() + (2 * LVI_BORDER);
+ if(iHeight < (LVI_ICON_SIZE + (2 * LVI_BORDER)))iHeight = LVI_ICON_SIZE + (2 * LVI_BORDER);
+ setHeight(iHeight);
+}
+
+void KviActionEditorListViewItem::paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align)
+{
+ p->fillRect(QRect(0,0,width,height()),isSelected() ? cg.highlight() : cg.base());
+ p->drawPixmap(LVI_BORDER,LVI_BORDER,*m_pIcon);
+ int afterIcon = LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING;
+ int www = m_pListView->visibleWidth() - (afterIcon + LVI_BORDER);
+ m_pText->setWidth(www);
+ m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,height() - (LVI_BORDER * 2)),cg);
+}
+
+
+KviSingleActionEditor::KviSingleActionEditor(QWidget * par,KviActionEditor * ed)
+: QWidget(par)
+{
+ m_pActionEditor = ed;
+ m_pActionData = 0;
+
+ QGridLayout * g = new QGridLayout(this,3,2,0,4);
+
+ QLabel * l = new QLabel(__tr2qs("Name:"),this);
+ g->addWidget(l,0,0);
+ m_pNameEdit = new QLineEdit(this);
+ g->addWidget(m_pNameEdit,0,1);
+ QToolTip::add(m_pNameEdit,__tr2qs("Internal unique name for the action"));
+
+ l = new QLabel(__tr2qs("Label:"),this);
+ g->addWidget(l,1,0);
+ m_pVisibleNameEdit = new QLineEdit(this);
+ g->addWidget(m_pVisibleNameEdit,1,1);
+ QToolTip::add(m_pVisibleNameEdit,__tr2qs("Visible name for this action.<br>This string will be displayed to the user so it is a good idea to use $tr() here"));
+
+ QTabWidget * tw = new QTabWidget(this);
+ g->addMultiCellWidget(tw,2,2,0,1);
+
+ // code tab
+ QWidget * tab = new QWidget(tw);
+ QGridLayout * gl = new QGridLayout(tab,1,1,8,4);
+
+ m_pScriptEditor = KviScriptEditor::createInstance(tab);
+ gl->addWidget(m_pScriptEditor,0,0);
+ QToolTip::add(m_pScriptEditor,__tr2qs("Action code"));
+
+ tw->addTab(tab,__tr2qs("Code"));
+
+ // properties tab
+ tab = new QWidget(tw);
+ gl = new QGridLayout(tab,7,4,8,4);
+
+ l = new QLabel(__tr2qs("Category:"),tab);
+ gl->addWidget(l,0,0);
+ m_pCategoryCombo = new QComboBox(false,tab);
+ gl->addMultiCellWidget(m_pCategoryCombo,0,0,1,3);
+ QToolTip::add(m_pCategoryCombo,__tr2qs("Choose the category that best fits for this action"));
+
+ l = new QLabel(__tr2qs("Description:"),tab);
+ gl->addWidget(l,1,0);
+ m_pDescriptionEdit = new QLineEdit(tab);
+ gl->addMultiCellWidget(m_pDescriptionEdit,1,1,1,3);
+ QToolTip::add(m_pDescriptionEdit,__tr2qs("Visible short description for this action.<br>This string will be displayed to the user so it is a good idea to use $tr() here"));
+
+ l = new QLabel(__tr2qs("Small Icon:"),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("The small icon associated to this action.<br>" \
+ "It will appear at least in the popup menus when this action is inserted.<br>" \
+ "It should be 16x16 pixels.");
+ QToolTip::add(m_pSmallIconEdit,s);
+ QToolTip::add(m_pSmallIconButton,s);
+
+ l = new QLabel(__tr2qs("Big Icon:"),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->setUsesBigPixmap(true);
+ connect(m_pBigIconButton,SIGNAL(clicked()),this,SLOT(chooseBigIcon()));
+ gl->addMultiCellWidget(m_pBigIconButton,3,4,2,3);
+ s = __tr2qs("The big icon associated to this action.<br>" \
+ "It will appear at least in the toolbar buttons when this action is inserted.<br>" \
+ "It should be 32x32 pixels.");
+ QToolTip::add(m_pBigIconEdit,s);
+ QToolTip::add(m_pBigIconButton,s);
+
+ l = new QLabel(__tr2qs("Key Sequence:"),tab);
+ gl->addMultiCellWidget(l,4,5,0,0);
+ m_pKeySequenceEdit = new QLineEdit(tab);
+ gl->addMultiCellWidget(m_pKeySequenceEdit,4,5,1,1);
+ QToolTip::add(m_pKeySequenceEdit,__tr2qs("Optional keyboard sequence that will activate this action.<br>" \
+ "The sequence should be expressed as a string of up to four key codes separated by commas " \
+ "eventually combined with the modifiers \"Ctrl\",\"Shift\",\"Alt\" and \"Meta\".<br>" \
+ "Examples of such sequences are \"Ctrl+X\", \"Ctrl+Alt+Z\", \"Ctrl+X,Ctrl+C\" ..."));
+
+ l = new QLabel(tab);
+ gl->addMultiCellWidget(l,6,6,0,3);
+
+ gl->setColStretch(1,1);
+ gl->setRowStretch(6,1);
+
+
+ tw->addTab(tab,__tr2qs("Properties"));
+
+
+
+ // flags tab
+ tab = new QWidget(tw);
+ gl = new QGridLayout(tab,12,4,8,4);
+
+
+ m_pNeedsContextCheck = new KviStyledCheckBox(__tr2qs("Needs IRC Context"),tab);
+ connect(m_pNeedsContextCheck,SIGNAL(toggled(bool)),this,SLOT(needsContextCheckToggled(bool)));
+ QToolTip::add(m_pNeedsContextCheck,__tr2qs("Check this option if this action should be enabled only when " \
+ "the active window belongs to an irc context"));
+ gl->addMultiCellWidget(m_pNeedsContextCheck,0,0,0,3);
+
+ l = new QLabel(tab);
+ l->setMinimumWidth(40);
+ gl->addWidget(l,1,0);
+
+ m_pNeedsConnectionCheck = new KviStyledCheckBox(__tr2qs("Needs IRC Connection"),tab);
+ connect(m_pNeedsConnectionCheck,SIGNAL(toggled(bool)),this,SLOT(needsConnectionCheckToggled(bool)));
+ QToolTip::add(m_pNeedsConnectionCheck,__tr2qs("Check this option if this action should be enabled only when " \
+ "the active window has an active IRC connection"));
+ gl->addMultiCellWidget(m_pNeedsConnectionCheck,1,1,1,3);
+
+ l = new QLabel(tab);
+ l->setMinimumWidth(40);
+ gl->addWidget(l,2,1);
+
+ m_pEnableAtLoginCheck = new KviStyledCheckBox(__tr2qs("Enable at Login"),tab);
+ QToolTip::add(m_pEnableAtLoginCheck,__tr2qs("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)"));
+ gl->addMultiCellWidget(m_pEnableAtLoginCheck,2,2,2,3);
+
+ m_pSpecificWindowsCheck = new KviStyledCheckBox(__tr2qs("Enable Only in Specified Windows"),tab);
+ connect(m_pSpecificWindowsCheck,SIGNAL(toggled(bool)),this,SLOT(specificWindowsCheckToggled(bool)));
+ QToolTip::add(m_pSpecificWindowsCheck,__tr2qs("Check this option if this action should be enabled only when " \
+ "the active window is of a specified type"));
+ gl->addMultiCellWidget(m_pSpecificWindowsCheck,3,3,0,3);
+
+ m_pWindowConsoleCheck = new KviStyledCheckBox(__tr2qs("Enable in Console Windows"),tab);
+ QToolTip::add(m_pWindowConsoleCheck,__tr2qs("Check this option if this action should be enabled only when " \
+ "the active window is a console"));
+ connect(m_pWindowConsoleCheck,SIGNAL(toggled(bool)),this,SLOT(channelQueryOrConsoleWindowCheckToggled(bool)));
+ gl->addMultiCellWidget(m_pWindowConsoleCheck,4,4,1,3);
+
+ m_pConsoleOnlyIfUsersSelectedCheck = new KviStyledCheckBox(__tr2qs("Only If There Are Selected Users"),tab);
+ QToolTip::add(m_pConsoleOnlyIfUsersSelectedCheck,__tr2qs("This will enable the action only if there are " \
+ "selected users in the active window"));
+ gl->addMultiCellWidget(m_pConsoleOnlyIfUsersSelectedCheck,5,5,2,3);
+
+ m_pWindowChannelCheck = new KviStyledCheckBox(__tr2qs("Enable in Channel Windows"),tab);
+ QToolTip::add(m_pWindowChannelCheck,__tr2qs("Check this option if this action should be enabled only when " \
+ "the active window is a channel"));
+ connect(m_pWindowChannelCheck,SIGNAL(toggled(bool)),this,SLOT(channelQueryOrConsoleWindowCheckToggled(bool)));
+ gl->addMultiCellWidget(m_pWindowChannelCheck,6,6,1,3);
+
+ m_pChannelOnlyIfUsersSelectedCheck = new KviStyledCheckBox(__tr2qs("Only If There Are Selected Users"),tab);
+ QToolTip::add(m_pChannelOnlyIfUsersSelectedCheck,__tr2qs("This will enable the action only if there are " \
+ "selected users in the active window"));
+ gl->addMultiCellWidget(m_pChannelOnlyIfUsersSelectedCheck,7,7,2,3);
+
+ m_pWindowQueryCheck = new KviStyledCheckBox(__tr2qs("Enable in Query Windows"),tab);
+ QToolTip::add(m_pWindowQueryCheck,__tr2qs("Check this option if this action should be enabled only when " \
+ "the active window is a query"));
+ connect(m_pWindowQueryCheck,SIGNAL(toggled(bool)),this,SLOT(channelQueryOrConsoleWindowCheckToggled(bool)));
+ gl->addMultiCellWidget(m_pWindowQueryCheck,8,8,1,3);
+
+ m_pQueryOnlyIfUsersSelectedCheck = new KviStyledCheckBox(__tr2qs("Only If There Are Selected Users"),tab);
+ QToolTip::add(m_pQueryOnlyIfUsersSelectedCheck,__tr2qs("This will enable the action only if there are " \
+ "selected users in the active window"));
+ gl->addMultiCellWidget(m_pQueryOnlyIfUsersSelectedCheck,9,9,2,3);
+
+ m_pWindowDccChatCheck = new KviStyledCheckBox(__tr2qs("Enable in DCC Chat Windows"),tab);
+ QToolTip::add(m_pWindowDccChatCheck,__tr2qs("Check this option if this action should be enabled only when " \
+ "the active window is a dcc chat"));
+ gl->addMultiCellWidget(m_pWindowDccChatCheck,10,10,1,3);
+
+
+
+ l = new QLabel(tab);
+ gl->addMultiCellWidget(l,11,11,0,3);
+
+ gl->setColStretch(3,1);
+ gl->setRowStretch(11,1);
+
+ tw->addTab(tab,__tr2qs("Flags"));
+
+
+
+ tw->setCurrentPage(0);
+
+ g->setRowStretch(2,1);
+ g->setColStretch(1,1);
+
+
+ KviPointerHashTableIterator<QString,KviActionCategory> it(*(KviActionManager::instance()->categories()));
+ while(KviActionCategory * ac = it.current())
+ {
+ m_pCategoryCombo->insertItem(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::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;
+ QPixmap * p = g_pIconManager->getImage(s.utf8().data());
+ if(!p)return;
+ m_pSmallIconEdit->setText(s);
+ m_pSmallIconButton->setPixmap(*p);
+}
+
+void KviSingleActionEditor::chooseBigIcon()
+{
+ if(!m_pActionData)return;
+ KviImageDialog * d = new KviImageDialog(this,QString::null,KID_TYPE_ALL,KID_TYPE_FULL_PATH);
+ int ret = d->exec();
+ QString s = d->selectedImage();
+ delete d;
+ if(ret != QDialog::Accepted)return;
+ QPixmap * p = g_pIconManager->getBigIcon(s);
+ if(!p)return;
+ m_pBigIconEdit->setText(s);
+ m_pBigIconButton->setPixmap(*p);
+}
+
+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)
+ debug("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;i<m_pCategoryCombo->count();i++)
+ {
+ QString t = m_pCategoryCombo->text(i);
+ int idx = t.findRev('(');
+ QString r = t.right(t.length() - (idx + 1));
+ QString r2 = r.left(r.length() - 1);
+ r2.stripWhiteSpace();
+ if(r2 == d->m_szCategory)
+ {
+ m_pCategoryCombo->setCurrentItem(i);
+ break;
+ }
+ }
+ if(i == m_pCategoryCombo->count())
+ {
+ m_pCategoryCombo->setCurrentItem(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);
+ QPixmap * p = g_pIconManager->getImage(d->m_szSmallIcon);
+ if(p)
+ {
+ m_pSmallIconEdit->setText(d->m_szSmallIcon);
+ m_pSmallIconButton->setPixmap(*p);
+ } else {
+ m_pSmallIconEdit->setText("");
+ m_pSmallIconButton->setPixmap(QPixmap());
+ }
+ p = g_pIconManager->getImage(d->m_szBigIcon);
+ if(p)
+ {
+ m_pBigIconEdit->setText(d->m_szBigIcon);
+ m_pBigIconButton->setPixmap(*p);
+ } else {
+ m_pBigIconEdit->setText("");
+ m_pBigIconButton->setPixmap(QPixmap());
+ }
+ 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->setPixmap(QPixmap());
+ m_pSmallIconButton->setEnabled(false);
+ m_pBigIconButton->setPixmap(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.findRev(')');
+ if(idx != -1)m_pActionData->m_szCategory = szCat.left(idx);
+ else m_pActionData->m_szCategory = szCat;
+ idx = m_pActionData->m_szCategory.findRev('(');
+ 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)
+ debug("invalid action flags in KviSingleActionEditor::commit(): %d fixed to %d",uOldFlags,m_pActionData->m_uFlags);
+}
+
+
+
+
+
+
+
+
+KviActionEditorListView::KviActionEditorListView(QWidget * pParent)
+: KviTalListView(pParent)
+{
+ setSelectionMode(Extended);
+ int iWidth = visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ addColumn(__tr2qs("Action"),iWidth);
+ setSorting(0,true);
+}
+
+KviActionEditorListView::~KviActionEditorListView()
+{
+}
+
+
+void KviActionEditorListView::resizeEvent(QResizeEvent * e)
+{
+ KviTalListView::resizeEvent(e);
+ int iWidth = visibleWidth();
+ 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,1,1,2,2);
+
+#ifdef COMPILE_USE_QT4
+ m_pSplitter = new QSplitter(Qt::Horizontal,this);
+ m_pSplitter->setOpaqueResize(false);
+
+#else
+ m_pSplitter = new QSplitter(QSplitter::Horizontal,this);
+#endif
+
+ l->addWidget(m_pSplitter,0,0);
+
+
+ KviTalVBox * box = new KviTalVBox(m_pSplitter);
+ m_pListView = new KviActionEditorListView(box);
+ //m_pListView->setMultiSelection(false);
+ m_pListView->setShowSortIndicator(true);
+#ifdef COMPILE_USE_QT4
+ m_pListView->setFocusPolicy(Qt::StrongFocus);
+#else
+ m_pListView->setFocusPolicy(QWidget::StrongFocus);
+#endif
+ connect(m_pListView,SIGNAL(currentChanged(KviTalListViewItem *)),this,SLOT(currentChanged(KviTalListViewItem *)));
+
+
+ m_pNewActionButton = new QPushButton(__tr2qs("New Action"),box);
+ connect(m_pNewActionButton,SIGNAL(clicked()),this,SLOT(newAction()));
+
+ m_pDeleteActionsButton = new QPushButton(__tr2qs("Delete Actions"),box);
+ connect(m_pDeleteActionsButton,SIGNAL(clicked()),this,SLOT(deleteActions()));
+
+ m_pExportActionsButton = new QPushButton(__tr2qs("Export Actions..."),box);
+ connect(m_pExportActionsButton,SIGNAL(clicked()),this,SLOT(exportActions()));
+
+ box->setSpacing(1);
+
+ m_pSingleActionEditor = new KviSingleActionEditor(m_pSplitter,this);
+
+ KviActionEditorListViewItem * last = 0;
+ KviActionEditorListViewItem * first = 0;
+
+ KviPointerHashTableIterator<QString,KviAction> 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->bigIconString(),
+ ((KviKvsUserAction *)a)->smallIconString(),
+ a->flags(),
+ a->keySequence(),
+ 0);
+ KviActionEditorListViewItem * lvi = new KviActionEditorListViewItem(m_pListView,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_pListView->setCurrentItem(last);
+ currentChanged(last);
+ } else {
+ currentChanged(0);
+ }
+
+}
+
+KviActionEditor::~KviActionEditor()
+{
+}
+
+void KviActionEditor::exportActions()
+{
+ QString szName = QDir::homeDirPath();
+ if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR;
+ szName += "myactions.kvs";
+
+ QString szFile;
+
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose a Filename - KVIrc"),szName,QString::null,true,true,true))return;
+
+ QString szCode;
+
+ KviActionEditorListViewItem * it = (KviActionEditorListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ if(it->isSelected())
+ {
+ KviActionData * a = it->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);
+ }
+
+ it = (KviActionEditorListViewItem *)(it->nextSibling());
+ }
+
+ if(!KviFileUtils::writeFile(szFile,szCode))
+ {
+ QMessageBox::warning(this,__tr2qs("Write Failed - KVIrc"),__tr2qs("Unable to write to the actions file."),__tr2qs("OK"));
+ }
+}
+
+void KviActionEditor::deleteActions()
+{
+ KviPointerList<KviActionEditorListViewItem> l;
+ l.setAutoDelete(false);
+
+ KviActionEditorListViewItem * it = (KviActionEditorListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ if(it->isSelected())
+ l.append(it);
+
+ it = (KviActionEditorListViewItem *)(it->nextSibling());
+ }
+
+ if(l.isEmpty())return;
+
+ //if(QMessageBox::question(this,__tr2qsf("Confirm Deletion"),__tr2qsf("Do you really want to delete the selected actions ?"),__tr2qsf("Yes"),__tr2qsf("No")) != 0)
+ // return;
+
+ for(KviActionEditorListViewItem * 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("My Action"));
+ QString szVis = __tr2qs("My Action");
+ QString szDes = __tr2qs("Put here a short description of your action");
+
+ szVis.prepend("$tr(\"");
+ szVis.append("\")");
+ szDes.prepend("$tr(\"");
+ szDes.append("\")");
+
+ KviActionData * ad = new KviActionData(szName,
+ QString::null,
+ szVis,
+ szDes,
+ KviActionManager::categoryGeneric()->name(),
+ QString::null,
+ QString::null,
+ 0,
+ QString::null,
+ 0);
+
+ KviActionEditorListViewItem * lvi = new KviActionEditorListViewItem(m_pListView,ad);
+ ad->m_pItem = lvi;
+ m_pListView->setCurrentItem(lvi);
+ currentChanged(lvi);
+}
+
+bool KviActionEditor::actionExists(const QString &szName)
+{
+ KviActionEditorListViewItem * it = (KviActionEditorListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ if(it->actionData()->m_szName == szName)return true;
+ it = (KviActionEditorListViewItem *)(it->nextSibling());
+ }
+ return false;
+}
+
+
+void KviActionEditor::currentChanged(KviTalListViewItem * i)
+{
+ if(m_pSingleActionEditor->actionData())
+ {
+ m_pSingleActionEditor->commit();
+ m_pSingleActionEditor->actionData()->m_pItem->setupForActionData();
+ }
+
+ m_pListView->update();
+
+ KviActionEditorListViewItem * it = (KviActionEditorListViewItem *)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_pListView->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();
+
+ KviActionEditorListViewItem * it = (KviActionEditorListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ 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);
+
+ it = (KviActionEditorListViewItem *)(it->nextSibling());
+ }
+
+ KviCustomToolBarManager::instance()->updateVisibleToolBars();
+}
+
+
+
+KviActionEditorWindow::KviActionEditorWindow(KviFrame * lpFrm)
+: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"actioneditor",0)
+{
+ g_pActionEditorWindow = this;
+ setFixedCaption(__tr2qs("Action Editor"));
+
+ m_pEditor = new KviActionEditor(this);
+
+ m_pBase = new QWidget(this);
+ QGridLayout * g = new QGridLayout(m_pBase,1,4,4,4);
+
+ QPushButton * btn = new QPushButton(__tr2qs("OK"),m_pBase);
+ btn->setMinimumWidth(80);
+ connect(btn,SIGNAL(clicked()),this,SLOT(okClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,1);
+
+ btn = new QPushButton(__tr2qs("Apply"),m_pBase);
+ btn->setMinimumWidth(80);
+ connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,2);
+
+ btn = new QPushButton(__tr2qs("Cancel"),m_pBase);
+ btn->setMinimumWidth(80);
+ connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ g->addWidget(btn,0,3);
+
+ g->setColStretch(0,1);
+
+}
+
+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::resizeEvent(QResizeEvent *e)
+{
+ int hght = m_pBase->sizeHint().height();
+ m_pEditor->setGeometry(0,0,width(),height()- hght);
+ m_pBase->setGeometry(0,height() - hght,width(),hght);
+}
+
+
+void KviActionEditorWindow::getConfigGroupName(KviStr &szName)
+{
+ szName = "actioneditor";
+}
+
+
+void KviActionEditorWindow::saveProperties(KviConfig *cfg)
+{
+ KviWindow::saveProperties(cfg);
+ cfg->writeEntry("Splitter",m_pEditor->m_pSplitter->sizes());
+}
+
+void KviActionEditorWindow::loadProperties(KviConfig *cfg)
+{
+ int w = width();
+ KviWindow::loadProperties(cfg);
+ KviValueList<int> 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 00000000..fc112614
--- /dev/null
+++ b/src/modules/actioneditor/actioneditor.h
@@ -0,0 +1,210 @@
+#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 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 "kvi_window.h"
+
+#include <qwidget.h>
+#include "kvi_tal_listview.h"
+#include "kvi_styled_controls.h"
+
+class KviActionEditorListViewItem;
+
+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;
+ KviActionEditorListViewItem * 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,
+ KviActionEditorListViewItem * 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 QLineEdit;
+class QComboBox;
+class KviScriptEditor;
+class QToolButton;
+class QSimpleRichText;
+class QPushButton;
+
+#ifdef COMPILE_USE_QT4
+ #include <q3simplerichtext.h>
+ #define QSimpleRichText Q3SimpleRichText
+#else
+ #include <qsimplerichtext.h>
+#endif
+
+
+
+class KviActionEditorListViewItem : public KviTalListViewItem
+{
+public:
+ KviActionEditorListViewItem(KviTalListView * v,KviActionData * a);
+ ~KviActionEditorListViewItem();
+protected:
+ KviActionData * m_pActionData;
+ QSimpleRichText * m_pText;
+ QPixmap * m_pIcon;
+ KviTalListView * m_pListView;
+ 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 KviActionEditorListView : public KviTalListView
+{
+ Q_OBJECT
+public:
+ KviActionEditorListView(QWidget * pParent);
+ ~KviActionEditorListView();
+protected:
+ virtual void resizeEvent(QResizeEvent * e);
+};
+
+class KviActionEditor;
+
+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;
+ KviStyledCheckBox * m_pNeedsContextCheck;
+ KviStyledCheckBox * m_pNeedsConnectionCheck;
+ KviStyledCheckBox * m_pEnableAtLoginCheck;
+ KviStyledCheckBox * m_pSpecificWindowsCheck;
+ KviStyledCheckBox * m_pWindowConsoleCheck;
+ KviStyledCheckBox * m_pWindowChannelCheck;
+ KviStyledCheckBox * m_pWindowQueryCheck;
+ KviStyledCheckBox * m_pWindowDccChatCheck;
+ KviStyledCheckBox * m_pConsoleOnlyIfUsersSelectedCheck;
+ KviStyledCheckBox * m_pChannelOnlyIfUsersSelectedCheck;
+ KviStyledCheckBox * m_pQueryOnlyIfUsersSelectedCheck;
+public:
+ KviActionData * actionData(){ return m_pActionData; };
+ void setActionData(KviActionData * d);
+ void commit();
+protected slots:
+ void chooseSmallIcon();
+ void chooseBigIcon();
+ void needsContextCheckToggled(bool);
+ void needsConnectionCheckToggled(bool);
+ void specificWindowsCheckToggled(bool);
+ void channelQueryOrConsoleWindowCheckToggled(bool);
+};
+
+class QSplitter;
+
+class KviActionEditor : public QWidget
+{
+ friend class KviActionEditorWindow;
+ Q_OBJECT
+public:
+ KviActionEditor(QWidget * par);
+ ~KviActionEditor();
+protected:
+ KviActionEditorListView * m_pListView;
+ 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 currentChanged(KviTalListViewItem * it);
+ void newAction();
+ void deleteActions();
+ void exportActions();
+};
+
+
+class KviActionEditorWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviActionEditorWindow(KviFrame * lpFrm);
+ ~KviActionEditorWindow();
+protected:
+ KviActionEditor * m_pEditor;
+ QWidget * m_pBase;
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void getConfigGroupName(KviStr &szName);
+ virtual void saveProperties(KviConfig *);
+ virtual void loadProperties(KviConfig *);
+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
new file mode 100644
index 00000000..c2e489e5
--- /dev/null
+++ b/src/modules/actioneditor/libkviactioneditor.cpp
@@ -0,0 +1,86 @@
+//=============================================================================
+//
+// File : libkviactioneditor.cpp
+// Creation date : Tue 29 Dec 2004 02:45:59 2002 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2004 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_module.h"
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+
+#include "actioneditor.h"
+KviActionEditorWindow * g_pActionEditorWindow = 0;
+
+
+/*
+ @doc: actioneditor.open
+ @type:
+ command
+ @title:
+ actioneditor.open
+ @short:
+ Shows the action editor
+ @syntax:
+ actioneditor.open
+ @description:
+ Opens the script action editor dialog.
+*/
+
+static bool actioneditor_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ if(!g_pActionEditorWindow)
+ {
+ g_pActionEditorWindow = new KviActionEditorWindow(c->window()->frame());
+ c->window()->frame()->addWindow(g_pActionEditorWindow);
+ }
+
+ g_pActionEditorWindow->setFocus();
+ return true;
+}
+static bool actioneditor_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",actioneditor_kvs_cmd_open);
+ g_pActionEditorWindow = 0;
+ return true;
+}
+
+static bool actioneditor_module_can_unload(KviModule * m)
+{
+ return (g_pActionEditorWindow == 0);
+}
+
+static bool actioneditor_module_cleanup(KviModule *m)
+{
+ if(g_pActionEditorWindow)delete g_pActionEditorWindow;
+ g_pActionEditorWindow = 0;
+ return true;
+}
+
+KVIRC_MODULE(
+ "ActionEditor", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Editor for the script actions",
+ actioneditor_module_init,
+ actioneditor_module_can_unload,
+ 0,
+ actioneditor_module_cleanup
+)
diff --git a/src/modules/addon/Makefile.am b/src/modules/addon/Makefile.am
new file mode 100644
index 00000000..e232b8ff
--- /dev/null
+++ b/src/modules/addon/Makefile.am
@@ -0,0 +1,22 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+SUBDIRS = pics
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviaddon.la
+
+libkviaddon_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviaddon_la_SOURCES = libkviaddon.cpp managementdialog.cpp
+nodist_libkviaddon_la_SOURCES = moc_managementdialog.cpp
+
+libkviaddon_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= managementdialog.h
+
+moc_managementdialog.cpp: managementdialog.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/addon/libkviaddon.cpp b/src/modules/addon/libkviaddon.cpp
new file mode 100644
index 00000000..a7cd4b88
--- /dev/null
+++ b/src/modules/addon/libkviaddon.cpp
@@ -0,0 +1,659 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// File : libkviaddon.cpp
+// Creation date : Tue 31 Mar 01:02:12 2005 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2005 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_module.h"
+#include "kvi_kvs_scriptaddonmanager.h"
+#include "kvi_locale.h"
+#include "kvi_qstring.h"
+#include "kvi_parameterlist.h"
+#include "kvi_cmdformatter.h"
+#include "kvi_qstring.h"
+#include "kvi_error.h"
+#include "kvi_out.h"
+#include "kvi_iconmanager.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_config.h"
+#include "kvi_sourcesdate.h"
+#include "kvi_miscutils.h"
+
+#include "managementdialog.h"
+
+
+
+QRect g_rectManagementDialogGeometry(0,0,0,0);
+
+/*
+ @doc: addon.exists
+ @type:
+ function
+ @title:
+ $addon.exists
+ @short:
+ Checks if an addon is currently installed
+ @syntax:
+ <boolean> $addon.exists(<id:string>[,<version:string>])
+ @description:
+ Returns 1 if the addon with the specified <id> is currently installed
+ and 0 otherwise. If <version> is specified then any addon with
+ a version lower than <version> is ignored (so you can effectively
+ check if a greater or equal version is present).
+*/
+
+static bool addon_kvs_fnc_exists(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ QString szVersion;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETER("version",KVS_PT_STRING,KVS_PF_OPTIONAL,szVersion)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsScriptAddon * a = KviKvsScriptAddonManager::instance()->findAddon(szId);
+ if(a)
+ {
+ if(szVersion.isEmpty())
+ {
+ c->returnValue()->setBoolean(true);
+ } else {
+ c->returnValue()->setBoolean(KviMiscUtils::compareVersions(a->version(),szVersion) < 0);
+ }
+ } else {
+ c->returnValue()->setBoolean(false);
+ }
+ return true;
+}
+
+/*
+ @doc: addon.version
+ @type:
+ function
+ @title:
+ $addon.version
+ @short:
+ Returns the version of an installed addon
+ @syntax:
+ <string> $addon.version(<id:string>)
+ @description:
+ Returns the version of the currently installed addon with the
+ specified <id>. If the addon with the given <id> does not exist
+ then an empty string is returned.
+*/
+
+static bool addon_kvs_fnc_version(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsScriptAddon * a = KviKvsScriptAddonManager::instance()->findAddon(szId);
+ if(a)
+ {
+ c->returnValue()->setString(a->version());
+ } else {
+ c->returnValue()->setNothing();
+ }
+ return true;
+}
+
+/*
+ @doc: addon.list
+ @type:
+ command
+ @title:
+ addon.list
+ @short:
+ Lists the installed addons
+ @syntax:
+ addon.list
+ @description:
+ Lists the currently installed addons
+ @seealso:
+ [cmd]addon.register[/cmd]
+*/
+
+static bool addon_kvs_cmd_list(KviKvsModuleCommandCall * c)
+{
+ KviPointerHashTable<QString,KviKvsScriptAddon> * da = KviKvsScriptAddonManager::instance()->addonDict();
+
+ int cnt = 0;
+ KviPointerHashTableIterator<QString,KviKvsScriptAddon> it(*da);
+ while(KviKvsScriptAddon * a = it.current())
+ {
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("%cAddon id %Q, version %Q%c"),KVI_TEXT_BOLD,&(a->name()),&(a->version()),KVI_TEXT_BOLD);
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Name: %Q"),&(a->visibleName()));
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Description: %Q"),&(a->description()));
+
+ ++it;
+ cnt++;
+ }
+
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Total: %d addons installed"),cnt);
+ return true;
+}
+
+/*
+ @doc: addon.uninstall
+ @type:
+ command
+ @title:
+ addon.uninstall
+ @short:
+ Uninstalls an addon
+ @syntax:
+ addon.uninstall [-q] [-n] <id:string>
+ @switches:
+ !sw: -n | --no-callback
+ Doesn't call the uninstall callback but only removes the
+ registration entry.
+ !sw: -q | --quiet
+ Makes the command run quietly
+ @description:
+ Uninstalls the specified addon by executing its uninstall callback function.
+ It also removes the addon's registration entry.
+ If the -n switch is specified the the uninstall callback is not called,
+ only the registration entry is removed.
+ @seealso:
+ [cmd]addon.register[/cmd]
+*/
+
+static bool addon_kvs_cmd_uninstall(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsScriptAddon * a = KviKvsScriptAddonManager::instance()->findAddon(szName);
+ if(a)
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Uninstalling existing addon version %Q"),&(a->version()));
+
+ // uninstall the existing version
+ KviKvsScriptAddonManager::instance()->unregisterAddon(szName,c->window(),!c->switches()->find('n',"no-callback"));
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The addon \"%1\" does not exist").arg(szName));
+ }
+
+ return true;
+}
+
+/*
+ @doc: addon.configure
+ @type:
+ command
+ @title:
+ addon.configure
+ @short:
+ Executes a addon's configuration callback
+ @syntax:
+ addon.configure [-q] <id:string>
+ @switches:
+ !sw: -q | --quiet
+ Makes the command run quietly
+ @description:
+ Executes the configuration callback of the specified addon.
+ @seealso:
+ [cmd]addon.register[/cmd]
+ [cmd]addon.setconfigurecallback[/cmd]
+*/
+
+static bool addon_kvs_cmd_configure(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsScriptAddon * a = KviKvsScriptAddonManager::instance()->findAddon(szName);
+ if(a)
+ {
+ QString ss = a->configureCallbackCode();
+ if(ss.isEmpty())
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The addon \"%1\" has no configure callback set").arg(szName));
+ } else {
+ a->executeConfigureCallback(c->window());
+ }
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The addon \"%1\" does not exist").arg(szName));
+ }
+
+ return true;
+}
+
+/*
+ @doc: addon.help
+ @type:
+ command
+ @title:
+ addon.help
+ @short:
+ Executes a addon's help callback
+ @syntax:
+ addon.help [-q] <id:string>
+ @switches:
+ !sw: -q | --quiet
+ Makes the command run quietly
+ @description:
+ Executes the help callback of the specified addon.
+ It will usually display the addon's documentation in the help viewer.
+ @seealso:
+ [cmd]addon.register[/cmd]
+ [cmd]addon.sethelpcallback[/cmd]
+*/
+
+static bool addon_kvs_cmd_help(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsScriptAddon * a = KviKvsScriptAddonManager::instance()->findAddon(szName);
+ if(a)
+ {
+ QString ss = a->helpCallbackCode();
+ if(ss.isEmpty())
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The addon \"%1\" has no help callback set").arg(szName));
+ } else {
+ a->executeHelpCallback(c->window());
+ }
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The addon \"%1\" does not exist").arg(szName));
+ }
+
+ return true;
+}
+
+/*
+ @doc: addon.setconfigurecallback
+ @type:
+ command
+ @title:
+ addon.setconfigurecallback
+ @short:
+ Sets a addon's configuration callback
+ @syntax:
+ addon.setconfigurecallback [-q] (<id:string>)
+ {
+ <configure_callback>
+ }
+ @switches:
+ !sw: -q
+ Makes the command run quietly
+ @description:
+ Sets the configure callback for the specified addon.
+ The configure callback will be called by the user either by the
+ means of [cmd]addon.configure[/cmd] or by accessing the
+ proper function via GUI.
+ @seealso:
+ [cmd]addon.register[/cmd]
+ [cmd]addon.configure[/cmd]
+*/
+
+static bool addon_kvs_cmd_setconfigurecallback(KviKvsModuleCallbackCommandCall * c)
+{
+ QString szName;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsScriptAddon * a = KviKvsScriptAddonManager::instance()->findAddon(szName);
+ if(a)
+ {
+ a->setConfigureCallback(c->callback()->code());
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The addon \"%1\" does not exist").arg(szName));
+ }
+
+ return true;
+}
+
+/*
+ @doc: addon.sethelpcallback
+ @type:
+ command
+ @title:
+ addon.sethelpcallback
+ @short:
+ Sets a addon's configuration callback
+ @syntax:
+ addon.sethelpcallback(<id:string>)
+ {
+ <configure_callback>
+ }
+ @switches:
+ !sw: -q
+ Makes the command run quietly
+ @description:
+ Sets the help callback for the specified addon.
+ The help callback will be called by the user either by the
+ means of [cmd]addon.help[/cmd] or by accessing the
+ proper function via GUI. It should display some sort
+ of addon documentation, usually in the help browser.
+ @seealso:
+ [cmd]addon.register[/cmd]
+ [cmd]addon.help[/cmd]
+*/
+
+static bool addon_kvs_cmd_sethelpcallback(KviKvsModuleCallbackCommandCall * c)
+{
+ QString szName;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsScriptAddon * a = KviKvsScriptAddonManager::instance()->findAddon(szName);
+ if(a)
+ {
+ a->setHelpCallback(c->callback()->code());
+ } else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The addon \"%1\" does not exist").arg(szName));
+ }
+
+ return true;
+}
+
+/*
+ @doc: addon.register
+ @type:
+ command
+ @title:
+ addon.register
+ @short:
+ Registers a script-based addon
+ @syntax:
+ addon.register [-f] [-n] [-q] (<id:string>,<version:string>,<visible_name:string>,<description:string>,<minkvircverion:string>[,<iconid:string>])
+ {
+ <uninstall callback>
+ }
+ @switches:
+ !sw: -f | --force
+ Registers the addon even if an addon with the same <id> and
+ a higher version already exists. The usage of this flag
+ is highly discouraged (i.e. use it only for debugging purposes
+ on your own machine).
+ !sw: -n | --no-uninstall
+ Performs no uninstallation of existing versions of the addon:
+ it simply replaces the registration entry with the new data.
+ Again, do NOT use this switch if not for debugging purposes
+ and on your own machine.
+ !sw: -q | --quiet
+ Makes the command run quietly
+ @description:
+ [p]
+ Registers a script-based addon.
+ [/p]
+ [p]
+ The registration process allows to "show" the addon in the script-addon manager
+ dialog and provides a standard way for the user to manage and uninstall the addons.
+ You simply register your addon BEFORE attempting to install it.
+ [/p]
+ [p]
+ A script-based addon is a set of scripts, icons, translations and possibly
+ other data files that add functionality to the KVIrc program.
+ The script-based addons are often simply called "scripts" and
+ we will adhere to that naming in certain parts of the documentation too.
+ [/p]
+ [p]
+ Each script-based addon (a set of scripts) is identified by an UNIQUE
+ <id>. Two addons with the same <id> can't co-exist in the same
+ KVIrc installation (so be sure to choose a token characteristic enough
+ to avoid collisions with others). The <id> itself is used only for
+ identification purposes and the user will almost always see the <visible_name>
+ instead, which can contain the [fnc]$tr[/fnc] function that will handle
+ the translation for it.
+ [/p]
+ [p]
+ Each addon has also a <version> which is a string in the form x.y.z
+ where x, y and z are numbers (yes.. that's the standard major-minor-patch level
+ version numbering scheme). A <version> of 2.4.23 is greater than 2.4.3
+ even if 2.4.3 comes after when compared as a string.
+ When an addon with a greater or equal version is installed over
+ an addon with a lower version, the lower one gets uninstalled first.
+ Installing a lower version over a greater one is not possible, unless
+ the lower versioned one is uninstalled first.
+ [/p]
+ [p]
+ <description> is another, possibly translated, string that will
+ be presented to the user in the addon management dialog.
+ [/p]
+ [p]
+ <minkvircversion> is the minimum KVIrc version required for the
+ addon to run. If the version of the running KVIrc executable
+ is lower than the requested one then the command will abort with an error.
+ If you want to completly ignore the KVIrc versioning (don't do it),
+ use "0.0.0" here. If you need fine tuning on cvs features you may add also
+ the sources date tag at the end of the required version string (e.g 3.2.1.20060303).
+ [/p]
+ [p]
+ <iconid> is the [doc:image_id]image identifier[/doc] of the icon
+ that will be displayed in the addon management dialog.
+ If not specified, a default icon will be used.
+ [/p]
+ [p]
+ The <uninstall_callback> is a snippet of code that should
+ wipe out the addon from the system. It is ALWAYS a good practice
+ to write a complete uninstallation procedure (think that YOU like
+ to be able to completly uninstall a program that you don't use anymore).
+ The <uninstall_callback> will be called by KVIrc when the addon
+ uninstallation is requested, either explicitly by using the GUI or the
+ command [cmd]addon.uninstall[/cmd], or implicitly by installing
+ a newer version of the addon (upgrading).
+ [/p]
+ [p]
+ If the user security rules don't allow your addon to be installed
+ or a higher version of a addon with the same name already exists
+ the command will fail with an error (aborting your whole intallation addon).
+ If you don't want to fail with an error but handle it gracefully instead
+ then you should use [fnc]$addon.exists()[/fnc] to check if a
+ addon with the same name and a greater version already exists.
+ You can't gracefully handle security error conditions: your installation
+ will be always aborted with an error in this case.
+ [/p]
+ [p]
+ The addon can also have a configuration callback settable with [cmd]addon.setconfigurecallback[/cmd]
+ and a help callback settable with [cmd]addon.sethelpcallback[/cmd]. The first
+ will usually display a configuration dialog, the second will display
+ some sort of addon's documentation, usually in the help browser.
+ [/p]
+ [p]
+ The registration process uninstalls any previous addon version
+ by executing its uninstall callback routine. This is another reason for that
+ you should call addon.register BEFORE you attempt to install your addon.
+ Failing to do that may cause your old uninstalled to wipe out your newly
+ installed files or code.
+ [/p]
+ @seealso:
+ [cmd]addon.uninstall[/cmd], [fnc]$addon.exists[/fnc],
+ [cmd]addon.setconfigurecallback[/cmd], [cmd]addon.configure[/cmd],
+ [cmd]addon.sethelpcallback[/cmd], [cmd]addon.help[/cmd]
+ @examples:
+ [example]
+
+ [/example]
+*/
+
+static bool addon_kvs_cmd_register(KviKvsModuleCallbackCommandCall * c)
+{
+ KviKvsScriptAddonRegistrationData rd;
+ QString szMinKVIrcVersion;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,(rd.szName))
+ KVSM_PARAMETER("version",KVS_PT_NONEMPTYSTRING,0,(rd.szVersion))
+ KVSM_PARAMETER_IGNORED("visible_text")
+ KVSM_PARAMETER_IGNORED("description")
+ KVSM_PARAMETER("min_kvirc_version",KVS_PT_NONEMPTYSTRING,0,szMinKVIrcVersion)
+ KVSM_PARAMETER("icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,(rd.szIconId))
+ KVSM_PARAMETERS_END(c)
+
+
+ if(!(c->getParameterCode(2,rd.szVisibleNameScript) && c->getParameterCode(3,rd.szDescriptionScript)))
+ {
+ c->error(__tr2qs("Internal error: call a head-shrinker"));
+ return false;
+ }
+
+ if(c->callback())
+ rd.szUninstallCallbackScript = c->callback()->code();
+
+ if(!KviMiscUtils::isValidVersionString(rd.szVersion))
+ {
+ c->error(__tr2qs("The specified version \"%Q\" is not a valid version string"),&(rd.szVersion));
+ return false;
+ }
+
+ if(!KviMiscUtils::isValidVersionString(szMinKVIrcVersion))
+ {
+ c->error(__tr2qs("The specified KVIrc version \"%Q\" is not a valid version string"),&szMinKVIrcVersion);
+ return false;
+ }
+
+ if(KviMiscUtils::compareVersions(szMinKVIrcVersion,KVI_VERSION "." KVI_SOURCES_DATE) < 0)
+ {
+ c->error(__tr2qs("This KVIrc executable is too old to run this addon (minimum version required is %Q)"),&szMinKVIrcVersion);
+ return false;
+ }
+
+ if(!c->switches()->find('q',"quiet"))
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Attempting to register addon \"%Q\" with version %Q"),&(rd.szName),&(rd.szVersion));
+
+ KviKvsScriptAddon * a = KviKvsScriptAddonManager::instance()->findAddon(rd.szName);
+ if(a)
+ {
+ // the same addon already exists
+ if(KviMiscUtils::compareVersions(a->version(),rd.szVersion) < 0)
+ {
+ // and it has a higher version...
+ // complain unless -f is used
+ if(!c->switches()->find('f',"force"))
+ {
+ c->error(__tr2qs("The script addon \"%Q\" already exists with version %Q which is higher than %Q"),&(rd.szName),&(a->version()),&(rd.szVersion));
+ return false;
+ }
+ }
+
+ if(!c->switches()->find('q',"quiet"))
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Uninstalling existing addon version %Q"),&(a->version()));
+
+ // uninstall the existing version
+ KviKvsScriptAddonManager::instance()->unregisterAddon(rd.szName,c->window(),!c->switches()->find('n',"no-uninstall"));
+ }
+
+ if(!KviKvsScriptAddonManager::instance()->registerAddon(&rd))
+ {
+ c->error(__tr2qs("Script registration failed"));
+ return false;
+ }
+
+ if(!c->switches()->find('q',"quiet"))
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Script succesfully registered"));
+
+ return true;
+}
+
+/*
+ @doc: addon.dialog
+ @type:
+ command
+ @title:
+ addon.dialog
+ @short:
+ Shows the addon addon management editor
+ @syntax:
+ addon.dialog
+ @description:
+ Shows the addon addon management editor
+*/
+
+static bool addon_kvs_cmd_dialog(KviKvsModuleCommandCall * c)
+{
+ KviScriptManagementDialog::display();
+ return true;
+}
+
+static bool addon_module_init(KviModule *m)
+{
+ KVSM_REGISTER_FUNCTION(m,"exists",addon_kvs_fnc_exists);
+ KVSM_REGISTER_FUNCTION(m,"version",addon_kvs_fnc_version);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"dialog",addon_kvs_cmd_dialog);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"list",addon_kvs_cmd_list);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"uninstall",addon_kvs_cmd_uninstall);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"configure",addon_kvs_cmd_configure);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"help",addon_kvs_cmd_help);
+
+ KVSM_REGISTER_CALLBACK_COMMAND(m,"setconfigurecallback",addon_kvs_cmd_setconfigurecallback);
+ KVSM_REGISTER_CALLBACK_COMMAND(m,"sethelpcallback",addon_kvs_cmd_sethelpcallback);
+ KVSM_REGISTER_CALLBACK_COMMAND(m,"register",addon_kvs_cmd_register);
+
+ QString szBuf;
+ m->getDefaultConfigFileName(szBuf);
+ KviConfig cfg(szBuf,KviConfig::Read);
+ g_rectManagementDialogGeometry = cfg.readRectEntry("EditorGeometry",QRect(10,10,390,440));
+
+ return true;
+}
+
+static bool addon_module_cleanup(KviModule *m)
+{
+ KviScriptManagementDialog::cleanup();
+
+ QString szBuf;
+ m->getDefaultConfigFileName(szBuf);
+ KviConfig cfg(szBuf,KviConfig::Write);
+ cfg.writeEntry("EditorGeometry",g_rectManagementDialogGeometry);
+
+ return true;
+}
+
+static bool addon_module_can_unload(KviModule * m)
+{
+ return (!KviScriptManagementDialog::instance());
+}
+
+
+KVIRC_MODULE(
+ "addon", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2005 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Script management functions for the KVS engine",
+ addon_module_init,
+ addon_module_can_unload,
+ 0,
+ addon_module_cleanup
+)
diff --git a/src/modules/addon/managementdialog.cpp b/src/modules/addon/managementdialog.cpp
new file mode 100644
index 00000000..a6765587
--- /dev/null
+++ b/src/modules/addon/managementdialog.cpp
@@ -0,0 +1,403 @@
+//=============================================================================
+//
+// File : managementdialog.cpp
+// Created on Fri 08 Apr 2005 14:54:56 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2005 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 "managementdialog.h"
+
+#include "kvi_listview.h"
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_kvs_scriptaddonmanager.h"
+#include "kvi_window.h"
+
+#include "kvi_filedialog.h"
+#include "kvi_fileutils.h"
+#include "kvi_kvs_script.h"
+#include "kvi_sourcesdate.h"
+
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qapplication.h>
+#include <qtooltip.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qmessagebox.h>
+#include <qframe.h>
+#include "kvi_tal_scrollview.h"
+#ifdef COMPILE_USE_QT4
+ #include <q3header.h>
+
+#else
+ #include <qheader.h>
+#endif
+#include "kvi_draganddrop.h"
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qmessagebox.h>
+#include <qevent.h>
+
+KviScriptManagementDialog * KviScriptManagementDialog::m_pInstance = 0;
+extern QRect g_rectManagementDialogGeometry;
+
+
+#define LVI_ICON_SIZE 32
+#define LVI_BORDER 4
+#define LVI_SPACING 8
+#define LVI_MINIMUM_TEXT_WIDTH 300
+#define LVI_MINIMUM_CELL_WIDTH (LVI_MINIMUM_TEXT_WIDTH + LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER)
+
+KviScriptAddonListViewItem::KviScriptAddonListViewItem(KviTalListView * v,KviKvsScriptAddon * a)
+: KviTalListViewItem(v,"")
+{
+ m_pAddon = new KviKvsScriptAddon(*a);
+ m_pListView = v;
+ QString t = "<nobr><b>";
+ t += a->visibleName();
+ t += "</b> [";
+ t += a->version();
+ t += "]";
+ t += " <font color=\"#a0a0a0\">[";
+ t += a->name();
+ t += "]</font></nobr>";
+ t += "<br><nobr><font size=\"-1\">";
+ t += a->description();
+ t += "</font></nobr>";
+ m_szKey = a->visibleName().upper();
+#ifdef COMPILE_USE_QT4
+ m_pText = new QTextDocument();
+ m_pText->setHtml(t);
+ m_pText->setDefaultFont(v->font());
+#else
+ m_pText = new QSimpleRichText(t,v->font());
+#endif
+
+ QPixmap * p = a->icon();
+ m_pIcon = p ? new QPixmap(*p) : new QPixmap(LVI_ICON_SIZE,LVI_ICON_SIZE);
+}
+
+KviScriptAddonListViewItem::~KviScriptAddonListViewItem()
+{
+ delete m_pIcon;
+ delete m_pText;
+ delete m_pAddon;
+}
+
+QString KviScriptAddonListViewItem::key(int,bool) const
+{
+ return m_szKey;
+}
+
+void KviScriptAddonListViewItem::setup()
+{
+ KviTalListViewItem::setup();
+ int iWidth = m_pListView->visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ iWidth -= LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER;
+
+ #ifdef COMPILE_USE_QT4
+ int iHeight = m_pText->size().height() + (2 * LVI_BORDER);
+ #else
+ m_pText->setWidth(iWidth);
+ int iHeight = m_pText->height() + (2 * LVI_BORDER);
+ #endif
+ if(iHeight < (LVI_ICON_SIZE + (2 * LVI_BORDER)))iHeight = LVI_ICON_SIZE + (2 * LVI_BORDER);
+ setHeight(iHeight+2);
+}
+
+void KviScriptAddonListViewItem::paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align)
+{
+ #ifdef COMPILE_USE_QT4
+ if (isSelected())
+ {
+ QColor col(m_pListView->palette().highlight());
+ col.setAlpha(127);
+ p->setBrush(col);
+ p->drawRect(0, 0, m_pListView->visibleWidth(), height());
+ }
+ p->drawPixmap(LVI_BORDER,LVI_BORDER,*m_pIcon);
+ int afterIcon = LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING;
+ int www = m_pListView->visibleWidth() - (afterIcon + LVI_BORDER);
+ p->translate(afterIcon,LVI_BORDER);
+ m_pText->setPageSize(QSizeF(www,height() - (LVI_BORDER * 2)));
+ m_pText->drawContents(p);
+ #else
+ p->drawPixmap(LVI_BORDER,LVI_BORDER,*m_pIcon);
+ int afterIcon = LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING;
+ int www = m_pListView->visibleWidth() - (afterIcon + LVI_BORDER);
+ m_pText->setWidth(www);
+ if(isSelected())
+ {
+ QColorGroup cg2(cg);
+ cg2.setColor(QColorGroup::HighlightedText,cg.text());
+
+ m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,height() - (LVI_BORDER * 2)),cg2);
+ } else {
+ m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,height() - (LVI_BORDER * 2)),cg);
+ }
+ #endif
+}
+
+
+
+
+
+
+
+KviScriptAddonListView::KviScriptAddonListView(QWidget * pParent)
+: KviListView(pParent)
+{
+ QPixmap * p = g_pIconManager->getImage("kvi_dialog_addons.png");
+ if(p)setBackgroundOverlayPixmap(p,Qt::AlignRight | Qt::AlignBottom);
+
+ setSelectionMode(Single);
+ header()->hide();
+ int iWidth = visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ addColumn("",iWidth);
+ setSorting(0,true);
+}
+
+KviScriptAddonListView::~KviScriptAddonListView()
+{
+}
+
+void KviScriptAddonListView::resizeEvent(QResizeEvent * e)
+{
+ KviListView::resizeEvent(e);
+ int iWidth = visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ setColumnWidth(0,iWidth);
+}
+
+
+KviScriptManagementDialog::KviScriptManagementDialog(QWidget * p)
+: QDialog(p,"" /*,WType_TopLevel | WStyle_Customize | WStyle_Title | WStyle_StaysOnTop | WStyle_DialogBorder*/)
+{
+ setCaption(__tr2qs("Manage Script-Based Addons"));
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ADDONS)));
+ setModal(true);
+
+ m_pInstance = this;
+
+ QGridLayout * g = new QGridLayout(this,11,3,4,5);
+
+ /*QLabel * lb = new QLabel(this);
+ lb->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
+
+ g->addMultiCellWidget(lb,0,10,0,0);
+ QPixmap * pix = g_pIconManager->getImage("kvi_dialog_addons.png");
+ if(pix)
+ {
+ lb->setPixmap(*pix);
+ lb->setFixedWidth(pix->width());
+ }
+ lb->setBackgroundColor(Qt::black);
+ lb->setAlignment(Qt::AlignBottom | Qt::AlignRight);
+ */
+ m_pListView = new KviScriptAddonListView(this);
+ g->addMultiCellWidget(m_pListView,0,10,1,1);
+
+ m_pConfigureButton = new QPushButton(__tr2qs("Configure"),this);
+ connect(m_pConfigureButton,SIGNAL(clicked()),this,SLOT(configureScript()));
+ g->addWidget(m_pConfigureButton,0,2);
+
+ m_pHelpButton = new QPushButton(__tr2qs("Show Help"),this);
+ connect(m_pHelpButton,SIGNAL(clicked()),this,SLOT(showScriptHelp()));
+ g->addWidget(m_pHelpButton,1,2);
+
+ g->addRowSpacing(2,40);
+
+ m_pUninstallButton = new QPushButton(__tr2qs("Uninstall"),this);
+ connect(m_pUninstallButton,SIGNAL(clicked()),this,SLOT(uninstallScript()));
+ g->addWidget(m_pUninstallButton,3,2);
+
+ g->addRowSpacing(4,15);
+
+ QFrame *f = new QFrame(this);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ g->addWidget(f,5,2);
+
+ g->addRowSpacing(6,15);
+
+ m_pInstallButton = new QPushButton(__tr2qs("Install Addon..."),this);
+ connect(m_pInstallButton,SIGNAL(clicked()),this,SLOT(installScript()));
+ g->addWidget(m_pInstallButton,7,2);
+
+ m_pGetScriptsButton = new QPushButton(__tr2qs("More Addons..."),this);
+ connect(m_pGetScriptsButton,SIGNAL(clicked()),this,SLOT(getMoreScripts()));
+ g->addWidget(m_pGetScriptsButton,8,2);
+
+ QPushButton * b = new QPushButton(__tr2qs("Close"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(closeClicked()));
+ g->addWidget(b,10,2);
+
+ g->setRowStretch(9,1);
+ g->setColStretch(1,1);
+
+ fillListView();
+
+ currentChanged(0);
+ connect(m_pListView,SIGNAL(currentChanged(KviTalListViewItem *)),this,SLOT(currentChanged(KviTalListViewItem *)));
+ //currentToolBarChanged();
+
+ if(g_rectManagementDialogGeometry.y() < 5)
+ {
+ g_rectManagementDialogGeometry.setY(5);
+ }
+ resize(g_rectManagementDialogGeometry.width(),
+ g_rectManagementDialogGeometry.height());
+ move(g_rectManagementDialogGeometry.x(),
+ g_rectManagementDialogGeometry.y());
+}
+
+KviScriptManagementDialog::~KviScriptManagementDialog()
+{
+ g_rectManagementDialogGeometry = QRect(pos().x(),pos().y(),size().width(),size().height());
+
+ //KviActionManager::instance()->customizeToolBarsDialogDestroyed();
+ m_pInstance = 0;
+}
+
+void KviScriptManagementDialog::fillListView()
+{
+ m_pListView->clear();
+ KviPointerHashTable<QString,KviKvsScriptAddon> * d = KviKvsScriptAddonManager::instance()->addonDict();
+ if(!d)return;
+ KviPointerHashTableIterator<QString,KviKvsScriptAddon> it(*d);
+ KviScriptAddonListViewItem * item;
+ while(KviKvsScriptAddon * a = it.current())
+ {
+ item = new KviScriptAddonListViewItem(m_pListView,a);
+ ++it;
+ }
+}
+
+void KviScriptManagementDialog::currentChanged(KviTalListViewItem *)
+{
+ KviScriptAddonListViewItem * it = (KviScriptAddonListViewItem *)m_pListView->currentItem();
+ if(!it)
+ {
+ m_pConfigureButton->setEnabled(false);
+ m_pUninstallButton->setEnabled(false);
+ m_pHelpButton->setEnabled(false);
+ } else {
+ m_pConfigureButton->setEnabled(!(it->addon()->configureCallbackCode().isEmpty()));
+ m_pHelpButton->setEnabled(!(it->addon()->helpCallbackCode().isEmpty()));
+ m_pUninstallButton->setEnabled(true);
+ }
+}
+
+void KviScriptManagementDialog::showScriptHelp()
+{
+ KviScriptAddonListViewItem * it = (KviScriptAddonListViewItem *)m_pListView->currentItem();
+ if(!it)return;
+ if(it->addon()->helpCallbackCode().isEmpty())return;
+ it->addon()->executeHelpCallback(g_pActiveWindow);
+}
+
+void KviScriptManagementDialog::configureScript()
+{
+ KviScriptAddonListViewItem * it = (KviScriptAddonListViewItem *)m_pListView->currentItem();
+ if(!it)return;
+ if(it->addon()->configureCallbackCode().isEmpty())return;
+ it->addon()->executeConfigureCallback(g_pActiveWindow);
+}
+
+void KviScriptManagementDialog::uninstallScript()
+{
+ KviScriptAddonListViewItem * it = (KviScriptAddonListViewItem *)m_pListView->currentItem();
+ if(!it)return;
+
+ QString txt = "<p>";
+ txt += __tr2qs("Do you really want to uninstall the addon \"%1\" ?").arg(it->addon()->visibleName());
+ txt += "</p>";
+
+ if(QMessageBox::question(this,
+ __tr2qs("Confirm addon uninstallation"),txt,__tr2qs("&Yes"),__tr2qs("&No"),0,1) != 0)return;
+
+ KviKvsScriptAddonManager::instance()->unregisterAddon(it->addon()->name(),g_pActiveWindow);
+
+ fillListView();
+ currentChanged(0);
+}
+
+void KviScriptManagementDialog::getMoreScripts()
+{
+ KviKvsScript::run("openurl http://www.kvirc.net/?id=addons&version=" KVI_VERSION "." KVI_SOURCES_DATE,g_pActiveWindow);
+}
+
+void KviScriptManagementDialog::installScript()
+{
+ QString buffer;
+
+ if(!KviFileDialog::askForOpenFileName(buffer,__tr2qs("Please select the addon installation file"),QString::null,"install.kvs",false,true))return;
+
+ buffer.replace("\\","\\\\");
+
+ QString szCmd = "parse \"";
+ szCmd += buffer;
+ szCmd += "\"";
+
+ KviKvsScript::run(szCmd,g_pActiveWindow);
+
+ fillListView();
+ currentChanged(0);
+
+ m_pListView->publicUpdateContents();
+ //m_pListView->triggerUpdate();
+}
+
+void KviScriptManagementDialog::showEvent(QShowEvent * e)
+{
+// QRect r = parentWidget() ? parentWidget()->rect() : QApplication::desktop()->rect();
+// int x = (r.width() - width()) / 2;
+// int y = (r.height() - height()) / 2;
+// move(x,y);
+}
+
+void KviScriptManagementDialog::closeClicked()
+{
+ delete this;
+}
+
+void KviScriptManagementDialog::cleanup()
+{
+ if(!m_pInstance)return;
+ delete m_pInstance;
+ m_pInstance = 0;
+}
+
+void KviScriptManagementDialog::display()
+{
+ if(m_pInstance)return;
+ m_pInstance = new KviScriptManagementDialog(g_pFrame);
+ m_pInstance->show();
+}
+
+void KviScriptManagementDialog::closeEvent(QCloseEvent * e)
+{
+ e->ignore();
+ delete this;
+}
+
diff --git a/src/modules/addon/managementdialog.h b/src/modules/addon/managementdialog.h
new file mode 100644
index 00000000..0abbb4f9
--- /dev/null
+++ b/src/modules/addon/managementdialog.h
@@ -0,0 +1,114 @@
+#ifndef _MANAGEMENTDIALOG_H_
+#define _MANAGEMENTDIALOG_H_
+//=============================================================================
+//
+// File : managementdialog.h
+// Created on Fri 08 Apr 2005 14:54:56 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2005 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 <qdialog.h>
+
+#include "kvi_listview.h"
+#include "kvi_settings.h"
+#include <qwidget.h>
+#include <qlabel.h>
+#include <qdialog.h>
+#include <qcolor.h>
+#include "kvi_tal_listview.h"
+
+class QPushButton;
+class QPixmap;
+class KviKvsScriptAddon;
+
+#ifdef COMPILE_USE_QT4
+ #include <QTextDocument>
+#else
+ #include <qsimplerichtext.h>
+#endif
+
+class KviScriptAddonListViewItem : public KviTalListViewItem
+{
+public:
+ KviScriptAddonListViewItem(KviTalListView * v,KviKvsScriptAddon * a);
+ ~KviScriptAddonListViewItem();
+protected:
+ KviKvsScriptAddon * m_pAddon;
+#ifdef COMPILE_USE_QT4
+ QTextDocument * m_pText;
+#else
+ QSimpleRichText * m_pText;
+#endif
+ QPixmap * m_pIcon;
+ KviTalListView * m_pListView;
+ QString m_szKey;
+public:
+ KviKvsScriptAddon * addon(){ return m_pAddon; };
+protected:
+ virtual QString key(int,bool) const;
+ virtual void paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align);
+ virtual void setup();
+};
+
+class KviScriptAddonListView : public KviListView
+{
+ Q_OBJECT
+public:
+ KviScriptAddonListView(QWidget * pParent);
+ ~KviScriptAddonListView();
+protected:
+ virtual void resizeEvent(QResizeEvent * e);
+};
+
+class KviScriptManagementDialog : public QDialog
+{
+ Q_OBJECT
+protected:
+ KviScriptManagementDialog(QWidget * p);
+public:
+ ~KviScriptManagementDialog();
+protected:
+ KviScriptAddonListView * m_pListView;
+ static KviScriptManagementDialog * m_pInstance;
+ QPushButton * m_pUninstallButton;
+ QPushButton * m_pConfigureButton;
+ QPushButton * m_pHelpButton;
+ QPushButton * m_pInstallButton;
+ QPushButton * m_pGetScriptsButton;
+public:
+ static KviScriptManagementDialog * instance(){ return m_pInstance; };
+ static void display();
+ static void cleanup();
+protected:
+ void fillListView();
+ virtual void showEvent(QShowEvent * e);
+ virtual void closeEvent(QCloseEvent *e);
+protected slots:
+ void currentChanged(KviTalListViewItem *i);
+ void closeClicked();
+ void showScriptHelp();
+ void configureScript();
+ void uninstallScript();
+ void getMoreScripts();
+ void installScript();
+};
+
+
+#endif //!_MANAGEMENTDIALOG_H_
diff --git a/src/modules/addon/pics/Makefile.am b/src/modules/addon/pics/Makefile.am
new file mode 100644
index 00000000..726f519d
--- /dev/null
+++ b/src/modules/addon/pics/Makefile.am
@@ -0,0 +1,9 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir = $(picsdir)
+
+tmp_DATA= kvi_dialog_addons.png
+
+EXTRA_DIST = $(tmp_DATA)
diff --git a/src/modules/addon/pics/kvi_dialog_addons.png b/src/modules/addon/pics/kvi_dialog_addons.png
new file mode 100644
index 00000000..6cfa53d9
--- /dev/null
+++ b/src/modules/addon/pics/kvi_dialog_addons.png
Binary files differ
diff --git a/src/modules/aliaseditor/Makefile.am b/src/modules/aliaseditor/Makefile.am
new file mode 100644
index 00000000..60845dbc
--- /dev/null
+++ b/src/modules/aliaseditor/Makefile.am
@@ -0,0 +1,21 @@
+###############################################################################
+# KVirc IRC client Makealiaseditor - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvialiaseditor.la
+
+libkvialiaseditor_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvialiaseditor_la_SOURCES = libkvialiaseditor.cpp aliaseditor.cpp
+nodist_libkvialiaseditor_la_SOURCES = moc_aliaseditor.cpp
+
+noinst_HEADERS = aliaseditor.h
+libkvialiaseditor_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+moc_aliaseditor.cpp: aliaseditor.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/aliaseditor/aliaseditor.cpp b/src/modules/aliaseditor/aliaseditor.cpp
new file mode 100644
index 00000000..3317fd3f
--- /dev/null
+++ b/src/modules/aliaseditor/aliaseditor.cpp
@@ -0,0 +1,1408 @@
+//=====================================================================================
+//
+// 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-2005 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 "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_imagedialog.h"
+#include "kvi_config.h"
+#include "kvi_filedialog.h"
+#include "kvi_fileutils.h"
+#include "kvi_scripteditor.h"
+#include "kvi_debug.h"
+#include "kvi_app.h"
+#include "kvi_qstring.h"
+#include "kvi_kvs_aliasmanager.h"
+#include "kvi_filedialog.h"
+#include "kvi_cmdformatter.h"
+#include "kvi_module.h"
+#include "kvi_valuelist.h"
+
+#include <qsplitter.h>
+#include <qlayout.h>
+#include "kvi_tal_vbox.h"
+#include <qtooltip.h>
+#include <qpushbutton.h>
+#include <qdir.h>
+#include <qmessagebox.h>
+#include <qinputdialog.h>
+#include <qregexp.h>
+
+extern KviAliasEditorWindow * g_pAliasEditorWindow;
+extern KviModule * g_pAliasEditorModule;
+
+KviAliasEditorListViewItem::KviAliasEditorListViewItem(KviTalListView * pListView,Type eType,const QString &szName)
+: KviTalListViewItem(pListView), m_eType(eType), m_pParentNamespaceItem(0)
+{
+ setName(szName);
+}
+
+KviAliasEditorListViewItem::KviAliasEditorListViewItem(KviAliasNamespaceListViewItem * pParentNamespaceItem,Type eType,const QString &szName)
+: KviTalListViewItem(pParentNamespaceItem), m_eType(eType), m_pParentNamespaceItem(pParentNamespaceItem)
+{
+ setName(szName);
+}
+
+QString KviAliasEditorListViewItem::key(int column,bool bAsc) const
+{
+ QString ret;
+ if(m_eType == Namespace)ret = "1";
+ else ret = "2";
+ ret += m_szName;
+ return ret;
+}
+
+
+void KviAliasEditorListViewItem::setName(const QString &szName)
+{
+ m_szName = szName;
+ setText(0,m_szName);
+}
+
+KviAliasListViewItem::KviAliasListViewItem(KviAliasNamespaceListViewItem * pParentNamespaceItem,const QString &szName)
+: KviAliasEditorListViewItem(pParentNamespaceItem,KviAliasEditorListViewItem::Alias,szName)
+{
+ setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)));
+ m_cPos=QPoint(0,0);
+}
+
+KviAliasListViewItem::KviAliasListViewItem(KviTalListView * pListView,const QString &szName)
+: KviAliasEditorListViewItem(pListView,KviAliasEditorListViewItem::Alias,szName)
+{
+ setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)));
+ m_cPos=QPoint(0,0);
+}
+
+
+KviAliasNamespaceListViewItem::KviAliasNamespaceListViewItem(KviTalListView * pListView,const QString &szName)
+: KviAliasEditorListViewItem(pListView,KviAliasEditorListViewItem::Namespace,szName)
+{
+ setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)));
+}
+
+KviAliasNamespaceListViewItem::KviAliasNamespaceListViewItem(KviAliasNamespaceListViewItem * pParentNamespaceItem,const QString &szName)
+: KviAliasEditorListViewItem(pParentNamespaceItem,KviAliasEditorListViewItem::Namespace,szName)
+{
+ setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)));
+}
+
+
+KviAliasNamespaceListViewItem * KviAliasNamespaceListViewItem::findNamespaceItem(const QString &szName)
+{
+ KviAliasEditorListViewItem * it = (KviAliasEditorListViewItem *)firstChild();
+ while(it)
+ {
+ if(it->isNamespace())
+ {
+ if(KviQString::equalCI(szName,it->name()))return (KviAliasNamespaceListViewItem *)it;
+ }
+ it = (KviAliasEditorListViewItem *)it->nextSibling();
+ }
+ return 0;
+}
+
+KviAliasNamespaceListViewItem * KviAliasNamespaceListViewItem::getNamespaceItem(const QString &szName)
+{
+ KviAliasNamespaceListViewItem * it = findNamespaceItem(szName);
+ if(it)return it;
+ it = new KviAliasNamespaceListViewItem(this,szName);
+ return it;
+}
+
+KviAliasListViewItem * KviAliasNamespaceListViewItem::findAliasItem(const QString &szName)
+{
+ KviAliasEditorListViewItem * it = (KviAliasEditorListViewItem *)firstChild();
+ while(it)
+ {
+ if(it->isAlias())
+ {
+ if(KviQString::equalCI(szName,it->name()))return (KviAliasListViewItem *)it;
+ }
+ it = (KviAliasEditorListViewItem *)it->nextSibling();
+ }
+ return 0;
+}
+
+KviAliasListViewItem * KviAliasNamespaceListViewItem::getAliasItem(const QString &szName)
+{
+ KviAliasListViewItem * it = findAliasItem(szName);
+ if(it)return it;
+ it = new KviAliasListViewItem(this,szName);
+ return it;
+}
+
+
+KviAliasListViewItem * KviAliasNamespaceListViewItem::createFullAliasItem(const QString &szFullName)
+{
+ QStringList lNamespaces;
+ QString szName;
+ KviAliasEditor::splitFullAliasOrNamespaceName(szFullName,lNamespaces,szName);
+
+ if(lNamespaces.isEmpty())
+ return getAliasItem(szName);
+
+ QStringList::Iterator it = lNamespaces.begin();
+
+ KviAliasNamespaceListViewItem * nit = getNamespaceItem(*it);
+ ++it;
+ while(it != lNamespaces.end())
+ {
+ nit = nit->getNamespaceItem(*it);
+ ++it;
+ }
+
+ return nit->getAliasItem(szName);
+}
+
+KviAliasNamespaceListViewItem * KviAliasNamespaceListViewItem::createFullNamespaceItem(const QString &szFullName)
+{
+ QStringList lNamespaces;
+ QString szName;
+ KviAliasEditor::splitFullAliasOrNamespaceName(szFullName,lNamespaces,szName);
+
+ if(lNamespaces.isEmpty())
+ return getNamespaceItem(szName);
+
+ QStringList::Iterator it = lNamespaces.begin();
+
+ KviAliasNamespaceListViewItem * nit = getNamespaceItem(*it);
+ ++it;
+ while(it != lNamespaces.end())
+ {
+ nit = nit->getNamespaceItem(*it);
+ ++it;
+ }
+
+ return nit->getNamespaceItem(szName);
+}
+
+
+KviAliasEditor::KviAliasEditor(QWidget * par)
+: QWidget(par)
+{
+ m_pLastEditedItem = 0;
+ m_pLastClickedItem = 0;
+ m_szDir = QDir::homeDirPath();
+
+
+ QGridLayout * l = new QGridLayout(this,1,1,2,2);
+
+#ifdef COMPILE_USE_QT4
+ m_pSplitter = new QSplitter(Qt::Horizontal,this);
+ m_pSplitter->setOpaqueResize(false);
+#else
+ m_pSplitter = new QSplitter(QSplitter::Horizontal,this);
+#endif
+
+ l->addWidget(m_pSplitter,0,0);
+
+ KviTalVBox * box = new KviTalVBox(m_pSplitter);
+ m_pListView = new KviTalListView(box);
+ m_pListView->addColumn(__tr2qs("Alias"));
+ m_pListView->setSelectionMode(KviTalListView::Extended);
+ m_pListView->setShowSortIndicator(true);
+ m_pListView->setRootIsDecorated(true);
+
+ box = new KviTalVBox(m_pSplitter);
+ KviTalHBox * hbox = new KviTalHBox(box);
+ m_pNameLabel = new QLabel(__tr2qs("No item selected"),hbox);
+ m_pRenameButton = new QPushButton(__tr2qs("Rename"),hbox);
+ m_pRenameButton->setEnabled(false);
+ connect(m_pRenameButton,SIGNAL(clicked()),this,SLOT(renameItem()));
+ hbox->setStretchFactor(m_pNameLabel,2);
+ QToolTip::add(m_pRenameButton,__tr2qs("Edit the alias or namespace name"));
+ 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);
+}
+
+KviAliasEditor::~KviAliasEditor()
+{
+ KviScriptEditor::destroyInstance(m_pEditor);
+}
+
+KviAliasNamespaceListViewItem * KviAliasEditor::findNamespaceItem(const QString &szName)
+{
+ KviAliasNamespaceListViewItem * it = (KviAliasNamespaceListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ if(KviQString::equalCI(szName,it->name()))return it;
+ it = (KviAliasNamespaceListViewItem *)it->nextSibling();
+ }
+ return 0;
+}
+
+KviAliasNamespaceListViewItem * KviAliasEditor::getNamespaceItem(const QString &szName)
+{
+ KviAliasNamespaceListViewItem * it = findNamespaceItem(szName);
+ if(it)return it;
+ it = new KviAliasNamespaceListViewItem(m_pListView,szName);
+ return it;
+}
+
+KviAliasListViewItem * KviAliasEditor::findAliasItem(const QString &szName)
+{
+ KviAliasEditorListViewItem * it = (KviAliasEditorListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ if(it->isAlias())
+ {
+ if(KviQString::equalCI(szName,it->name()))return (KviAliasListViewItem *)it;
+ }
+ it = (KviAliasEditorListViewItem *)it->nextSibling();
+ }
+ return 0;
+}
+
+KviAliasListViewItem * KviAliasEditor::getAliasItem(const QString &szName)
+{
+ KviAliasListViewItem * it = findAliasItem(szName);
+ if(it)return it;
+ it = new KviAliasListViewItem(m_pListView,szName);
+ return it;
+}
+
+
+void KviAliasEditor::splitFullAliasOrNamespaceName(const QString &szFullName,QStringList &lNamespaces,QString &szName)
+{
+ lNamespaces = QStringList::split("::",szFullName);
+ if(lNamespaces.count() < 1)
+ {
+ szName = "unnamed";
+ lNamespaces.append(QString(""));
+ return;
+ }
+ szName = *(lNamespaces.fromLast());
+ lNamespaces.remove(lNamespaces.fromLast());
+}
+
+QString KviAliasEditor::buildFullItemName(KviAliasEditorListViewItem * it)
+{
+ if(!it) return QString::null;
+ QString szName = it->name();
+ KviAliasNamespaceListViewItem * nit = it->parentNamespaceItem();
+ while(nit)
+ {
+ QString tmp = nit->name();
+ if(!tmp.isEmpty())
+ {
+ szName.prepend("::");
+ szName.prepend(tmp);
+ }
+ nit = nit->parentNamespaceItem();
+ }
+ return szName;
+}
+
+
+KviAliasListViewItem * KviAliasEditor::createFullAliasItem(const QString &szFullName)
+{
+ QStringList lNamespaces;
+ QString szName;
+ splitFullAliasOrNamespaceName(szFullName,lNamespaces,szName);
+
+ if(lNamespaces.isEmpty())
+ return getAliasItem(szName);
+
+ QStringList::Iterator it = lNamespaces.begin();
+
+ KviAliasNamespaceListViewItem * nit = getNamespaceItem(*it);
+ ++it;
+ while(it != lNamespaces.end())
+ {
+ nit = nit->getNamespaceItem(*it);
+ ++it;
+ }
+
+ return nit->getAliasItem(szName);
+}
+
+KviAliasNamespaceListViewItem * KviAliasEditor::createFullNamespaceItem(const QString &szFullName)
+{
+ QStringList lNamespaces;
+ QString szName;
+ splitFullAliasOrNamespaceName(szFullName,lNamespaces,szName);
+
+ if(lNamespaces.isEmpty())
+ return getNamespaceItem(szName);
+
+ QStringList::Iterator it = lNamespaces.begin();
+
+ KviAliasNamespaceListViewItem * nit = getNamespaceItem(*it);
+ ++it;
+ while(it != lNamespaces.end())
+ {
+ nit = nit->getNamespaceItem(*it);
+ ++it;
+ }
+
+ return nit->getNamespaceItem(szName);
+}
+
+void KviAliasEditor::oneTimeSetup()
+{
+ KviPointerHashTable<QString,KviKvsScript> * a = KviKvsAliasManager::instance()->aliasDict();
+ if(!a)return;
+
+ KviPointerHashTableIterator<QString,KviKvsScript> it(*a);
+
+ KviAliasListViewItem * item;
+ while(it.current())
+ {
+ KviKvsScript * alias = it.current();
+ item = createFullAliasItem(alias->name());
+ item->setBuffer(alias->code());
+ ++it;
+ }
+
+ connect(m_pListView,SIGNAL(currentChanged(KviTalListViewItem *)),this,SLOT(currentItemChanged(KviTalListViewItem *)));
+ connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),
+ this,SLOT(itemPressed(KviTalListViewItem *,const QPoint &,int)));
+}
+
+bool KviAliasEditor::hasSelectedItems(KviTalListViewItem * it)
+{
+ if(!it)return false;
+ if(it->isSelected())return true;
+ if(it->isOpen())
+ {
+ if(hasSelectedItems(it->firstChild()))return true;
+ }
+ return hasSelectedItems(it->nextSibling());
+}
+
+bool KviAliasEditor::itemExists(KviTalListViewItem *pSearchFor,KviTalListViewItem * pSearchAt)
+{
+ if(!pSearchFor)return false;
+ if(!pSearchAt)return false;
+ if(pSearchFor == pSearchAt)return true;
+ if(itemExists(pSearchFor,pSearchAt->firstChild()))return true;
+ return itemExists(pSearchFor,pSearchAt->nextSibling());
+}
+
+
+void KviAliasEditor::itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ m_pContextPopup->clear();
+
+ m_pLastClickedItem = (KviAliasEditorListViewItem *)it;
+
+ int id;
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)),
+ __tr2qs("Add Alias"),
+ this,SLOT(newAlias()));
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)),
+ __tr2qs("Add Namespace"),
+ this,SLOT(newNamespace()));
+
+
+ bool bHasItems = m_pListView->firstChild() != 0;
+ bool bHasSelected = hasSelectedItems(m_pListView->firstChild());
+
+ m_pContextPopup->insertSeparator();
+
+ id = m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),
+ __tr2qs("Remove Selected"),
+ this,SLOT(removeSelectedItems()));
+ m_pContextPopup->setItemEnabled(id,bHasSelected);
+
+
+ m_pContextPopup->insertSeparator();
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)),
+ __tr2qs("Export Selected..."),
+ this,SLOT(exportSelected()));
+ m_pContextPopup->setItemEnabled(id,bHasSelected);
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)),
+ __tr2qs("Export Selected in singles files..."),
+ this,SLOT(exportSelectedSepFiles()));
+
+ m_pContextPopup->setItemEnabled(id,bHasSelected);
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)),
+ __tr2qs("Export All..."),
+ this,SLOT(exportAll()));
+ m_pContextPopup->setItemEnabled(id,bHasItems);
+
+ m_pContextPopup->insertSeparator();
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_SEARCH)),
+ __tr2qs("Find In Aliases..."),
+ this,SLOT(slotFind()));
+ m_pContextPopup->setItemEnabled(id,bHasItems);
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)),
+ __tr2qs("Collapse All Namespaces"),
+ this,SLOT(slotCollapseNamespaces()));
+
+ m_pContextPopup->setItemEnabled(id,bHasItems);
+
+
+ m_pContextPopup->popup(pnt);
+}
+
+void KviAliasEditor::recursiveSearchReplace(const QString &szSearch,KviAliasEditorListViewItem * it,bool bReplace,const QString &szReplace)
+{
+ if(!it)return;
+ if(it->isAlias())
+ {
+ if(((KviAliasListViewItem *)it)->buffer().find(szSearch,0,false) != -1)
+ {
+ it->setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIASHIGHLIGHTED)));
+ if (bReplace) ((QString &)((KviAliasListViewItem *)it)->buffer()).replace(szSearch,szReplace,false);
+ openParentItems(it);
+ } else
+ it->setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)));
+ } else {
+ recursiveSearchReplace(szSearch,(KviAliasEditorListViewItem *)(it->firstChild()),bReplace,szReplace);
+ }
+ recursiveSearchReplace(szSearch,(KviAliasEditorListViewItem *)(it->nextSibling()),bReplace,szReplace);
+}
+
+void KviAliasEditor::slotFind()
+{
+ g_pAliasEditorModule->lock();
+ bool bOk;
+ QString szSearch = QInputDialog::getText(
+ __tr2qs("Find In Aliases"),
+ __tr2qs("Please enter the text to be searched for. The matching aliases will be highlighted."),
+ QLineEdit::Normal,
+ "",
+ &bOk,
+ this);
+ g_pAliasEditorModule->unlock();
+ if(!bOk)return;
+ if(szSearch.isEmpty())return;
+ m_pEditor->setFindText(szSearch);
+
+ recursiveSearchReplace(szSearch,(KviAliasEditorListViewItem *)m_pListView->firstChild());
+}
+void KviAliasEditor::slotFindWord(const QString &szSearch)
+{
+ m_pEditor->setFindText(szSearch);
+
+ recursiveSearchReplace(szSearch,(KviAliasEditorListViewItem *)m_pListView->firstChild());
+
+}
+void KviAliasEditor::recursiveCollapseNamespaces(KviAliasEditorListViewItem * it)
+{
+ if(!it)return;
+ if(it->isNamespace())
+ {
+ recursiveCollapseNamespaces((KviAliasEditorListViewItem *)(it->firstChild()));
+ }
+ recursiveCollapseNamespaces((KviAliasEditorListViewItem *)(it->nextSibling()));
+ it->setOpen(false);
+}
+
+void KviAliasEditor::slotCollapseNamespaces()
+{
+ recursiveCollapseNamespaces((KviAliasEditorListViewItem *)m_pListView->firstChild());
+}
+
+
+void KviAliasEditor::slotReplaceAll(const QString &before,const QString &after)
+{
+ recursiveSearchReplace(before,(KviAliasEditorListViewItem *)m_pListView->firstChild(),true,after);
+}
+
+
+
+void KviAliasEditor::getExportAliasBuffer(QString &buffer,KviAliasListViewItem * 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<KviAliasListViewItem> *l)
+{
+ if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))m_szDir += KVI_PATH_SEPARATOR;
+ debug ("dir %s",m_szDir.latin1());
+ if (!l->first())
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::warning(this,__tr2qs("Alias Export"),__tr2qs("There is not selection!"),__tr2qs("Ok"));
+ g_pAliasEditorModule->unlock();
+ return;
+ }
+ g_pAliasEditorModule->lock();
+
+ if(!KviFileDialog::askForDirectoryName(m_szDir,__tr2qs("Choose a Directory - KVIrc"),m_szDir)){
+ g_pAliasEditorModule->unlock();
+ return;
+ }
+
+ if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))m_szDir += KVI_PATH_SEPARATOR;
+ debug ("dir changed in %s",m_szDir.latin1());
+
+ bool bReplaceAll=false;
+
+ for(KviAliasListViewItem * 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("The file \"%Q\" exists. Do you want to replace it ?"),&szFileName);
+ int ret = QMessageBox::question(this,__tr2qs("Replace file"),szMsg,__tr2qs("Yes"),__tr2qs("Yes to All"),__tr2qs("No"));
+ 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<KviAliasListViewItem> l;
+ l.setAutoDelete(false);
+
+ QString out;
+
+ appendAliasItems(&l,(KviAliasEditorListViewItem *)(m_pListView->firstChild()),bSelectedOnly);
+ if (bSingleFiles)
+ {
+ exportSelectionInSinglesFiles(&l);
+ return;
+
+ }
+ int count=0;
+ KviAliasListViewItem * tempitem=0;
+ for(KviAliasListViewItem * it = l.first();it;it = l.next())
+ {
+ tempitem=it;
+ count ++;
+ QString tmp;
+ getExportAliasBuffer(tmp,it);
+ out += tmp;
+ out += "\n";
+ }
+ QString szNameFile;
+ if(out.isEmpty())
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::warning(this,__tr2qs("Alias Export"),__tr2qs("There exported file would be empty: cowardly refusing to write it"),__tr2qs("Ok"));
+ 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(tempitem);
+ szNameFile = tmp.replace("::","_");
+ }
+ else szNameFile="aliases";
+ szName += szNameFile;
+ szName += ".kvs";
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose a Filename - KVIrc"),szName,"*.kvs",false,true,true))
+ {
+ g_pAliasEditorModule->unlock();
+ return;
+ }
+ m_szDir=QFileInfo(szFile).dirPath(TRUE);
+ g_pAliasEditorModule->unlock();
+
+ if(!KviFileUtils::writeFile(szFile,out))
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::warning(this,__tr2qs("Write Failed - KVIrc"),__tr2qs("Unable to write to the alias file."),__tr2qs("Ok"));
+ g_pAliasEditorModule->unlock();
+ }
+}
+
+void KviAliasEditor::saveProperties(KviConfig *cfg)
+{
+ cfg->writeEntry("Sizes",m_pSplitter->sizes());
+ QString szName;
+ if(m_pLastEditedItem)
+ szName = buildFullItemName(m_pLastEditedItem);
+ cfg->writeEntry("LastAlias",szName);
+}
+
+void KviAliasEditor::loadProperties(KviConfig *cfg)
+{
+ KviValueList<int> def;
+ def.append(20);
+ def.append(80);
+ m_pSplitter->setSizes(cfg->readIntListEntry("Sizes",def));
+ QString tmp = cfg->readEntry("LastAlias",QString::null);
+
+ KviAliasEditorListViewItem * it = findAliasItem(tmp);
+ if(!it)it = findNamespaceItem(tmp);
+ if(it)activateItem(it);
+}
+
+void KviAliasEditor::appendAliasItems(KviPointerList<KviAliasListViewItem> * l,KviAliasEditorListViewItem * pStartFrom,bool bSelectedOnly)
+{
+ if(!pStartFrom)return;
+ if(pStartFrom->isAlias())
+ {
+ if(bSelectedOnly)
+ {
+ if(pStartFrom->isSelected())
+ l->append((KviAliasListViewItem *)pStartFrom);
+ } else {
+ l->append((KviAliasListViewItem *)pStartFrom);
+ }
+ } else {
+ if(bSelectedOnly)
+ {
+ if(pStartFrom->isSelected())
+ appendAliasItems(l,(KviAliasEditorListViewItem *)(pStartFrom->firstChild()),false); // ALL the items below the selected namespace
+ else
+ appendAliasItems(l,(KviAliasEditorListViewItem *)(pStartFrom->firstChild()),true); // only the selected items below
+ } else {
+ appendAliasItems(l,(KviAliasEditorListViewItem *)(pStartFrom->firstChild()),false);
+ }
+ }
+ appendAliasItems(l,(KviAliasEditorListViewItem *)(pStartFrom->nextSibling()),bSelectedOnly);
+}
+
+void KviAliasEditor::appendNamespaceItems(KviPointerList<KviAliasListViewItem> * l,KviAliasEditorListViewItem * pStartFrom,bool bSelectedOnly)
+{
+ if(!pStartFrom)return;
+ if(pStartFrom->isNamespace())
+ {
+ if(bSelectedOnly)
+ {
+ if(pStartFrom->isSelected())
+ l->append((KviAliasListViewItem *)pStartFrom);
+ } else {
+ l->append((KviAliasListViewItem *)pStartFrom);
+ }
+ } else {
+ if(bSelectedOnly)
+ {
+ if(pStartFrom->isSelected())
+ appendNamespaceItems(l,(KviAliasEditorListViewItem *)(pStartFrom->firstChild()),false); // ALL the items below the selected namespace
+ else
+ appendNamespaceItems(l,(KviAliasEditorListViewItem *)(pStartFrom->firstChild()),true); // only the selected items below
+ } else {
+ appendNamespaceItems(l,(KviAliasEditorListViewItem *)(pStartFrom->firstChild()),false);
+ }
+ }
+ appendNamespaceItems(l,(KviAliasEditorListViewItem *)(pStartFrom->nextSibling()),bSelectedOnly);
+}
+
+void KviAliasEditor::appendSelectedItems(KviPointerList<KviAliasEditorListViewItem> * l,KviAliasEditorListViewItem * pStartFrom,bool bIncludeChildrenOfSelected)
+{
+ if(!pStartFrom)return;
+ if(pStartFrom->isSelected())
+ {
+ l->append(pStartFrom);
+ if(bIncludeChildrenOfSelected)
+ appendSelectedItems(l,(KviAliasEditorListViewItem *)(pStartFrom->firstChild()),bIncludeChildrenOfSelected);
+ } else {
+ appendSelectedItems(l,(KviAliasEditorListViewItem *)(pStartFrom->firstChild()),bIncludeChildrenOfSelected);
+ }
+ appendSelectedItems(l,(KviAliasEditorListViewItem *)(pStartFrom->nextSibling()),bIncludeChildrenOfSelected);
+}
+
+bool KviAliasEditor::removeItem(KviAliasEditorListViewItem *it,bool * pbYesToAll,bool bDeleteEmptyTree)
+{
+ if(!it)return true;
+ QString szMsg;
+ QString szName = it->name();
+
+ if(!*pbYesToAll)
+ {
+ if(it->isAlias())
+ KviQString::sprintf(szMsg,__tr2qs("Do you really want to remove the alias \"%Q\" ?"),&szName);
+ else {
+ KviQString::sprintf(szMsg,__tr2qs("Do you really want to remove the namespace \"%Q\" ?"),&szName);
+ szMsg += "<br>";
+ szMsg += __tr2qs("Please note that all the children items will be deleted too.");
+ }
+
+ g_pAliasEditorModule->lock();
+ int ret = QMessageBox::question(this,__tr2qs("Remove item"),szMsg,__tr2qs("Yes"),__tr2qs("Yes to All"),__tr2qs("No"));
+ 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(bDeleteEmptyTree)
+ {
+ while(it)
+ {
+ KviAliasEditorListViewItem * par = (KviAliasEditorListViewItem *)(it->parent());
+ delete it;
+ if(par)
+ {
+ if(!par->firstChild())it = par;
+ else it = 0;
+ } else {
+ it = 0;
+ }
+ }
+ } else {
+ delete it;
+ }
+ return true;
+}
+
+void KviAliasEditor::removeSelectedItems()
+{
+ KviPointerList<KviAliasEditorListViewItem> l;
+ l.setAutoDelete(false);
+ appendSelectedItems(&l,(KviAliasEditorListViewItem *)(m_pListView->firstChild()),false);
+
+ bool bYesToAll = false;
+
+ for(KviAliasEditorListViewItem *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(
+ szAction,
+ szText,
+ QLineEdit::Normal,
+ szInitialText,
+ &bOk,
+ this);
+ g_pAliasEditorModule->unlock();
+ if(!bOk)return QString::null;
+ if(szNewName.isEmpty())
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::warning(this,
+ __tr2qs("Missing Alias Name"),
+ __tr2qs("You must specify a valid name for the alias"),
+ __tr2qs("Ok, Let me try again..."));
+ g_pAliasEditorModule->unlock();
+ continue;
+ }
+
+ // we allow only [\w:]+
+ QRegExp re("[\\w:]+");
+ if(!re.exactMatch(szNewName))
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs("Bad Alias Name"),
+ __tr2qs("Alias names can contain only letters, digits, underscores and '::' namespace separators"),
+ __tr2qs("Ok, Let me try again..."));
+ 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.find(":") != -1)
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs("Bad Alias Name"),
+ __tr2qs("Stray ':' character in alias name: did you mean ...<namespace>::<name> ?"),
+ __tr2qs("Ok, Let me try again..."));
+ g_pAliasEditorModule->unlock();
+ szNewName = "";
+ continue;
+ }
+ if(tmp.find("@@") != -1)
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs("Bad Alias Name"),
+ __tr2qs("Found an empty namespace in alias name"),
+ __tr2qs("Ok, Let me try again..."));
+ 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(
+ szAction,
+ szText,
+ QLineEdit::Normal,
+ szInitialText,
+ &bOk,
+ this);
+ g_pAliasEditorModule->unlock();
+ if(!bOk)return QString::null;
+ if(szNewName.isEmpty())
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::warning(this,
+ __tr2qs("Missing Namespace Name"),
+ __tr2qs("You must specify a valid name for the namespace"),
+ __tr2qs("Ok, Let me try again..."));
+ g_pAliasEditorModule->unlock();
+ continue;
+ }
+
+ // we allow only [\w:]+
+ QRegExp re("[\\w:]+");
+ if(!re.exactMatch(szNewName))
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs("Bad Namespace Name"),
+ __tr2qs("Namespace names can contain only letters, digits, underscores and '::' namespace separators"),
+ __tr2qs("Ok, Let me try again..."));
+ 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.find(":") != -1)
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs("Bad Namespace Name"),
+ __tr2qs("Stray ':' character in namespace name: did you mean ...<namespace>::<name> ?"),
+ __tr2qs("Ok, Let me try again..."));
+ g_pAliasEditorModule->unlock();
+ szNewName = "";
+ continue;
+ }
+ if(tmp.find("@@") != -1)
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs("Bad Namespace Name"),
+ __tr2qs("Found an empty namespace in namespace name"),
+ __tr2qs("Ok, Let me try again..."));
+ g_pAliasEditorModule->unlock();
+ szNewName = "";
+ continue;
+ }
+ }
+ return szNewName;
+}
+
+void KviAliasEditor::openParentItems(KviTalListViewItem * it)
+{
+ if(it->parent())
+ {
+ it->parent()->setOpen(true);
+ openParentItems(it->parent());
+ }
+}
+
+
+void KviAliasEditor::selectOneItem(KviTalListViewItem * it,KviTalListViewItem *pStartFrom)
+{
+ if(!pStartFrom)return;
+ if(pStartFrom == it)pStartFrom->setSelected(true);
+ else pStartFrom->setSelected(false);
+ selectOneItem(it,pStartFrom->firstChild());
+ selectOneItem(it,pStartFrom->nextSibling());
+}
+
+
+void KviAliasEditor::activateItem(KviTalListViewItem * it)
+{
+ openParentItems(it);
+ selectOneItem(it,m_pListView->firstChild());
+ m_pListView->setCurrentItem(it);
+}
+
+
+void KviAliasEditor::newAlias()
+{
+ if(m_pLastClickedItem)
+ {
+ if(!itemExists(m_pLastClickedItem,m_pListView->firstChild()))return; // dead ?
+ if(m_pLastClickedItem->isAlias())
+ m_pLastClickedItem = m_pLastClickedItem->parentNamespaceItem();
+ }
+
+ QString szNewName = askForAliasName(__tr2qs("Add Alias"),__tr2qs("Please enter the name for the new alias"),"myfunction");
+ if(szNewName.isEmpty())return;
+
+ getUniqueItemName(m_pLastClickedItem,szNewName,KviAliasEditorListViewItem::Alias);
+
+ KviAliasListViewItem * it;
+
+ if(m_pLastClickedItem)
+ it = ((KviAliasNamespaceListViewItem *)m_pLastClickedItem)->createFullAliasItem(szNewName);
+ else
+ it = createFullAliasItem(szNewName);
+
+ activateItem(it);
+}
+
+void KviAliasEditor::newNamespace()
+{
+ if(m_pLastClickedItem)
+ {
+ if(!itemExists(m_pLastClickedItem,m_pListView->firstChild()))return; // dead ?
+ if(m_pLastClickedItem->isAlias())
+ m_pLastClickedItem = m_pLastClickedItem->parentNamespaceItem();
+ }
+
+
+ QString szNewName = askForNamespaceName(__tr2qs("Add Namespace"),__tr2qs("Please enter the name for the new namespace"),"mynamespace");
+ if(szNewName.isEmpty())return;
+
+ getUniqueItemName(m_pLastClickedItem,szNewName,KviAliasEditorListViewItem::Namespace);
+
+ KviAliasNamespaceListViewItem * it;
+
+ if(m_pLastClickedItem)
+ it = ((KviAliasNamespaceListViewItem *)m_pLastClickedItem)->createFullNamespaceItem(szNewName);
+ else
+ it = createFullNamespaceItem(szNewName);
+
+ activateItem(it);
+}
+
+bool KviAliasEditor::aliasExists(QString &szFullItemName)
+{
+ KviPointerList<KviAliasListViewItem> l;
+ l.setAutoDelete(false);
+
+ appendAliasItems(&l,(KviAliasEditorListViewItem *)(m_pListView->firstChild()),false);
+ for(KviAliasListViewItem * it = l.first();it;it = l.next())
+ {
+ if (KviQString::equalCI(buildFullItemName(it),szFullItemName))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool KviAliasEditor::namespaceExists(QString &szFullItemName)
+{
+ KviPointerList<KviAliasListViewItem> l;
+ l.setAutoDelete(false);
+
+ appendNamespaceItems(&l,(KviAliasEditorListViewItem *)(m_pListView->firstChild()),false);
+ for(KviAliasListViewItem * 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,m_pListView->firstChild()))return; // dead ?
+
+ QString szName = buildFullItemName(m_pLastEditedItem);
+ QString szNewName;
+
+ bool bAlias = m_pLastEditedItem->isAlias();
+
+ if(bAlias)
+ szNewName = askForAliasName(__tr2qs("Rename Alias"),__tr2qs("Please enter the new name for the alias"),szName);
+ else
+ szNewName = askForNamespaceName(__tr2qs("Rename Namespace"),__tr2qs("Please enter the new name for the namespace"),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("Alias already exists"),
+ __tr2qs("This name is already in use. Please choose another one."),
+ __tr2qs("Ok, Let me try again..."));
+ g_pAliasEditorModule->unlock();
+ return;
+ }
+ } else {
+ // check if there is already a anmespace with this name
+ if (namespaceExists(szNewName))
+ {
+ g_pAliasEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs("Namespace already exists"),
+ __tr2qs("This name is already in use. Please choose another one."),
+ __tr2qs("Ok, let me try again..."));
+ g_pAliasEditorModule->unlock();
+ return;
+ }
+ }
+
+ QString szCode;
+ QPoint pntCursor;
+ if(bAlias)
+ {
+ m_pEditor->getText(szCode);
+ pntCursor = m_pEditor->getCursor();
+ }
+
+ // take child items, if any
+ KviPointerList<KviTalListViewItem> lChildren;
+ lChildren.setAutoDelete(false);
+ KviTalListViewItem * it = m_pLastEditedItem->firstChild();
+ while(it)
+ {
+ lChildren.append(it);
+ it = it->nextSibling();
+ }
+ for(it = lChildren.first();it;it = lChildren.next())
+ m_pLastEditedItem->takeItem(it);
+
+ 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())
+
+ if(bAlias)
+ {
+ KviAliasListViewItem * ait = createFullAliasItem(szNewName);
+ ait->setBuffer(szCode);
+ ait->setCursorPosition(pntCursor);
+ activateItem(ait);
+
+ for(it = lChildren.first();it;it = lChildren.next())
+ ait->insertItem(it);
+ } else {
+ KviAliasNamespaceListViewItem * nit = createFullNamespaceItem(szNewName);
+ activateItem(nit);
+
+ for(it = lChildren.first();it;it = lChildren.next())
+ {
+ ((KviAliasEditorListViewItem*)it)->setParentNamespaceItem(nit);
+ nit->insertItem(it);
+ }
+ }
+}
+
+// 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(!m_pEditor->isModified())return; // nothing to save
+ if(!itemExists(m_pLastEditedItem,m_pListView->firstChild()))return; // dead ?
+
+ if(m_pLastEditedItem->isNamespace())return;
+
+ QString newCode;
+ m_pEditor->getText(newCode);
+ ((KviAliasListViewItem *)m_pLastEditedItem)->setBuffer(newCode);
+ ((KviAliasListViewItem *)m_pLastEditedItem)->setCursorPosition(m_pEditor->getCursor());
+}
+
+void KviAliasEditor::currentItemChanged(KviTalListViewItem *it)
+{
+ saveLastEditedItem();
+
+ m_pLastEditedItem = (KviAliasEditorListViewItem *)it;
+
+ if(!m_pLastEditedItem)
+ {
+ m_pNameLabel->setText(__tr2qs("No item selected"));
+ m_pRenameButton->setEnabled(false);
+ m_pEditor->setText("");
+ m_pEditor->setEnabled(false);
+ return;
+ }
+
+ QString szNam = buildFullItemName(m_pLastEditedItem);
+ if(m_pLastEditedItem->isNamespace())
+ {
+ QString szLabelText = __tr2qs("Namespace");
+ szLabelText += ": <b>";
+ szLabelText += szNam;
+ szLabelText += "</b>";
+ m_pNameLabel->setText(szLabelText);
+ m_pRenameButton->setEnabled(true);
+ m_pEditor->setText("");
+ m_pEditor->setEnabled(false);
+ return;
+ }
+
+ QString szLabelText = __tr2qs("Alias");
+ szLabelText += ": <b>";
+ szLabelText += szNam;
+ szLabelText += "</b>";
+ m_pNameLabel->setText(szLabelText);
+ m_pRenameButton->setEnabled(true);
+ m_pEditor->setText(((KviAliasListViewItem *)it)->buffer());
+ m_pEditor->setCursorPosition(((KviAliasListViewItem *)it)->cursorPosition());
+ m_pEditor->setEnabled(true);
+}
+
+void KviAliasEditor::recursiveCommit(KviAliasEditorListViewItem * it)
+{
+ if(!it)return;
+ if(it->isAlias())
+ {
+ QString szName = buildFullItemName(it);
+ //debug("ADDING %s",szName.latin1());
+ // WARNING: On MSVC operator new here is valid ONLY because
+ // KviKvsScript has a non virtual detructor!
+ KviKvsScript * a = new KviKvsScript(szName,((KviAliasListViewItem *)it)->buffer());
+ KviKvsAliasManager::instance()->add(szName,a);
+ } else {
+ recursiveCommit((KviAliasEditorListViewItem *)(it->firstChild()));
+ }
+ recursiveCommit((KviAliasEditorListViewItem *)(it->nextSibling()));
+}
+
+
+void KviAliasEditor::commit()
+{
+ saveLastEditedItem();
+ KviKvsAliasManager::instance()->clear();
+
+ recursiveCommit((KviAliasEditorListViewItem *)(m_pListView->firstChild()));
+
+ g_pApp->saveAliases();
+}
+
+
+void KviAliasEditor::getUniqueItemName(KviAliasEditorListViewItem *item,QString &buffer,KviAliasEditorListViewItem::Type eType)
+{
+ QString ret;
+
+ int idx = 0;
+ KviAliasEditorListViewItem * found;
+
+ for(;;)
+ {
+ ret = buffer;
+ if(idx > 0)
+ {
+ QString tmp;
+ tmp.setNum(idx);
+ ret.append(tmp);
+ }
+
+ if(item)
+ {
+ if(!item->isNamespace())
+ {
+ buffer = ret;
+ return;
+ }
+
+ if(eType == KviAliasEditorListViewItem::Namespace)
+ found = ((KviAliasNamespaceListViewItem *)item)->findNamespaceItem(ret);
+ else
+ found = ((KviAliasNamespaceListViewItem *)item)->findAliasItem(ret);
+ } else {
+ if(eType == KviAliasEditorListViewItem::Namespace)
+ found = findNamespaceItem(ret);
+ else
+ found = findAliasItem(ret);
+ }
+
+ if(!found)
+ {
+ buffer = ret;
+ return;
+ }
+
+ idx++;
+ }
+}
+
+
+
+
+KviAliasEditorWindow::KviAliasEditorWindow(KviFrame * lpFrm)
+: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"aliaseditor",0)
+{
+ g_pAliasEditorWindow = this;
+
+ setFixedCaption(__tr2qs("Alias Editor"));
+
+ m_pEditor = new KviAliasEditor(this);
+
+ m_pBase = new QWidget(this);
+ QGridLayout * g = new QGridLayout(m_pBase,1,4,4,4);
+
+ QPushButton * btn = new QPushButton(__tr2qs("&OK"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(okClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,1);
+
+ btn = new QPushButton(__tr2qs("&Apply"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,2);
+
+ btn = new QPushButton(__tr2qs("Cancel"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ g->addWidget(btn,0,3);
+
+ g->setColStretch(0,1);
+}
+
+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::resizeEvent(QResizeEvent *e)
+{
+ int hght = m_pBase->sizeHint().height();
+ m_pEditor->setGeometry(0,0,width(),height()- hght);
+ m_pBase->setGeometry(0,height() - hght,width(),hght);
+}
+
+
+void KviAliasEditorWindow::getConfigGroupName(KviStr &szName)
+{
+ szName = "aliaseditor";
+}
+
+
+void KviAliasEditorWindow::saveProperties(KviConfig *cfg)
+{
+ m_pEditor->saveProperties(cfg);
+}
+
+
+
+void KviAliasEditorWindow::loadProperties(KviConfig *cfg)
+{
+ m_pEditor->loadProperties(cfg);
+}
diff --git a/src/modules/aliaseditor/aliaseditor.h b/src/modules/aliaseditor/aliaseditor.h
new file mode 100644
index 00000000..fa49fc96
--- /dev/null
+++ b/src/modules/aliaseditor/aliaseditor.h
@@ -0,0 +1,197 @@
+#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-2005 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 "kvi_window.h"
+#include "kvi_string.h"
+#include "kvi_pointerlist.h"
+
+
+#include <qwidget.h>
+#include "kvi_tal_listview.h"
+#include <qlineedit.h>
+#include "kvi_tal_popupmenu.h"
+#include <qstringlist.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+
+class KviScriptEditor;
+class KviAliasNamespaceListViewItem;
+
+
+class KviAliasEditorListViewItem : public KviTalListViewItem
+{
+public:
+ enum Type { Alias, Namespace };
+public:
+ KviAliasEditorListViewItem(KviTalListView * pListView,Type eType,const QString &szName);
+ KviAliasEditorListViewItem(KviAliasNamespaceListViewItem * pParentNamespaceItem,Type eType,const QString &szName);
+ ~KviAliasEditorListViewItem(){};
+protected:
+ Type m_eType;
+ KviAliasNamespaceListViewItem * m_pParentNamespaceItem;
+ QString m_szName;
+public:
+ const QString & name(){ return m_szName; };
+ void setName(const QString &szName);
+ Type type(){ return m_eType; };
+ bool isAlias(){ return m_eType == Alias; };
+ bool isNamespace(){ return m_eType == Namespace; };
+ void setParentNamespaceItem(KviAliasNamespaceListViewItem* it){ m_pParentNamespaceItem=it; };
+ KviAliasNamespaceListViewItem * parentNamespaceItem(){ return m_pParentNamespaceItem; };
+ virtual QString key(int column,bool bAsc) const;
+};
+
+class KviAliasListViewItem;
+
+class KviAliasNamespaceListViewItem : public KviAliasEditorListViewItem
+{
+public:
+ KviAliasNamespaceListViewItem(KviTalListView * pListView,const QString &szName);
+ KviAliasNamespaceListViewItem(KviAliasNamespaceListViewItem * pParentNamespace,const QString &szName);
+ ~KviAliasNamespaceListViewItem(){};
+public:
+ KviAliasNamespaceListViewItem * findNamespaceItem(const QString &szName);
+ KviAliasNamespaceListViewItem * getNamespaceItem(const QString &szName);
+ KviAliasListViewItem * findAliasItem(const QString &szName);
+ KviAliasListViewItem * getAliasItem(const QString &szName);
+ KviAliasListViewItem * createFullAliasItem(const QString &szFullName);
+ KviAliasNamespaceListViewItem * createFullNamespaceItem(const QString &szFullName);
+};
+
+
+class KviAliasListViewItem : public KviAliasEditorListViewItem
+{
+public:
+ KviAliasListViewItem(KviAliasNamespaceListViewItem * pParentNamespace,const QString &szName);
+ KviAliasListViewItem(KviTalListView *pListView,const QString &szName);
+ ~KviAliasListViewItem(){};
+public:
+ QString m_szBuffer;
+ QPoint m_cPos;
+public:
+ const QString & buffer(){ return m_szBuffer; };
+ const QPoint & cursorPosition(){ return m_cPos; };
+ void setBuffer(const QString &szBuffer){ m_szBuffer = szBuffer; };
+ void setCursorPosition(const QPoint &cPos){ m_cPos = cPos; };
+};
+
+class QSplitter;
+
+class KviAliasEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ KviAliasEditor(QWidget * par);
+ ~KviAliasEditor();
+public:
+ KviScriptEditor * m_pEditor;
+ KviTalListView * m_pListView;
+ QLabel * m_pNameLabel;
+ QPushButton * m_pRenameButton;
+ KviAliasEditorListViewItem * m_pLastEditedItem;
+ KviAliasEditorListViewItem * m_pLastClickedItem;
+ //KviAliasListViewItem * m_pLastEditedItem;
+ KviTalPopupMenu * m_pContextPopup;
+ QSplitter * m_pSplitter;
+ QString m_szDir;
+public:
+ //bool modified(){ return m_bModified; };
+ void commit();
+ void exportAliases(bool,bool=false);
+ void exportSelectionInSinglesFiles(KviPointerList<KviAliasListViewItem> *l);
+
+ void saveProperties(KviConfig *);
+ void loadProperties(KviConfig *);
+ static void splitFullAliasOrNamespaceName(const QString &szFullName,QStringList &lNamespaces,QString &szName);
+protected slots:
+ void currentItemChanged(KviTalListViewItem *it);
+ void newAlias();
+ void newNamespace();
+ void exportAll();
+ void exportSelectedSepFiles();
+ void exportSelected();
+ void removeSelectedItems();
+ void itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col);
+ void renameItem();
+ void slotFind();
+ void slotCollapseNamespaces();
+ void slotFindWord(const QString &);
+ void slotReplaceAll(const QString &before,const QString &after);
+protected:
+// QString const & findWord(const QString &txt,bool);
+ void recursiveCollapseNamespaces(KviAliasEditorListViewItem * it);
+ void recursiveSearchReplace(const QString &szSearch,KviAliasEditorListViewItem * it,bool bReplace=false,const QString &szReplace="n");
+
+ void recursiveCommit(KviAliasEditorListViewItem * it);
+ void getExportAliasBuffer(QString &buffer,KviAliasListViewItem * it);
+ void oneTimeSetup();
+ void selectOneItem(KviTalListViewItem * it,KviTalListViewItem *pStartFrom);
+ void saveLastEditedItem();
+ void getUniqueItemName(KviAliasEditorListViewItem *item,QString &buffer,KviAliasEditorListViewItem::Type eType);
+ void appendSelectedItems(KviPointerList<KviAliasEditorListViewItem> * l,KviAliasEditorListViewItem * pStartFrom,bool bIncludeChildrenOfSelected = false);
+ void appendAliasItems(KviPointerList<KviAliasListViewItem> * l,KviAliasEditorListViewItem * pStartFrom,bool bSelectedOnly);
+ void appendNamespaceItems(KviPointerList<KviAliasListViewItem> * l,KviAliasEditorListViewItem * pStartFrom,bool bSelectedOnly);
+ bool removeItem(KviAliasEditorListViewItem *it,bool * pbYesToAll,bool bDeleteEmptyTree);
+ void openParentItems(KviTalListViewItem * it);
+ void activateItem(KviTalListViewItem * 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(KviTalListViewItem *pSearchFor,KviTalListViewItem * pSearchAt);
+ bool namespaceExists(QString &szFullItemName);
+ bool aliasExists(QString &szFullItemName);
+ bool hasSelectedItems(KviTalListViewItem * it);
+ KviAliasNamespaceListViewItem * findNamespaceItem(const QString &szName);
+ KviAliasNamespaceListViewItem * getNamespaceItem(const QString &szName);
+ KviAliasListViewItem * findAliasItem(const QString &szName);
+ KviAliasListViewItem * getAliasItem(const QString &szName);
+ KviAliasListViewItem * createFullAliasItem(const QString &szFullName);
+ KviAliasNamespaceListViewItem * createFullNamespaceItem(const QString &szFullName);
+ QString buildFullItemName(KviAliasEditorListViewItem * it);
+};
+
+
+class KviAliasEditorWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviAliasEditorWindow(KviFrame * lpFrm);
+ ~KviAliasEditorWindow();
+protected:
+ KviAliasEditor * m_pEditor;
+ QWidget * m_pBase;
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void getConfigGroupName(KviStr &szName);
+ virtual void saveProperties(KviConfig *);
+ virtual void loadProperties(KviConfig *);
+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
new file mode 100644
index 00000000..079197c7
--- /dev/null
+++ b/src/modules/aliaseditor/libkvialiaseditor.cpp
@@ -0,0 +1,90 @@
+//==========================================================================================
+//
+// File : libkvialiaseditor.cpp
+// Creation date : Mon 23 Dec 2002 14:30:59 2002 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2002-2005 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_module.h"
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+
+#include "aliaseditor.h"
+KviAliasEditorWindow * g_pAliasEditorWindow = 0;
+KviModule * g_pAliasEditorModule = 0;
+
+
+/*
+ @doc: aliaseditor.open
+ @type:
+ command
+ @title:
+ aliaseditor.open
+ @short:
+ Shows the alias editor
+ @syntax:
+ aliaseditor.open
+ @description:
+ Opens the script alias editor dialog.
+*/
+
+static bool aliaseditor_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ if(!g_pAliasEditorWindow)
+ {
+ g_pAliasEditorWindow = new KviAliasEditorWindow(c->window()->frame());
+ c->window()->frame()->addWindow(g_pAliasEditorWindow);
+ }
+
+ g_pAliasEditorWindow->setFocus();
+
+ return true;
+}
+
+static bool aliaseditor_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",aliaseditor_kvs_cmd_open);
+ g_pAliasEditorWindow = 0;
+ g_pAliasEditorModule = m;
+ return true;
+}
+
+static bool aliaseditor_module_can_unload(KviModule * m)
+{
+ return (g_pAliasEditorWindow == 0);
+}
+
+static bool aliaseditor_module_cleanup(KviModule *m)
+{
+ if(g_pAliasEditorWindow)delete g_pAliasEditorWindow;
+ g_pAliasEditorWindow = 0;
+ return true;
+}
+
+KVIRC_MODULE(
+ "AliasEditor", // module name
+ "2.0.0", // module version
+ "Copyright (C) 2002-2005 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Editor for the script aliases",
+ aliaseditor_module_init,
+ aliaseditor_module_can_unload,
+ 0,
+ aliaseditor_module_cleanup
+)
diff --git a/src/modules/avatar/Makefile.am b/src/modules/avatar/Makefile.am
new file mode 100644
index 00000000..8e8a793a
--- /dev/null
+++ b/src/modules/avatar/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviavatar.la
+
+libkviavatar_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviavatar_la_SOURCES = libkviavatar.cpp
+nodist_libkviavatar_la_SOURCES = moc_libkviavatar.cpp
+
+libkviavatar_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS = libkviavatar.h
+
+moc_%.cpp: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/avatar/libkviavatar.cpp b/src/modules/avatar/libkviavatar.cpp
new file mode 100644
index 00000000..e97b1f67
--- /dev/null
+++ b/src/modules/avatar/libkviavatar.cpp
@@ -0,0 +1,585 @@
+//=============================================================================
+//
+// File : libkviavatar.cpp
+// Creation date : Thu Nov 12 02:32:59 2004 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2004 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 "libkviavatar.h"
+
+#include "kvi_module.h"
+#include "kvi_fileutils.h"
+#include "kvi_locale.h"
+#include "kvi_malloc.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_http.h"
+#include "kvi_iconmanager.h"
+#include "kvi_avatar.h"
+#include "kvi_ircuserdb.h"
+
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_console.h"
+#include "kvi_filedialog.h"
+#include "kvi_pointerlist.h"
+#include "kvi_frame.h"
+#include "kvi_sharedfiles.h"
+#include "kvi_out.h"
+#include "kvi_ircmask.h"
+#include "kvi_qcstring.h"
+
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qmessagebox.h>
+#include <qtimer.h>
+#include <qlabel.h>
+#include "kvi_tal_hbox.h"
+#include <qlayout.h>
+
+static KviPointerList<KviAsyncAvatarSelectionDialog> * g_pAvatarSelectionDialogList = 0;
+extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager;
+
+KviAsyncAvatarSelectionDialog::KviAsyncAvatarSelectionDialog(QWidget * par,const QString &szInitialPath,KviIrcConnection * c)
+: QDialog(par,0,false,Qt::WType_Dialog | Qt::WStyle_DialogBorder | Qt::WStyle_StaysOnTop)
+{
+ g_pAvatarSelectionDialogList->append(this);
+
+ m_pConnection = c;
+
+ setCaption(__tr2qs("Choose Avatar - KVIrc"));
+
+ QGridLayout * g = new QGridLayout(this,3,3,4,8);
+
+ QString msg = "<center>";
+ msg += __tr2qs("Please select an avatar image. " \
+ "The full path to a local file or an image on the Web can be used.<br>" \
+ "If you wish to use a local image file, click the \"<b>Browse</b>\"" \
+ "button to browse local folders.<br>" \
+ "The full URL for an image (including <b>http://</b>) can be entered manually.");
+ msg += "</center><br>";
+
+ QLabel * l = new QLabel(msg,this);
+ l->setMinimumWidth(250);
+
+ g->addMultiCellWidget(l,0,0,0,2);
+
+ m_pLineEdit = new QLineEdit(this);
+ m_pLineEdit->setText(szInitialPath);
+ m_pLineEdit->setMinimumWidth(180);
+
+ g->addMultiCellWidget(m_pLineEdit,1,1,0,1);
+
+ QPushButton * b = new QPushButton(__tr2qs("&Browse..."),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(chooseFileClicked()));
+ g->addWidget(b,1,2);
+ KviTalHBox * h = new KviTalHBox(this);h->setSpacing(8);g->addMultiCellWidget(h,2,2,1,2);
+ b = new QPushButton(__tr2qs("&OK"),h);
+ b->setMinimumWidth(80);
+ b->setDefault(true);
+ connect(b,SIGNAL(clicked()),this,SLOT(okClicked()));
+
+ b = new QPushButton(__tr2qs("Cancel"),h);
+ b->setMinimumWidth(80);
+ connect(b,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+
+ g->setRowStretch(0,1);
+ g->setColStretch(0,1);
+}
+
+KviAsyncAvatarSelectionDialog::~KviAsyncAvatarSelectionDialog()
+{
+ g_pAvatarSelectionDialogList->removeRef(this);
+}
+
+void KviAsyncAvatarSelectionDialog::okClicked()
+{
+ m_szAvatarName = m_pLineEdit->text();
+
+ if(!g_pApp->connectionExists(m_pConnection))return; // the connection no longer exists :/
+
+ if(!m_szAvatarName.isEmpty())
+ {
+ QString tmp = m_szAvatarName;
+ tmp.replace("\\","\\\\");
+ QString szBuffer=QString("avatar.set \"%1\"").arg(tmp);
+ KviKvsScript::run(szBuffer,m_pConnection->console());
+ }
+
+ accept();
+ deleteLater();
+}
+
+void KviAsyncAvatarSelectionDialog::cancelClicked()
+{
+ reject();
+ deleteLater();
+}
+
+void KviAsyncAvatarSelectionDialog::chooseFileClicked()
+{
+ QString tmp;
+ if(KviFileDialog::askForOpenFileName(tmp,__tr2qs("Choose an Image File - KVIrc")))
+ {
+ m_pLineEdit->setText(tmp);
+ }
+}
+
+void KviAsyncAvatarSelectionDialog::closeEvent(QCloseEvent * e)
+{
+ e->ignore();
+ reject();
+ deleteLater();
+}
+
+/*
+ @doc: avatar.set
+ @type:
+ command
+ @title:
+ avatar.set
+ @keyterms:
+ setting your avatar, avatar
+ @short:
+ Sets the local user's avatar
+ @syntax:
+ avatar.set [avatar:string]
+ @description:
+ Sets your avatar in the current connection to <avatar>.
+ <avatar> may be a local filename or a http url.[br]
+ If avatar is an empty string then an asynchronous dialog
+ will be opened that will allow choosing an avatar.[br]
+ Note that this command does NOT notify the avatar to
+ any target: use [cmd]avatar.notify[/cmd] for that purpose.
+ Note also that this will NOT set your default avatar
+ option: you must use the options dialog for that.[br]
+ @examples:
+ [example]
+ avatar.set /home/myavatar.png
+ avatar.set http://www.kvirc.net/img/pragma.png
+ [/example]
+ @seealso:
+ [cmd]avatar.unset[/cmd]
+*/
+
+static bool avatar_kvs_cmd_set(KviKvsModuleCommandCall * c)
+{
+ QString szAvatar;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("avatar",KVS_PT_NONEMPTYSTRING,KVS_PF_OPTIONAL,szAvatar)
+ KVSM_PARAMETERS_END(c)
+
+ KVSM_REQUIRE_CONNECTION(c)
+
+ QString absPath;
+
+ if(szAvatar.isEmpty())
+ {
+ KviAsyncAvatarSelectionDialog * d = new KviAsyncAvatarSelectionDialog(g_pFrame,QString::null,c->window()->connection());
+ d->show();
+ return true;
+ }
+
+ // new avatar specified...try to load it
+
+ KviIrcUserEntry * e = c->window()->connection()->userDataBase()->find(c->window()->connection()->currentNickName());
+ if(!e)
+ {
+ c->warning(__tr2qs("Internal error: I'm not in the user database ?"));
+ return true;
+ }
+
+ KviAvatar * av = g_pIconManager->getAvatar(QString::null,szAvatar);
+ if(av)
+ {
+ // Ok...got it...
+ e->setAvatar(av);
+ c->window()->console()->avatarChanged(av,
+ c->window()->connection()->userInfo()->nickName(),
+ c->window()->connection()->userInfo()->userName(),
+ c->window()->connection()->userInfo()->hostName(),
+ QString::null);
+ } else {
+ bool bIsUrl = KviQString::equalCIN(szAvatar,"http://",7) && (szAvatar.length() > 7);
+
+ if(bIsUrl)
+ {
+ // This is an url, and we don't have a cached copy for now
+ QString szLocalFilePath;
+ QString szLocalFile = szAvatar;
+ g_pIconManager->urlToCachedFileName(szLocalFile);
+ g_pApp->getLocalKvircDirectory(szLocalFilePath,KviApp::Avatars,szLocalFile);
+
+ szLocalFilePath.replace("\\","\\\\");
+
+ QString szCommand = "http.get -w=nm ";
+ szCommand += szAvatar;
+ szCommand += " ";
+ szCommand += szLocalFilePath;
+
+ if(KviKvsScript::run(szCommand,c->window()->console()))
+ {
+ g_pApp->setAvatarOnFileReceived(c->window()->console(),
+ szAvatar,
+ c->window()->connection()->userInfo()->nickName(),
+ c->window()->connection()->userInfo()->userName(),
+ c->window()->connection()->userInfo()->hostName());
+ } else {
+ c->warning(__tr2qs("Can't set the current avatar to '%Q': failed to start the http transfer"),&szAvatar);
+ return true;
+ }
+ } else {
+ c->warning(__tr2qs("Can't set the current avatar to '%Q': can't load the image"),&szAvatar);
+ return true;
+ }
+ }
+
+ return true;
+}
+
+
+/*
+ @doc: avatar.unset
+ @type:
+ command
+ @title:
+ avatar.unset
+ @short:
+ Unsets the local user's avatar
+ @syntax:
+ avatar.unset
+ @description:
+ Unsets the local user's avatar.
+ Note also that this will NOT unset your default avatar
+ option: you must use the options dialog for that.[br]
+ @seealso:
+ [cmd]avatar.set[/cmd]
+*/
+
+static bool avatar_kvs_cmd_unset(KviKvsModuleCommandCall * c)
+{
+ KVSM_REQUIRE_CONNECTION(c)
+
+ KviIrcUserEntry * e = c->window()->connection()->userDataBase()->find(c->window()->connection()->currentNickName());
+ if(!e)
+ {
+ c->warning(__tr2qs("Internal error: I'm not in the user database ?"));
+ return true;
+ }
+
+ e->setAvatar(0);
+ c->window()->console()->avatarChanged(0,
+ c->window()->connection()->userInfo()->nickName(),
+ c->window()->connection()->userInfo()->userName(),
+ c->window()->connection()->userInfo()->hostName(),
+ QString::null);
+
+ return true;
+}
+
+/*
+ @doc: avatar.notify
+ @type:
+ command
+ @title:
+ avatar.notify
+ @short:
+ Notifies the current avatar to a remote target
+ @syntax:
+ avatar.notify [-q] [-t=<timeout:integer>] <target:string>
+ @switches:
+ !sw: -q | --quiet
+ Do not print warnings
+ !sw: -t=<timeout> | --timeout=<integer>
+ @description:
+ Notifies the current avatar to the remote <target> via CTCP AVATAR.
+ See the [doc:ctcp_avatar]avatar protocol documentation[/doc] for the
+ description of the protocol.[br]
+ This has the effect to notify your avatar image to the <target>.[br]
+ The CTCP is sent thru a NOTICE and the current avatar image
+ is added to the public offer list for <timeout> seconds (or a default timeout if the -t switch is not used).[br]
+ If the -q switch is specified, the command executes in quet mode and
+ prints nothing in the current window.[br]
+ If you don't have an avatar set, the ctcp will unset the previous avatar
+ on the target side.[br]
+ [b]Warning:[/b] The implementation of the avatar protocol is actually
+ restricted to KVIrc clients only. In the future other clients may implement it.[br]
+ This command is [doc:connection_dependant_commands]connection dependant[/doc].[br]
+ @examples:
+ [example]
+ [comment]# Notify your current avatar to Pragma[/comment]
+ avatar.notify Pragma
+ [comment]# Notify your avatar to the channel #kvirc and to Pragma[/comment]
+ avatar #kvirc,Pragma
+ [/example]
+ @seealso:
+ [cmd]avatar.set[/cmd], [cmd]avatar.unset[/cmd]
+*/
+
+static bool avatar_kvs_cmd_notify(KviKvsModuleCommandCall * c)
+{
+ QString szTarget;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szTarget)
+ KVSM_PARAMETERS_END(c)
+
+ KVSM_REQUIRE_CONNECTION(c)
+
+ kvs_int_t iTimeout = (kvs_int_t)KVI_OPTION_UINT(KviOption_uintAvatarOfferTimeoutInSecs);
+ if(KviKvsVariant * pTimeout = c->switches()->find('t',"timeout"))
+ {
+ if(!pTimeout->asInteger(iTimeout))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("Invalid timeout specified, using default"));
+ }
+ }
+
+ KviIrcUserEntry * e = c->window()->connection()->userDataBase()->find(c->window()->connection()->currentNickName());
+ if(!e)
+ {
+ c->warning(__tr2qs("Internal error: I'm not in the user database ?"));
+ return true;
+ }
+
+ QString absPath,avatar;
+
+ if(e->avatar())
+ {
+ absPath = e->avatar()->localPath();
+ avatar = e->avatar()->name();
+ }
+
+ KviSharedFile * o = 0;
+ if((!absPath.isEmpty()) && (!avatar.isEmpty()))
+ {
+ bool bTargetIsChan = (szTarget.contains('#') || szTarget.contains('&') || szTarget.contains('!'));
+ if(bTargetIsChan)o = g_pSharedFilesManager->lookupSharedFile(avatar,0);
+ else {
+ KviIrcMask u(szTarget);
+ o = g_pSharedFilesManager->lookupSharedFile(avatar,&u);
+ }
+ if(!o)
+ {
+ // FIXME: #warning "OPTION FOR PERMANENT OR TIMEDOUT OFFER...TIMEDOUT WOULD ALSO NEED TO EXTEND EXISTING OFFERS LIFETIME"
+ QString szUserMask = bTargetIsChan ? QString("*") : szTarget;
+ szUserMask += "!*@*";
+ o = g_pSharedFilesManager->addSharedFile(avatar,absPath,szUserMask,iTimeout);
+ if(!o)
+ {
+ // Don't delete o...it has been already deleted by g_pFileTrader
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("Can't add a file offer for file %Q (huh ? file not readable ?)"),&absPath);
+ return true;
+ }
+
+ if(_OUTPUT_VERBOSE)
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Added %d secs file offer for file %Q (%Q) and receiver %Q"),
+ iTimeout,&(o->absFilePath()),&avatar,&(o->userMask()));
+ }
+ }
+ }
+
+ if(!c->switches()->find('q',"quiet"))
+ c->window()->output(KVI_OUT_AVATAR,__tr2qs("Notifying avatar '%Q' to %Q"),&avatar,&szTarget);
+
+ KviQCString encodedTarget = c->window()->connection()->encodeText(szTarget);
+
+ if(!avatar.isEmpty())
+ {
+ KviQCString encodedAvatar = c->window()->connection()->encodeText(avatar);
+
+ if(o)
+ {
+ c->window()->connection()->sendFmtData("NOTICE %s :%cAVATAR %s %u%c",encodedTarget.data(),0x01,
+ encodedAvatar.data(),o->fileSize(),0x01);
+ } else {
+ c->window()->connection()->sendFmtData("NOTICE %s :%cAVATAR %s%c",encodedTarget.data(),0x01,
+ encodedAvatar.data(),0x01);
+ }
+ } else {
+ c->window()->connection()->sendFmtData("NOTICE %s :%cAVATAR%c",encodedTarget.data(),0x01,0x01);
+ }
+
+ return true;
+}
+
+/*
+ @doc: avatar.name
+ @type:
+ function
+ @title:
+ $avatar.name
+ @short:
+ Returns the avatar name for the specified user
+ @syntax:
+ <string> $avatar.name
+ <string> $avatar.name(<nick:string>)
+ @description:
+ Returns the name of the avatar belonging to <nick> in the current IRC context.
+ If <nick> is omitted then the name of the avatar of the current local user
+ is returned. The returned string is empty if the specified user has no
+ avatar set or there is no such user at all.
+ @seealso:
+ [fnc]$avatar.path[/fnc]
+*/
+
+static bool avatar_kvs_fnc_name(KviKvsModuleFunctionCall * c)
+{
+ QString szNick;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("nick",KVS_PT_STRING,KVS_PF_OPTIONAL,szNick)
+ KVSM_PARAMETERS_END(c)
+
+ KVSM_REQUIRE_CONNECTION(c)
+
+ if(szNick.isEmpty())szNick = c->window()->connection()->currentNickName();
+
+ KviIrcUserEntry * e = c->window()->connection()->userDataBase()->find(szNick);
+ if(e)
+ {
+ if(e->avatar())
+ {
+ c->returnValue()->setString(e->avatar()->name());
+ return true;
+ }
+ }
+ c->returnValue()->setNothing();
+ return true;
+}
+
+/*
+ @doc: avatar.path
+ @type:
+ function
+ @title:
+ $avatar.path
+ @short:
+ Returns the avatar path for the specified user
+ @syntax:
+ <string> $avatar.path
+ <string> $avatar.path(<nick:string>)
+ @description:
+ Returns the local path of the avatar belonging to <nick> in the current IRC context.
+ If <nick> is omitted then the path of the avatar of the current local user
+ is returned. The returned string is empty if the specified user has no
+ avatar set or there is no such user at all.
+ @seealso:
+ [fnc]$avatar.name[/fnc]
+*/
+
+static bool avatar_kvs_fnc_path(KviKvsModuleFunctionCall * c)
+{
+ QString szNick;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("path",KVS_PT_STRING,KVS_PF_OPTIONAL,szNick)
+ KVSM_PARAMETERS_END(c)
+
+ KVSM_REQUIRE_CONNECTION(c)
+
+ if(szNick.isEmpty())szNick = c->window()->connection()->currentNickName();
+
+ KviIrcUserEntry * e = c->window()->connection()->userDataBase()->find(szNick);
+ if(e)
+ {
+ if(e->avatar())
+ {
+ c->returnValue()->setString(e->avatar()->localPath());
+ return true;
+ }
+ }
+ c->returnValue()->setNothing();
+ return true;
+}
+
+/*
+ @doc: avatar.query
+ @type:
+ command
+ @title:
+ avatar.query
+ @short:
+ Queries the avatar of a remote target
+ @syntax:
+ avatar.query <target:string>
+ @description:
+ Queries the avatar of a remote target via CTCP AVATAR.
+ The <target> can be a channel or a nickname.
+ This command is equivalent to "[cmd]ctcp[/cmd] <target> AVATAR".
+ @seealso:
+ [cmd]avatar.set[/cmd]
+*/
+
+static bool avatar_kvs_cmd_query(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KVSM_REQUIRE_CONNECTION(c)
+
+ KviQCString target = c->window()->connection()->encodeText(szName);
+ c->window()->connection()->sendFmtData("PRIVMSG %s :%cAVATAR%c",target.data(),0x01,0x01);
+
+ return true;
+}
+
+static bool avatar_module_init(KviModule * m)
+{
+ g_pAvatarSelectionDialogList = new KviPointerList<KviAsyncAvatarSelectionDialog>;
+ g_pAvatarSelectionDialogList->setAutoDelete(false);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"query",avatar_kvs_cmd_query);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"set",avatar_kvs_cmd_set);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"unset",avatar_kvs_cmd_set);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"notify",avatar_kvs_cmd_notify);
+
+ KVSM_REGISTER_FUNCTION(m,"name",avatar_kvs_fnc_name);
+ KVSM_REGISTER_FUNCTION(m,"path",avatar_kvs_fnc_path);
+
+ return true;
+}
+
+static bool avatar_module_can_unload(KviModule *m)
+{
+ return g_pAvatarSelectionDialogList->isEmpty();
+}
+
+static bool avatar_module_cleanup(KviModule *m)
+{
+ while(KviAsyncAvatarSelectionDialog * d = g_pAvatarSelectionDialogList->first())
+ delete d;
+ delete g_pAvatarSelectionDialogList;
+ return true;
+}
+
+KVIRC_MODULE(
+ "Avatar",
+ "1.0.0",
+ "Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net)",
+ "Avatar manipulation routines",
+ avatar_module_init,
+ avatar_module_can_unload,
+ 0,
+ avatar_module_cleanup
+)
diff --git a/src/modules/avatar/libkviavatar.h b/src/modules/avatar/libkviavatar.h
new file mode 100644
index 00000000..d30b4233
--- /dev/null
+++ b/src/modules/avatar/libkviavatar.h
@@ -0,0 +1,54 @@
+#ifndef _LIBKVIAVATAR_H_
+#define _LIBKVIAVATAR_H_
+//=============================================================================
+//
+// File : libkviavatar.cpp
+// Creation date : Thu Nov 12 02:32:59 2004 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2004 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 "kvi_qstring.h"
+#include <qdialog.h>
+
+class QLineEdit;
+class KviIrcConnection;
+
+class KviAsyncAvatarSelectionDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviAsyncAvatarSelectionDialog(QWidget * par,const QString &szInitialPath,KviIrcConnection * c);
+ ~KviAsyncAvatarSelectionDialog();
+protected:
+ QLineEdit * m_pLineEdit;
+ QString m_szAvatarName;
+ KviIrcConnection * m_pConnection;
+protected:
+ virtual void closeEvent(QCloseEvent * e);
+ const QString &avatarName(){ return m_szAvatarName; };
+protected slots:
+ void okClicked();
+ void cancelClicked();
+ void chooseFileClicked();
+};
+
+
+#endif //!_LIBKVIAVATAR_H_
diff --git a/src/modules/chan/Makefile.am b/src/modules/chan/Makefile.am
new file mode 100644
index 00000000..620836ac
--- /dev/null
+++ b/src/modules/chan/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makefile - 31.01.2002 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvichan.la
+
+libkvichan_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvichan_la_SOURCES = libkvichan.cpp
+libkvichan_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/chan/libkvichan.cpp b/src/modules/chan/libkvichan.cpp
new file mode 100644
index 00000000..99f8e38e
--- /dev/null
+++ b/src/modules/chan/libkvichan.cpp
@@ -0,0 +1,1635 @@
+//=============================================================================
+//
+// File : libkvichan.cpp
+// Creation date : Sun Feb 02 2002 05:27:11 GMT by Szymon Stefanek
+//
+// This chan is part of the KVirc irc client distribution
+// Copyright (C) 2002-2005 Szymon Stefanek (pragma@kvirc.net)
+// Copyright (C) 2002-2004 Juanjo Alvarez (juanjux@yahoo.es)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under 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_module.h"
+#include "kvi_string.h"
+#include "kvi_app.h"
+#include "kvi_channel.h"
+#include "kvi_locale.h"
+#include "kvi_topicw.h"
+#include "kvi_ircmask.h"
+#include "kvi_maskeditor.h"
+#include "kvi_ircurl.h"
+#include "kvi_ircconnectiontarget.h"
+#include "kvi_ircconnection.h"
+
+static KviChannel * chan_kvs_find_channel(KviKvsModuleFunctionCall * c,QString &szChan,bool noWarnings=false)
+{
+ if(szChan.isEmpty())
+ {
+ if(c->window()->type() == KVI_WINDOW_TYPE_CHANNEL)return (KviChannel *)(c->window());
+ if(c->window()->type() == KVI_WINDOW_TYPE_DEADCHANNEL)return (KviChannel *)(c->window());
+ if(!noWarnings) c->warning(__tr2qs("The current window is not a channel"));
+ } else {
+ KviWindow * w = g_pApp->findWindow(szChan);
+ if(!w)
+ {
+ if(!noWarnings) c->warning(__tr2qs("Can't find the window with id '%Q'"),&szChan);
+ return 0;
+ }
+ if(w->type() == KVI_WINDOW_TYPE_CHANNEL)return (KviChannel *)w;
+ if(!noWarnings) c->warning(__tr2qs("The specified window (%Q) is not a channel"),&szChan);
+ }
+ return 0;
+}
+
+/*
+ @doc: chan.name
+ @type:
+ function
+ @title:
+ $chan.name
+ @short:
+ Returns the name of a channel
+ @syntax:
+ <string> $chan.name
+ <string> $chan.name(<window_id:string>)
+ @description:
+ The first form returns the name of the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the name of the channel specified by <window_id>.[br]
+ This function works also on dead channels.[br]
+*/
+
+static bool chan_kvs_fnc_name(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) {
+ c->returnValue()->setString(ch->windowName());
+ }
+ return true;
+}
+
+/*
+ @doc: chan.getUrl
+ @type:
+ function
+ @title:
+ $chan.getUrl
+ @short:
+ Returns the URL of a channel
+ @syntax:
+ <string> $chan.getUrl
+ <string> $chan.getUrl(<window_id:string>)
+ <string> $chan.getUrl(<channel_name:string>)
+ @description:
+ Returns IRC URL for this channel
+*/
+
+static bool chan_kvs_fnc_getUrl(KviKvsModuleFunctionCall * c)
+{
+ QString szId,url;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("channel id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId,true);
+ if (ch) {
+ KviIrcUrl::join(url,ch->connection()->target()->server());
+ url.append(ch->windowName());
+ if(ch->hasChannelKey())
+ {
+ url.append('?');
+ url.append(ch->channelKey());
+ }
+ } else {
+ if(c->window()->connection()) {
+ KviIrcUrl::join(url,c->window()->connection()->target()->server());
+ url.append(szId);
+ } else {
+ c->error("There is no active IRC connection for current context");
+ }
+ }
+ c->returnValue()->setString(url);
+ return true;
+}
+
+/*
+ @doc: chan.isDead
+ @type:
+ function
+ @title:
+ $chan.isDead
+ @short:
+ Checks if a channel is dead
+ @syntax:
+ <boolean> $chan.isDead
+ <boolean> $chan.isDead(<window_id:string>)
+ @description:
+ Returns 1 if the channel specified by <window_id> is a dead channel and 0 otherwise.[br]
+ The form without parameters works on the current window.[br]
+*/
+
+static bool chan_kvs_fnc_isdead(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setBoolean((ch->type() == KVI_WINDOW_TYPE_DEADCHANNEL));
+ return true;
+}
+
+/*
+ @doc: chan.topic
+ @type:
+ function
+ @title:
+ $chan.topic
+ @short:
+ Returns the topic of a channel
+ @syntax:
+ <string> $chan.topic
+ <string> $chan.topic(<window_id:string>)
+ @description:
+ The first form returns the topic of the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the topic of the channel specified by <window_id>.[br]
+ The topic is returned as it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get an empty string (the topic is not yet known).[br]
+ This function works also on dead channels altough the topic returned is the last
+ topic seen while the channel wasn't dead.[br]
+*/
+
+static bool chan_kvs_fnc_topic(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setString(ch->topicWidget()->topic());
+ return true;
+}
+
+/*
+ @doc: chan.topicsetby
+ @type:
+ function
+ @title:
+ $chan.topicsetby
+ @short:
+ Returns the author of the topic of a channel
+ @syntax:
+ <string> $chan.topicsetby
+ <string> $chan.topicsetby(<window_id:string>)
+ @description:
+ The first form returns the author of the topic of the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the author of the topic of the channel specified by <window_id>.[br]
+ The topic author nickname is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get an empty string (the topic is not yet known).[br]
+ This function works also on dead channels altough the information returned is the last
+ information seen while the channel wasn't dead.[br]
+*/
+
+static bool chan_kvs_fnc_topicsetby(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setString(ch->topicWidget()->topicSetBy());
+ return true;
+}
+
+/*
+ @doc: chan.topicsetat
+ @type:
+ function
+ @title:
+ $chan.topicsetat
+ @short:
+ Returns the set time of the topic of a channel
+ @syntax:
+ <string> $chan.topicsetat
+ <string> $chan.topicsetat(<window_id:string>)
+ @description:
+ The first form returns the set time of the topic of the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the set time of the topic of the channel specified by <window_id>.[br]
+ The topic set time is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get an empty string (the topic is not yet known).[br]
+ This function works also on dead channels altough the information returned is the last
+ information seen while the channel wasn't dead.[br]
+*/
+
+static bool chan_kvs_fnc_topicsetat(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setString(ch->topicWidget()->topicSetAt());
+ return true;
+}
+/*
+ @doc: chan.usercount
+ @type:
+ function
+ @title:
+ $chan.usercount
+ @short:
+ Returns the number of users on a channel
+ @syntax:
+ <intger> $chan.usercount
+ <integer> $chan.usercount(<window_id:string>)
+ @description:
+ The first form returns the number of users on the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the number of users on the channel specified by <window_id>.[br]
+ The number of users is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_usercount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->count());
+ return true;
+}
+
+/*
+ @doc: chan.ownercount
+ @type:
+ function
+ @title:
+ $chan.ownercount
+ @short:
+ Returns the number of channel owner users on a channel
+ @syntax:
+ <integer> $chan.ownercount
+ <integer> $chan.ownercount(<window_id:integer>)
+ @description:
+ The first form returns the number of owners users on the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the number of owners users on the channel specified by <window_id>.[br]
+ The number of owners is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_ownercount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->chanOwnerCount());
+ return true;
+}
+
+/*
+ @doc: chan.admincount
+ @type:
+ function
+ @title:
+ $chan.admincount
+ @short:
+ Returns the number of channel admin users on a channel
+ @syntax:
+ <integer> $chan.admincount
+ <integer> $chan.admincount(<window_id:string>)
+ @description:
+ The first form returns the number of administrator users on the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the number of administrator users on the channel specified by <window_id>.[br]
+ The number of administrators is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_admincount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->chanAdminCount());
+ return true;
+}
+
+
+/*
+ @doc: chan.opcount
+ @type:
+ function
+ @title:
+ $chan.opcount
+ @short:
+ Returns the number of op users on a channel
+ @syntax:
+ <integer> $chan.opcount
+ <integer> $chan.opcount(<window_id:string>)
+ @description:
+ The first form returns the number of op users on the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the number of op users on the channel specified by <window_id>.[br]
+ The number of ops is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_opcount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->opCount());
+ return true;
+}
+
+/*
+ @doc: chan.voicecount
+ @type:
+ function
+ @title:
+ $chan.voicecount
+ @short:
+ Returns the number of voiced users on a channel
+ @syntax:
+ <integer> $chan.voicecount
+ <integer> $chan.voicecount(<window_id:string>)
+ @description:
+ The first form returns the number of voiced users on the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the number of voiced users on the channel specified by <window_id>.[br]
+ The number of voiced users is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_voicecount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->voiceCount());
+ return true;
+}
+
+/*
+ @doc: chan.halfopcount
+ @type:
+ function
+ @title:
+ $chan.halfopcount
+ @short:
+ Returns the number of halfop users on a channel
+ @syntax:
+ <integer> $chan.halfOpCount
+ <integer> $chan.halfOpCount(<window_id:string>)
+ @description:
+ The first form returns the number of half-operator users on the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the number of half-operator users on the channel specified by <window_id>.[br]
+ The number of half-operator users is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_halfopcount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->halfOpCount());
+ return true;
+}
+
+/*
+ @doc: chan.useropcount
+ @type:
+ function
+ @title:
+ $chan.useropcount
+ @short:
+ Returns the number of userop users on a channel
+ @syntax:
+ <integer> $chan.userOpCount
+ <integer> $chan.userOpCount(<window_id:string>)
+ @description:
+ The first form returns the number of user-operator users on the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and an empty string is returned.[br]
+ The second form returns the number of user-operator users on the channel specified by <window_id>.[br]
+ The number of user-operator users is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_useropcount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->userOpCount());
+ return true;
+}
+
+/*
+ @doc: chan.bancount
+ @type:
+ function
+ @title:
+ $chan.bancount
+ @short:
+ Returns the number of entries in the channel ban list
+ @syntax:
+ <integer> $chan.bancount
+ <integer> $chan.bancount(<window_id:string>)
+ @description:
+ The first form returns the number of entries in the ban list of the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and 0 is returned.[br]
+ The second form returns the number entries in the ban list of the channel specified by <window_id>.[br]
+ The number of ban list entries is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_bancount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->banCount());
+ return true;
+}
+
+/*
+ @doc: chan.banexceptioncount
+ @type:
+ function
+ @title:
+ $chan.banexceptioncount
+ @short:
+ Returns the number of entries in the channel ban exception list
+ @syntax:
+ <integer> $chan.banexceptioncount
+ <integer> $chan.banexceptioncount(<window_id:string>)
+ @description:
+ The first form returns the number of entries in the ban exception list of the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and 0 is returned.[br]
+ The second form returns the number entries in the ban exception list of the channel specified by <window_id>.[br]
+ The number of ban exception list entries is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_banexceptioncount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->banExceptionCount());
+ return true;
+}
+
+/*
+ @doc: chan.invitecount
+ @type:
+ function
+ @title:
+ $chan.invitecount
+ @short:
+ Returns the number of entries in the channel invite list
+ @syntax:
+ <integer> $chan.invitecount
+ <integer> $chan.invitecount(<window_id:string>)
+ @description:
+ The first form returns the number of entries in the invite list of the current channel (assuming that the current window
+ is a channel at all). If the current window is not a channel, a warning is printed
+ and 0 is returned.[br]
+ The second form returns the number entries in the invite list of the channel specified by <window_id>.[br]
+ The number of invite list entries is returned if it is known form at the call time: this means that
+ if the channel is not synchronized with the server (as just after the join, for example)
+ you might get a number that is actually smaller.[br]
+*/
+
+static bool chan_kvs_fnc_invitecount(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setInteger(ch->inviteCount());
+ return true;
+}
+
+/*
+ @doc: chan.ison
+ @type:
+ function
+ @title:
+ $chan.ison
+ @short:
+ Checks if an user is on a channel
+ @syntax:
+ <boolean> $chan.ison(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns 1 if <nickname> is on the channel identified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not specified the current window is used (assuming that it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+*/
+
+static bool chan_kvs_fnc_ison(KviKvsModuleFunctionCall * c)
+{
+ QString szId,szNick;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("nickname",KVS_PT_NONEMPTYSTRING,0,szNick)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setBoolean(ch->isOn(szNick));
+ return true;
+}
+
+/*
+ @doc: chan.getflag
+ @type:
+ function
+ @title:
+ $chan.getflag
+ @short:
+ Returns the channel-user mode flag of an user
+ @syntax:
+ <char> $chan.getflag(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns the channel user mode flag of an user on the channel specified by <window_id>.[br]
+ If <window_id> is not passed, the current window is used.[br]
+ If the specified window is not a channel, a warning is printed and an empty string is returned.[br]
+ If the specified user is not on the channel identified by <window_id>, and empty string is returned.[br]
+ The possible user flags are:[br]
+ '!' for channel administrators[br]
+ '@' for ops[br]
+ '%' for halfops[br]
+ '+' for voiced users[br]
+ '-' for userops[br]
+ If the user has more than one flag then the highest one is returned.[br]
+ If the user has no flag at all then an empty string is returned.
+*/
+
+static bool chan_kvs_fnc_getflag(KviKvsModuleFunctionCall * c)
+{
+ QString szId,szNick;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("nickname",KVS_PT_NONEMPTYSTRING,0,szNick)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if(ch)
+ {
+ QChar cFlag = ch->userListView()->getUserFlag(szNick);
+ if(cFlag != QChar(0))
+ {
+ QString szFlag = cFlag;
+ c->returnValue()->setString(szFlag);
+ } else {
+ c->returnValue()->setNothing();
+ }
+ }
+ return true;
+}
+
+#define IS_KVS_FUNC(__clbkname,__chanfunc) \
+static bool __clbkname(KviKvsModuleFunctionCall * c) \
+{ \
+ QString szId,szNick;\
+ KVSM_PARAMETERS_BEGIN(c)\
+ KVSM_PARAMETER("nickname",KVS_PT_NONEMPTYSTRING,0,szNick)\
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)\
+ KVSM_PARAMETERS_END(c)\
+ KviChannel * ch = chan_kvs_find_channel(c,szId); \
+ if(ch) c->returnValue()->setBoolean(ch->__chanfunc(szNick,true)); \
+ return true; \
+}
+
+/*
+ @doc: chan.isowner
+ @type:
+ function
+ @title:
+ $chan.isowner
+ @short:
+ Checks if an user is at least a channel owner
+ @syntax:
+ <boolean> $chan.isowner(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns 1 if <nickname> is at least an owner on the channel identified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not specified the current window is used (assuming that it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ Note that if the user is not on the channel at all, you will get 0 as return value.[br]
+*/
+
+IS_KVS_FUNC(chan_kvs_fnc_isowner,isChanOwner)
+
+/*
+ @doc: chan.isadmin
+ @type:
+ function
+ @title:
+ $chan.isadmin
+ @short:
+ Checks if an user is at least channel administrator
+ @syntax:
+ <boolean> $chan.isadmin(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns 1 if <nickname> is at least an administrator on the channel identified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not specified the current window is used (assuming that it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ Note that if the user is not on the channel at all, you will get 0 as return value.[br]
+*/
+
+IS_KVS_FUNC(chan_kvs_fnc_isadmin,isChanAdmin)
+
+/*
+ @doc: chan.isop
+ @type:
+ function
+ @title:
+ $chan.isop
+ @short:
+ Checks if an user is at least an op on a channel
+ @syntax:
+ <boolean> $chan.isop(<nickname:string>[,<window_id:stringn>])
+ @description:
+ Returns 1 if <nickname> is at least an operator on the channel identified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not specified the current window is used (assuming that it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ Note that if the user is not on the channel at all, you will get 0 as return value.[br]
+*/
+
+IS_KVS_FUNC(chan_kvs_fnc_isop,isOp)
+
+/*
+ @doc: chan.isvoice
+ @type:
+ function
+ @title:
+ $chan.isvoice
+ @short:
+ Checks if an user is at least voiced on a channel
+ @syntax:
+ <boolean> $chan.isvoice(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns 1 if <nickname> is at least voiced on the channel identified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not specified the current window is used (assuming that it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ Note that if the user is not on the channel at all, you will get 0 as return value.[br]
+*/
+
+IS_KVS_FUNC(chan_kvs_fnc_isvoice,isVoice)
+
+/*
+ @doc: chan.ishalfop
+ @type:
+ function
+ @title:
+ $chan.ishalfop
+ @short:
+ Checks if an user is at least halfop on a channel
+ @syntax:
+ <boolean> $chan.ishalfop(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns 1 if <nickname> is at least a half-operator on the channel identified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not specified the current window is used (assuming that it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ Note that if the user is not on the channel at all, you will get 0 as return value.[br]
+*/
+
+IS_KVS_FUNC(chan_kvs_fnc_ishalfop,isHalfOp)
+
+/*
+ @doc: chan.isuserop
+ @type:
+ function
+ @title:
+ $chan.isuserop
+ @short:
+ Checks if an user is at least an userop on a channel
+ @syntax:
+ <boolean> $chan.isuserop(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns 1 if <nickname> is at least an user-operator on the channel identified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not specified the current window is used (assuming that it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ Note that if the user is not on the channel at all, you will get 0 as return value.[br]
+*/
+
+IS_KVS_FUNC(chan_kvs_fnc_isuserop,isUserOp)
+
+
+/*
+ @doc: chan.ismeowner
+ @type:
+ function
+ @title:
+ $chan.isMeOwner
+ @short:
+ Checks if the current user is at least an owner on a channel
+ @syntax:
+ <boolean> $chan.isMeOwner
+ <boolean> $chan.isMeOwner(<window_id:string>)
+ @description:
+ Returns 1 if the current user is at least an owner on the channel specified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not passed, the current window is used (assuming it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ This function is a "shortcut" for [fnc]$chan.isowner[/fnc]([fnc]$me[/fnc]).[br]
+*/
+
+#define IS_ME_KVS_FUNC(__clbkname,__chanfunc) \
+static bool __clbkname(KviKvsModuleFunctionCall * c) \
+{ \
+ QString szId;\
+ KVSM_PARAMETERS_BEGIN(c)\
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)\
+ KVSM_PARAMETERS_END(c)\
+ KviChannel * ch = chan_kvs_find_channel(c,szId); \
+ if(ch) c->returnValue()->setBoolean(ch->__chanfunc(true)); \
+ return true; \
+}
+
+IS_ME_KVS_FUNC(chan_kvs_fnc_ismeowner,isMeChanOwner)
+
+/*
+ @doc: chan.ismeadmin
+ @type:
+ function
+ @title:
+ $chan.isMeAdmin
+ @short:
+ Checks if the current user is at least an administrator on a channel
+ @syntax:
+ <boolean> $chan.isMeAdmin
+ <boolean> $chan.isMeAdmin(<window_id:string>)
+ @description:
+ Returns 1 if the current user is at least an administrator on the channel specified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not passed, the current window is used (assuming it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ This function is a "shortcut" for [fnc]$chan.isadmin[/fnc]([fnc]$me[/fnc]).[br]
+*/
+
+IS_ME_KVS_FUNC(chan_kvs_fnc_ismeadmin,isMeChanAdmin)
+
+/*
+ @doc: chan.ismeop
+ @type:
+ function
+ @title:
+ $chan.isMeOp
+ @short:
+ Checks if the current user is at least op on a channel
+ @syntax:
+ <boolean> $chan.isMeOp
+ <boolean> $chan.isMeOp(<window_id:string>)
+ @description:
+ Returns 1 if the current user is at least op on the channel specified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not passed, the current window is used (assuming it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ This function is a "shortcut" for [fnc]$chan.isop[/fnc]([fnc]$me[/fnc]).[br]
+*/
+
+IS_ME_KVS_FUNC(chan_kvs_fnc_ismeop,isMeOp)
+
+/*
+ @doc: chan.ismehalfop
+ @type:
+ function
+ @title:
+ $chan.isMeHalfOp
+ @short:
+ Checks if the current user is at least an half operator on a channel
+ @syntax:
+ <boolean> $chan.isMeHalfOp
+ <boolean> $chan.isMeHalfOp(<window_id:string>)
+ @description:
+ Returns 1 if the current user is at least an half operator on the channel specified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not passed, the current window is used (assuming it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ This function is a "shortcut" for [fnc]$chan.ishalfop[/fnc]([fnc]$me[/fnc]).[br]
+*/
+
+IS_ME_KVS_FUNC(chan_kvs_fnc_ismehalfop,isMeHalfOp)
+
+/*
+ @doc: chan.ismevoice
+ @type:
+ function
+ @title:
+ $chan.isMeVoice
+ @short:
+ Checks if the current user is at least voice on a channel
+ @syntax:
+ <boolean> $chan.isMeVoice
+ <boolean> $chan.isMeVoice(<window_id:string>)
+ @description:
+ Returns 1 if the current user is at least voice on the channel specified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not passed, the current window is used (assuming it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ This function is a "shortcut" for [fnc]$chan.isvoice[/fnc]([fnc]$me[/fnc]).[br]
+*/
+
+IS_ME_KVS_FUNC(chan_kvs_fnc_ismevoice,isMeVoice)
+
+/*
+ @doc: chan.ismeuserop
+ @type:
+ function
+ @title:
+ $chan.isMeUserOp
+ @short:
+ Checks if the current user is at least an user operator on a channel
+ @syntax:
+ <boolean> $chan.isMeUserOp
+ <boolean> $chan.isMeUserOp(<window_id:String>)
+ @description:
+ Returns 1 if the current user is at least an user operator on the channel specified by <window_id>, 0 otherwise.[br]
+ If <window_id> is not passed, the current window is used (assuming it is a channel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ This function is a "shortcut" for [fnc]$chan.isuserop[/fnc]([fnc]$me[/fnc]).[br]
+*/
+
+IS_ME_KVS_FUNC(chan_kvs_fnc_ismeuserop,isMeUserOp)
+
+/*
+ @doc: chan.mode
+ @type:
+ function
+ @title:
+ $chan.mode
+ @short:
+ Returns the mode string of a channel
+ @syntax:
+ <string> $chan.mode
+ <string> $chan.mode(<window_id:string>)
+ @description:
+ Returns the mode string of the channel identified by <window_id>.[br]
+ If no <window_id> is passed, the current channel mode string is returned (assuming that
+ the current window is a chnannel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+*/
+
+static bool chan_kvs_fnc_mode(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if(ch)
+ {
+ QString chMode;
+ ch->getChannelModeString(chMode);
+ c->returnValue()->setString(chMode);
+ }
+ return true;
+}
+
+
+/*
+ @doc: chan.key
+ @type:
+ function
+ @title:
+ $chan.key
+ @short:
+ Returns the key of a channel
+ @syntax:
+ <string> $chan.key
+ <string> $chan.key(<window_id:string>)
+ @description:
+ Returns the key of the channel identified by <window_id>.[br]
+ If no <window_id> is passed, the current channel key is returned (assuming that
+ the current window is a chnannel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ If the channel has no key set, an empty string is returned.[br]
+*/
+
+static bool chan_kvs_fnc_key(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ if (ch) c->returnValue()->setString(ch->channelKey());
+ return true;
+}
+
+/*
+ @doc: chan.limit
+ @type:
+ function
+ @title:
+ $chan.limit
+ @short:
+ Returns the limit of a channel
+ @syntax:
+ <integer> $chan.limit
+ <integer> $chan.limit(<window_id:string>)
+ @description:
+ Returns the limit of the channel identified by <window_id>.[br]
+ If no <window_id> is passed, the current channel limit is returned (assuming that
+ the current window is a chnannel at all).[br]
+ If the window is not a channel, a warning is printed and an empty string is returned.[br]
+ If the channel has no limit set, "0" is returned.[br]
+*/
+
+static bool chan_kvs_fnc_limit(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szId);
+ kvs_int_t limit=0;
+ QString lim;
+ if (ch)
+ {
+ if(ch->hasChannelLimit())
+ {
+ lim=ch->channelLimit().ptr();
+ limit=lim.toInt();
+ }
+ c->returnValue()->setInteger(limit);
+ }
+ return true;
+}
+
+
+/*
+ @doc: chan.users
+ @type:
+ function
+ @title:
+ $chan.users
+ @short:
+ Returns an array of channel user nicknames
+ @syntax:
+ <array> $chan.users([window_id:string],[mask:string],[flags:string])
+ @description:
+ Returns an array of nicknames on the channel specified by [window_id].[br]
+ If [window_id] is empty, the current window is used.[br]
+ If the window designated by [window_id] is not a channel a warning is printed and an empty array is returned.[br]
+ If [mask] is given, each user is added to the array only
+ if it matches the [mask].[br]
+ [flags] may contain a subset of the letters "aovhnmi":[br]
+ "ovhn" are mode flags: the users are added to the array only if they are channel administrators ('a'), operators ('o'),
+ voiced users ('v'), half-operators ('h'), user-operators ('u') or unflagged ('n') users. (Unflagged means not operators, not
+ voiced and not half-operators). If none of the "ovhun" flags are used, KVIrc behaves like all five were passed.[br]
+ The flag 'm' causes the entire user masks to be added to the
+ array entries, as known by KVIrc at the moment of this function call.[br]
+ The flag 'i' causes KVIrc to invert the match and add only the users that do NOT match [mask].[br]
+ Please note that on really large channels this function may be time consuming (especially if [mask] is used):
+ use with care.[br]
+ @example:
+ [example]
+ [comment]# Get the nickname list[/comment]
+ %test[] = $chan.users
+ [comment]# And loop thru the items[/comment]
+ %i = 0
+ [comment]# %test[]# returns the number of elements in the array[/comment]
+ %count = %test[]#
+ while(%i < %count)
+ {
+ echo "User %i : %test[%i]"
+ %i++
+ }
+ [comment]# Another way of looping[/comment]
+ foreach(%tmp,%test[])echo "User %tmp"
+ [comment]# Find all the users that come from the *.org domain[/comment]
+ %test[]=$chan.users(,*!*@*.org)
+ echo %test[]
+ [comment]# This will work too![/comment]
+ echo $chan.users(,*!*@*.org)
+ [comment]# Find all the channel operators[/comment]
+ %test[] = $chan.users(,,o)
+ echo %test[]
+ [comment]# Find all the voiced users that do NOT come from *.edu[/comment]
+ [comment]# See also their whole mask[/comment]
+ %test[] = $chan.users(,*!*@*.edu,vim)
+ echo %test[]
+ [/example]
+
+*/
+
+static bool chan_kvs_fnc_users(KviKvsModuleFunctionCall * c)
+{
+ QString szWinId,szMask,szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWinId)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,KVS_PF_OPTIONAL,szMask)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray * pArray = new KviKvsArray();
+ c->returnValue()->setArray(pArray);
+
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+ if(!ch)return true;
+
+ KviUserListEntry * e = ch->userListView()->firstItem(); // Thnx Julien :)
+
+ bool bCheckMask = !szMask.isEmpty();
+ bool bOp = szFlags.find('o',false) != -1;
+ bool bVoice = szFlags.find('v',false) != -1;
+ bool bHalfOp = szFlags.find('h',false) != -1;
+ bool bChanAdmins = szFlags.find('a',false) != -1;
+ bool bUserOp = szFlags.find('u',false) != -1;
+ bool bNone = szFlags.find('n',false) != -1;
+ bool bCheckFlags = bOp || bVoice || bHalfOp || bNone || bChanAdmins || bUserOp;
+ bool bAddMask = szFlags.find('m',false) != -1;
+
+ int idx = 0;
+
+ if(bAddMask || bCheckFlags || bCheckMask)
+ {
+ bool bMaskMustMatch = szFlags.find('i',false) == -1;
+ KviIrcMask mask(szMask);
+
+ while(e)
+ {
+ if(bCheckFlags)
+ {
+ if(bChanAdmins)
+ {
+ if(e->flags() & KVI_USERFLAG_CHANADMIN)goto check_mask;
+ }
+ if(bOp)
+ {
+ if(e->flags() & KVI_USERFLAG_OP)goto check_mask;
+ }
+ if(bVoice)
+ {
+ if(e->flags() & KVI_USERFLAG_VOICE)goto check_mask;
+ }
+ if(bHalfOp)
+ {
+ if(e->flags() & KVI_USERFLAG_HALFOP)goto check_mask;
+ }
+ if(bUserOp)
+ {
+ if(e->flags() & KVI_USERFLAG_USEROP)goto check_mask;
+ }
+ if(bNone)
+ {
+ if(!(e->flags() & KVI_USERFLAG_MASK))goto check_mask;
+ }
+ goto next_item;
+ }
+check_mask:
+ if(bCheckMask)
+ {
+ if(mask.matchesFixed(e->nick(),e->globalData()->user(),e->globalData()->host()) == bMaskMustMatch)goto add_item;
+ goto next_item;
+ }
+add_item:
+ if(bAddMask)
+ {
+ QString x(e->nick());
+ x.append('!');
+ x.append(e->globalData()->user());
+ x.append('@');
+ x.append(e->globalData()->host());
+ pArray->set(idx,new KviKvsVariant(x));
+ } else {
+ pArray->set(idx,new KviKvsVariant(e->nick()));
+ }
+ idx++;
+next_item:
+ e = e->next();
+ }
+ } else {
+ while(e)
+ {
+ pArray->set(idx,new KviKvsVariant(e->nick()));
+ idx++;
+ e = e->next();
+ }
+ }
+
+
+ return true;
+}
+
+/*
+ @doc: chan.banlist
+ @type:
+ function
+ @title:
+ $chan.banlist
+ @short:
+ Returns an array of channel ban masks
+ @syntax:
+ $chan.banlist([window_id])
+ @description:
+ Returns an array of ban masks set ont the channel identified by [window_id].[br]
+ If [window_id] is empty, the current window is used.[br]
+ If the window designated by [window_id] is not a channel a warning is printed and an empty array is returned.[br]
+*/
+
+static bool chan_kvs_fnc_banlist(KviKvsModuleFunctionCall * c)
+{
+ QString szWinId,szMask,szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWinId)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray * pArray = new KviKvsArray();
+ c->returnValue()->setArray(pArray);
+
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+
+ if(!ch)return true;
+
+ int idx = 0;
+
+ KviPointerList<KviMaskEntry> * l = ((KviChannel *)(c->window()))->banList();
+
+ for(KviMaskEntry * e = l->first();e;e = l->next())
+ {
+ pArray->set(idx,new KviKvsVariant(e->szMask));
+ idx++;
+ }
+
+ return true;
+}
+
+/*
+ @doc: chan.banexceptionlist
+ @type:
+ function
+ @title:
+ $chan.banexceptionlist
+ @short:
+ Returns an array of channel ban exception masks
+ @syntax:
+ <array> $chan.banexceptionlist([window_id])
+ @description:
+ Returns an array of ban exception masks set ont the channel identified by [window_id].[br]
+ If [window_id] is empty, the current window is used.[br]
+ If the window designated by [window_id] is not a channel a warning is printed and an empty array is returned.[br]
+*/
+
+static bool chan_kvs_fnc_banexceptionlist(KviKvsModuleFunctionCall * c)
+{
+ QString szWinId,szMask,szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWinId)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray * pArray = new KviKvsArray();
+ c->returnValue()->setArray(pArray);
+
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+
+ if(!ch)return true;
+
+ int idx = 0;
+
+ KviPointerList<KviMaskEntry> * l = ((KviChannel *)(c->window()))->banExceptionList();
+
+ for(KviMaskEntry * e = l->first();e;e = l->next())
+ {
+ pArray->set(idx,new KviKvsVariant(e->szMask));
+ idx++;
+ }
+
+ return true;
+}
+
+/*
+ @doc: chan.invitelist
+ @type:
+ function
+ @title:
+ $chan.invitelist
+ @short:
+ Returns an array of channel invite masks
+ @syntax:
+ <array> $chan.banexceptionlist([window_id])
+ @description:
+ Returns an array of invite masks set ont the channel identified by [window_id].[br]
+ If [window_id] is empty, the current window is used.[br]
+ If the window designated by [window_id] is not a channel a warning is printed and an empty array is returned.[br]
+*/
+
+static bool chan_kvs_fnc_invitelist(KviKvsModuleFunctionCall * c)
+{
+ QString szWinId,szMask,szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWinId)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray * pArray = new KviKvsArray();
+ c->returnValue()->setArray(pArray);
+
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+
+ if(!ch)return true;
+
+ int idx = 0;
+
+ KviPointerList<KviMaskEntry> * l = ((KviChannel *)(c->window()))->inviteList();
+
+ for(KviMaskEntry * e = l->first();e;e = l->next())
+ {
+ pArray->set(idx,new KviKvsVariant(e->szMask));
+ idx++;
+ }
+
+ return true;
+}
+
+/*
+ @doc: chan.matchban
+ @type:
+ function
+ @title:
+ $chan.matchban
+ @short:
+ Matches a mask agains the channel ban list
+ @syntax:
+ <string> $chan.matchban([window_id],<complete_mask>)
+ @description:
+ Returns the ban mask that matches <complete_mask> on channel identified by [window_id].[br]
+ If no ban mask matches <complete_mask> an empty string is returned.[br]
+ If [window_id] is empty, the current window is used.[br]
+ If the window designated by [window_id] is not a channel a warning is printed and an empty string is returned.[br]
+ This function is useful to determine if a ban set on the channel matches an user.[br]
+*/
+
+static bool chan_kvs_fnc_matchban(KviKvsModuleFunctionCall * c)
+{
+ QString szWinId,szMask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,0,szWinId)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,szMask)
+ KVSM_PARAMETERS_END(c)
+
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+
+ if(!ch)
+ {
+ c->returnValue()->setNothing();
+ return true;
+ }
+
+ KviPointerList<KviMaskEntry> * l = ((KviChannel *)(c->window()))->banList();
+
+ for(KviMaskEntry * e = l->first();e;e = l->next())
+ {
+ if(KviQString::matchStringCI(e->szMask,szMask))
+ {
+ c->returnValue()->setString(e->szMask);
+ return true;
+ }
+ }
+
+ c->returnValue()->setNothing();
+ return true;
+}
+
+/*
+ @doc: chan.matchbanexception
+ @type:
+ function
+ @title:
+ $chan.matchbanexception
+ @short:
+ Matches a mask agains the channel ban exception list
+ @syntax:
+ <string> $chan.matchbanexception([window_id],<complete_mask>)
+ @description:
+ Returns the ban exception mask that matches <complete_mask> on channel identified by [window_id].[br]
+ If no ban exception mask matches <complete_mask> an empty string is returned.[br]
+ If [window_id] is empty, the current window is used.[br]
+ If the window designated by [window_id] is not a channel a warning is printed and an empty string is returned.[br]
+ This function is useful to determine if a ban exception set on the channel matches an user.[br]
+*/
+
+static bool chan_kvs_fnc_matchbanexception(KviKvsModuleFunctionCall * c)
+{
+ QString szWinId,szMask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,0,szWinId)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,szMask)
+ KVSM_PARAMETERS_END(c)
+
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+
+ if(!ch)
+ {
+ c->returnValue()->setNothing();
+ return true;
+ }
+
+ KviPointerList<KviMaskEntry> * l = ((KviChannel *)(c->window()))->banExceptionList();
+
+ for(KviMaskEntry * e = l->first();e;e = l->next())
+ {
+ if(KviQString::matchStringCI(e->szMask,szMask))
+ {
+ c->returnValue()->setString(e->szMask);
+ return true;
+ }
+ }
+
+ c->returnValue()->setNothing();
+ return true;
+}
+
+/*
+ @doc: chan.matchinvite
+ @type:
+ function
+ @title:
+ $chan.matchinvite
+ @short:
+ Matches a mask agains the channel invite list
+ @syntax:
+ <string> $chan.matchinvite([window_id:string],<complete_mask>)
+ @description:
+ Returns the invite mask that matches <complete_mask> on channel identified by [window_id].[br]
+ If no invite mask matches <complete_mask> an empty string is returned.[br]
+ If [window_id] is empty, the current window is used.[br]
+ If the window designated by [window_id] is not a channel a warning is printed and an empty string is returned.[br]
+ This function is useful to determine if a invite set on the channel matches an user.[br]
+*/
+
+static bool chan_kvs_fnc_matchinvite(KviKvsModuleFunctionCall * c)
+{
+ QString szWinId,szMask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,0,szWinId)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,szMask)
+ KVSM_PARAMETERS_END(c)
+
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+
+ if(!ch)
+ {
+ c->returnValue()->setNothing();
+ return true;
+ }
+
+ KviPointerList<KviMaskEntry> * l = ((KviChannel *)(c->window()))->inviteList();
+
+ for(KviMaskEntry * e = l->first();e;e = l->next())
+ {
+ if(KviQString::matchStringCI(e->szMask,szMask))
+ {
+ c->returnValue()->setString(e->szMask);
+ return true;
+ }
+ }
+
+ c->returnValue()->setNothing();
+ return true;
+}
+
+/*
+ @doc: chan.usermodelevel
+ @type:
+ function
+ @title:
+ $chan.usermodelevel
+ @short:
+ Returns the channel user-mode level
+ @syntax:
+ <integer> $chan.userModeLevel(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns an integer identifying the specified user's channel mode on the channel specified by <window_id>.[br]
+ If <window_id> is not passed, the current window is used.[br]
+ If the specified window is not a channel, a warning is printed and '0' is returned.[br]
+ This number can be useful to implement comparison functions between
+ users in order to determine the actions they can issue between each other.[br]
+ For example it is granted that an op will have userModeLevel greater than
+ a voiced user or that a simple "modeless" user will have
+ an userModeLevel lower than a halfop.[br]
+ IRC allows multiple modes to be applied to a single user on a channel,
+ in that case this function will return the level of the highest mode
+ applied to the user.[br]
+ Note: Don't rely on this number being any particular exact value except
+ for the completely modeless users (in which case this function will return always '0').
+*/
+
+static bool chan_kvs_fnc_usermodelevel(KviKvsModuleFunctionCall * c)
+{
+ QString szNick,szWinId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("nickname",KVS_PT_STRING,0,szNick)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWinId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+
+ kvs_int_t mode=0;
+ if(ch) mode=ch->userListView()->getUserModeLevel(szNick);
+ c->returnValue()->setInteger(mode);
+ return true;
+}
+
+/*
+ @doc: chan.userjointime
+ @type:
+ function
+ @title:
+ $chan.userJoinTime
+ @short:
+ Returns the time that an user has joined the channel
+ @syntax:
+ <integer> $chan.userJoinTime(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns the unix time at which the user specified by <nickname> has joined the channel specified by <window_id>.[br]
+ If <window_id> is not passed, the current window is used.[br]
+ If the specified window is not a channel, a warning is printed and '0' is returned.[br]
+ '0' is also returned when the user's join time is unknown: this is true
+ for all the users that were on the channel before the local user has joined it (e.g.
+ you know the join time only for users that YOU see joining).[br]
+ @seealso:
+ [fnc]$unixTime[/fnc], [fnc]$chan.userLastActionTime[/fnc]
+*/
+
+static bool chan_kvs_fnc_userjointime(KviKvsModuleFunctionCall * c)
+{
+ QString szNick,szWinId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("nickname",KVS_PT_STRING,0,szNick)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWinId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+
+ kvs_int_t time=0;
+ if(ch) time=ch->userListView()->getUserJoinTime(szNick);
+ c->returnValue()->setInteger(time);
+ return true;
+}
+
+/*
+ @doc: chan.userlastactiontime
+ @type:
+ function
+ @title:
+ $chan.userLastActionTime
+ @short:
+ Returns the time that an user has last performed some kind of action on the channel
+ @syntax:
+ <integer> $chan.userLastActionTime(<nickname:string>[,<window_id:string>])
+ @description:
+ Returns the unix time at which the user specified by <nickname> has performed
+ some kind of action on the channel specified by <window_id>.[br]
+ If <window_id> is not passed, the current window is used.[br]
+ If the specified window is not a channel, a warning is printed and '0' is returned.[br]
+ '0' is also returned when the user's last action time is unknown: this is true
+ for all the users that were on the channel before the local user has joined it
+ and have performed no actions since that moment.
+ @seealso:
+ [fnc]$unixTime[/fnc], [fnc]$chan.userJoinTime[/fnc]
+*/
+
+static bool chan_kvs_fnc_userlastactiontime(KviKvsModuleFunctionCall * c)
+{
+ QString szNick,szWinId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("nickname",KVS_PT_STRING,0,szNick)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWinId)
+ KVSM_PARAMETERS_END(c)
+ KviChannel * ch = chan_kvs_find_channel(c,szWinId);
+
+ kvs_int_t time=0;
+ if(ch) time=ch->userListView()->getUserLastActionTime(szNick);
+ c->returnValue()->setInteger(time);
+ return true;
+}
+
+static bool chan_module_init(KviModule * m)
+{
+ KVSM_REGISTER_FUNCTION(m,"name",chan_kvs_fnc_name);
+ KVSM_REGISTER_FUNCTION(m,"topic",chan_kvs_fnc_topic);
+ KVSM_REGISTER_FUNCTION(m,"topicsetby",chan_kvs_fnc_topicsetby);
+ KVSM_REGISTER_FUNCTION(m,"topicsetat",chan_kvs_fnc_topicsetat);
+ KVSM_REGISTER_FUNCTION(m,"usercount",chan_kvs_fnc_usercount);
+ KVSM_REGISTER_FUNCTION(m,"ownercount",chan_kvs_fnc_ownercount);
+ KVSM_REGISTER_FUNCTION(m,"admincount",chan_kvs_fnc_admincount);
+ KVSM_REGISTER_FUNCTION(m,"opcount",chan_kvs_fnc_opcount);
+ KVSM_REGISTER_FUNCTION(m,"voicecount",chan_kvs_fnc_voicecount);
+ KVSM_REGISTER_FUNCTION(m,"halfopcount",chan_kvs_fnc_halfopcount);
+ KVSM_REGISTER_FUNCTION(m,"useropcount",chan_kvs_fnc_useropcount);
+ KVSM_REGISTER_FUNCTION(m,"isowner",chan_kvs_fnc_isowner);
+ KVSM_REGISTER_FUNCTION(m,"ison",chan_kvs_fnc_ison);
+ KVSM_REGISTER_FUNCTION(m,"isadmin",chan_kvs_fnc_isadmin);
+ KVSM_REGISTER_FUNCTION(m,"isop",chan_kvs_fnc_isop);
+ KVSM_REGISTER_FUNCTION(m,"isvoice",chan_kvs_fnc_isvoice);
+ KVSM_REGISTER_FUNCTION(m,"ishalfop",chan_kvs_fnc_ishalfop);
+ KVSM_REGISTER_FUNCTION(m,"isuserop",chan_kvs_fnc_isuserop);
+ KVSM_REGISTER_FUNCTION(m,"ismeuserop",chan_kvs_fnc_ismeuserop);
+ KVSM_REGISTER_FUNCTION(m,"ismevoice",chan_kvs_fnc_ismevoice);
+ KVSM_REGISTER_FUNCTION(m,"ismehalfop",chan_kvs_fnc_ismehalfop);
+ KVSM_REGISTER_FUNCTION(m,"ismeop",chan_kvs_fnc_ismeop);
+ KVSM_REGISTER_FUNCTION(m,"ismeadmin",chan_kvs_fnc_ismeadmin);
+ KVSM_REGISTER_FUNCTION(m,"ismeowner",chan_kvs_fnc_ismeowner);
+ KVSM_REGISTER_FUNCTION(m,"isdead",chan_kvs_fnc_isdead);
+ KVSM_REGISTER_FUNCTION(m,"getflag",chan_kvs_fnc_getflag);
+
+ KVSM_REGISTER_FUNCTION(m,"usermodelevel",chan_kvs_fnc_usermodelevel);
+ KVSM_REGISTER_FUNCTION(m,"userjointime",chan_kvs_fnc_userjointime);//
+ KVSM_REGISTER_FUNCTION(m,"userlastactiontime",chan_kvs_fnc_userlastactiontime);
+ KVSM_REGISTER_FUNCTION(m,"mode",chan_kvs_fnc_mode);
+
+ KVSM_REGISTER_FUNCTION(m,"key",chan_kvs_fnc_key);
+ KVSM_REGISTER_FUNCTION(m,"limit",chan_kvs_fnc_limit);
+ KVSM_REGISTER_FUNCTION(m,"users",chan_kvs_fnc_users);
+ KVSM_REGISTER_FUNCTION(m,"bancount",chan_kvs_fnc_bancount);
+ KVSM_REGISTER_FUNCTION(m,"banexceptioncount",chan_kvs_fnc_banexceptioncount);
+ KVSM_REGISTER_FUNCTION(m,"invitecount",chan_kvs_fnc_invitecount);
+ KVSM_REGISTER_FUNCTION(m,"banlist",chan_kvs_fnc_banlist);
+ KVSM_REGISTER_FUNCTION(m,"banexceptionlist",chan_kvs_fnc_banexceptionlist);
+ KVSM_REGISTER_FUNCTION(m,"invitelist",chan_kvs_fnc_invitelist);
+ KVSM_REGISTER_FUNCTION(m,"matchban",chan_kvs_fnc_matchban);
+ KVSM_REGISTER_FUNCTION(m,"matchbanexception",chan_kvs_fnc_matchbanexception);
+ KVSM_REGISTER_FUNCTION(m,"matchinvite",chan_kvs_fnc_matchinvite);
+ KVSM_REGISTER_FUNCTION(m,"getUrl",chan_kvs_fnc_getUrl);
+
+ return true;
+}
+
+static bool chan_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+
+KVIRC_MODULE(
+ "Chan", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)"\
+ " (C) 2002 Juanjo Alvarez (juanjux at yahoo dot es)",
+ "Scripting interface for the channel management",
+ chan_module_init,
+ 0,
+ 0,
+ chan_module_cleanup
+)
diff --git a/src/modules/channelsjoin/Makefile.am b/src/modules/channelsjoin/Makefile.am
new file mode 100644
index 00000000..c9f8a78e
--- /dev/null
+++ b/src/modules/channelsjoin/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+################################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvichannelsjoin.la
+
+libkvichannelsjoin_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvichannelsjoin_la_SOURCES = libkvichannelsjoin.cpp channelsjoinwindow.cpp
+libkvichannelsjoin_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= channelsjoinwindow.h
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+channelsjoinwindow.cpp: m_channelsjoinwindow.moc
diff --git a/src/modules/channelsjoin/channelsjoinwindow.cpp b/src/modules/channelsjoin/channelsjoinwindow.cpp
new file mode 100644
index 00000000..5f73b55e
--- /dev/null
+++ b/src/modules/channelsjoin/channelsjoinwindow.cpp
@@ -0,0 +1,301 @@
+//=============================================================================
+//
+// 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-2003 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 "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_selectors.h"
+#include "kvi_app.h"
+
+#include "kvi_string.h"
+#include "kvi_iconmanager.h"
+#include "kvi_console.h"
+#include "kvi_regchan.h"
+#include "kvi_kvs_script.h"
+
+#include <qlabel.h>
+#include <qlineedit.h>
+#include "kvi_tal_listview.h"
+#include <kvi_tal_groupbox.h>
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#ifdef COMPILE_USE_QT4
+ #include <q3header.h>
+#else
+ #include <qheader.h>
+#endif
+#include <qevent.h>
+
+extern KviChannelsJoinWindow * g_pChannelsWindow;
+extern QRect g_rectChannelsJoinGeometry;
+// kvi_app.cpp
+extern KVIRC_API KviRegisteredChannelDataBase * g_pRegisteredChannelDataBase;
+
+
+KviChannelsJoinWindow::KviChannelsJoinWindow(QWidget * par, const char * name)
+: QDialog(par,name)
+{
+ m_pConsole=0;
+ setCaption(__tr2qs("Join Channels"));
+
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)));
+
+ QGridLayout * g = new QGridLayout(this,4,2,4,8);
+
+ m_pListView = new KviTalListView(this);
+ m_pListView->addColumn(__tr2qs("Channel"));
+ m_pListView->setRootIsDecorated(true);
+ m_pListView->setSelectionMode(KviTalListView::Single);
+ g->addMultiCellWidget(m_pListView,0,0,0,1);
+ connect(m_pListView,SIGNAL(clicked(KviTalListViewItem *)),this,SLOT(itemClicked(KviTalListViewItem *)));
+ connect(m_pListView,SIGNAL(doubleClicked(KviTalListViewItem *)),this,SLOT(itemDoubleClicked(KviTalListViewItem *)));
+
+
+ m_pGroupBox = new KviTalGroupBox(2,Qt::Horizontal,__tr2qs("Channel" ),this);
+ QString szMsg = __tr2qs("Name");
+ szMsg.append(":");
+ QLabel * l = 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(":");
+ l = new QLabel(szMsg,m_pGroupBox);
+
+ m_pPass = new QLineEdit(m_pGroupBox);
+ m_pPass->setEchoMode(QLineEdit::Password);
+
+ g->addMultiCellWidget(m_pGroupBox,1,1,0,1);
+
+
+ m_pJoinButton = new QPushButton(__tr2qs("&Join"),this);
+ // Join on return pressed
+ m_pJoinButton->setDefault(true);
+ connect(m_pJoinButton,SIGNAL(clicked()),this,SLOT(joinClicked()));
+
+#ifdef COMPILE_USE_QT4
+ g->addMultiCellWidget(m_pJoinButton,2,2,0,1,Qt::AlignHCenter);
+#else
+ g->addMultiCellWidget(m_pJoinButton,2,2,0,1,AlignHCenter);
+#endif
+
+
+ m_pShowAtStartupCheck = new KviStyledCheckBox(__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->setColStretch(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(KviConsole * pConsole)
+{
+ m_pConsole=pConsole;
+ fillListView();
+}
+
+void KviChannelsJoinWindow::fillListView()
+{
+ m_pListView->clear();
+
+ m_pListView->header()->hide();
+
+ KviTalListViewItem * par = new KviTalListViewItem(m_pListView,__tr2qs("Recent Channels"));
+ par->setOpen(true);
+ KviTalListViewItem * chld;
+
+ if(m_pConsole)
+ {
+
+ QStringList* pList=g_pApp->getRecentChannels(m_pConsole->currentNetworkName());
+ if(pList)
+ {
+ for(QStringList::Iterator it = pList->begin(); it != pList->end(); ++it)
+ {
+ chld = new KviTalListViewItem(par,*it);
+ chld->setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)));
+ }
+ }
+ }
+
+ // FIXME: Registered channels go here!
+ par = new KviTalListViewItem(m_pListView,__tr2qs("Registered Channels"));
+ par->setOpen(true);
+
+ KviPointerHashTable<const char *,KviRegisteredChannelList> * d = g_pRegisteredChannelDataBase->channelDict();
+ if(d)
+ {
+ KviPointerHashTableIterator<const char *,KviRegisteredChannelList> it(*d);
+ while(it.current())
+ {
+ chld = new KviTalListViewItem(par,it.currentKey());
+ chld->setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)));
+ ++it;
+ }
+ }
+
+
+}
+
+void KviChannelsJoinWindow::itemClicked(KviTalListViewItem * it)
+{
+ if(!it)return;
+ if(!it->parent())return;
+ KviStr tmp = it->text(0);
+ m_pChannelEdit->setText(tmp.ptr());
+ enableJoin();
+}
+
+void KviChannelsJoinWindow::itemDoubleClicked(KviTalListViewItem * it)
+{
+ if(!it)return;
+ if(!it->parent())return;
+ KviStr tmp = it->text(0);
+ m_pChannelEdit->setText(tmp.ptr());
+ enableJoin();
+ joinClicked();
+}
+
+
+void KviChannelsJoinWindow::editTextChanged(const QString &)
+{
+ enableJoin();
+}
+
+void KviChannelsJoinWindow::enableJoin()
+{
+ KviStr tmp = m_pChannelEdit->text();
+ KviConsole * c = g_pApp->topmostConnectedConsole();
+ if(c)
+ {
+ if(tmp.isEmpty())
+ m_pJoinButton->setEnabled(false);
+ else
+ m_pJoinButton->setEnabled(true);
+ } else {
+ m_pListView->setEnabled(false);
+ m_pGroupBox->setEnabled(false);
+ m_pJoinButton->setEnabled(false);
+ }
+}
+
+void KviChannelsJoinWindow::cancelClicked()
+{
+ delete this;
+}
+
+void KviChannelsJoinWindow::joinClicked()
+{
+ KviStr pass = m_pPass->text();
+ KviStr tmp = m_pChannelEdit->text();
+
+ if(tmp.isEmpty())return;
+
+ KviStr command(KviStr::Format,"join %s %s",tmp.ptr(),pass.ptr());
+
+ KviConsole * c = g_pApp->topmostConnectedConsole();
+ if(!c)return; // no connection
+ KviWindow * w = g_pActiveWindow;
+ if(w->console() != c)w = c;
+ KviKvsScript::run(command.ptr(),w);
+
+ m_pChannelEdit->setText("");
+ m_pPass->setText("");
+}
+
+/*
+void KviChannelsJoinWindow::whoClicked()
+{
+ KviStr tmp = m_pChannelEdit->text();
+ if(!tmp.isEmpty())doCmd("who", tmp.ptr());
+}
+
+void KviChannelsJoinWindow::namesClicked()
+{
+ KviStr 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;
+ KviStr 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;
+}
+
+#include "m_channelsjoinwindow.moc"
diff --git a/src/modules/channelsjoin/channelsjoinwindow.h b/src/modules/channelsjoin/channelsjoinwindow.h
new file mode 100644
index 00000000..d0ce62a9
--- /dev/null
+++ b/src/modules/channelsjoin/channelsjoinwindow.h
@@ -0,0 +1,70 @@
+//
+// File : channelsjoinwindow.h
+// Creation date : Thu Nov 06 2001 12:30:25 CEST by Juan Jos��varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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.
+//
+
+
+#ifndef _CHANNELSJOIN_H_
+#define _CHANNELSJOIN_H_
+#include "kvi_window.h"
+#include "kvi_string.h"
+
+#include <qdialog.h>
+
+class KviConsole;
+class KviTalGroupBox;
+class QPushButton;
+class QLineEdit;
+
+#include "kvi_styled_controls.h"
+#include "kvi_tal_listview.h"
+
+class KviChannelsJoinWindow : public QDialog
+{
+ Q_OBJECT
+public:
+ KviChannelsJoinWindow(QWidget * par, const char * name);
+ ~KviChannelsJoinWindow();
+protected:
+ QLineEdit * m_pChannelEdit;
+ KviTalListView * m_pListView;
+ KviTalGroupBox * m_pGroupBox;
+ QLineEdit * m_pPass;
+ KviStyledCheckBox * m_pShowAtStartupCheck;
+ KviStyledCheckBox * m_pCloseAfterJoinCheck;
+ QPushButton * m_pJoinButton;
+ KviConsole * m_pConsole;
+public:
+ virtual void closeEvent(QCloseEvent *e);
+ void fillListView();
+ void enableJoin();
+ void setConsole(KviConsole * pConsole);
+protected slots:
+ void editTextChanged(const QString &);
+ void itemClicked(KviTalListViewItem *it);
+ void itemDoubleClicked(KviTalListViewItem *it);
+ void editReturnPressed();
+ void cancelClicked();
+ void joinClicked();
+// void whoClicked();
+// void namesClicked();
+};
+
+#endif //_CHANNELSJOINSWINDOW_H_
diff --git a/src/modules/channelsjoin/libkvichannelsjoin.cpp b/src/modules/channelsjoin/libkvichannelsjoin.cpp
new file mode 100644
index 00000000..a2936e8e
--- /dev/null
+++ b/src/modules/channelsjoin/libkvichannelsjoin.cpp
@@ -0,0 +1,108 @@
+//=============================================================================
+//
+// File : libkvichannelsjoin.cpp
+// Creation date : Thu Nov 06 2001 12:30:25 CEST by Juanjo Alvarez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 Juanjo Alvarez
+// Copyright (C) 2001-2005 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_module.h"
+
+#include "channelsjoinwindow.h"
+#include "kvi_window.h"
+#include "kvi_frame.h"
+#include "kvi_locale.h"
+#include "kvi_config.h"
+
+#include <qsplitter.h>
+
+KviChannelsJoinWindow * g_pChannelsWindow = 0;
+QRect g_rectChannelsJoinGeometry;
+
+/*
+ @doc: channelsjoin.open
+ @type:
+ command
+ @title:
+ channelsjoin.open
+ @short:
+ Opens a window to join channels
+ @syntax:
+ channelsjoin.open
+ @description:
+ Shows a dialog that allows the user to enter channels in a visual manner.[br]
+ This command is exported by the "channelsjoin" module.
+
+*/
+
+static bool channelsjoin_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ if(!g_pChannelsWindow)g_pChannelsWindow = new KviChannelsJoinWindow(c->window()->frame(),"channelsjoin");
+
+ g_pChannelsWindow->setConsole(c->window()->console());
+
+ g_pChannelsWindow->show();
+ g_pChannelsWindow->raise();
+ g_pChannelsWindow->setFocus();
+
+ return true;
+
+
+}
+
+static bool channelsjoin_module_init(KviModule * m)
+{
+ QString fName;
+ m->getDefaultConfigFileName(fName);
+ KviConfig cfg(fName,KviConfig::Read);
+
+ g_rectChannelsJoinGeometry = cfg.readRectEntry("geometry",QRect(30,30,320,410));
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",channelsjoin_kvs_cmd_open);
+ return true;
+}
+
+static bool channelsjoin_module_cleanup(KviModule *m)
+{
+ QString fName;
+ m->getDefaultConfigFileName(fName);
+ KviConfig cfg(fName,KviConfig::Write);
+
+ cfg.writeEntry("geometry",g_rectChannelsJoinGeometry);
+
+ if (g_pChannelsWindow)delete g_pChannelsWindow;
+ g_pChannelsWindow = 0;
+ return true;
+}
+
+static bool channelsjoin_module_can_unload(KviModule *m)
+{
+ return (!g_pChannelsWindow);
+}
+
+KVIRC_MODULE(
+ "ChannelsJoin",
+ "0.0.3",
+ "Copyright (C) 2001-2006 Juan Jos��varez (juanjux@yahoo.es), Alexey (wizard@opendoor.ru)",
+ "Window to join channels in a GUI",
+ channelsjoin_module_init,
+ channelsjoin_module_can_unload,
+ 0,
+ channelsjoin_module_cleanup
+)
diff --git a/src/modules/clock/Makefile.am b/src/modules/clock/Makefile.am
new file mode 100644
index 00000000..bf0a6816
--- /dev/null
+++ b/src/modules/clock/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviclock.la
+
+libkviclock_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviclock_la_SOURCES = libkviclock.cpp
+libkviclock_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= libkviclock.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkviclock.cpp: libkviclock.moc
diff --git a/src/modules/clock/libkviclock.cpp b/src/modules/clock/libkviclock.cpp
new file mode 100644
index 00000000..03757b0d
--- /dev/null
+++ b/src/modules/clock/libkviclock.cpp
@@ -0,0 +1,257 @@
+//
+// File : kvi_clock.cpp
+// Creation date : Mon Aug 13 2001 16:34:12 CEST 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 "libkviclock.h"
+#include "kvi_module.h"
+#include "kvi_console.h"
+#include "kvi_options.h"
+#include "kvi_frame.h"
+#include "kvi_locale.h"
+
+#include "kvi_pointerlist.h"
+#include <qbitmap.h>
+#include <qtooltip.h>
+#include <qpainter.h>
+
+
+
+
+//#include <X11/Xlib.h>
+#include <time.h>
+
+#if 0
+
+
+#warning "Change this XPM to bitmap bits! (And thus use the QBitmap(w,h,bits) constructor)"
+#warning "Support GMT , LOCAL , DATE , ALARM..."
+
+/* XPM */
+static const char * kvi_clock_digits_xpm[] = {
+"234 25 3 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"+................+++++++++++.......++................++................+...+++++++.......++................++................++................++................++................+++++++++++++++++++++++++++++++++++++++++++++...+++++++",
+"+................+++++++++++.......++...+++++++......++...+++++++......+...+++++++.......++....++++++++++++++....++++++......++...+++++++......++....++++++......++...+++++++......++++++++++++++++++++++++++++++++++++++++++++.....++++++",
+"+....++++++......+++++++++++.......++...+++++++......++...+++++++......+...+++++++.......++....++++++++++++++....++++++......++...+++++++......++....++++++......++...+++++++......++++++++++++++++++++++++++++++++++++++++++++.....++++++",
+"+....++++++......+++++++++++.......++...+++++++......++...+++++++......+...+++++++.......++....++++++++++++++....++++++......++...+++++++......++....++++++......++...+++++++......++++...+++++++++++++++++++++++++++++++++++++.....++++++",
+"+....++++++......+++++++++++.......++...+++++++......++...+++++++......+...+++++++.......++....++++++++++++++....++++++......++...+++++++......++....++++++......++...+++++++......++++...++++++++++++++++++++++++++++++++++++.......+++++",
+"+....++++++......+++++++++++.......++++++++++++......++...+++++++......+...+++++++.......++....++++++++++++++....++++++++++++++...+++++++......++....++++++......++...+++++++......++++...++++..++++++++++++++++++++++++++++++++++++++++++",
+"+....++++++......+++++++++++.......++++++++++++......++++++++++++......+...+++++++.......++....++++++++++++++....++++++++++++++++++++++++......++....++++++......++...+++++++......+++++++++++..+++++++++++++++++++++++++++++++++.++++++++",
+"+....++++++......+++++++++++.......++................+++...............+.................++................++................++++++++++++......++................++...+++++++......+++++++++++..++++++++++++++++++++++++++++++++++++++++++",
+"+....++++++......+++++++++++.......++................+++...............+.................++................++................++++++++++++......++................++................+++++++++++..++++++++++++++++++++++++++++++++++++++++++",
+"+....++++++......+++++++++++.......++...+++++++++++++++++++++++++......+++++++++++.......++++++++++++......++....++++++......++++++++++++......++....++++++......++++++++++++......+++++++++++..++++++++++++++++++++++++++++++++++++++++++",
+"+....++++++......+++++++++++.......++...+++++++++++++++++++++++++......+++++++++++.......++++++++++++......++....++++++......++++++++++++......++....++++++......++++++++++++......++++...++++.......++.......++.......+++++.+++++++++.+++",
+"+....++++++......+++++++++++.......++...+++++++++++++++...+++++++......+++++++++++.......++....++++++......++....++++++......++++++++++++......++....++++++......++++++++++++......++++...++++..+++..++..+.+..++..+++++++++.++.++.++.++.++",
+"+....++++++......+++++++++++.......++...+++++++++++++++...+++++++......+++++++++++.......++....++++++......++....++++++......++++++++++++......++....++++++......++++++++++++......++++...++++..+++..++..+.+..++.......++++.+.++...++.+.++",
+"+....++++++......+++++++++++.......++...+++++++++++++++...+++++++......+++++++++++.......++....++++++......++....++++++......++++++++++++......++....++++++......++++++++++++......+++++++++++..+++..++..+.+..+++++++..++++.+.++...++.+.++",
+"+................+++++++++++.......++................++................+++++++++++.......++................++................++++++++++++......++................++++++++++++......+++++++++++..+++..++..+.+..++..+++..++++.++.++.++.++.++",
+"+................+++++++++++.......++................++................+++++++++++.......++................++................++++++++++++......++................++++++++++++......+++++++++++..+++..++..+.+..++.......+++++.+++++++++.+++",
+"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"+................++................++................++................++................+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"+..+...+++.++++..++..+.+.+++.++++..++..+++.+++.+.....++..+++.+++.+.....++..+++.+++.+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"+..+...+.+.+.....++..+.+..+..+.....++..+...+.+.+.....++..+...+.+.+.....++..+...+.+.+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"+..+...+.+.+.....++..+.+..+..+.....++..+...+++.+.....++..+...+++.+.....++..+...+++.+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"+..+...+.+.+.....++..+.+..+..+.....++..+...+.+.+.....++..+...+.+.+.....++..+...+.+.+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"+..+++.+++.++++..++..+++..+..++++..++..+++.+.+.++++..++..+++.+.+.++++..++..+++.+.+.++++..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
+"+................++................++................++................++................+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"};
+
+
+// kvi_app.cpp
+//extern Display * g_display;
+//extern GC g_iccGC;
+extern QPixmap * g_pIccMemBuffer;
+//extern HANDLE g_hIccMemBuffer;
+
+
+static KviPointerList<KviClockDisplay> * g_pClockWidgetList;
+
+static QBitmap * g_pClockBitmap = 0;
+
+
+KviClockDisplay::KviClockDisplay(KviIrcToolBarAppletContainer * pContainer)
+: KviIrcToolBarGraphicalApplet(pContainer,"clock_display")
+{
+ g_pClockWidgetList->append(this);
+
+ for(int i=0;i<6;i++)
+ {
+ m_uDigit[i] = 0;
+ }
+
+ startTimer(1000);
+}
+
+KviClockDisplay::~KviClockDisplay()
+{
+ g_pClockWidgetList->removeRef(this);
+}
+
+void KviClockDisplay::timerEvent(QTimerEvent *e)
+{
+ time_t t = time(0);
+ struct tm * pTm = gmtime(&t);
+
+ m_uDigit[0] = pTm->tm_hour / 10;
+ m_uDigit[1] = pTm->tm_hour % 10;
+ m_uDigit[2] = pTm->tm_min / 10;
+ m_uDigit[3] = pTm->tm_min % 10;
+ m_uDigit[4] = pTm->tm_sec / 10;
+ m_uDigit[5] = pTm->tm_sec % 10;
+
+ update();
+}
+
+
+
+void KviClockDisplay::drawContents(QPainter *p)
+{
+ //XSetLineAttributes(g_display,g_iccGC,1,LineSolid,CapButt,JoinMiter); //need this for line size
+
+
+ //XSetClipMask(g_display,g_iccGC,g_pClockBitmap->handle());
+
+ #define LOW_ROW_Y 6
+
+
+
+#define DRAW_DIGIT(_x,_num,_br) \
+ p->setBrushOrigin(- (m_uDigit[_num] * 18) + _x,LOW_ROW_Y); \
+ p->fillRect(_x,LOW_ROW_Y,18,18,_br);
+
+#define DRAW_DOTS(_x,_br) \
+ p->setBrushOrigin(- 180 + _x,LOW_ROW_Y); \
+ p->fillRect(_x,LOW_ROW_Y,9,18,_br);
+
+ QBrush br1(KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundLowContrast),*g_pClockBitmap);
+
+ p->setBrushOrigin(- 216,LOW_ROW_Y);
+ p->fillRect(0,LOW_ROW_Y,18,18,br1);
+
+ p->setBrushOrigin(22,LOW_ROW_Y + 2 /*-18 + LOW_ROW_Y + 20 */);
+ p->fillRect(22,LOW_ROW_Y + 20,18 * 5,7,br1);
+
+ QBrush br2(KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundHighContrastActive1),*g_pClockBitmap);
+
+ DRAW_DIGIT(22,0,br2)
+ DRAW_DIGIT(40,1,br2)
+
+ DRAW_DOTS(58,br2)
+
+ DRAW_DIGIT(67,2,br2)
+ DRAW_DIGIT(85,3,br2)
+
+ DRAW_DOTS(103,br2)
+
+ DRAW_DIGIT(112,4,br2)
+ DRAW_DIGIT(130,5,br2)
+
+}
+
+QSize KviClockDisplay::sizeHint() const
+{
+ return QSize(KVI_IRCTOOLBARAPPLET_MAXIMUM_WIDTH,KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT);
+}
+
+
+/*
+ @doc: clock.add
+ @type:
+ command
+ @title:
+ clock.add
+ @short:
+ Adds a Clock applet
+ @syntax:
+ clock.add
+ @description:
+*/
+
+
+
+static bool clock_module_cmd_add(KviModule *m,KviCommand *c)
+{
+ ENTER_STACK_FRAME(c,"clock_module_cmd_add");
+
+ KviStr dummy;
+ if(!g_pUserParser->parseCmdFinalPart(c,dummy))return false;
+
+ KviClockDisplay * dpy = new KviClockDisplay(c->window()->frame()->frameAppletContainer());
+ c->window()->frame()->frameAppletContainer()->addApplet(dpy);
+ dpy->show();
+
+ return c->leaveStackFrame();
+}
+#endif
+
+
+static bool clock_module_init(KviModule *m)
+{
+#if 0
+ g_pClockBitmap = new QBitmap();
+ QPixmap pix(kvi_clock_digits_xpm);
+ *g_pClockBitmap = pix;
+ g_pClockWidgetList = new KviPointerList<KviClockDisplay>;
+ g_pClockWidgetList->setAutoDelete(false);
+ m->registerCommand("add",clock_module_cmd_add);
+#endif
+ return true;
+}
+
+static bool clock_module_cleanup(KviModule *m)
+{
+#if 0
+ while(g_pClockWidgetList->first())
+ {
+ KviClockDisplay * dpy = g_pClockWidgetList->first();
+ dpy->container()->removeApplet(dpy); // deleted path
+ }
+ delete g_pClockWidgetList;
+ delete g_pClockBitmap;
+#endif
+ return true;
+}
+
+static bool clock_module_can_unload(KviModule *m)
+{
+#if 0
+ return g_pClockWidgetList->isEmpty();
+#else
+ return true;
+#endif
+}
+
+KVIRC_MODULE(
+ "Clock", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Clock toolbar applet",
+ clock_module_init,
+ clock_module_can_unload,
+ 0,
+ clock_module_cleanup
+)
+#if 0
+#include "libkviclock.moc"
+#endif
diff --git a/src/modules/clock/libkviclock.h b/src/modules/clock/libkviclock.h
new file mode 100644
index 00000000..bf4881a6
--- /dev/null
+++ b/src/modules/clock/libkviclock.h
@@ -0,0 +1,46 @@
+#ifndef _LIBKVICLOCK_H_
+#define _LIBKVICLOCK_H_
+
+//
+// File : kvi_clock.cpp
+// Creation date : Mon Aug 13 2001 16:33:12 CEST 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.
+//
+
+#if 0
+
+#include "kvi_irctoolbar.h"
+
+class KviClockDisplay : public KviIrcToolBarGraphicalApplet
+{
+ Q_OBJECT
+public:
+ KviClockDisplay(KviIrcToolBarAppletContainer * pContainer);
+ ~KviClockDisplay();
+protected:
+ unsigned char m_uDigit[6];
+protected:
+ virtual void drawContents(QPainter * p);
+ virtual QSize sizeHint() const;
+ virtual void timerEvent(QTimerEvent *e);
+};
+
+#endif
+
+#endif
diff --git a/src/modules/codetester/Makefile.am b/src/modules/codetester/Makefile.am
new file mode 100644
index 00000000..37540094
--- /dev/null
+++ b/src/modules/codetester/Makefile.am
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvicodetester.la
+
+libkvicodetester_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvicodetester_la_SOURCES = libkvicodetester.cpp codetester.cpp
+nodist_libkvicodetester_la_SOURCES = moc_codetester.cpp
+
+noinst_HEADERS = codetester.h
+libkvicodetester_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+moc_codetester.cpp: codetester.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/codetester/codetester.cpp b/src/modules/codetester/codetester.cpp
new file mode 100644
index 00000000..69a46abc
--- /dev/null
+++ b/src/modules/codetester/codetester.cpp
@@ -0,0 +1,157 @@
+//
+// 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 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 "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_config.h"
+#include "kvi_filedialog.h"
+#include "kvi_fileutils.h"
+#include "kvi_scripteditor.h"
+
+#include "kvi_app.h"
+#include "kvi_console.h"
+#include "kvi_parameterlist.h"
+#include "kvi_kvs_script.h"
+#include "kvi_kvs_variantlist.h"
+
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qtoolbutton.h>
+#include "kvi_tal_popupmenu.h"
+
+extern KviPointerList<KviCodeTesterWindow> * g_pCodeTesterWindowList;
+
+
+
+
+KviCodeTester::KviCodeTester(QWidget * par)
+: QWidget(par,"code_tester")
+{
+ QGridLayout * g = new QGridLayout(this,2,4,2,2);
+ m_pEditor = KviScriptEditor::createInstance(this);
+ g->addMultiCellWidget(m_pEditor,0,0,0,3);
+ m_pExecuteButton = new QPushButton(__tr2qs("&Execute"),this);
+ g->addWidget(m_pExecuteButton,1,3);
+ connect(m_pExecuteButton,SIGNAL(clicked()),this,SLOT(execute()));
+
+ m_pModeLabel = new QLabel(__tr("Params:"),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);
+ KviConsole * con = g_pApp->activeConsole();
+ //KviParameterList * l = new KviParameterList(parms.ptr());
+ KviKvsScript::run(buffer,con,new KviKvsVariantList(new QString(parms)));
+}
+
+KviCodeTesterWindow::KviCodeTesterWindow(KviFrame * 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 *e)
+{
+ m_pTester->setGeometry(0,0,width(),height());
+}
+
+void KviCodeTesterWindow::fillCaptionBuffers()
+{
+ m_szPlainTextCaption = __tr2qs("Script Tester");
+
+ static QString p1("<nobr><font color=\"");
+ static QString p2("\"><b>");
+ static QString p3("</b></font></nobr>");
+
+ m_szHtmlActiveCaption = p1;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += p2;
+ m_szHtmlActiveCaption += m_szPlainTextCaption;
+ m_szHtmlActiveCaption += p3;
+
+ m_szHtmlInactiveCaption = p1;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += p2;
+ m_szHtmlInactiveCaption += m_szPlainTextCaption;
+ m_szHtmlInactiveCaption += p3;
+}
+
+
+void KviCodeTesterWindow::getConfigGroupName(KviStr &szName)
+{
+ szName = "codetester";
+}
+
+
+void KviCodeTesterWindow::saveProperties(KviConfig *cfg)
+{
+/*
+#ifdef COMPILE_SCRIPTTOOLBAR
+ cfg->writeEntry("Sizes",m_pEditor->sizes());
+ cfg->writeEntry("LastRaw",m_pEditor->lastEditedRaw().ptr());
+ //debug("LAST EDITED=%s",m_pEditor->lastEditedRaw().ptr());
+#endif // COMPILE_SCRIPTTOOLBAR
+*/
+}
+
+void KviCodeTesterWindow::loadProperties(KviConfig *cfg)
+{
+/*
+#ifdef COMPILE_SCRIPTTOOLBAR
+ QValueList<int> def;
+ def.append(20);
+ def.append(80);
+ m_pEditor->setSizes(cfg->readIntListEntry("Sizes",def));
+ KviStr tmp = cfg->readEntry("LastRaw","");
+ m_pEditor->editRaw(tmp);
+ //debug("LAST EDITED WAS %s",tmp.ptr());
+#endif // COMPILE_SCRIPTTOOLBAR
+*/
+}
diff --git a/src/modules/codetester/codetester.h b/src/modules/codetester/codetester.h
new file mode 100644
index 00000000..ce24ca5d
--- /dev/null
+++ b/src/modules/codetester/codetester.h
@@ -0,0 +1,67 @@
+#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 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 "kvi_window.h"
+#include "kvi_string.h"
+
+#include <qlineedit.h>
+
+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(KviFrame * lpFrm);
+ ~KviCodeTesterWindow();
+protected:
+ KviCodeTester * m_pTester;
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void getConfigGroupName(KviStr &szName);
+ virtual void saveProperties(KviConfig *);
+ virtual void loadProperties(KviConfig *);
+};
+
+#endif //_CODETESTER_H_
diff --git a/src/modules/codetester/libkvicodetester.cpp b/src/modules/codetester/libkvicodetester.cpp
new file mode 100644
index 00000000..ec84a217
--- /dev/null
+++ b/src/modules/codetester/libkvicodetester.cpp
@@ -0,0 +1,89 @@
+//===============================================================================
+//
+// File : libkvicodetester.cpp
+// Creation date : Mon 23 Dec 2002 20:23:59 2002 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2002-2005 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_module.h"
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+#include "kvi_pointerlist.h"
+
+#include "codetester.h"
+
+KviPointerList<KviCodeTesterWindow> * g_pCodeTesterWindowList = 0;
+
+
+/*
+ @doc: codetester.open
+ @type:
+ command
+ @title:
+ codetester.open
+ @short:
+ Shows the code tester window
+ @syntax:
+ codetester.open
+ @description:
+ Opens a new code tester window
+*/
+
+static bool codetester_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ KviCodeTesterWindow * w = new KviCodeTesterWindow(c->window()->frame());
+ c->window()->frame()->addWindow(w);
+ w->setFocus();
+ return true;
+}
+
+static bool codetester_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",codetester_kvs_cmd_open);
+
+ g_pCodeTesterWindowList = new KviPointerList<KviCodeTesterWindow>();
+ g_pCodeTesterWindowList->setAutoDelete(false);
+ return true;
+}
+
+static bool codetester_module_can_unload(KviModule * m)
+{
+ return (g_pCodeTesterWindowList->count() == 0);
+}
+
+static bool codetester_module_cleanup(KviModule *m)
+{
+ while(KviCodeTesterWindow * w = g_pCodeTesterWindowList->first())
+ {
+ w->close(); // deleted path!
+ }
+ return true;
+}
+
+KVIRC_MODULE(
+ "CodeTester", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Code tester window",
+ codetester_module_init,
+ codetester_module_can_unload,
+ 0,
+ codetester_module_cleanup
+)
diff --git a/src/modules/config/Makefile.am b/src/modules/config/Makefile.am
new file mode 100644
index 00000000..1a43c2e9
--- /dev/null
+++ b/src/modules/config/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makefile - 31.01.2002 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviconfig.la
+
+libkviconfig_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviconfig_la_SOURCES = libkviconfig.cpp
+libkviconfig_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/config/libkviconfig.cpp b/src/modules/config/libkviconfig.cpp
new file mode 100644
index 00000000..854c321b
--- /dev/null
+++ b/src/modules/config/libkviconfig.cpp
@@ -0,0 +1,877 @@
+//=============================================================================
+//
+// File : libkviconfig.cpp
+// Creation date : Thu Jan 31 2002 22:50:12 GMT by Szymon Stefanek
+//
+// This config is part of the KVirc irc client distribution
+// Copyright (C) 2002-2005 Szymon Stefanek (pragma@kvirc.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_module.h"
+#include "kvi_string.h"
+#include "kvi_config.h"
+#include "kvi_fileutils.h"
+#include "kvi_app.h"
+#include "kvi_locale.h"
+
+#include "kvi_pointerhashtable.h"
+
+static KviPointerHashTable<QString,KviConfig> * g_pConfigDict = 0;
+static int g_iNextConfigId = 0;
+
+/*
+ @doc: config.open
+ @type:
+ function
+ @title:
+ $config.open
+ @short:
+ Opens a config file
+ @syntax:
+ $config.open(<filename:string>[,<flags:string>])
+ @description:
+ Opens a config file.
+ If the file already exists , its contents
+ are parsed and available for extracting by the [fnc]$config.read[/fnc]() function.[br]
+ <filename> may be an absolute path or a relative path: if a relative path is used,
+ KVIrc will complete it with a local kvirc directory suitable for writing script config files.[br]
+ If the config file doesn't exist , it is opened as empty config file.[br]
+ Flags can contain a combination of letters 'r' and 'w'.[br]
+ If only 'r' is specified , the config file is opened in "read-only" mode: no changes will be written to disk.[br]
+ If only 'w' is specified , the config file is opened in "write-only" mode: the contents of the file on disk
+ are not readed.[br]
+ If <flags> are not specified then 'rw' is assumed.[br]
+ The function returns an identifier for the open config file. This identifier
+ is a mandatory parameter in all the other config.* functions and commands.[br]
+ The config section is set to the default section name: you can change it by using
+ [cmd]config.setsection[/cmd].[br]
+ After you have finished using the file , don't forget to call [cmd]config.close[/cmd]!
+ KVIrc tries to not open a config file twice: if the file was already opened then
+ the identifier of the open file is returned.[br]
+ You can check if a config file is already open by using the
+ [fnc]$config.id[/fnc]() function.[br]
+ @examples:
+ [example]
+ # It is a good idea to store the returned id to a variable :)
+ %cfg = $config.open(myscript.kvc)
+ %num = [fnc]$config.read[/fnc](%cfg,Number,0)
+ [cmd]echo[/cmd] Number of entries is %num
+ %num++;
+ [cmd]config.write[/cmd] %cfg Number %num
+ [cmd]config.close[/cmd] %cfg
+ [/example]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+
+static bool config_kvs_fnc_open(KviKvsModuleFunctionCall * c)
+{
+ QString szFile;
+ QString szMode;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_STRING,0,szFile)
+ KVSM_PARAMETER("mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szMode)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig::FileMode fileMode;
+
+ if(szMode.contains('r'))
+ {
+ if(szMode.contains('w'))fileMode = KviConfig::ReadWrite;
+ else fileMode = KviConfig::Read;
+ } else {
+ if(szMode.contains('w'))fileMode = KviConfig::Write;
+ else fileMode = KviConfig::ReadWrite;
+ }
+
+ KviFileUtils::adjustFilePath(szFile);
+ QString szAbsFile;
+
+ if(KviFileUtils::isAbsolutePath(szFile))szAbsFile = szFile;
+ else g_pApp->getLocalKvircDirectory(szAbsFile,KviApp::ConfigScripts,szFile,true);
+
+ KviPointerHashTableIterator<QString,KviConfig> it(*g_pConfigDict);
+ while(it.current())
+ {
+ if(KviQString::equalCI(it.current()->fileName(),szAbsFile))
+ {
+ c->returnValue()->setString(it.currentKey());
+ if(it.current()->readOnly() && (fileMode & KviConfig::Write))
+ {
+ it.current()->setReadOnly(false);
+ }
+ return true;
+ }
+ ++it;
+ }
+
+ KviConfig * cfg = new KviConfig(szAbsFile,fileMode);
+ g_iNextConfigId++;
+ QString tmp = QString("%1").arg(g_iNextConfigId);
+ g_pConfigDict->insert(tmp,cfg);
+ c->returnValue()->setString(tmp);
+ return true;
+}
+
+/*
+ @doc: config.id
+ @type:
+ function
+ @title:
+ $config.id
+ @short:
+ Returns the id of an open config file
+ @syntax:
+ $config.id(<filename>)
+ @description:
+ Returns the id of an open config file specified by <filename>.[br]
+ (This is the same id that is returned by [fnc]$config.open[/fnc].[br]
+ If no such file is open, 0 is returned (that is an invalid config identifier).[br]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_fnc_id(KviKvsModuleFunctionCall * c)
+{
+ QString szFile;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("file",KVS_PT_STRING,0,szFile)
+ KVSM_PARAMETERS_END(c)
+
+ KviFileUtils::adjustFilePath(szFile);
+
+ QString szAbsFile;
+
+ if(KviFileUtils::isAbsolutePath(szFile))szAbsFile = szFile;
+ else g_pApp->getLocalKvircDirectory(szAbsFile,KviApp::ConfigScripts,szFile,true);
+
+ KviPointerHashTableIterator<QString,KviConfig> it(*g_pConfigDict);
+ while(it.current())
+ {
+ if(KviQString::equalCI(it.current()->fileName(),szAbsFile))
+ {
+ c->returnValue()->setString(it.currentKey());
+ return true;
+ }
+ ++it;
+ }
+
+ c->returnValue()->setString("0");
+
+ return true;
+}
+
+/*
+ @doc: config.read
+ @type:
+ function
+ @title:
+ $config.read
+ @short:
+ Reads an entry from a config file
+ @syntax:
+ $config.read(<id:string>,<key:string>[,<default:string>])
+ @description:
+ Reads and returns the value associated to <key> in the current section of the config
+ file identified by <id>.[br]
+ <id> must be a valid config identifier returned by [fnc]$config.open[/fnc]()
+ If no value is associated with <key> in the current section the return value
+ is an empty string or the string <default> if it has been passed.[br]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_fnc_read(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ QString szKey;
+ QString szDefault;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETER("key",KVS_PT_STRING,0,szKey)
+ KVSM_PARAMETER("default",KVS_PT_STRING,KVS_PF_OPTIONAL,szDefault)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ c->returnValue()->setString(cfg->readEntry(szKey,szDefault));
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+ return true;
+}
+
+/*
+ @doc: config.section
+ @type:
+ function
+ @title:
+ $config.section
+ @short:
+ Returns the name of the current section of a config file
+ @syntax:
+ $config.section(<id>)
+ @description:
+ Returns the name of the current section in the config file identifier by <id>.[br]
+ <id> must be a valid config identifier returned by [fnc]$config.open[/fnc]()
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_fnc_section(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ c->returnValue()->setString(cfg->group());
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+ return true;
+}
+
+/*
+ @doc: config.readonly
+ @type:
+ function
+ @title:
+ $config.readonly
+ @short:
+ Checks wheter a config file is opened in readonly mode
+ @syntax:
+ $config.readonly(<id>)
+ @description:
+ Returns 1 if the config file identified by <id> is opened in readonly mode,
+ 0 otherwise.[br]
+ <id> must be a valid config identifier returned by [fnc]$config.open[/fnc]()
+ If <id> does not identify an open config file, a warning is printed and 0 is returned.[br]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_fnc_readonly(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ c->returnValue()->setBoolean(cfg->readOnly());
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ c->returnValue()->setInteger(false);
+ }
+ return true;
+}
+
+/*
+ @doc: config.filename
+ @type:
+ function
+ @title:
+ $config.filename
+ @short:
+ Returns the filename of an open config file
+ @syntax:
+ $config.filename(<id>)
+ @description:
+ Returns the filename of the [b]open[/b] config file identifier by <id>.[br]
+ <id> must be a valid config identifier returned by [fnc]$config.open[/fnc]()
+ If the <id> doesn't match any open file, and empty string is returned.[br]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_fnc_filename(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ c->returnValue()->setString(cfg->fileName());
+ }
+ return true;
+}
+
+/*
+ @doc: config.hassection
+ @type:
+ function
+ @title:
+ $config.hassection
+ @short:
+ Checks wheter a section is present in a config file
+ @syntax:
+ $config.hassection(<id>,<section_name>)
+ @description:
+ Returns 1 if the section <section_name> exists in the config file identifier by <id>,
+ 0 otherwise.[br]
+ <id> must be a valid config identifier returned by [fnc]$config.open[/fnc]()
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_fnc_hassection(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ QString szSect;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szSect)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ c->returnValue()->setBoolean(cfg->hasGroup(szSect));
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+ return true;
+}
+
+/*
+ @doc: config.sectionlist
+ @type:
+ function
+ @title:
+ $config.sectionlist
+ @short:
+ Returns a list of the sections in a config file
+ @syntax:
+ $config.sectionlist(<id>)
+ @description:
+ Returns an array of sections present in the config file identified by <id>.[br]
+ <id> must be a valid config identifier returned by [fnc]$config.open[/fnc]()
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_fnc_sectionlist(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ KviConfigIterator it(*(cfg->dict()));
+ KviKvsArray* pArray = new KviKvsArray();
+ int id=0;
+ while(it.current())
+ {
+ pArray->set(id++, new KviKvsVariant(it.currentKey()));
+ ++it;
+ }
+ c->returnValue()->setArray(pArray);
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+ return true;
+}
+
+/*
+ @doc: config.keylist
+ @type:
+ function
+ @title:
+ $config.keylist
+ @short:
+ Returns a list of keys in a config file
+ @syntax:
+ $config.keylist(<id>)
+ @description:
+ Returns an array of keys present in the current section of the config file identified by <id>.[br]
+ <id> must be a valid config identifier returned by [fnc]$config.open[/fnc]()
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_fnc_keylist(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ KviConfigGroup * d = cfg->dict()->find(cfg->group());
+ if(!d)return true;
+
+ KviConfigGroupIterator it(*d);
+
+ KviKvsArray* pArray = new KviKvsArray();
+ int id=0;
+
+ while(it.current())
+ {
+ pArray->set(id++, new KviKvsVariant(it.currentKey()));
+ ++it;
+ }
+ c->returnValue()->setArray(pArray);
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+ return true;
+}
+
+/*
+ @doc: config.filelist
+ @type:
+ function
+ @title:
+ $config.filelist
+ @short:
+ Returns a list of open config files
+ @syntax:
+ $config.filelist
+ @description:
+ Returns an array of open config files.[br]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_fnc_filelist(KviKvsModuleFunctionCall * c)
+{
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray* pArray = new KviKvsArray();
+ int id=0;
+
+ KviPointerHashTableIterator<QString,KviConfig> it(*g_pConfigDict);
+ while(it.current())
+ {
+ pArray->set(id++, new KviKvsVariant(it.currentKey()));
+ ++it;
+ }
+ c->returnValue()->setArray(pArray);
+ return true;
+}
+
+/*
+ @doc: config.close
+ @type:
+ command
+ @title:
+ config.close
+ @keyterms:
+ storing & reading configuration entries
+ @short:
+ Closes a config file
+ @syntax:
+ config.close [-q] <id>
+ @description:
+ Closes the config file identified by <id>.[br]
+ <id> must be a a valid config file identifier returned by [fnc]$config.open[/fnc].[br]
+ If the config file was opened as read-write (default), the changes will be stored
+ to disk. If the config was opened as read-only , changes will not be written.[br]
+ If the <id> does not match any open config file, a warning is printed unless
+ the -q switch is used.[br]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_cmd_close(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ if(cfg->dirty() && cfg->readOnly())
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("The config file '%Q' has been changed but is opened as read-only: changes will be lost"),&cfg->fileName());
+ }
+ g_pConfigDict->remove(szId);
+ } else {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+
+ return true;
+}
+
+/*
+ @doc: config.flush
+ @type:
+ command
+ @title:
+ config.flush
+ @keyterms:
+ storing & reading configuration entries
+ @short:
+ Flushes a config file
+ @syntax:
+ config.flush <id>
+ @description:
+ Flushes the config file identified by <id>.[br]
+ <id> must be a a valid config file identifier returned by [fnc]$config.open[/fnc].[br]
+ If the config file was opened as read-write (default), the changes will be stored
+ to disk. If the config was opened as read-only ,an error is printed.[br]
+ If the <id> does not match any open config file, a warning is printed.
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_cmd_flush(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ if(cfg->readOnly())
+ c->warning(__tr2qs("The config file with id '%Q' is read only"),&szId);
+ else
+ cfg->sync();
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+
+ return true;
+}
+
+/*
+ @doc: config.clear
+ @type:
+ command
+ @title:
+ config.clear
+ @keyterms:
+ storing & reading configuration entries
+ @short:
+ Clears a config file
+ @syntax:
+ config.clear <id>
+ @description:
+ Clears the contents of the config file identified by <id>.[br]
+ All the sections are removed (except for the default section) and all the key=value
+ pairs are destroyed.[br]
+ <id> must be a a valid config file identifier returned by [fnc]$config.open[/fnc].[br]
+ If the <id> does not match any open config file, a warning is printed.
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_cmd_clear(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ cfg->clear();
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+
+ return true;
+}
+
+/*
+ @doc: config.clearsection
+ @type:
+ command
+ @title:
+ config.clearsection
+ @keyterms:
+ storing & reading configuration entries
+ @short:
+ Clears a section in a config file
+ @syntax:
+ config.clearsection <id> <section_name>
+ @description:
+ Clears the contents of the section <section_name> in the config file identified by <id>.[br]
+ All the key=value pairs in the section are destroyed.[br]
+ <id> must be a a valid config file identifier returned by [fnc]$config.open[/fnc].[br]
+ If the <id> does not match any open config file, a warning is printed.
+ If <section_name> was also the current section, the current section is set to the default one.[br]
+ No warning is printed if the section wasn't existing.[br]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_cmd_clearsection(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ QString szSect;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETER("section",KVS_PT_STRING,0,szSect)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ cfg->clearGroup(szSect);
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+
+ return true;
+}
+
+/*
+ @doc: config.write
+ @type:
+ command
+ @title:
+ config.write
+ @keyterms:
+ storing & reading configuration entries
+ @short:
+ Writes a data field to a config file
+ @syntax:
+ config.write <id> <key> <value>
+ @description:
+ Writes the <key>=<value> pair to the config file identifier by <id>.[br]
+ <id> must be a valid config file id returned by [fnc]$config.open[/fnc]().[br]
+ <key> and <value> can be any strings.[br]
+ The <key>=<value> pair is written in the current section of the config file.[br]
+ If <key> already exists in the current section of the config , the corresponding value is replaced with <value>.[br]
+ If <value> is an empty string, the <key> is simply removed from the current section.[br]
+ If a section remains empty (with no keys) at file write time, that section will be removed.[br]
+ The changes are NOT written to disk: you must call [cmd]config.flush[/cmd] or (better) [cmd]config.close[/cmd]
+ for the changes to be effectively written.[br]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_cmd_write(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ QString szKey;
+ QString szVal;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETER("key",KVS_PT_STRING,0,szKey)
+ KVSM_PARAMETER("value",KVS_PT_STRING,0,szVal)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ cfg->writeEntry(szKey,szVal);
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+
+ return true;
+}
+
+/*
+ @doc: config.setsection
+ @type:
+ command
+ @title:
+ config.setsection
+ @keyterms:
+ storing & reading configuration entries
+ @short:
+ Changes the current section of a config file
+ @syntax:
+ config.setsection <id> <section_name>
+ @description:
+ Changes the current section of the config file <id> to <section_name>.[br]
+ Sections are effectively namespaces for the keys: each section can contain
+ a set of keys and equal keys in different sections do not collide.[br]
+ <id> must be a valid config file id returned by [fnc]$config.open[/fnc]().[br]
+ @seealso:
+ [module:config]Config module documentation[/module]
+*/
+
+static bool config_kvs_cmd_setsection(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ QString szSect;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_STRING,0,szId)
+ KVSM_PARAMETER("section",KVS_PT_STRING,0,szSect)
+ KVSM_PARAMETERS_END(c)
+
+ KviConfig * cfg = g_pConfigDict->find(szId);
+
+ if(cfg)
+ {
+ cfg->setGroup(szSect);
+ } else {
+ c->warning(__tr2qs("The config file with id '%Q' is not open"),&szId);
+ }
+
+ return true;
+}
+
+/*
+ @doc: config
+ @type:
+ module
+ @short:
+ Managing of configuration files
+ @title:
+ The config module
+ @body:
+ The config module is a powerful interface that manages text configuration files.[br]
+ The files are arranged in named sections and the data is stored in key=value pairs
+ belonging to each section.[br]
+ [br]
+ [section1_name][br]
+ <key1>=<value1>[br]
+ <key2>=<value2>[br]
+ <key3>=<value3>[br]
+ ....[br]
+ [section2_name][br]
+ <key1>=<value1>[br]
+ ....[br]
+ [br]
+ Keys and values are plain text strings. Eventual newlines in values are encoded using
+ a simple hexadecimal notation.[br]
+ The config files can be also edited by using any text editor.[br]
+ The config module works on config files loaded in memory. For this reason,
+ you must first open a config file by the means of [fnc]$config.open[/fnc]().[br]
+ Once you open the file , if it exists on disk , its contents are loaded into memory
+ and you can access the data stored in it. If the file wasn't existing, and empty
+ memory config file is created.[br]
+ The config file is opened in read-write mode by default. You can also choose
+ the "read-only" method: a read-only config file is never flushed to disk (but you can
+ set the values in memory!).[br]
+ It is not a good idea to keep a config file open forever: a good approach
+ is to keep settings in memory variables and write them all at once when it comes to
+ write settings: you open the config file , write all your values and close the file.[br]
+ You can obviously keep the config file open for some time but remember that
+ no change is written to the disk until [cmd]config.flush[/cmd] or [cmd]config.close[/cmd] is called.[br]
+ You write entries by using [cmd]config.write[/cmd] and read them by using [fnc]$config.read[/fnc]().[br]
+ You can change the "current" config section by using [cmd]config.setsection[/cmd].[br]
+ Here comes a complete list of commands and functions exported by this module:[br]
+ [fnc]$config.open[/fnc][br]
+ [fnc]$config.read[/fnc][br]
+ [fnc]$config.section[/fnc][br]
+ [fnc]$config.hassection[/fnc][br]
+ [fnc]$config.sectionlist[/fnc][br]
+ [fnc]$config.keylist[/fnc][br]
+ [fnc]$config.filelist[/fnc][br]
+ [fnc]$config.filename[/fnc][br]
+ [fnc]$config.id[/fnc][br]
+ [fnc]$config.readonly[/fnc][br]
+ [cmd]config.close[/cmd][br]
+ [cmd]config.flush[/cmd][br]
+ [cmd]config.clear[/cmd][br]
+ [cmd]config.clearsection[/cmd][br]
+ [cmd]config.setsection[/cmd][br]
+ [cmd]config.write[/cmd][br]
+*/
+
+static bool config_module_init(KviModule * m)
+{
+ g_pConfigDict = new KviPointerHashTable<QString,KviConfig>;
+ g_pConfigDict->setAutoDelete(true);
+
+ KVSM_REGISTER_FUNCTION(m,"open",config_kvs_fnc_open);
+ KVSM_REGISTER_FUNCTION(m,"id",config_kvs_fnc_id);
+ KVSM_REGISTER_FUNCTION(m,"read",config_kvs_fnc_read);
+ KVSM_REGISTER_FUNCTION(m,"section",config_kvs_fnc_section);
+ KVSM_REGISTER_FUNCTION(m,"hassection",config_kvs_fnc_hassection);
+ KVSM_REGISTER_FUNCTION(m,"sectionlist",config_kvs_fnc_sectionlist);
+ KVSM_REGISTER_FUNCTION(m,"keylist",config_kvs_fnc_keylist);
+ KVSM_REGISTER_FUNCTION(m,"filelist",config_kvs_fnc_filelist);
+ KVSM_REGISTER_FUNCTION(m,"filename",config_kvs_fnc_filename);
+ KVSM_REGISTER_FUNCTION(m,"readonly",config_kvs_fnc_readonly);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"close",config_kvs_cmd_close);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"flush",config_kvs_cmd_flush);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"clear",config_kvs_cmd_clear);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"clearsection",config_kvs_cmd_clearsection);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setsection",config_kvs_cmd_setsection);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"write",config_kvs_cmd_write);
+
+ return true;
+}
+
+static bool config_module_cleanup(KviModule *m)
+{
+ delete g_pConfigDict;
+ g_pConfigDict = 0;
+ return true;
+}
+
+static bool config_module_can_unload(KviModule *m)
+{
+ return g_pConfigDict->isEmpty();
+}
+
+KVIRC_MODULE(
+ "Config", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Config file system for KVIrc",
+ config_module_init,
+ config_module_can_unload,
+ 0,
+ config_module_cleanup
+)
diff --git a/src/modules/context/Makefile.am b/src/modules/context/Makefile.am
new file mode 100644
index 00000000..e4ec3252
--- /dev/null
+++ b/src/modules/context/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvicontext.la
+
+libkvicontext_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvicontext_la_SOURCES = libkvicontext.cpp
+libkvicontext_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/context/libkvicontext.cpp b/src/modules/context/libkvicontext.cpp
new file mode 100644
index 00000000..a6a3bb97
--- /dev/null
+++ b/src/modules/context/libkvicontext.cpp
@@ -0,0 +1,401 @@
+//=============================================================================
+//
+// File : libkvicontext.cpp
+// Creation date : Wed Jan 02 2007 03:04:12 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2007 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.
+//
+//=============================================================================
+
+//#warning: FIXME: Incomplete documentation ('seealso', 'example', etc)
+
+#include "kvi_module.h"
+#include "kvi_locale.h"
+#include "kvi_qstring.h"
+#include "kvi_window.h"
+#include "kvi_frame.h"
+#include "kvi_console.h"
+#include "kvi_app.h"
+
+#include "kvi_ircserver.h"
+#include "kvi_irccontext.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionserverinfo.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_ircconnectiontarget.h"
+
+#define GET_CONSOLE_FROM_STANDARD_PARAMS \
+ kvs_int_t iContextId; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER("irc_context_id",KVS_PT_UINT,KVS_PF_OPTIONAL,iContextId) \
+ KVSM_PARAMETERS_END(c) \
+ KviConsole * pConsole = NULL; \
+ if(c->parameterCount() > 0) \
+ pConsole = g_pApp->findConsole(iContextId); \
+ else \
+ pConsole = c->window()->console();
+
+#define GET_CONNECTION_FROM_STANDARD_PARAMS \
+ GET_CONSOLE_FROM_STANDARD_PARAMS \
+ KviIrcConnection * pConnection = NULL; \
+ if(pConsole) \
+ pConnection = pConsole->context()->connection();
+
+#define STANDARD_IRC_CONNECTION_TARGET_PARAMETER(_fncName,_setCall) \
+ static bool _fncName(KviKvsModuleFunctionCall * c) \
+ { \
+ GET_CONNECTION_FROM_STANDARD_PARAMS \
+ if(pConnection) \
+ { \
+ if(pConnection->target()) \
+ { \
+ _setCall; \
+ return true; \
+ } \
+ } \
+ c->returnValue()->setNothing(); \
+ return true; \
+ }
+
+/*
+ @doc: context.networkName
+ @type:
+ function
+ @title:
+ $context.networkName
+ @short:
+ Returns the IRC network name of an IRC context
+ @syntax:
+ <string> $contex.networkName
+ <string> $contex.networkName(<irc_context_id:uint>)
+ @description:
+ Returns the name of the network for the specified IRC context.
+ If no irc_context_id is specified then the current irc_context is used.
+ If the irc_context_id specification is not valid then this function
+ returns nothing. If the specified IRC context is not currently connected
+ then this function returns nothing.
+ @seealso:
+ [fnc]$context.serverHostName[/fnc]
+*/
+
+STANDARD_IRC_CONNECTION_TARGET_PARAMETER(
+ context_kvs_fnc_networkName,
+ c->returnValue()->setString(pConnection->target()->network()->name())
+ )
+
+
+/*
+ @doc: context.serverHostName
+ @type:
+ function
+ @title:
+ $context.serverHostName
+ @short:
+ Returns the IRC server name of an IRC context
+ @syntax:
+ <string> $contex.serverHostName
+ <string> $contex.serverHostName(<irc_context_id:uint>)
+ @description:
+ Returns the host name of the IRC server that was used to perform
+ the connection in the specified irc context.
+ If no irc_context_id is specified then the current irc_context is used.
+ If the irc_context_id specification is not valid then this function
+ returns nothing. If the specified IRC context is not currently connected
+ then this function returns nothing.
+ If the returned value is non empty then it will always be a valid
+ DNS hostname that can be used to perform a real connection.
+ Please note that this is different from $my.server() which might
+ return an invalid DNS entry.
+ @seealso:
+ [fnc]$context.serverPort[/fnc],
+ [fnc]$context.serverIpAddress[/fnc],
+ [fnc]$context.serverPassword[/fnc]
+*/
+
+STANDARD_IRC_CONNECTION_TARGET_PARAMETER(
+ context_kvs_fnc_serverHostName,
+ c->returnValue()->setString(pConnection->target()->server()->hostName())
+ )
+
+/*
+ @doc: context.serverIpAddress
+ @type:
+ function
+ @title:
+ $context.serverIpAddress
+ @short:
+ Returns the IRC server ip address of an IRC context
+ @syntax:
+ <string> $contex.serverIpAddress
+ <string> $contex.serverIpAddress(<irc_context_id:uint>)
+ @description:
+ Returns the ip address of the IRC server for the specified irc context.
+ If no irc_context_id is specified then the current irc_context is used.
+ If the irc_context_id specification is not valid then this function
+ returns nothing. If the specified IRC context is not currently connected
+ then this function returns nothing.
+ @seealso:
+ [fnc]$context.serverPort[/fnc],
+ [fnc]$context.serverHostName[/fnc],
+ [fnc]$context.serverPassword[/fnc]
+*/
+
+STANDARD_IRC_CONNECTION_TARGET_PARAMETER(
+ context_kvs_fnc_serverIpAddress,
+ c->returnValue()->setString(pConnection->target()->server()->ipAddress())
+ )
+
+/*
+ @doc: context.serverIsIPV6
+ @type:
+ function
+ @title:
+ $context.serverIsIPV6
+ @short:
+ Returns the IPV6 state of an IRC context
+ @syntax:
+ <string> $contex.serverIsIPV6
+ <string> $contex.serverIsIPV6(<irc_context_id:uint>)
+ @description:
+ Returns true if the current irc context connection runs over IPV6.
+ If no irc_context_id is specified then the current irc_context is used.
+ If the irc_context_id specification is not valid then this function
+ returns nothing (that evaluates to false). If the specified IRC context
+ is not currently connected then this function returns nothing (that
+ evaluates to false).
+ @seealso:
+ [fnc]$context.serverPort[/fnc],
+ [fnc]$context.serverHostName[/fnc],
+ [fnc]$context.serverPassword[/fnc]
+*/
+
+STANDARD_IRC_CONNECTION_TARGET_PARAMETER(
+ context_kvs_fnc_serverIsIPV6,
+ c->returnValue()->setBoolean(pConnection->target()->server()->isIpV6())
+ )
+
+/*
+ @doc: context.serverIsSSL
+ @type:
+ function
+ @title:
+ $context.serverIsSSL
+ @short:
+ Returns the SSL state of an IRC context
+ @syntax:
+ <string> $contex.serverIsSSL
+ <string> $contex.serverIsSSL(<irc_context_id:uint>)
+ @description:
+ Returns true if the current irc context connection runs over SSL.
+ If no irc_context_id is specified then the current irc_context is used.
+ If the irc_context_id specification is not valid then this function
+ returns nothing (that evaluates to false). If the specified IRC context
+ is not currently connected then this function returns nothing (that
+ evaluates to false).
+ @seealso:
+ [fnc]$context.serverPort[/fnc],
+ [fnc]$context.serverHostName[/fnc],
+ [fnc]$context.serverPassword[/fnc]
+*/
+
+STANDARD_IRC_CONNECTION_TARGET_PARAMETER(
+ context_kvs_fnc_serverIsSSL,
+ c->returnValue()->setBoolean(pConnection->target()->server()->useSSL())
+ )
+
+/*
+ @doc: context.serverPassword
+ @type:
+ function
+ @title:
+ $context.serverPassword
+ @short:
+ Returns the password used to login to the server of an IRC context
+ @syntax:
+ <string> $contex.serverPassword
+ <string> $contex.serverPassword(<irc_context_id:uint>)
+ @description:
+ Returns the password used to login to the IRC server for the specified irc context.
+ If no irc_context_id is specified then the current irc_context is used.
+ If the irc_context_id specification is not valid then this function
+ returns nothing. If the specified IRC context is not currently connected
+ then this function returns nothing.
+ @seealso:
+ [fnc]$context.serverHostName[/fnc],
+ [fnc]$context.serverIpAddress[/fnc],
+ [fnc]$context.serverPort[/fnc]
+*/
+
+STANDARD_IRC_CONNECTION_TARGET_PARAMETER(
+ context_kvs_fnc_serverPassword,
+ c->returnValue()->setString(pConnection->target()->server()->password())
+ )
+
+
+/*
+ @doc: context.serverPort
+ @type:
+ function
+ @title:
+ $context.serverPort
+ @short:
+ Returns the port of the IRC server of an IRC context
+ @syntax:
+ <uint> $contex.serverPort
+ <uint> $contex.serverPort(<irc_context_id:uint>)
+ @description:
+ Returns the port of the IRC server for the specified irc context.
+ If no irc_context_id is specified then the current irc_context is used.
+ If the irc_context_id specification is not valid then this function
+ returns nothing. If the specified IRC context is not currently connected
+ then this function returns nothing.
+ @seealso:
+ [fnc]$context.serverHostName[/fnc],
+ [fnc]$context.serverIpAddress[/fnc]
+*/
+
+STANDARD_IRC_CONNECTION_TARGET_PARAMETER(
+ context_kvs_fnc_serverPort,
+ c->returnValue()->setInteger(pConnection->target()->server()->port())
+ )
+
+
+/*
+ @doc: context.state
+ @type:
+ function
+ @title:
+ $context.state
+ @short:
+ Returns the state of an IRC context
+ @syntax:
+ <string> $context.state
+ <string> $context.state(<irc_context_id:uint>)
+ @description:
+ Returns a string describing the state of the specified irc context.
+ The string will be either "idle","connecting","loggingin" or "connected".
+ If no irc_context_id is specified then the current irc_context is used.
+ If the irc_context_id specification is not valid then this function
+ returns nothing.
+ @seealso:
+ [fnc]$context.serverHostName[/fnc],
+ [fnc]$context.serverIpAddress[/fnc]
+*/
+
+static bool context_kvs_fnc_state(KviKvsModuleFunctionCall * c)
+{
+ GET_CONSOLE_FROM_STANDARD_PARAMS
+
+ if(pConsole)
+ {
+ switch(pConsole->ircContext()->state())
+ {
+ case KviIrcContext::Idle:
+ c->returnValue()->setString(QString("idle"));
+ break;
+ case KviIrcContext::Connecting:
+ c->returnValue()->setString(QString("connecting"));
+ break;
+ case KviIrcContext::LoggingIn:
+ c->returnValue()->setString(QString("loggingin"));
+ break;
+ case KviIrcContext::Connected:
+ c->returnValue()->setString(QString("connected"));
+ break;
+ default:
+ c->returnValue()->setString(QString("unknown"));
+ break;
+ }
+ return true;
+ }
+
+ c->returnValue()->setNothing();
+ return true;
+}
+
+
+/*
+ @doc: context.list
+ @type:
+ function
+ @title:
+ $context.list
+ @short:
+ Returns a list of existing IRC contexts
+ @syntax:
+ <array> $contex.list
+ @description:
+ Returns the array of currently existing IRC context identifiers.
+ @seealso:
+ @examples:
+ Print the names of the currently connected servers
+ [example]
+ foreach(%ic,$context.list)
+ echo "IRC Context" %ic ": " $context.serverHostName
+ [/example]
+*/
+
+static bool context_kvs_fnc_list(KviKvsModuleFunctionCall * c)
+{
+ KviKvsArray * pArray = new KviKvsArray();
+
+ KviPointerList<KviWindow> * pWinList = g_pFrame->windowList();
+ int idx = 0;
+ for(KviWindow * pWnd = pWinList->first();pWnd;pWnd = pWinList->next())
+ {
+ if(pWnd->type() == KVI_WINDOW_TYPE_CONSOLE)
+ {
+ pArray->set(idx,new KviKvsVariant((kvs_int_t)((KviConsole *)pWnd)->ircContextId()));
+ idx++;
+ }
+ }
+
+ c->returnValue()->setArray(pArray);
+ return true;
+}
+
+static bool context_module_init(KviModule * m)
+{
+ KVSM_REGISTER_FUNCTION(m,"serverHostName",context_kvs_fnc_serverHostName);
+ KVSM_REGISTER_FUNCTION(m,"serverIpAddress",context_kvs_fnc_serverIpAddress);
+ KVSM_REGISTER_FUNCTION(m,"serverPort",context_kvs_fnc_serverPort);
+ KVSM_REGISTER_FUNCTION(m,"serverIsIPV6",context_kvs_fnc_serverIsIPV6);
+ KVSM_REGISTER_FUNCTION(m,"serverIsSSL",context_kvs_fnc_serverIsSSL);
+ KVSM_REGISTER_FUNCTION(m,"serverPassword",context_kvs_fnc_serverPassword);
+ KVSM_REGISTER_FUNCTION(m,"networkName",context_kvs_fnc_networkName);
+ KVSM_REGISTER_FUNCTION(m,"state",context_kvs_fnc_state);
+ KVSM_REGISTER_FUNCTION(m,"list",context_kvs_fnc_list);
+
+ return true;
+}
+
+static bool context_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "context",
+ "1.0.0",
+ "Copyright (C) 2007 Szymon Stefanek (pragma at kvirc dot net)",
+ "Irc Context Related Functions",
+ context_module_init,
+ 0,
+ 0,
+ context_module_cleanup
+)
diff --git a/src/modules/dcc/Makefile.am b/src/modules/dcc/Makefile.am
new file mode 100644
index 00000000..8a63b888
--- /dev/null
+++ b/src/modules/dcc/Makefile.am
@@ -0,0 +1,66 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir=$(picsdir)
+
+tmp_DATA=kvi_dccfiletransfericons.png
+
+EXTRA_DIST=kvi_dccfiletransfericons.png
+
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvidcc.la
+
+libkvidcc_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvidcc_la_SOURCES = adpcmcodec.cpp \
+ broker.cpp \
+ canvas.cpp \
+ canvaswidget.cpp \
+ chat.cpp \
+ codec.cpp \
+ descriptor.cpp \
+ dialogs.cpp \
+ gsmcodec.cpp \
+ libkvidcc.cpp \
+ marshal.cpp \
+ requests.cpp \
+ send.cpp \
+ thread.cpp \
+ utils.cpp \
+ voice.cpp \
+ window.cpp
+
+libkvidcc_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= adpcmcodec.h \
+ broker.h \
+ canvas.h \
+ canvaswidget.h \
+ chat.h \
+ codec.h \
+ descriptor.h \
+ dialogs.h \
+ gsmcodec.h \
+ marshal.h \
+ send.h \
+ thread.h \
+ utils.h \
+ voice.h \
+ window.h
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+broker.cpp: m_broker.moc
+canvas.cpp: m_canvas.moc
+canvaswidget.cpp: m_canvaswidget.moc
+chat.cpp: m_chat.moc
+dialogs.cpp: m_dialogs.moc
+marshal.cpp: m_marshal.moc
+send.cpp: m_send.moc
+voice.cpp: m_voice.moc
+window.cpp: m_window.moc
diff --git a/src/modules/dcc/adpcmcodec.cpp b/src/modules/dcc/adpcmcodec.cpp
new file mode 100644
index 00000000..65f12a00
--- /dev/null
+++ b/src/modules/dcc/adpcmcodec.cpp
@@ -0,0 +1,294 @@
+//
+// File : adpcmcodec.cpp
+// Creation date : Wed Aug 22 19:12:50 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+//
+// Code derived from adpcm.c : Intel ADPCM coder/decoder
+// Adapted for the KVirc distribution by Szymon Stefanek (pragma at kvirc dot net)
+// Last revision : 20 Sep 1999
+//
+// 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 <stdio.h> /*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
new file mode 100644
index 00000000..63343df0
--- /dev/null
+++ b/src/modules/dcc/adpcmcodec.h
@@ -0,0 +1,59 @@
+#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
+// Code derived from adpcm.c : Intel ADPCM coder/decoder
+// Adapted for the KVirc distribution by Szymon Stefanek (pragma at kvirc dot net)
+// Last revision : 22 Aug 2001
+// See kvi_adpcm.cpp for the complete copyright notice.
+//
+//
+// 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 <qstring.h> // 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
new file mode 100644
index 00000000..b6548e0c
--- /dev/null
+++ b/src/modules/dcc/broker.cpp
@@ -0,0 +1,898 @@
+//
+// 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) 1999-2000 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 "dialogs.h"
+#include "chat.h"
+#include "send.h"
+#ifdef COMPILE_DCC_CANVAS
+#include "canvas.h"
+#endif
+#include "voice.h"
+
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_console.h"
+#include "kvi_fileutils.h"
+#include "kvi_out.h"
+#include "kvi_mediatype.h"
+#include "kvi_ircconnection.h"
+#include "kvi_sharedfiles.h"
+
+// kvi_app.cpp
+extern KVIRC_API KviMediaManager * g_pMediaManager;
+extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager;
+
+#include <qfileinfo.h>
+#include <qstring.h>
+
+//#warning "The broker might lookup the remote host name"
+
+KviDccBroker::KviDccBroker()
+: QObject(0,"dcc_broker")
+{
+ KviDccFileTransfer::init();
+
+ m_pBoxList = new KviPointerList<KviDccBox>;
+ m_pBoxList->setAutoDelete(false);
+
+ m_pDccWindowList = new KviPointerList<KviWindow>;
+ m_pDccWindowList->setAutoDelete(false);
+
+ m_pZeroPortTags = new KviPointerHashTable<QString,KviDccZeroPortTag>(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)
+{
+ //debug("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;
+ KviDccDescriptor * templ = dcc;
+ QStringList::Iterator it=filenames.begin();
+ while(it != filenames.end())
+ {
+ d = new KviDccDescriptor(*dcc);
+ d->szLocalFileName = *(it);
+ d->szLocalFileName.stripWhiteSpace();
+ ++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.latin1()); // latin1() should be ok here
+ szTag = t->m_szTag;
+
+ // DCC [ST]SEND <filename> <fakeipaddress> <zero-port> <filesize> <sessionid>
+ 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( \
+ "<b>%1 [%2@%3]</b> requests a " \
+ "<b>Direct Client Connection</b> in <b>%4</b> mode.<br>", \
+ "dcc").arg(dcc->szNick).arg(dcc->szUser).arg(dcc->szHost).arg(dcc->szType);
+
+#ifdef COMPILE_SSL_SUPPORT
+ if(dcc->bIsSSL)tmp += __tr2qs_ctx("The connection will be secured using SSL.<br>","dcc");
+#endif
+
+ if(dcc->isZeroPortRequest())
+ {
+ tmp += __tr2qs_ctx( \
+ "You will be the passive side of the connection.<br>" \
+ ,"dcc");
+ } else {
+ tmp += __tr2qs_ctx( \
+ "The connection target will be host <b>%1</b> on port <b>%2</b><br>" \
+ ,"dcc").arg(dcc->szIp).arg(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());
+ }
+
+ KviStr szSubProto = dcc->szType;
+ szSubProto.toLower();
+
+ QString tmp = QString("dcc: %1 %2@%3:%4").arg(szSubProto.ptr()).arg(dcc->szNick).arg(dcc->szIp).arg(dcc->szPort);
+ KviDccChat * chat = new KviDccChat(dcc->console()->frame(),dcc,tmp.utf8().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(
+ "<b>%1 [%2@%3]</b> requests a<br>" \
+ "<b>Direct Client Connection</b> in <b>VOICE</b> mode.<br>" \
+ "The connection target will be host <b>%4</b> on port <b>%5</b><br>" \
+ ,"dcc" \
+ ).arg(dcc->szNick).arg(dcc->szUser).arg(dcc->szHost).arg(dcc->szIp).arg(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());
+ }
+
+ KviStr tmp(KviStr::Format,"dcc: voice %s@%s:%s",dcc->szNick.utf8().data(),dcc->szIp.utf8().data(),dcc->szPort.utf8().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)
+{
+ KviStr tmp(KviStr::Format,"dcc: voice %s@%s:%s",dcc->szNick.utf8().data(),dcc->szIp.utf8().data(),dcc->szPort.utf8().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 CANVAS
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef COMPILE_DCC_CANVAS
+
+void KviDccBroker::activeCanvasManage(KviDccDescriptor * dcc)
+{
+ if(!dcc->bAutoAccept)
+ {
+ // need confirmation
+ QString tmp = __tr2qs_ctx( \
+ "<b>%1 [%2@%3]</b> requests a<br>" \
+ "<b>Direct Client Connection</b> in <b>CANVAS</b> mode.<br>" \
+ "The connection target will be host <b>%4</b> on port <b>%5</b><br>" \
+ ,"dcc" \
+ ).arg(dcc->szNick).arg(dcc->szUser).arg(dcc->szHost).arg(dcc->szIp).arg(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
+
+void KviDccBroker::activeCanvasExecute(KviDccBox *box,KviDccDescriptor * dcc)
+{
+#ifdef COMPILE_DCC_CANVAS
+ if(box)box->forgetDescriptor();
+
+ if(!g_pApp->windowExists(dcc->console()))
+ {
+ // rebind to the first available console....
+ dcc->setConsole(g_pApp->activeConsole());
+ }
+
+ KviStr tmp(KviStr::Format,"dcc: canvas %s@%s:%s",dcc->szNick.utf8().data(),dcc->szIp.utf8().data(),dcc->szPort.utf8().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);
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PASSIVE CANVAS
+///////////////////////////////////////////////////////////////////////////////
+#ifdef COMPILE_DCC_CANVAS
+void KviDccBroker::passiveCanvasExecute(KviDccDescriptor * dcc)
+{
+ KviStr tmp(KviStr::Format,"dcc: canvas %s@%s:%s",dcc->szNick.utf8().data(),dcc->szIp.utf8().data(),dcc->szPort.utf8().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;
+ uint size = dcc->szFileSize.toUInt(&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( \
+ "<b>%1 [%2@%3]</b> " \
+ "wants to send you the file " \
+ "'<b>%4</b>', " \
+ "<b>%5</b> large.<br>" \
+ "The connection target will be host <b>%6</b> on port <b>%7</b><br>" \
+ ,"dcc" \
+ ).arg(dcc->szNick).arg(dcc->szUser).arg(dcc->szHost).arg(
+ dcc->szFileName).arg(KviQString::makeSizeReadable(dcc->szFileSize.toInt())).arg(
+ dcc->szIp).arg(dcc->szPort);
+
+ } else {
+ // passive: we will be listening!
+ tmp = __tr2qs_ctx( \
+ "<b>%1 [%2@%3]</b> "
+ "wants to send you the file " \
+ "'<b>%4</b>', " \
+ "<b>%5</b> large.<br>" \
+ "You will be the passive side of the connection.<br>" \
+ ,"dcc" \
+ ).arg(dcc->szNick).arg(dcc->szUser).arg(dcc->szHost).arg(
+ dcc->szFileName).arg(KviQString::makeSizeReadable(dcc->szFileSize.toInt()));
+ }
+
+ if(dcc->bIsIncomingAvatar)
+ {
+ tmp += __tr2qs_ctx( \
+ "<center><b>Note:</b></center>" \
+ "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 <tt>boolAutoAcceptIncomingAvatars</tt> to true.<br>" \
+ ,"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,KviApp::Avatars);
+ else {
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseIncomingDccMediaTypeSavePath))
+ {
+ g_pMediaManager->lock();
+ if(KviMediaType * mt = g_pMediaManager->findMediaType(dcc->szFileName.utf8().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);
+ dcc->szLocalFileName.append(dcc->szNick);
+ KviFileUtils::adjustFilePath(dcc->szLocalFileName);
+ }
+ KviFileUtils::makeDir(dcc->szLocalFileName);
+ }
+ }
+ g_pMediaManager->unlock();
+ }
+
+ if(dcc->szLocalFileName.isEmpty())
+ {
+ g_pApp->getLocalKvircDirectory(dcc->szLocalFileName,KviApp::Incoming);
+ if(KVI_OPTION_BOOL(KviOption_boolSortReceivedByDccFilesByNicks))
+ {
+ KviQString::ensureLastCharIs(dcc->szLocalFileName,KVI_PATH_SEPARATOR_CHAR);
+ dcc->szLocalFileName.append(dcc->szNick);
+ KviFileUtils::adjustFilePath(dcc->szLocalFileName);
+ KviFileUtils::makeDir(dcc->szLocalFileName);
+ }
+ }
+ }
+ KviFileUtils::adjustFilePath(dcc->szLocalFileName);
+ KviQString::ensureLastCharIs(dcc->szLocalFileName,KVI_PATH_SEPARATOR_CHAR);
+
+ if(!(dcc->bAutoAccept))
+ {
+ dcc->szLocalFileName+=dcc->szFileName;
+ 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
+ dcc->szLocalFileName.append(dcc->szFileName);
+
+ 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;
+ int iRemoteSize = dcc->szFileSize.toInt(&bOk);
+ if(!bOk)iRemoteSize = -1;
+
+ // FIXME: Files downloaded succesfully shouldn't be resumed
+ // we should keep a db of downloaded files!
+
+ if(!dcc->bAutoAccept)
+ {
+ QString tmp;
+ bool bDisableResume = false;
+
+ if((iRemoteSize > -1) || // remote size is unknown
+ (iRemoteSize > ((int)(fi.size())))) // or it is larger than the actual size on disk
+ {
+ tmp = __tr2qs_ctx( \
+ "The file '<b>%1</b>' already exists " \
+ "and is <b>%2</b> large.<br>" \
+ "Do you wish to<br>" \
+ "<b>overwrite</b> the existing file,<br> " \
+ "<b>auto-rename</b> the new file, or<br>" \
+ "<b>resume</b> an incomplete download?" \
+ ,"dcc" \
+ ).arg(dcc->szLocalFileName).arg(KviQString::makeSizeReadable(fi.size()));
+ } else {
+ bDisableResume = true;
+ // the file on disk is larger or equal to the remote one
+ tmp = __tr2qs_ctx( \
+ "The file '<b>%1</b>' already exists" \
+ "and is larger than the offered one.<br>" \
+ "Do you wish to<br>" \
+ "<b>overwrite</b> the existing file, or<br> " \
+ "<b>auto-rename</b> the new 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;
+ } else {
+ // auto resume ?
+ if(KVI_OPTION_BOOL(KviOption_boolAutoResumeDccSendWhenAutoAccepted) &&
+ (iRemoteSize > -1) && // only if the remote size is really known
+ (iRemoteSize > ((int)(fi.size()))) && // only if the remote size is larger than the local size
+ (!KviDccFileTransfer::nonFailedTransferWithLocalFileName(dcc->szLocalFileName.utf8().data()))) // only if there is no transfer with this local file name yet
+ {
+ // yep, auto resume...
+ dcc->bResume = true;
+ recvFileExecute(0,dcc);
+ } else {
+ // otherwise auto rename
+ renameDccSendFile(0,dcc);
+ }
+ return;
+ }
+ } else dcc->szLocalFileSize = "0";
+
+ // everything OK
+ recvFileExecute(0,dcc);
+}
+
+void KviDccBroker::renameDccSendFile(KviDccBox *box,KviDccDescriptor * dcc)
+{
+ if(box)box->forgetDescriptor();
+
+
+ if(QFileInfo(dcc->szLocalFileName).exists())
+ {
+ KviStr szOrig = dcc->szLocalFileName;
+ int i = 1;
+ do {
+ KviStr 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;
+ KviDccDescriptor * templ = dcc;
+ QStringList::Iterator it=filenames.begin();
+ while(it != filenames.end())
+ {
+ d = new KviDccDescriptor(*dcc);
+ d->szLocalFileName = *(it);
+ d->szLocalFileName.stripWhiteSpace();
+ ++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 int filePos,const char * szZeroPortTag)
+{
+ //debug("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 <filename> <fakeip> 0 <tag>
+ KviDccZeroPortTag * t = findZeroPortTag(QString(szZeroPortTag));
+ if(t)
+ {
+ //debug("FOUND");
+ // valid zero port resume request
+ if(filePos < t->m_uFileSize)
+ {
+ //debug("VALID");
+ // ok!
+ t->m_uResumePosition = filePos;
+
+ KviStr szBuffy;
+ KviServerParser::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;
+ } else {
+ return false; // invalid resume size
+ }
+ }
+ }
+ //debug("NOT A ZeRO PORT");
+
+ return KviDccFileTransfer::handleResumeRequest(filename,port,filePos);
+}
+
+
+#include "m_broker.moc"
diff --git a/src/modules/dcc/broker.h b/src/modules/dcc/broker.h
new file mode 100644
index 00000000..80fa9768
--- /dev/null
+++ b/src/modules/dcc/broker.h
@@ -0,0 +1,124 @@
+#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) 1999-2006 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_QT4
+ // #define COMPILE_DCC_CANVAS
+#else
+ #define COMPILE_DCC_CANVAS
+#endif
+
+#include "kvi_string.h"
+#include "kvi_pointerlist.h"
+#include "kvi_sparser.h"
+
+#include "kvi_pointerhashtable.h"
+#include <qdatetime.h>
+#include <qobject.h>
+
+class KviConsole;
+class KviDccBroker;
+class KviWindow;
+class KviDccBox;
+
+#include "descriptor.h"
+
+class KviDccZeroPortTag
+{
+public:
+ QDateTime m_tTimestamp;
+ QString m_szTag;
+ unsigned int m_uFileSize; // outgoing file size, valid only for file transfers obviously
+ unsigned int m_uResumePosition; // if 0 = no resume, valid only for file transfers obviously
+};
+
+class KviDccBroker : public QObject
+{
+ Q_OBJECT
+public:
+ KviDccBroker();
+ ~KviDccBroker();
+protected:
+ KviPointerList<KviDccBox> * m_pBoxList;
+ KviPointerList<KviWindow> * m_pDccWindowList;
+ KviPointerHashTable<QString,KviDccZeroPortTag> * 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 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 int 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 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
new file mode 100644
index 00000000..e80272ae
--- /dev/null
+++ b/src/modules/dcc/canvas.cpp
@@ -0,0 +1,301 @@
+//
+// 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 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 "kvi_options.h"
+#include "kvi_input.h"
+#include "kvi_ircview.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+#include "kvi_error.h"
+#include "kvi_out.h"
+#include "kvi_netutils.h"
+#include "kvi_console.h"
+#include "kvi_frame.h"
+#include "kvi_malloc.h"
+#include "kvi_memmove.h"
+#include "kvi_thread.h"
+#include "kvi_ircsocket.h"
+#include "kvi_settings.h"
+#include "kvi_themedlabel.h"
+#include "kvi_ircconnection.h"
+
+#include <qsplitter.h>
+
+extern KviDccBroker * g_pDccBroker;
+
+
+KviDccCanvas::KviDccCanvas(KviFrame *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.utf8().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.utf8().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.utf8().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.utf8().data(),dcc->szPort.utf8().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.utf8().data(),m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data());
+ return m_szTarget;
+}
+
+void KviDccCanvas::fillCaptionBuffers()
+{
+ KviStr tmp(KviStr::Format,"DCC Canvas %s@%s:%s",
+ m_pDescriptor->szNick.utf8().data(),m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data());
+
+ m_szPlainTextCaption = tmp;
+
+ m_szHtmlActiveCaption.sprintf("<nobr><font color=\"%s\"><b>%s</b></font></nobr>",
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(),tmp.ptr());
+ m_szHtmlInactiveCaption.sprintf("<nobr><font color=\"%s\"><b>%s</b></font></nobr>",
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(),tmp.ptr());
+}
+
+QPixmap * KviDccCanvas::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_CANVAS);
+}
+
+
+void KviDccCanvas::getBaseLogFileName(KviStr &buffer)
+{
+ buffer.sprintf("%s_%s_%s",m_pDescriptor->szNick.utf8().data(),m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data());
+}
+
+void KviDccCanvas::ownMessage(const char * text)
+{
+ KviStr buf(KviStr::Format,"%s\r\n",text);
+// m_pSlaveThread->sendRawData(buf.ptr(),buf.len());
+ m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,
+ m_pDescriptor->szLocalNick.utf8().data(),m_pDescriptor->szLocalUser.utf8().data(),
+ m_pDescriptor->szLocalHost.utf8().data(),text);
+}
+
+void KviDccCanvas::ownAction(const char * text)
+{
+ KviStr buf(KviStr::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<int> *)e)->getData();
+// output(KVI_OUT_DCCERROR,__tr("ERROR: %s"),kvi_getErrorString(*err));
+// delete err;
+// return true;
+// }
+// break;
+// case KVI_DCC_THREAD_EVENT_DATA:
+// {
+// KviStr * d = ((KviThreadDataEvent<KviStr> *)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))
+// {
+// KviStr 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()))
+// {
+// KviStr 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
new file mode 100644
index 00000000..8e6b1fb3
--- /dev/null
+++ b/src/modules/dcc/canvas.h
@@ -0,0 +1,74 @@
+#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 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 "kvi_window.h"
+#include "kvi_string.h"
+
+#include "descriptor.h"
+#include "window.h"
+#include "thread.h"
+
+#include "kvi_pointerlist.h"
+
+
+
+class KviDccMarshal;
+class KviCanvasWidget;
+
+class QSplitter;
+
+
+class KviDccCanvas : public KviDccWindow
+{
+ Q_OBJECT
+public:
+ KviDccCanvas(KviFrame *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(KviStr &buffer);
+ virtual QPixmap * myIconPtr();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual QSize sizeHint() const;
+ virtual bool event(QEvent *e);
+ virtual void ownMessage(const char *text);
+ 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
new file mode 100644
index 00000000..203e0b36
--- /dev/null
+++ b/src/modules/dcc/canvaswidget.cpp
@@ -0,0 +1,1601 @@
+//
+// File : canvaswidget.cpp
+// Creation date : Mon Jul 30 07 2001 04:50:50 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 "canvaswidget.h"
+
+#ifdef COMPILE_DCC_CANVAS
+
+
+#include <qcursor.h>
+#include <qpainter.h>
+#include <qsimplerichtext.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qvalidator.h>
+#include <stdlib.h>
+
+#include "kvi_string.h"
+
+#include "kvi_locale.h"
+#include "kvi_tal_popupmenu.h"
+
+#include <math.h>
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasRectangleItem
+//
+
+KviCanvasRectangleItem::KviCanvasRectangleItem(QCanvas * c,int x,int y,int w,int h)
+: QCanvasRectangle(x,y,w,h,c)
+{
+}
+
+KviCanvasRectangleItem::~KviCanvasRectangleItem()
+{
+}
+
+void KviCanvasRectangleItem::drawSelection(QPainter &p)
+{
+ p.setRasterOp(NotROP);
+ p.fillRect((int)x() + 1,(int)y() + 1,width() - 2,height() - 2,QBrush(Dense6Pattern));
+ p.setPen(QPen(DotLine));
+ p.drawRect((int)x(),(int)y(),width(),height());
+ p.setRasterOp(CopyROP);
+}
+
+
+void KviCanvasRectangleItem::setProperty(const QString &property,const QVariant &val)
+{
+ if(m_properties[property].isValid())
+ {
+ m_properties.replace(property,val);
+ hide();
+ show();
+ }
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasPolygon
+//
+
+
+KviCanvasPolygon::KviCanvasPolygon(QCanvas * c,int x,int y,QPointArray &pnts,double dScaleFactor)
+: QCanvasPolygon(c)
+{
+ m_properties.insert("clrForeground",QVariant(QColor(0,0,0)));
+ m_properties.insert("uLineWidth",QVariant((unsigned int)0));
+
+ m_properties.insert("clrBackground",QVariant(QColor(0,0,0)));
+ m_properties.insert("bHasBackground",QVariant(false,1));
+
+ m_dScaleFactor = dScaleFactor;
+ m_points = pnts;
+
+ resetPoints();
+ move(x,y);
+}
+
+
+KviCanvasPolygon::~KviCanvasPolygon()
+{
+}
+
+void KviCanvasPolygon::setScaleFactor(double dScaleFactor)
+{
+ m_dScaleFactor = dScaleFactor;
+ resetPoints();
+}
+
+void KviCanvasPolygon::setInternalPoints(const QPointArray &pnts)
+{
+ m_points = pnts;
+ resetPoints();
+
+}
+
+void KviCanvasPolygon::resetPoints()
+{
+ QPointArray scaled(m_points.size());
+ for(unsigned int i=0;i<m_points.size();i++)
+ {
+ int px;
+ int py;
+ m_points.point(i,&px,&py);
+ px = (int)(px * m_dScaleFactor);
+ py = (int)(py * m_dScaleFactor);
+ scaled.setPoint(i,px,py);
+ }
+ setPoints(scaled);
+}
+
+int KviCanvasPolygon::rtti() const
+{
+ return KVI_CANVAS_RTTI_POLYGON;
+}
+
+void KviCanvasPolygon::setProperty(const QString &property,const QVariant &val)
+{
+ if(m_properties[property].isValid())
+ {
+ m_properties.replace(property,val);
+ if((property == "clrForeground") || (property == "uLineWidth"))
+ {
+ setPen(QPen(m_properties["clrForeground"].asColor(),m_properties["uLineWidth"].toInt()));
+ } else if((property == "clrBackground") || (property == "bHasBackground"))
+ {
+ if(m_properties["bHasBackground"].asBool())
+ setBrush(QBrush(m_properties["clrBackground"].asColor()));
+ else
+ setBrush(QBrush());
+ } else {
+ hide(); show();
+ }
+ }
+}
+
+void KviCanvasPolygon::draw(QPainter &p)
+{
+#if QT_VERSION >= 300
+ if(isEnabled())
+#else
+ if(enabled())
+#endif
+ {
+ p.setBrush(brush());
+ p.setPen(pen());
+ p.drawPolygon(areaPoints());
+ }
+
+#if QT_VERSION >=300
+ if(isSelected())
+#else
+ if(selected())
+#endif
+ {
+ p.setRasterOp(NotROP);
+ p.setPen(QPen(DotLine));
+ p.drawPolygon(areaPoints());
+ p.setBrush(QBrush());
+ double dVal = 10;
+ p.drawEllipse((int)(x() - dVal),(int)(y() - dVal),(int)(dVal * 2),(int)(dVal * 2));
+ p.drawLine((int)(x() - (dVal * 2)),(int)y(),(int)(x() + (dVal * 2)),(int)y());
+ p.drawLine((int)x(),(int)(y() - (dVal * 2)),(int)x(),(int)(y() + (dVal * 2)));
+ p.setRasterOp(CopyROP);
+ canvas()->setChanged(QRect((int)(x() - dVal),(int)(y() - dVal),(int)(dVal * 4),(int)(dVal * 4)));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasEllipticItem
+//
+
+KviCanvasEllipticItem::KviCanvasEllipticItem(QCanvas * c,int x,int y,int w,int h)
+: KviCanvasRectangleItem(c,x,y,w,h)
+{
+ m_properties.insert("clrForeground",QVariant(QColor(0,0,0)));
+ m_properties.insert("uLineWidth",QVariant((unsigned int)0));
+
+ m_properties.insert("clrBackground",QVariant(QColor(0,0,0)));
+ m_properties.insert("bHasBackground",QVariant(false,1));
+
+// m_properties.insert("iStartAngle",QVariant(0));
+// m_properties.insert("iEndAngle",QVariant(360));
+}
+
+KviCanvasEllipticItem::~KviCanvasEllipticItem()
+{
+}
+
+void KviCanvasEllipticItem::draw(QPainter &p)
+{
+#if QT_VERSION >= 300
+ if(isEnabled())
+#else
+ if(enabled())
+#endif
+ {
+ QBrush b = p.brush();
+ if(m_properties["bHasBackground"].asBool())p.setBrush(m_properties["clrBackground"].asColor());
+ else p.setBrush(QBrush());
+ p.setPen(pen());
+ drawContent(p);
+ p.setBrush(b);
+ }
+
+#if QT_VERSION >= 300
+ if(isSelected())drawSelection(p);
+#else
+ if(selected())drawSelection(p);
+#endif
+}
+
+void KviCanvasEllipticItem::drawContent(QPainter &p)
+{
+}
+
+
+void KviCanvasEllipticItem::setProperty(const QString & property,const QVariant &val)
+{
+ if(m_properties[property].isValid())
+ {
+ m_properties.replace(property,val);
+ if((property == "clrForeground") || (property == "uLineWidth"))
+ {
+ setPen(QPen(m_properties["clrForeground"].asColor(),m_properties["uLineWidth"].toInt()));
+ } else {
+ hide(); show();
+ }
+ }
+}
+
+int KviCanvasEllipticItem::rtti() const
+{
+ return KVI_CANVAS_RTTI_ELLIPSE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasEllipse
+//
+
+
+KviCanvasEllipse::KviCanvasEllipse(QCanvas * c,int x,int y,int w,int h)
+: KviCanvasEllipticItem(c,x,y,w,h)
+{
+}
+
+KviCanvasEllipse::~KviCanvasEllipse()
+{
+}
+
+int KviCanvasEllipse::rtti() const
+{
+ return KVI_CANVAS_RTTI_ELLIPSE;
+}
+
+void KviCanvasEllipse::drawContent(QPainter &p)
+{
+ p.drawEllipse((int)x(),(int)y(),width(),height());
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasPie
+//
+
+
+KviCanvasPie::KviCanvasPie(QCanvas * c,int x,int y,int w,int h)
+: KviCanvasEllipticItem(c,x,y,w,h)
+{
+ m_properties.insert("iStartAngle",QVariant((int)0));
+ m_properties.insert("iExtensionAngle",QVariant((int)360));
+}
+
+KviCanvasPie::~KviCanvasPie()
+{
+}
+
+int KviCanvasPie::rtti() const
+{
+ return KVI_CANVAS_RTTI_PIE;
+}
+
+void KviCanvasPie::drawContent(QPainter &p)
+{
+ int iStartAngle = m_properties["iStartAngle"].asInt() * 16;
+ int iEndAngle = m_properties["iExtensionAngle"].asInt() * 16;
+ p.drawPie((int)x(),(int)y(),width(),height(),iStartAngle,iEndAngle);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasChord
+//
+
+
+KviCanvasChord::KviCanvasChord(QCanvas * c,int x,int y,int w,int h)
+: KviCanvasEllipticItem(c,x,y,w,h)
+{
+ m_properties.insert("iStartAngle",QVariant((int)0));
+ m_properties.insert("iExtensionAngle",QVariant((int)360));
+}
+
+KviCanvasChord::~KviCanvasChord()
+{
+}
+
+int KviCanvasChord::rtti() const
+{
+ return KVI_CANVAS_RTTI_CHORD;
+}
+
+void KviCanvasChord::drawContent(QPainter &p)
+{
+ int iStartAngle = m_properties["iStartAngle"].asInt() * 16;
+ int iEndAngle = m_properties["iExtensionAngle"].asInt() * 16;
+ p.drawChord((int)x(),(int)y(),width(),height(),iStartAngle,iEndAngle);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasRectangle
+//
+
+KviCanvasRectangle::KviCanvasRectangle(QCanvas * c,int x,int y,int w,int h)
+: KviCanvasRectangleItem(c,x,y,w,h)
+{
+ m_properties.insert("clrForeground",QVariant(QColor(0,0,0)));
+ m_properties.insert("uLineWidth",QVariant((unsigned int)0));
+
+ m_properties.insert("clrBackground",QVariant(QColor(0,0,0)));
+ m_properties.insert("bHasBackground",QVariant(false,1));
+}
+
+KviCanvasRectangle::~KviCanvasRectangle()
+{
+}
+
+int KviCanvasRectangle::rtti() const
+{
+ return KVI_CANVAS_RTTI_RECTANGLE;
+}
+
+
+void KviCanvasRectangle::setProperty(const QString &property,const QVariant &val)
+{
+ if(m_properties[property].isValid())
+ {
+ m_properties.replace(property,val);
+ if((property == "clrForeground") || (property == "uLineWidth"))
+ {
+ setPen(QPen(m_properties["clrForeground"].asColor(),m_properties["uLineWidth"].toInt()));
+ } else {
+ hide(); show();
+ }
+ }
+}
+
+void KviCanvasRectangle::draw(QPainter & p)
+{
+#if QT_VERSION >= 300
+ if(isEnabled())
+#else
+ if(enabled())
+#endif
+ {
+ if(m_properties["bHasBackground"].asBool())
+ {
+ p.fillRect((int)x() + 1,(int)y() + 1,width() - 2,height() - 2,m_properties["clrBackground"].asColor());
+ }
+ p.setPen(pen());
+ p.drawRect((int)x(),(int)y(),width(),height());
+ }
+#if QT_VERSION >= 300
+ if(isSelected())drawSelection(p);
+#else
+ if(selected())drawSelection(p);
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasRichText
+//
+
+KviCanvasRichText::KviCanvasRichText(QCanvas * c,int x,int y,int w,int h)
+: KviCanvasRectangleItem(c,x,y,w,h)
+{
+ QFont f = QFont();
+ f.setStyleHint(QFont::SansSerif);
+ f.setPointSize(12);
+ m_properties.insert("szText",QVariant(QString("<center>Insert here your <font color=\"#FF0000\"><b>RICH TEXT</b></font></center>")));
+ m_properties.insert("fntDefault",QVariant(f));
+}
+
+KviCanvasRichText::~KviCanvasRichText()
+{
+}
+
+int KviCanvasRichText::rtti() const
+{
+ return KVI_CANVAS_RTTI_RICHTEXT;
+}
+
+void KviCanvasRichText::draw(QPainter & p)
+{
+#if QT_VERSION >= 300
+ if(isEnabled())
+#else
+ if(enabled())
+#endif
+ {
+ QString szText = m_properties["szText"].asString();
+ QSimpleRichText text(szText,m_properties["fntDefault"].asFont());
+ text.setWidth(width());
+#if QT_VERSION >= 300
+ text.draw(&p,(int)x() + 1,(int)y() + 1,QRegion(QRect((int)x() + 1,(int)y() + 1,width(),height())),QColorGroup());
+#else
+ text.draw(&p,(int)x() + 1,(int)y() + 1,QRegion(QRect((int)x() + 1,(int)y() + 1,width(),height())),QPalette());
+#endif
+ }
+#if QT_VERSION >= 300
+ if(isSelected())drawSelection(p);
+#else
+ if(selected())drawSelection(p);
+#endif
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasLine
+//
+
+
+KviCanvasLine::KviCanvasLine(QCanvas * c,int x1,int y1,int x2,int y2)
+: QCanvasLine(c)
+{
+ setPoints(x1,y1,x2,y2);
+ m_properties.insert("uLineWidth",QVariant((unsigned int)0));
+ m_properties.insert("clrForeground",QVariant(QColor()));
+}
+
+KviCanvasLine::~KviCanvasLine()
+{
+}
+
+void KviCanvasLine::setProperty(const QString &property,const QVariant &val)
+{
+ m_properties.replace(property,val);
+ if((property == "uLineWidth") || (property == "clrForeground"))
+ {
+ setPen(QPen(m_properties["clrForeground"].asColor(),m_properties["uLineWidth"].toInt()));
+ }
+}
+
+int KviCanvasLine::rtti() const
+{
+ return KVI_CANVAS_RTTI_LINE;
+}
+
+void KviCanvasLine::draw(QPainter &p)
+{
+#if QT_VERSION >= 300
+ if(isEnabled())
+#else
+ if(enabled())
+#endif
+ {
+ p.setPen(pen());
+ p.drawLine(startPoint(),endPoint());
+ }
+
+#if QT_VERSION >= 300
+ if(isSelected())
+#else
+ if(selected())
+#endif
+ {
+ p.setRasterOp(NotROP);
+ p.setPen(QPen(DotLine));
+ p.drawLine(startPoint(),endPoint());
+ p.setRasterOp(CopyROP);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasView
+//
+
+KviCanvasView::KviCanvasView(QCanvas * c,KviCanvasWidget * cw,QWidget * par)
+: QCanvasView(c,par)
+{
+ m_pCanvasWidget = cw;
+ m_state = Idle;
+ m_dragMode = None;
+ m_pSelectedItem = 0;
+ viewport()->setMouseTracking(true);
+}
+
+
+KviCanvasView::~KviCanvasView()
+{
+}
+
+
+void KviCanvasView::insertRectangle()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = Rectangle;
+}
+
+void KviCanvasView::insertRichText()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = RichText;
+}
+
+void KviCanvasView::insertLine()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = Line;
+}
+
+void KviCanvasView::insertEllipse()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = Ellipse;
+}
+
+void KviCanvasView::insertPie()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = Pie;
+}
+
+void KviCanvasView::insertChord()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = Chord;
+}
+
+
+void KviCanvasView::insertPolygonTriangle()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = PolygonTriangle;
+}
+
+
+void KviCanvasView::insertPolygonRectangle()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = PolygonRectangle;
+}
+
+
+void KviCanvasView::insertPolygonPentagon()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = PolygonPentagon;
+}
+
+void KviCanvasView::insertPolygonHexagon()
+{
+ m_state = SelectOrigin;
+ setCursor(crossCursor);
+ m_objectToInsert = PolygonPentagon;
+}
+
+#ifndef M_PI
+ #define M_PI 3.14159265358979323846
+#endif
+
+static void calcPolygonPoints(QPointArray &pnts,unsigned int nVertices)
+{
+ double dDelta = (2 * M_PI) / nVertices;
+ for(unsigned int i=0;i<nVertices;i++)
+ {
+ double dAng = dDelta * i;
+ double theX = 300 * sin(dAng);
+ double theY = 300 * cos(dAng);
+ pnts.setPoint(i,(int)theX,(int)theY);
+ }
+}
+
+void KviCanvasView::insertObjectAt(const QPoint & pnt,ObjectType o)
+{
+ QCanvasItem * r = 0;
+
+ switch(o)
+ {
+ case Rectangle:
+ r = new KviCanvasRectangle(canvas(),pnt.x(),pnt.y(),0,0);
+ break;
+ case RichText:
+ r = new KviCanvasRichText(canvas(),pnt.x(),pnt.y(),0,0);
+ break;
+ case Line:
+ r = new KviCanvasLine(canvas(),pnt.x(),pnt.y(),pnt.x(),pnt.y());
+ break;
+ case Ellipse:
+ r = new KviCanvasEllipse(canvas(),pnt.x(),pnt.y(),0,0);
+ break;
+ case Pie:
+ r = new KviCanvasPie(canvas(),pnt.x(),pnt.y(),0,0);
+ break;
+ case Chord:
+ r = new KviCanvasChord(canvas(),pnt.x(),pnt.y(),0,0);
+ break;
+ case PolygonTriangle:
+ {
+ QPointArray pa(3);
+ pa.setPoint(0,0,-500);
+ pa.setPoint(1,-450,220);
+ pa.setPoint(2,450,220);
+ r = new KviCanvasPolygon(canvas(),pnt.x(),pnt.y(),pa,0.1);
+ }
+ break;
+ case PolygonRectangle:
+ {
+ QPointArray pa(4);
+ pa.setPoint(0,-350,-350);
+ pa.setPoint(1,350,-350);
+ pa.setPoint(2,350,350);
+ pa.setPoint(3,-350,350);
+ r = new KviCanvasPolygon(canvas(),pnt.x(),pnt.y(),pa,0.1);
+ }
+ break;
+ case PolygonPentagon:
+ {
+ QPointArray pa(5);
+ calcPolygonPoints(pa,5);
+ r = new KviCanvasPolygon(canvas(),pnt.x(),pnt.y(),pa,0.1);
+ }
+ break;
+ case PolygonHexagon:
+ {
+ QPointArray pa(6);
+ calcPolygonPoints(pa,6);
+ r = new KviCanvasPolygon(canvas(),pnt.x(),pnt.y(),pa,0.1);
+ }
+ break;
+ }
+
+ if(r)
+ {
+ setItemSelected(r);
+ r->setEnabled(true);
+ r->show();
+ }
+
+ switch(KVI_CANVAS_RTTI_CONTROL_TYPE(r))
+ {
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE:
+ beginDragRectangle((KviCanvasRectangleItem *)r,pnt,true);
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_LINE:
+ beginDragLine((KviCanvasLine *)r,pnt,true);
+ break;
+// case KVI_CANVAS_RTTI_CONTROL_TYPE_POLYGON:
+// beginDragPolygon((KviCanvasPolygon *)r,pnt,true);
+// break;
+ }
+
+// canvas()->update();
+}
+
+void KviCanvasView::setItemSelected(QCanvasItem * it)
+{
+ clearSelection();
+ it->setSelected(true);
+ m_pSelectedItem = it;
+ m_pCanvasWidget->m_pPropertiesWidget->editItem(it);
+
+}
+
+void KviCanvasView::clearSelection()
+{
+ if(!m_pSelectedItem)return;
+ m_pSelectedItem->setSelected(false);
+ m_pSelectedItem = 0;
+ m_pCanvasWidget->m_pPropertiesWidget->editItem(0);
+}
+
+
+
+void KviCanvasView::beginDragLine(KviCanvasLine * it,const QPoint &p,bool bInitial)
+{
+ QPoint sp = it->startPoint();
+
+ m_dragBegin = p - sp;
+
+ if(bInitial)
+ {
+ m_dragMode = Bottom;
+ setCursor(sizeAllCursor);
+ return;
+ }
+
+ if((abs(p.x() - sp.x()) < 3) && (abs(p.y() - sp.y()) < 3))
+ {
+ m_dragMode = Top;
+ setCursor(sizeAllCursor);
+ return;
+ }
+
+ sp = it->endPoint();
+ if((abs(p.x() - sp.x()) < 3) && (abs(p.y() - sp.y()) < 3))
+ {
+ m_dragMode = Bottom;
+ setCursor(sizeAllCursor);
+ return;
+ }
+
+ m_dragMode = All;
+ setCursor(pointingHandCursor);
+}
+
+void KviCanvasView::dragLine(KviCanvasLine * it,const QPoint &p)
+{
+ switch(m_dragMode)
+ {
+ case Bottom:
+ {
+ QPoint sp = it->startPoint();
+ it->setPoints(sp.x(),sp.y(),p.x(),p.y());
+ }
+ break;
+ case Top:
+ {
+ QPoint ep = it->endPoint();
+ it->setPoints(p.x(),p.y(),ep.x(),ep.y());
+ }
+ break;
+ case All:
+ {
+ QPoint sp = p - m_dragBegin;
+ QPoint ep = sp + (it->endPoint() - it->startPoint());
+ it->setPoints(sp.x(),sp.y(),ep.x(),ep.y());
+ }
+ break;
+ default: /* make gcc happy */
+ break;
+ }
+ canvas()->update();
+}
+
+
+static double ssm_2d_rotationAngleFromXAxis(double dx,double dy)
+{
+ //
+ // v1 . v2 dx * 1 + dy * 0 dx
+ //acos(---------) = acos(-----------------) = acos(---------)
+ // |v1||v2| |(dx,dy)| * 1 |(dx,dy)|
+ //
+
+ //double dVal = hypot(dx,dy);
+ double dVal = sqrt((dx * dx) + (dy * dy));
+
+ if(dVal == 0.0)return 0; // ???
+
+ dVal = acos(dx / dVal);
+
+ return (dy > 0.0) ? dVal : -dVal;
+}
+
+static double ssm_2d_rotationAngle(double drefx,double drefy,double drotatedx,double drotatedy)
+{
+ double dRefAngle = ssm_2d_rotationAngleFromXAxis(drefx,drefy);
+ double dRotAngle = ssm_2d_rotationAngleFromXAxis(drotatedx,drotatedy);
+ return dRotAngle - dRefAngle;
+}
+
+static void ssm_2d_rotate(double &dx,double &dy,double dAngle)
+{
+ // Rotation matrix:
+ //
+ // | cos(x) sin(x) |
+ // | |
+ // | -sin(x) cos(x) |
+
+ double s = sin(dAngle);
+ double c = cos(dAngle);
+
+ double tmpX = (dx * c) - (dy * s);
+ double tmpY = (dx * s) + (dy * c);
+
+ dx = tmpX;
+ dy = tmpY;
+}
+
+static double ssm_hypot(double a,double b)
+{
+ return sqrt((a * a) + (b * b));
+}
+
+void KviCanvasView::beginDragPolygon(KviCanvasPolygon * it,const QPoint &p,bool bShift,bool bCtrl)
+{
+ m_dragBegin = QPoint((int)(p.x() - it->x()),(int)(p.y() - it->y()));
+
+ QPointArray pa = it->areaPoints();
+
+ for(unsigned int i=0;i<pa.size();i++)
+ {
+ QPoint pnt = pa.point(i);
+ double dX = pnt.x() - p.x();
+ double dY = pnt.y() - p.y();
+ double dHypot = sqrt((dX * dX) + (dY * dY));
+ if(dHypot < 3.0)
+ {
+ // We're dragging a point
+ m_dragMode = SinglePoint;
+ m_dragPointIndex = i;
+ setCursor(crossCursor);
+ return;
+ }
+ }
+
+ if(bShift)
+ {
+ m_dragMode = Scale;
+ m_dragScaleFactor = it->scaleFactor();
+ setCursor(sizeAllCursor);
+ return;
+ }
+
+ if(bCtrl)
+ {
+ m_dragMode = Rotate;
+ m_dragPointArray = it->internalPoints();
+// debug("Here");
+ setCursor(sizeHorCursor);
+ return;
+ }
+
+ m_dragMode = All;
+ setCursor(pointingHandCursor);
+}
+
+void KviCanvasView::dragPolygon(KviCanvasPolygon * it,const QPoint &p)
+{
+ switch(m_dragMode)
+ {
+ case All:
+ it->move(p.x() - m_dragBegin.x(),p.y() - m_dragBegin.y());
+ break;
+ case SinglePoint:
+ {
+ QPointArray pnt = it->internalPoints();
+ pnt.setPoint(m_dragPointIndex,(int)((p.x() - it->x()) / it->scaleFactor()),(int)((p.y() - it->y()) / it->scaleFactor()));
+ it->setInternalPoints(pnt);
+ }
+ break;
+ case Scale:
+ {
+ double dDistance = ssm_hypot(p.x() - it->x(),p.y() - it->y());
+ double dOriginal = ssm_hypot(m_dragBegin.x(),m_dragBegin.y());
+ if(dOriginal < 1)dOriginal = 1;
+ if(dDistance < 0.1)dDistance = 0.1;
+ it->setScaleFactor(m_dragScaleFactor * dDistance / dOriginal);
+ }
+ break;
+ case Rotate:
+ {
+ QPoint act((int)(p.x() - it->x()),(int)(p.y() - it->y()));
+ double dAngle = ssm_2d_rotationAngle(m_dragBegin.x(),m_dragBegin.y(),act.x(),act.y());
+// debug("%d,%d %d,%d %f",m_dragBegin.x(),m_dragBegin.y(),act.x(),act.y(),dAngle);
+ QPointArray thePoints = m_dragPointArray.copy();
+ for(unsigned int i=0;i<thePoints.size();i++)
+ {
+ QPoint tmp = thePoints.point(i);
+ double dx = tmp.x();
+ double dy = tmp.y();
+ ssm_2d_rotate(dx,dy,dAngle);
+ thePoints.setPoint(i,(int)dx,(int)dy);
+ }
+ it->setInternalPoints(thePoints);
+ }
+ break;
+ default:
+ break;
+ }
+ canvas()->update();
+}
+
+void KviCanvasView::beginDragRectangle(KviCanvasRectangleItem * it,const QPoint & p,bool bInitial)
+{
+ m_dragBegin = QPoint((int)(p.x() - it->x()),(int)(p.y() - it->y()));
+
+ if(bInitial)
+ {
+ // Right bottom
+ m_dragMode = RightBottom;
+ setCursor(sizeFDiagCursor);
+ return;
+ }
+
+ if(p.x() < (((int)it->x()) + 2))
+ {
+ // Left edge
+ if(p.y() < (((int)it->y()) + 2))
+ {
+ // Left top
+ m_dragMode = LeftTop;
+ setCursor(sizeFDiagCursor);
+ return;
+ }
+ if(p.y() > ( it->bottom() - 2))
+ {
+ // Left bottom
+ m_dragMode = LeftBottom;
+ setCursor(sizeBDiagCursor);
+ return;
+ }
+ m_dragMode = Left;
+ setCursor(sizeHorCursor);
+ return;
+ }
+
+ if(p.x() > (it->right() - 2))
+ {
+ // Right edge
+ if(p.y() < (((int)it->y()) + 2))
+ {
+ // Right top
+ m_dragMode = RightTop;
+ setCursor(sizeBDiagCursor);
+ return;
+ }
+ if(p.y() > ( it->bottom() - 2))
+ {
+ // Right bottom
+ m_dragMode = RightBottom;
+ setCursor(sizeFDiagCursor);
+ return;
+ }
+ m_dragMode = Right;
+ setCursor(sizeHorCursor);
+ return;
+ }
+
+ // Somewhere in the middle
+ if(p.y() < (((int)it->y()) + 2))
+ {
+ // Top
+ m_dragMode = Top;
+ setCursor(sizeVerCursor);
+ return;
+ }
+ if(p.y() > ( it->bottom() - 2))
+ {
+ // Bottom
+ m_dragMode = Bottom;
+ setCursor(sizeVerCursor);
+ return;
+ }
+
+ m_dragMode = All;
+ setCursor(pointingHandCursor);
+}
+
+void KviCanvasView::dragRectangle(KviCanvasRectangleItem * it,const QPoint & p)
+{
+
+ int aux1,aux2,aux3,aux4;
+
+ switch(m_dragMode)
+ {
+ case All:
+ it->move(p.x() - m_dragBegin.x(),p.y() - m_dragBegin.y());
+ break;
+ case Left:
+ aux1 = it->width() + (int)(it->x() - p.x());
+ aux2 = p.x();
+ if(aux1 < 1)
+ {
+ aux2 += (aux1 - 1);
+ aux1 = 1;
+ }
+ it->move(aux2,it->y());
+ it->setSize(aux1,it->height());
+ break;
+ case Right:
+ aux1 = it->width() + (p.x() - it->right());
+ if(aux1 < 1)aux1 = 1;
+ it->setSize(aux1,it->height());
+ break;
+ case Top:
+ aux1 = it->height() + (int)(it->y() - p.y());
+ aux2 = p.y();
+ if(aux1 < 1)
+ {
+ aux2 += (aux1 - 1);
+ aux1 = 1;
+ }
+ it->move(it->x(),aux2);
+ it->setSize(it->width(),aux1);
+ break;
+ case Bottom:
+ aux1 = (int)it->height() + (p.y() - it->bottom());
+ if(aux1 < 1)aux1 = 1;
+ it->setSize(it->width(),aux1);
+ break;
+ case LeftTop:
+ aux1 = it->width() + (int)(it->x() - p.x());
+ aux3 = p.x();
+ if(aux1 < 1)
+ {
+ aux3 += (aux1 - 1);
+ aux1 = 1;
+ }
+ aux2 = it->height() + (int)(it->y() - p.y());
+ aux4 = p.y();
+ if(aux2 < 1)
+ {
+ aux4 += (aux2 - 1);
+ aux2 = 1;
+ }
+ it->setSize(aux1,aux2);
+ it->move(aux3,aux4);
+ break;
+ case RightTop:
+ aux1 = it->width() + (int)(p.x() - it->right());
+ if(aux1 < 1)aux1 = 1;
+ aux2 = it->height() + (int)(it->y() - p.y());
+ aux4 = p.y();
+ if(aux2 < 1)
+ {
+ aux4 += (aux2 - 1);
+ aux2 = 1;
+ }
+ it->setSize(aux1,aux2);
+ it->move(it->x(),aux4);
+ break;
+ case LeftBottom:
+ aux1 = it->width() + (int)(it->x() - p.x());
+ aux3 = p.x();
+ if(aux1 < 1)
+ {
+ aux3 += (aux1 - 1);
+ aux1 = 1;
+ }
+ aux2 = it->height() + (int)(p.y() - it->bottom());
+ if(aux2 < 1)aux2 = 1;
+ it->setSize(aux1,aux2);
+ it->move(aux3,it->y());
+ break;
+ case RightBottom:
+ aux1 = it->width() + (int)(p.x() - it->right());
+ if(aux1 < 1)aux1 = 1;
+ aux2 = it->height() + (int)(p.y() - it->bottom());
+ if(aux2 < 1)aux2 = 1;
+ it->setSize(aux1,aux2);
+ break;
+ default:
+ break;
+ }
+
+ canvas()->update();
+}
+
+void KviCanvasView::contentsMouseMoveEvent(QMouseEvent *e)
+{
+// QPoint p = inverseWorldMatrix().map(e->pos());
+ QPoint p = e->pos();
+ if(e->state() & Qt::LeftButton)
+ {
+ if((m_dragMode != None) && (m_pSelectedItem))
+ {
+#if QT_VERSION >= 300
+ if(m_pSelectedItem->isEnabled())m_pSelectedItem->setEnabled(false);
+#else
+ if(m_pSelectedItem->enabled())m_pSelectedItem->setEnabled(false);
+#endif
+ switch(KVI_CANVAS_RTTI_CONTROL_TYPE(m_pSelectedItem))
+ {
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE:
+ dragRectangle((KviCanvasRectangleItem *)m_pSelectedItem,p);
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_LINE:
+ dragLine((KviCanvasLine *)m_pSelectedItem,p);
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_POLYGON:
+ dragPolygon((KviCanvasPolygon *)m_pSelectedItem,p);
+ break;
+ }
+ }
+ } else {
+ // Without buttons
+ if(m_state == Idle)
+ {
+ QCanvasItemList l = canvas()->collisions(p);
+ QCanvasItemList::Iterator it = l.begin();
+
+ if(it != l.end())
+ {
+ // Got an item
+ QCanvasItem * hit = (QCanvasItem *)*it;
+ // Now find the point on that we have clicked it
+ if(hit == m_pSelectedItem)
+ {
+ switch(KVI_CANVAS_RTTI_CONTROL_TYPE(m_pSelectedItem))
+ {
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE:
+ beginDragRectangle((KviCanvasRectangleItem *)m_pSelectedItem,p);
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_LINE:
+ beginDragLine((KviCanvasLine *)m_pSelectedItem,p);
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_POLYGON:
+ beginDragPolygon((KviCanvasPolygon *)m_pSelectedItem,p);
+ break;
+ }
+ }
+ else if(m_dragMode != None)setCursor(arrowCursor);
+ } else {
+ if(m_dragMode != None)setCursor(arrowCursor);
+ }
+ }
+ }
+}
+
+void KviCanvasView::contentsMouseReleaseEvent(QMouseEvent *e)
+{
+ if(m_dragMode != None)
+ {
+ // Was just dragging a rectangle
+ m_dragMode = None;
+ setCursor(arrowCursor);
+ if(m_pSelectedItem)
+ {
+ m_pSelectedItem->setEnabled(true);
+ canvas()->update();
+ }
+ }
+}
+
+void KviCanvasView::contentsMousePressEvent(QMouseEvent *e)
+{
+ if(e->button() & Qt::LeftButton)
+ {
+// QPoint p = inverseWorldMatrix().map(e->pos());
+ QPoint p = e->pos();
+
+ switch(m_state)
+ {
+ case SelectOrigin:
+ clearSelection();
+ setCursor(arrowCursor);
+ m_state = Idle;
+ insertObjectAt(p,m_objectToInsert);
+ canvas()->update();
+ break;
+
+ case Idle:
+ {
+ QCanvasItemList l = canvas()->collisions(p);
+ QCanvasItemList::Iterator it = l.begin();
+
+ if(it != l.end())
+ {
+ // Got an item
+ QCanvasItem * hit = *it;
+ if(hit != m_pSelectedItem)
+ {
+ // Was not selected yet
+ setItemSelected(hit);
+ canvas()->update();
+ }
+ // Now find the point on that we have clicked it
+ switch(KVI_CANVAS_RTTI_CONTROL_TYPE(hit))
+ {
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE:
+ beginDragRectangle(((KviCanvasRectangleItem *)hit),p);
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_LINE:
+ beginDragLine(((KviCanvasLine *)hit),p);
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_POLYGON:
+ beginDragPolygon(((KviCanvasPolygon *)hit),p,e->state() & Qt::ShiftButton,e->state() & Qt::ControlButton);
+ break;
+ }
+ } else {
+ // No item
+ clearSelection();
+ canvas()->update();
+ }
+ }
+ break;
+ }
+ }
+}
+
+
+void KviCanvasView::propertyChanged(const QString &s,const QVariant &v)
+{
+ if(!m_pSelectedItem)return;
+
+
+ switch(KVI_CANVAS_RTTI_CONTROL_TYPE(m_pSelectedItem))
+ {
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE:
+ ((KviCanvasRectangleItem *)m_pSelectedItem)->setProperty(s,v);
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_LINE:
+ ((KviCanvasLine *)m_pSelectedItem)->setProperty(s,v);
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_POLYGON:
+ ((KviCanvasPolygon *)m_pSelectedItem)->setProperty(s,v);
+ break;
+ }
+
+ canvas()->update();
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviVariantTableItem
+//
+
+
+
+KviVariantTableItem::KviVariantTableItem(QTable * t,const QVariant & property)
+: QTableItem(t,QTableItem::WhenCurrent,QString::null)
+{
+ m_property = property;
+}
+
+KviVariantTableItem::~KviVariantTableItem()
+{
+}
+
+
+QWidget * KviVariantTableItem::createEditor() const
+{
+ switch(m_property.type())
+ {
+ case QVariant::String:
+ {
+ QLineEdit * e = new QLineEdit(table()->viewport());
+ e->setText(m_property.toString());
+ return e;
+ }
+ break;
+ case QVariant::Int:
+ {
+ QLineEdit * e = new QLineEdit(table()->viewport());
+ QString sz;
+ sz.setNum(m_property.toInt());
+ e->setText(sz);
+ e->setValidator(new QIntValidator(e));
+ return e;
+ }
+ break;
+ case QVariant::UInt:
+ {
+ QLineEdit * e = new QLineEdit(table()->viewport());
+ QString sz;
+ sz.setNum(m_property.toInt());
+ e->setText(sz);
+ QIntValidator * i = new QIntValidator(e);
+ i->setBottom(0);
+ e->setValidator(i);
+ return e;
+ }
+ break;
+ case QVariant::Bool:
+ {
+ QComboBox * b = new QComboBox(false,table()->viewport());
+ b->insertItem("FALSE");
+ b->insertItem("TRUE");
+ b->setCurrentItem(m_property.toBool() ? 1 : 0);
+ return b;
+ }
+ break;
+ case QVariant::Color:
+ {
+ QLineEdit * e = new QLineEdit(table()->viewport());
+ e->setText(m_property.toColor().name());
+ return e;
+ }
+ break;
+ case QVariant::Font:
+ {
+ QComboBox * b = new QComboBox(true,table()->viewport());
+
+ QString tmp;
+ QString tmpDefault;
+ QFont f = QFont();
+ f.setStyleHint(QFont::SansSerif);
+ tmpDefault = f.family();
+ f.setStyleHint(QFont::TypeWriter);
+ tmp.setNum(m_property.toFont().pointSize());
+ tmp.prepend(", ");
+ tmp.prepend(m_property.toFont().family());
+ b->insertItem(tmp);
+ b->insertItem(tmpDefault + ", 8");
+ b->insertItem(tmpDefault + ", 10");
+ b->insertItem(tmpDefault + ", 12");
+ b->insertItem(tmpDefault + ", 14");
+ b->insertItem(tmpDefault + ", 16");
+ b->insertItem(tmpDefault + ", 18");
+ b->insertItem(tmpDefault + ", 20");
+ b->insertItem(tmpDefault + ", 24");
+ b->insertItem(tmpDefault + ", 28");
+ b->insertItem(tmpDefault + ", 32");
+ b->insertItem(tmpDefault + ", 40");
+ b->insertItem(tmpDefault + ", 48");
+ b->insertItem(f.family() + ", 12");
+ b->setCurrentItem(0);
+
+ b->setCurrentItem(m_property.toBool() ? 1 : 0);
+ return b;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+void KviVariantTableItem::setContentFromEditor(QWidget * w)
+{
+ switch(m_property.type())
+ {
+ case QVariant::String:
+ m_property = QVariant(((QLineEdit *)w)->text());
+ break;
+ case QVariant::Int:
+ m_property = QVariant(((QLineEdit *)w)->text().toInt());
+ break;
+ case QVariant::UInt:
+ m_property = QVariant(((QLineEdit *)w)->text().toUInt());
+ break;
+ case QVariant::Bool:
+ m_property = QVariant(((QComboBox *)w)->currentItem(),1);
+ break;
+ case QVariant::Color:
+ m_property.asColor().setNamedColor(((QLineEdit *)w)->text());
+ break;
+ case QVariant::Font:
+ {
+ KviStr txt = ((QComboBox *)w)->currentText();
+ if(txt.hasData())
+ {
+ KviStr fam = txt;
+ fam.cutFromFirst(',',true);
+ fam.stripWhiteSpace();
+ KviStr psz = txt;
+ psz.cutToFirst(',',true);
+ psz.stripWhiteSpace();
+ bool bOk;
+ unsigned int uSize = psz.toUInt(&bOk);
+ if(!bOk)uSize = 12;
+ m_property = QVariant(QFont(fam.ptr(),uSize));
+ }
+
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+void KviVariantTableItem::paint(QPainter *p,const QColorGroup &cg,const QRect &cr,bool)
+{
+ p->fillRect(0,0,cr.width(),cr.height(),cg.base());
+
+ if(m_property.type() == QVariant::Color)
+ {
+ p->fillRect(3,3,cr.width() - 6,cr.height() - 6,m_property.asColor());
+ } else {
+ QString sz;
+ switch(m_property.type())
+ {
+ case QVariant::String:
+ sz = m_property.toString();
+ break;
+ case QVariant::Bool:
+ sz = m_property.toBool() ? "TRUE" : "FALSE";
+ break;
+ case QVariant::Font:
+ sz.setNum(m_property.toFont().pointSize());
+ sz.prepend(", ");
+ sz.prepend(m_property.toFont().family());
+ break;
+ case QVariant::Int:
+ sz.setNum(m_property.toInt());
+ break;
+ case QVariant::UInt:
+ sz.setNum(m_property.toUInt());
+ break;
+ default:
+ break;
+ }
+ p->setPen(cg.text());
+ p->drawText(0,0,cr.width(),cr.height(),Qt::AlignLeft | Qt::AlignTop,sz);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasItemPropertiesWidget
+//
+
+
+KviCanvasItemPropertiesWidget::KviCanvasItemPropertiesWidget(QWidget * par)
+: QTable(par)
+{
+ setSelectionMode(QTable::NoSelection);
+ setColumnMovingEnabled(false);
+ setRowMovingEnabled(false);
+ setShowGrid(true);
+ setNumCols(2);
+ setSorting(false);
+ setLeftMargin(0);
+ verticalHeader()->hide();
+ connect(this,SIGNAL(valueChanged(int,int)),this,SLOT(cellEdited(int,int)));
+}
+
+KviCanvasItemPropertiesWidget::~KviCanvasItemPropertiesWidget()
+{
+}
+
+void KviCanvasItemPropertiesWidget::cellEdited(int row,int)
+{
+ QTableItem * it = item(row,0);
+ if(!it)return;
+ QString szName = it->text();
+ it = item(row,1);
+ if(!it)return;
+ emit propertyChanged(szName,((KviVariantTableItem *)it)->property());
+}
+
+void KviCanvasItemPropertiesWidget::editItem(QCanvasItem * it)
+{
+ if(!it)
+ {
+ for(int i=0;i<numRows();i++)
+ {
+ clearCell(i,0);
+ clearCell(i,1);
+ clearCellWidget(i,1);
+ }
+ setNumRows(0);
+ return;
+ }
+
+ QMap<QString,QVariant> * m = 0;
+
+ switch(KVI_CANVAS_RTTI_CONTROL_TYPE(it))
+ {
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE:
+ m = ((KviCanvasRectangleItem *)it)->properties();
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_LINE:
+ m = ((KviCanvasLine *)it)->properties();
+ break;
+ case KVI_CANVAS_RTTI_CONTROL_TYPE_POLYGON:
+ m = ((KviCanvasPolygon *)it)->properties();
+ break;
+ }
+
+ if(!m)
+ {
+ editItem(0);
+ return;
+ }
+
+ for(int i=0;i<numRows();i++)
+ {
+ clearCell(i,0);
+ clearCell(i,1);
+ clearCellWidget(i,1);
+ }
+
+ setNumRows(m->count());
+
+ QTableItem * item;
+
+ int idx = 0;
+
+ for(QMap<QString,QVariant>::ConstIterator iter = m->begin();iter != m->end();++iter)
+ {
+ item = new QTableItem(this,QTableItem::Never,iter.key().utf8().data());
+ setItem(idx,0,item);
+ item = new KviVariantTableItem(this,iter.data());
+ setItem(idx,1,item);
+ idx++;
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// KviCanvasWidget
+//
+
+KviCanvasWidget::KviCanvasWidget(QWidget * par)
+: QWidget(par,"canvas_widget")
+{
+ m_pCanvas = new QCanvas(this);
+//#warning "Make this size as parameter of Dcc ?"
+ m_pCanvas->resize(648,480);
+ m_pMenuBar = new QMenuBar(this);
+ m_pSplitter = new QSplitter(QSplitter::Horizontal,this);
+ m_pCanvasView = new KviCanvasView(m_pCanvas,this,m_pSplitter);
+ m_pStatusLabel = new QLabel(this);
+ m_pPropertiesWidget = new KviCanvasItemPropertiesWidget(m_pSplitter);
+ QValueList<int> l;
+ l.append(80);
+ l.append(20);
+ m_pSplitter->setSizes(l);
+
+ connect(m_pPropertiesWidget,SIGNAL(propertyChanged(const QString &,const QVariant &)),m_pCanvasView,SLOT(propertyChanged(const QString &,const QVariant &)));
+
+ KviTalPopupMenu * add = new KviTalPopupMenu(m_pMenuBar);
+ KviTalPopupMenu * shapes = new KviTalPopupMenu(add);
+ KviTalPopupMenu * polygons = new KviTalPopupMenu(add);
+ KviTalPopupMenu * items = new KviTalPopupMenu(add);
+ shapes->insertItem(__tr2qs_ctx("&Line","dcc"),m_pCanvasView,SLOT(insertLine()));
+ shapes->insertItem(__tr2qs_ctx("&Rectangle","dcc"),m_pCanvasView,SLOT(insertRectangle()));
+ shapes->insertItem(__tr2qs_ctx("&Ellipse","dcc"),m_pCanvasView,SLOT(insertEllipse()));
+ shapes->insertItem(__tr2qs_ctx("&Pie","dcc"),m_pCanvasView,SLOT(insertPie()));
+ shapes->insertItem(__tr2qs_ctx("&Chord","dcc"),m_pCanvasView,SLOT(insertChord()));
+
+ items->insertItem(__tr2qs_ctx("&Rich text (html)","dcc"),m_pCanvasView,SLOT(insertRichText()));
+
+ polygons->insertItem(__tr2qs_ctx("&Triangle","dcc"),m_pCanvasView,SLOT(insertPolygonTriangle()));
+ polygons->insertItem(__tr2qs_ctx("&Rectangle","dcc"),m_pCanvasView,SLOT(insertPolygonRectangle()));
+ polygons->insertItem(__tr2qs_ctx("&Pentagon","dcc"),m_pCanvasView,SLOT(insertPolygonPentagon()));
+ polygons->insertItem(__tr2qs_ctx("&Hexagon","dcc"),m_pCanvasView,SLOT(insertPolygonHexagon()));
+
+ add->insertItem(__tr2qs_ctx("&Shape","dcc"),shapes);
+ add->insertItem(__tr2qs_ctx("&Item","dcc"),items);
+ add->insertItem(__tr2qs_ctx("&Polygons","dcc"),polygons);
+
+ m_pMenuBar->insertItem(__tr2qs_ctx("&Insert","dcc"),add);
+}
+
+KviCanvasWidget::~KviCanvasWidget()
+{
+}
+
+
+
+void KviCanvasWidget::resizeEvent(QResizeEvent *)
+{
+ int h = m_pMenuBar->sizeHint().height();
+ m_pMenuBar->setGeometry(0,0,width(),h);
+ int h2 = m_pStatusLabel->sizeHint().height();
+ m_pStatusLabel->setGeometry(0,height() - h2,width(),h2);
+ m_pSplitter->setGeometry(0,h,width(),height() - (h + h2));
+}
+
+
+#include "m_canvaswidget.moc"
+
+#endif
diff --git a/src/modules/dcc/canvaswidget.h b/src/modules/dcc/canvaswidget.h
new file mode 100644
index 00000000..41d451e4
--- /dev/null
+++ b/src/modules/dcc/canvaswidget.h
@@ -0,0 +1,322 @@
+#ifndef _CANVAS_WIDGET_H_
+#define _CANVAS_WIDGET_H_
+//
+// File : canvaswidget.h
+// Creation date : Mon Jul 30 07 2001 04:49:49 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 "broker.h"
+
+#ifdef COMPILE_DCC_CANVAS
+
+
+#include <qcanvas.h>
+
+//#ifdef QT_NO_CANVAS
+// #warning "HEre is not"
+//#endif
+
+
+#include <qmenubar.h>
+#include <qlabel.h>
+
+#include <qmap.h>
+#include <qvariant.h>
+#include <qtable.h>
+#include <qsplitter.h>
+
+
+
+class KviCanvasWidget;
+
+
+
+#define KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE 1
+#define KVI_CANVAS_RTTI_CONTROL_TYPE_LINE 2
+#define KVI_CANVAS_RTTI_CONTROL_TYPE_POLYGON 4
+
+#define KVI_CANVAS_RTTI_CONTROL_TYPE_MASK 255
+
+#define KVI_CANVAS_RTTI_RECTANGLE (KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE | (1 << 8))
+#define KVI_CANVAS_RTTI_RICHTEXT (KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE | (2 << 8))
+#define KVI_CANVAS_RTTI_LINE (KVI_CANVAS_RTTI_CONTROL_TYPE_LINE | (3 << 8))
+#define KVI_CANVAS_RTTI_ELLIPSE (KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE | (4 << 8))
+#define KVI_CANVAS_RTTI_CHORD (KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE | (5 << 8))
+#define KVI_CANVAS_RTTI_PIE (KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE | (6 << 8))
+#define KVI_CANVAS_RTTI_POLYGON (KVI_CANVAS_RTTI_CONTROL_TYPE_POLYGON | (7 << 8))
+
+#define KVI_CANVAS_RTTI_CONTROL_TYPE(__item) (__item->rtti() & KVI_CANVAS_RTTI_CONTROL_TYPE_MASK)
+
+
+
+class KviCanvasPolygon : public QCanvasPolygon
+{
+public:
+ KviCanvasPolygon(QCanvas * c,int x,int y,QPointArray &pnts,double dScaleFactor);
+ virtual ~KviCanvasPolygon();
+protected:
+ QMap<QString,QVariant> m_properties;
+ double m_dScaleFactor;
+ QPointArray m_points;
+public:
+ virtual void draw(QPainter & p);
+ double scaleFactor(){ return m_dScaleFactor; };
+ void setScaleFactor(double dScaleFactor);
+ void resetPoints();
+ const QPointArray & internalPoints(){ return m_points; };
+ void setInternalPoints(const QPointArray &pnts);
+ QMap<QString,QVariant> * properties(){ return &m_properties; };
+ virtual void setProperty(const QString &property,const QVariant &val);
+ virtual int rtti() const;
+};
+
+
+
+
+class KviCanvasRectangleItem : public QCanvasRectangle
+{
+ friend class KviCanvasRectangle;
+ friend class KviCanvasRichText;
+ friend class KviCanvasEllipticItem;
+protected:
+ KviCanvasRectangleItem(QCanvas * c,int x,int y,int w,int h);
+public:
+ virtual ~KviCanvasRectangleItem();
+protected:
+ QMap<QString,QVariant> m_properties;
+public:
+ int right(){ return ((int)x()) + width(); };
+ int bottom(){ return ((int)y()) + height(); };
+ QMap<QString,QVariant> * properties(){ return &m_properties; };
+ virtual void setProperty(const QString &property,const QVariant &val);
+// QVariant property(const QString &name){ return m_properties[name]; };
+protected:
+ void drawSelection(QPainter &p);
+};
+
+
+class KviCanvasEllipticItem : public KviCanvasRectangleItem
+{
+ friend class KviCanvasEllipse;
+ friend class KviCanvasChord;
+ friend class KviCanvasPie;
+protected:
+ KviCanvasEllipticItem(QCanvas * c,int x,int y,int w,int h);
+ ~KviCanvasEllipticItem();
+public:
+ virtual void setProperty(const QString & property,const QVariant &val);
+ virtual void draw(QPainter & p);
+ virtual void drawContent(QPainter & p);
+ virtual int rtti() const;
+};
+
+
+class KviCanvasEllipse : public KviCanvasEllipticItem
+{
+public:
+ KviCanvasEllipse(QCanvas * c,int x,int y,int w,int h);
+ ~KviCanvasEllipse();
+public:
+ virtual void drawContent(QPainter & p);
+ virtual int rtti() const;
+};
+
+
+class KviCanvasPie : public KviCanvasEllipticItem
+{
+public:
+ KviCanvasPie(QCanvas * c,int x,int y,int w,int h);
+ ~KviCanvasPie();
+public:
+ virtual void drawContent(QPainter & p);
+ virtual int rtti() const;
+};
+
+
+class KviCanvasChord : public KviCanvasEllipticItem
+{
+public:
+ KviCanvasChord(QCanvas * c,int x,int y,int w,int h);
+ ~KviCanvasChord();
+public:
+ virtual void drawContent(QPainter & p);
+ virtual int rtti() const;
+};
+
+
+class KviCanvasLine : public QCanvasLine
+{
+public:
+ KviCanvasLine(QCanvas * c,int x1,int y1,int x2,int y2);
+ virtual ~KviCanvasLine();
+protected:
+ QMap<QString,QVariant> m_properties;
+public:
+ QMap<QString,QVariant> * properties(){ return &m_properties; };
+ virtual void setProperty(const QString &property,const QVariant &val);
+// QVariant property(const QString &name){ return m_properties[name]; };
+ virtual void draw(QPainter & p);
+ virtual int rtti() const;
+};
+
+
+
+class KviCanvasRectangle : public KviCanvasRectangleItem
+{
+public:
+ KviCanvasRectangle(QCanvas * c,int x,int y,int w,int h);
+ ~KviCanvasRectangle();
+public:
+ virtual void draw(QPainter & p);
+ virtual void setProperty(const QString &property,const QVariant &val);
+ virtual int rtti() const;
+};
+
+
+class KviCanvasRichText : public KviCanvasRectangleItem
+{
+public:
+ KviCanvasRichText(QCanvas * c,int x,int y,int w,int h);
+ ~KviCanvasRichText();
+public:
+ virtual void draw(QPainter & p);
+ virtual int rtti() const;
+};
+
+
+class KviCanvasView : public QCanvasView
+{
+ Q_OBJECT
+public:
+ KviCanvasView(QCanvas * c,KviCanvasWidget * cw,QWidget * par);
+ ~KviCanvasView();
+public:
+ enum State { Idle , SelectOrigin };
+ enum ObjectType {
+ Rectangle , RichText , Line , Ellipse , Chord , Pie ,
+ PolygonTriangle , PolygonRectangle , PolygonPentagon ,
+ PolygonHexagon
+ };
+ enum DragMode {
+ None , All , Left , Right , Top , Bottom , LeftTop , RightTop ,
+ LeftBottom , RightBottom , Scale , SinglePoint , Rotate
+ };
+protected:
+ KviCanvasWidget * m_pCanvasWidget;
+
+ // Insertion of objects
+ State m_state;
+ ObjectType m_objectToInsert;
+
+ // Selected item
+ QCanvasItem * m_pSelectedItem;
+
+ DragMode m_dragMode;
+ QPoint m_dragBegin;
+ double m_dragScaleFactor;
+ unsigned int m_dragPointIndex;
+ QPointArray m_dragPointArray;
+protected:
+ void beginDragRectangle(KviCanvasRectangleItem * it,const QPoint &p,bool bInitial = false);
+ void dragRectangle(KviCanvasRectangleItem * it,const QPoint & p);
+
+ void beginDragLine(KviCanvasLine * it,const QPoint &p,bool bInitial = false);
+ void dragLine(KviCanvasLine * it,const QPoint &p);
+
+ void beginDragPolygon(KviCanvasPolygon * it,const QPoint &p,bool bShift = false,bool bCtrl = false);
+ void dragPolygon(KviCanvasPolygon * it,const QPoint &p);
+
+
+ void setItemSelected(QCanvasItem * it);
+ void clearSelection();
+ void insertObjectAt(const QPoint & pnt,ObjectType o);
+ virtual void contentsMousePressEvent(QMouseEvent *e);
+ virtual void contentsMouseMoveEvent(QMouseEvent *e);
+ virtual void contentsMouseReleaseEvent(QMouseEvent *e);
+public slots:
+ void insertRectangle();
+ void insertRichText();
+ void insertLine();
+ void insertPie();
+ void insertChord();
+ void insertEllipse();
+ void insertPolygonTriangle();
+ void insertPolygonRectangle();
+ void insertPolygonPentagon();
+ void insertPolygonHexagon();
+ void propertyChanged(const QString &s,const QVariant &v);
+};
+
+// For Qt3.0 this might need to be changed
+
+class KviVariantTableItem : public QTableItem
+{
+public:
+ KviVariantTableItem(QTable * t,const QVariant & property);
+ ~KviVariantTableItem();
+private:
+ QVariant m_property;
+public:
+ virtual QWidget * createEditor() const;
+ virtual void setContentFromEditor(QWidget *w);
+ QVariant & property(){ return m_property; };
+ virtual void paint(QPainter *p,const QColorGroup &cg,const QRect &cr,bool selected);
+};
+
+
+
+class KviCanvasItemPropertiesWidget : public QTable
+{
+ Q_OBJECT
+public:
+ KviCanvasItemPropertiesWidget(QWidget * par);
+ ~KviCanvasItemPropertiesWidget();
+public:
+ void editItem(QCanvasItem * it);
+protected slots:
+ void cellEdited(int row,int col);
+signals:
+ void propertyChanged(const QString &s,const QVariant &v);
+};
+
+
+
+class KviCanvasWidget : public QWidget
+{
+ friend class KviCanvasView;
+ Q_OBJECT
+public:
+ KviCanvasWidget(QWidget * par);
+ ~KviCanvasWidget();
+protected:
+ QSplitter * m_pSplitter;
+ QCanvas * m_pCanvas;
+ QMenuBar * m_pMenuBar;
+ KviCanvasView * m_pCanvasView;
+ QLabel * m_pStatusLabel;
+ KviCanvasItemPropertiesWidget * m_pPropertiesWidget;
+protected:
+ virtual void resizeEvent(QResizeEvent *);
+};
+
+
+#endif
+
+#endif //_CANVAS_WIDGET_H_
diff --git a/src/modules/dcc/chat.cpp b/src/modules/dcc/chat.cpp
new file mode 100644
index 00000000..715d17b9
--- /dev/null
+++ b/src/modules/dcc/chat.cpp
@@ -0,0 +1,842 @@
+//=======================================================================================
+//
+// 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) 1999-2000 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
+
+#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+#include "kvi_options.h"
+#include "kvi_input.h"
+#include "kvi_ircview.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+#include "kvi_error.h"
+#include "kvi_out.h"
+#include "kvi_netutils.h"
+#include "kvi_console.h"
+#include "kvi_frame.h"
+#include "kvi_malloc.h"
+#include "kvi_memmove.h"
+#include "kvi_thread.h"
+#include "kvi_ircsocket.h"
+#include "kvi_settings.h"
+#include "kvi_themedlabel.h"
+#include "kvi_socket.h"
+#include "kvi_app.h"
+#include "kvi_parameterlist.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_kvs_eventtriggers.h"
+#include "kvi_qcstring.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ #include "kvi_crypt.h"
+ #include "kvi_cryptcontroller.h"
+ #include "kvi_mirccntrl.h"
+#endif
+
+#include <qsplitter.h>
+#include <qevent.h>
+#include "kvi_tal_vbox.h"
+
+
+#ifdef COMPILE_SSL_SUPPORT
+ #include "kvi_sslmaster.h"
+#endif
+
+
+
+extern KviDccBroker * g_pDccBroker;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////
+////// WINDOW
+//////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviDccChat::KviDccChat(KviFrame *pFrm,KviDccDescriptor * dcc,const char * name)
+: KviDccWindow(KVI_WINDOW_TYPE_DCCCHAT,pFrm,name,dcc)
+{
+ m_pTopSplitter = new QSplitter(Qt::Horizontal,this,"top_splitter");
+ KviThemedLabel * dummy;
+ dummy = new KviThemedLabel(m_pTopSplitter,"dummy_label");
+ KviTalVBox * box = new KviTalVBox(m_pTopSplitter);
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ createCryptControllerButton(box);
+#endif
+
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"splitter");
+ 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.utf8().data());
+#ifdef COMPILE_SSL_SUPPORT
+ int ret = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL);
+#else
+ int ret = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout);
+#endif
+ if(ret != KviError_success)handleMarshalError(ret);
+
+ } else {
+ // ACTIVE CONNECTION
+ output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC %s connection","dcc"),m_pDescriptor->szType.utf8().data());
+#ifdef COMPILE_SSL_SUPPORT
+ int ret = m_pMarshal->dccConnect(m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data(),m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL);
+#else
+ int ret = m_pMarshal->dccConnect(m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data(),m_pDescriptor->bDoTimeout);
+#endif
+ if(ret != KviError_success)handleMarshalError(ret);
+ }
+}
+
+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)
+ {
+
+ KviStr 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())
+ {
+ KviStr tmp = m_pDescriptor->console()->connection() ? m_pDescriptor->console()->connection()->userInfo()->hostIp().utf8().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(kvi_stringIpToBinaryIp(ip.ptr(),&a))ip.setNum(htonl(a.s_addr));
+
+ QString szReq = QString("PRIVMSG %1 :%2DCC %3 chat %4 %5").arg(m_pDescriptor->szNick).arg((char)0x01).arg(m_pDescriptor->szType).arg(ip.ptr()).arg(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").arg(
+#else
+ "Chat").arg(
+#endif
+ m_pDescriptor->szNick).arg(m_pDescriptor->szIp).arg(m_pDescriptor->szPort);
+
+ m_szPlainTextCaption = tmp;
+
+ m_szHtmlActiveCaption.sprintf("<nobr><font color=\"%s\"><b>%s</b></font></nobr>",
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(),tmp.utf8().data());
+ m_szHtmlInactiveCaption.sprintf("<nobr><font color=\"%s\"><b>%s</b></font></nobr>",
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(),tmp.utf8().data());
+}
+
+QPixmap * KviDccChat::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG);
+}
+
+
+void KviDccChat::getBaseLogFileName(KviStr &buffer)
+{
+ buffer.sprintf("%s_%s_%s",m_pDescriptor->szNick.utf8().data(),m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data());
+}
+
+void KviDccChat::ownMessage(const QString &text)
+{
+ if(!m_pSlaveThread)
+ {
+ output(KVI_OUT_SYSTEMWARNING,__tr2qs_ctx("Cannot send data: No active connection","dcc"));
+ return;
+ }
+
+ KviQCString szData = encodeText(text);
+ const char * d = szData.data();
+ if(!d)return;
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ if(cryptSessionInfo())
+ {
+ if(cryptSessionInfo()->bDoEncrypt)
+ {
+ if(*d != KVI_TEXT_CRYPTESCAPE)
+ {
+ KviStr encrypted;
+ cryptSessionInfo()->pEngine->setMaxEncryptLen(-1);
+ switch(cryptSessionInfo()->pEngine->encrypt(d,encrypted))
+ {
+ case KviCryptEngine::Encrypted:
+ {
+ KviStr buf(KviStr::Format,"%s\r\n",encrypted.ptr());
+ m_pSlaveThread->sendRawData(buf.ptr(),buf.len());
+ m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSGCRYPTED,
+ m_pDescriptor->szLocalNick.utf8().data(),m_pDescriptor->szLocalUser.utf8().data(),
+ m_pDescriptor->szLocalHost.utf8().data(),text,KviConsole::NoNotifications);
+ }
+ break;
+ case KviCryptEngine::Encoded:
+ {
+ KviStr buf(KviStr::Format,"%s\r\n",encrypted.ptr());
+ m_pSlaveThread->sendRawData(buf.ptr(),buf.len());
+ QString encr = decodeText(encrypted.ptr());
+ m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,
+ m_pDescriptor->szLocalNick.utf8().data(),m_pDescriptor->szLocalUser.utf8().data(),
+ m_pDescriptor->szLocalHost.utf8().data(),encr,KviConsole::NoNotifications);
+ }
+ break;
+ default: // also case KviCryptEngine::EncryptError
+ {
+ QString szErr = cryptSessionInfo()->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
+ KviStr buf(KviStr::Format,"%s\r\n",d);
+ QString tmp = text.right(text.length() - 1);
+ m_pSlaveThread->sendRawData(buf.ptr(),buf.len());
+ m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,
+ m_pDescriptor->szLocalNick.utf8().data(),m_pDescriptor->szLocalUser.utf8().data(),
+ m_pDescriptor->szLocalHost.utf8().data(),tmp,KviConsole::NoNotifications);
+ return;
+ }
+ }
+ }
+#endif
+ KviStr buf(KviStr::Format,"%s\r\n",d);
+ m_pSlaveThread->sendRawData(buf.ptr(),buf.len());
+ m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,
+ m_pDescriptor->szLocalNick.utf8().data(),m_pDescriptor->szLocalUser.utf8().data(),
+ m_pDescriptor->szLocalHost.utf8().data(),text,KviConsole::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)
+ {
+ KviQCString szData = encodeText(text);
+ const char * d = szData.data();
+ if(!d)return;
+ KviStr buf(KviStr::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),&text);
+ } 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:
+ {
+ int * err = ((KviThreadDataEvent<int> *)e)->getData();
+ QString szErr = KviError::getDescription(*err);
+ 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 err;
+ return true;
+ }
+ break;
+ case KVI_DCC_THREAD_EVENT_DATA:
+ {
+ KviStr * encoded = ((KviThreadDataEvent<KviStr> *)e)->getData();
+ KviStr d=KviStr(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());
+ } else {
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ if(KviCryptSessionInfo * cinf = cryptSessionInfo())
+ {
+ if(cinf->bDoDecrypt)
+ {
+ KviStr decryptedStuff;
+ switch(cinf->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.utf8().data(),m_pDescriptor->szUser.utf8().data(),
+ m_pDescriptor->szHost.utf8().data(),decryptedStuff.ptr());
+ }
+ delete encoded;
+ return true;
+ break;
+
+ default: // also case KviCryptEngine::DecryptError
+ {
+ QString szErr = cinf->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.utf8().data(),m_pDescriptor->szUser.utf8().data(),
+ m_pDescriptor->szHost.utf8().data(),d.ptr());
+#ifdef COMPILE_CRYPT_SUPPORT
+ }
+#endif
+ }
+ delete encoded;
+ return true;
+ }
+ break;
+ }
+ }
+ return KviWindow::event(e);
+}
+
+void KviDccChat::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,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(int err)
+{
+ QString szErr = KviError::getDescription(err);
+ 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()));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////
+////// THREAD
+//////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviDccChatThread::KviDccChatThread(KviWindow *wnd,kvi_socket_t fd)
+: KviDccThread(wnd,fd)
+{
+ m_pOutBuffers = new KviPointerList<KviDataBuffer>;
+ 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 *) kvi_realloc(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 *)kvi_realloc(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 *)kvi_realloc(data.buffer,data.iLen * sizeof(char));
+ } else {
+ kvi_free(data.buffer);
+ data.buffer = 0;
+ }
+
+ if(!handleInvalidSocketRead(readLen))
+ {
+ if(data.iLen)handleIncomingData(&data,true); // critical
+ __range_invalid(data.iLen);
+ break; // error
+ }
+ }
+ }
+ msleep(100);
+ }
+ }
+
+out_of_the_loop:
+
+
+ if(data.iLen)kvi_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)
+{
+ __range_valid(data->iLen);
+ __range_valid(data->buffer);
+ char * aux = data->buffer;
+ char * end = data->buffer + data->iLen;
+ while(aux != end)
+ {
+ if((*aux == '\n') || (*aux == '\0'))
+ {
+ KviThreadDataEvent<KviStr> * e = new KviThreadDataEvent<KviStr>(KVI_DCC_THREAD_EVENT_DATA);
+ // The left part is len chars long
+ int len = aux - data->buffer;
+// debug("LEN = %d, iLen = %d",len,data->iLen);
+//#warning "DO IT BETTER (the \r cutting)"
+ KviStr * s = new KviStr(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);
+// debug("iLen now = %d",data->iLen);
+ __range_valid(data->iLen >= 0);
+ if(data->iLen > 0)
+ {
+ // memmove the remaining part to the beginning
+ // aux points after \n or \0
+ kvi_memmove(data->buffer,aux,data->iLen);
+ data->buffer = (char *)kvi_realloc(data->buffer,data->iLen);
+ end = data->buffer + data->iLen;
+ aux = data->buffer;
+ } else {
+ // no more data in the buffer
+ __range_valid(data->iLen == 0);
+ kvi_free(data->buffer);
+ data->buffer = end = aux = 0;
+ }
+ postEvent(parent(),e);
+ } else aux++;
+// debug("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<KviStr> * e = new KviThreadDataEvent<KviStr>(KVI_DCC_THREAD_EVENT_DATA);
+ KviStr * s = new KviStr(data->buffer,data->iLen);
+ if(s->lastCharIs('\r'))s->cutRight(1);
+ e->setData(s);
+ data->iLen = 0;
+ kvi_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();
+#ifdef COMPILE_ON_WINDOWS
+ 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;
+}
+
+#include "m_chat.moc"
diff --git a/src/modules/dcc/chat.h b/src/modules/dcc/chat.h
new file mode 100644
index 00000000..ae1d51b9
--- /dev/null
+++ b/src/modules/dcc/chat.h
@@ -0,0 +1,101 @@
+#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-2004 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_window.h"
+#include "kvi_string.h"
+#include "kvi_databuffer.h"
+
+#include "window.h"
+#include "descriptor.h"
+#include "thread.h"
+
+#include "kvi_pointerlist.h"
+
+#ifdef COMPILE_SSL_SUPPORT
+ class KviSSL;
+#endif
+
+class KviDccChatThread : public KviDccThread
+{
+public:
+ KviDccChatThread(KviWindow * wnd,kvi_socket_t fd);
+ ~KviDccChatThread();
+protected:
+ KviPointerList<KviDataBuffer> * 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 KviDccMarshal;
+class QSplitter;
+
+class KviDccChat : public KviDccWindow
+{
+ Q_OBJECT
+public:
+ KviDccChat(KviFrame *pFrm,KviDccDescriptor * dcc,const char * name);
+ ~KviDccChat();
+protected:
+ KviDccChatThread * m_pSlaveThread;
+ QSplitter * m_pTopSplitter;
+ QString m_szTarget;
+ QString m_szLocalNick;
+protected:
+ virtual const QString & target();
+ virtual void fillCaptionBuffers();
+ virtual void getBaseLogFileName(KviStr &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);
+ virtual void ownAction(const QString &text);
+ virtual void triggerCreationEvents();
+ virtual void triggerDestructionEvents();
+ void startConnection();
+protected slots:
+ void handleMarshalError(int err);
+ 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
new file mode 100644
index 00000000..833796ac
--- /dev/null
+++ b/src/modules/dcc/codec.cpp
@@ -0,0 +1,88 @@
+//
+// 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 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"
+
+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;
+}
diff --git a/src/modules/dcc/codec.h b/src/modules/dcc/codec.h
new file mode 100644
index 00000000..72fa6023
--- /dev/null
+++ b/src/modules/dcc/codec.h
@@ -0,0 +1,57 @@
+#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 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_string.h"
+#include "kvi_databuffer.h"
+
+class KviDccVoiceCodec
+{
+public:
+ KviDccVoiceCodec();
+ virtual ~KviDccVoiceCodec();
+protected:
+ KviStr 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();
+};
+
+
+
+#endif //_CODEC_H_
diff --git a/src/modules/dcc/descriptor.cpp b/src/modules/dcc/descriptor.cpp
new file mode 100644
index 00000000..b21b0561
--- /dev/null
+++ b/src/modules/dcc/descriptor.cpp
@@ -0,0 +1,224 @@
+//=============================================================================
+//
+// File : src/modules/dcc/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 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_locale.h"
+#include "kvi_kvs_eventtriggers.h"
+
+#include "kvi_window.h"
+#include "kvi_app.h"
+
+#include "send.h"
+#include "window.h"
+
+
+static unsigned int g_uNextDescriptorId = 1; // we use 0 as an invalid descriptor id
+static KviPointerHashTable<int,KviDccDescriptor> * g_pDescriptorDict = 0;
+
+KviPointerHashTable<int,KviDccDescriptor> * KviDccDescriptor::descriptorDict()
+{
+ return g_pDescriptorDict;
+}
+
+/*
+KviDccDescriptor::KviDccDescriptor(const KviDccDescriptor & src)
+{
+ copyFrom(src);
+}
+*/
+
+KviDccDescriptor::KviDccDescriptor(KviConsole * 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<int,KviDccDescriptor>;
+ 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)
+ {
+ debug("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_pDccWindow = src.m_pDccWindow;
+ m_pDccTransfer = src.m_pDccTransfer;
+ m_uId = src.m_uId;
+ 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;
+#ifdef COMPILE_SSL_SUPPORT
+ bIsSSL = src.bIsSSL;
+#endif
+}
+*/
+
+bool KviDccDescriptor::isFileUpload()
+{
+ if(szType.upper()=="SEND")return true;
+ if(szType.upper()=="TSEND")return true;
+#ifdef COMPILE_SSL_SUPPORT
+ if(szType.upper()=="SSEND")return true;
+#endif
+ return false;
+}
+
+bool KviDccDescriptor::isFileDownload()
+{
+ if(szType.upper()=="RECV")return true;
+ if(szType.upper()=="TRECV")return true;
+#ifdef COMPILE_SSL_SUPPORT
+ if(szType.upper()=="SRECV")return true;
+#endif
+ return false;
+}
+
+bool KviDccDescriptor::isDccChat()
+{
+ if(szType.upper()=="CHAT")return true;
+#ifdef COMPILE_SSL_SUPPORT
+ if(szType.upper()=="SCHAT")return true;
+#endif
+ return false;
+}
diff --git a/src/modules/dcc/descriptor.h b/src/modules/dcc/descriptor.h
new file mode 100644
index 00000000..f3f6c3f3
--- /dev/null
+++ b/src/modules/dcc/descriptor.h
@@ -0,0 +1,163 @@
+#ifndef _DESCRIPTOR_H_
+#define _DESCRIPTOR_H_
+//=============================================================================
+//
+// File : src/modules/dcc/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-2004 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 "kvi_string.h"
+#include "kvi_console.h"
+
+#include "kvi_pointerhashtable.h"
+
+
+class KviDccWindow;
+class KviDccFileTransfer;
+
+class KviDccDescriptor
+{
+public:
+ KviDccDescriptor(KviConsole * pConsole);
+ //KviDccDescriptor(const KviDccDescriptor & src);
+ ~KviDccDescriptor();
+protected:
+ KviConsole * m_pConsole;
+
+ // mIrc zero port reverse send/chat extension
+ KviStr 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)
+ KviConsole * console() const { return m_pConsole; };
+ void setConsole(KviConsole * 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 KviStr &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<int,KviDccDescriptor> * 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
+
+ KviStr szCodec; // codec name
+ int iSampleRate; // Sample rate
+public:
+ // new interface... but should be converted to QString...
+ QString protocol(){ return szType; };
+ bool isActive(){ return bActive; };
+ QString remoteNick(){ return szNick; };
+ QString remoteUser(){ return szUser; };
+ QString remoteHost(){ return szHost; };
+ QString remoteIp(){ return szIp; };
+ QString remotePort(){ return szPort; };
+ QString remoteFileName(){ return szFileName; };
+ QString remoteFileSize(){ return szFileSize; };
+ QString localNick(){ return szLocalNick; };
+ QString localUser(){ return szLocalUser; };
+ QString localHost(){ return szLocalHost; };
+ QString localIp(){ return szIp; };
+ QString localPort(){ return szPort; };
+ QString localFileName(){ return szLocalFileName; };
+ QString localFileSize(){ return szLocalFileSize; };
+ bool isFileUpload();
+ bool isFileDownload();
+ bool isDccChat();
+ bool isFileTransfer(){ return (isFileUpload() || isFileDownload()); };
+};
+
+
+
+
+#endif //_DESCRIPTOR_H_
diff --git a/src/modules/dcc/dialogs.cpp b/src/modules/dcc/dialogs.cpp
new file mode 100644
index 00000000..0ec0afba
--- /dev/null
+++ b/src/modules/dcc/dialogs.cpp
@@ -0,0 +1,206 @@
+//
+// 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) 1999-2000 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 "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_app.h"
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <qstringlist.h>
+#include <qevent.h>
+#include <qdesktopwidget.h>
+
+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,"dcc_accept_box") , KviDccBox(br,dcc)
+{
+ QVBoxLayout * vb = new QVBoxLayout(this,4,4);
+ QLabel * l = new QLabel(text,this);
+#ifdef COMPILE_USE_QT4
+ l->setWordWrap(true);
+#endif
+ vb->addWidget(l);
+ QHBoxLayout *hb = new QHBoxLayout(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);
+
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG)));
+ setCaption(capt);
+
+ l->setActiveWindow();
+ l->setFocus();
+}
+
+KviDccAcceptBox::~KviDccAcceptBox()
+{
+}
+
+void KviDccAcceptBox::acceptClicked()
+{
+ hide();
+ emit accepted(this,m_pDescriptor);
+ g_pApp->collectGarbage(this);
+}
+
+void KviDccAcceptBox::rejectClicked()
+{
+ hide();
+ emit rejected(this,m_pDescriptor);
+ g_pApp->collectGarbage(this);
+}
+
+void KviDccAcceptBox::closeEvent(QCloseEvent *e)
+{
+ hide();
+ e->ignore();
+ emit rejected(this,m_pDescriptor);
+ g_pApp->collectGarbage(this);
+}
+
+void KviDccAcceptBox::showEvent(QShowEvent *e)
+{
+ move((g_pApp->desktop()->width() - width()) >> 1,
+ (g_pApp->desktop()->height() - height()) >> 1);
+ QWidget::showEvent(e);
+}
+
+
+
+
+KviDccRenameBox::KviDccRenameBox(KviDccBroker * br,KviDccDescriptor * dcc,const QString &text,bool bDisableResume)
+: QWidget(0,"dcc_rename_box") , KviDccBox(br,dcc)
+{
+ QVBoxLayout * vb = new QVBoxLayout(this,4,4);
+ QLabel * l = new QLabel(text,this);
+#ifdef COMPILE_USE_QT4
+ l->setWordWrap(true);
+#endif
+ vb->addWidget(l);
+
+ QHBoxLayout *hb = new QHBoxLayout(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();
+
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG)));
+ setCaption(__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);
+ }
+}
+
+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);
+}
+
+void KviDccRenameBox::overwriteClicked()
+{
+ hide();
+ emit overwriteSelected(this,m_pDescriptor);
+ g_pApp->collectGarbage(this);
+}
+
+void KviDccRenameBox::resumeClicked()
+{
+ hide();
+ m_pDescriptor->bResume = true;
+ emit overwriteSelected(this,m_pDescriptor);
+ g_pApp->collectGarbage(this);
+}
+
+void KviDccRenameBox::cancelClicked()
+{
+ hide();
+ emit cancelSelected(this,m_pDescriptor);
+ g_pApp->collectGarbage(this);
+}
+
+
+
+
+#include "m_dialogs.moc"
diff --git a/src/modules/dcc/dialogs.h b/src/modules/dcc/dialogs.h
new file mode 100644
index 00000000..805c0147
--- /dev/null
+++ b/src/modules/dcc/dialogs.h
@@ -0,0 +1,82 @@
+#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) 1999-2000 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 <qwidget.h>
+#include "kvi_filedialog.h"
+
+#include "broker.h"
+
+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
new file mode 100644
index 00000000..58af1473
--- /dev/null
+++ b/src/modules/dcc/gsmcodec.cpp
@@ -0,0 +1,149 @@
+//
+// 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 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 <dlfcn.h>
+
+#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
new file mode 100644
index 00000000..a1de407b
--- /dev/null
+++ b/src/modules/dcc/gsmcodec.h
@@ -0,0 +1,54 @@
+#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 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/kvi_dccfiletransfericons.png b/src/modules/dcc/kvi_dccfiletransfericons.png
new file mode 100644
index 00000000..11999a03
--- /dev/null
+++ b/src/modules/dcc/kvi_dccfiletransfericons.png
Binary files differ
diff --git a/src/modules/dcc/libkvidcc.cpp b/src/modules/dcc/libkvidcc.cpp
new file mode 100644
index 00000000..717f568d
--- /dev/null
+++ b/src/modules/dcc/libkvidcc.cpp
@@ -0,0 +1,2766 @@
+//=============================================================================
+//
+// File : libkviobjects.cpp
+// Creation date : Wed Sep 09 2000 20:59:01 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2005 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 "kvi_settings.h"
+#include "kvi_string.h"
+#include "kvi_module.h"
+#include "kvi_sparser.h"
+#include "kvi_locale.h"
+#include "kvi_out.h"
+#include "kvi_console.h"
+#include "kvi_netutils.h"
+#include "kvi_frame.h"
+#include "kvi_console.h"
+#include "kvi_error.h"
+#include "kvi_options.h"
+#include "kvi_defaults.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_app.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+
+#include "gsmcodec.h"
+#include "broker.h"
+#include "voice.h"
+#include "utils.h"
+#include "send.h"
+#include "window.h"
+
+#include <qfileinfo.h>
+
+#ifdef COMPILE_ON_WINDOWS
+ // Ugly Windoze compiler...
+ #include "dialogs.h"
+#endif
+
+//#warning "KviOption_boolIgnoreDccChat and other types too"
+
+//extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager;
+
+KviDccBroker * g_pDccBroker = 0;
+
+
+static void dcc_module_set_dcc_type(KviDccDescriptor * d,const char * szBaseType)
+{
+ d->szType = szBaseType;
+#ifdef COMPILE_SSL_SUPPORT
+ if(d->bIsSSL)d->szType.prepend('S');
+#endif
+ if(d->bIsTdcc)d->szType.prepend('T');
+}
+
+static bool dcc_kvs_parse_default_parameters(KviDccDescriptor * d,KviKvsModuleCommandCall *c)
+{
+ d->bIsTdcc = c->switches()->find('t',"tdcc");
+
+ KviKvsVariant * pSw = c->switches()->find('m',"minimize");
+
+ if(pSw != 0)
+ d->bOverrideMinimize = pSw->asBoolean();
+ else
+ d->bOverrideMinimize = false;
+
+ if(!d->console())
+ {
+ // We don't need a console with -c and -n , otherwise we need it
+ if(!(c->switches()->find('c',"connect") || c->switches()->find('n',"no-ctcp")))
+ {
+ delete d;
+ c->error(__tr2qs_ctx("This window has no associated IRC context (an IRC context is required unless -c or -n are passed)","dcc"));
+ return false;
+ } else d->setConsole(c->window()->frame()->firstConsole());
+ }
+
+ __range_valid(d->console());
+
+ if(!d->console()->isConnected())
+ {
+ // We don't need a connection with -c and -n , otherwise we need it
+ if(!(c->switches()->find('c',"connect") || c->switches()->find('n',"no-ctcp")))
+ {
+ delete d;
+ c->error(__tr2qs_ctx("You're not connected to a server (an active connection is required unless -c or -n are passed)","dcc"));
+ return false;
+ } else {
+ // -c or -n , grab a local nick from somewhere
+ d->szLocalNick = KVI_OPTION_STRING(KviOption_stringNickname1);
+ d->szLocalNick.stripWhiteSpace();
+ if(d->szLocalNick.isEmpty())d->szLocalNick = KVI_DEFAULT_NICKNAME1;
+ d->szLocalUser = __tr2qs_ctx("unknown","dcc"); // we can live without it
+ d->szLocalHost = d->szLocalUser; // we can live without it
+ }
+ } else {
+ // We know everything
+ d->szLocalNick = d->console()->connection()->userInfo()->nickName();
+ d->szLocalUser = d->console()->connection()->userInfo()->userName();
+ d->szLocalHost = d->console()->connection()->userInfo()->hostName();
+ }
+
+ if(pSw = c->switches()->find('i',"ip"))
+ {
+ pSw->asString(d->szListenIp);
+ if(!(d->szListenIp.contains('.') || d->szListenIp.contains(':')))
+ {
+ // This will magically work with the same buffer as source and dst!
+ if(!KviNetUtils::getInterfaceAddress(d->szListenIp,d->szListenIp))
+ {
+ c->error(__tr2qs_ctx("Unable to get address of interface %Q","dcc"),&(d->szListenIp));
+ delete d;
+ return false;
+ }
+ }
+ } else {
+ QString tmp;
+ if(!dcc_kvs_get_listen_ip_address(c,d->console(),tmp))
+ {
+ delete d;
+ c->error(__tr2qs_ctx("No suitable interfaces to listen on, use -i","dcc"));
+ return false;
+ }
+ d->szListenIp=tmp;
+ }
+
+ if(pSw = c->switches()->find('p',"port"))
+ {
+ pSw->asString(d->szListenPort); // fixme!
+ }
+ else d->szListenPort = "0"; // any port is ok
+
+ if(pSw = c->switches()->find('a',"fake-address"))
+ {
+ pSw->asString(d->szFakeIp);
+ }
+ else {
+ if(KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault))
+ {
+ d->szFakeIp = KVI_OPTION_STRING(KviOption_stringDefaultDccFakeAddress);
+ if(d->szFakeIp.isEmpty())KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault) = false;
+ }
+ }
+
+ if(pSw = c->switches()->find('f',"fake-port"))
+ {
+ pSw->asString(d->szFakePort);
+ }
+
+ d->bDoTimeout = (!c->switches()->find('u',"unlimited"));
+#ifdef COMPILE_SSL_SUPPORT
+ d->bIsSSL = c->switches()->find('s',"ssl");
+#else
+ if(c->switches()->find('s',"ssl"))c->warning(__tr2qs_ctx("This executable was built without SSL support, -s switch ignored","dcc"));
+#endif
+
+ return true;
+}
+
+
+/*
+ @doc: dcc.chat
+ @type:
+ command
+ @title:
+ dcc.chat
+ @short:
+ Starts a DCC Chat connection
+ @syntax:
+ dcc.chat [-s] [-n] [-c] [-u] [-m[=<boolean>]] [-i=<interface>] [-p=<port>] [-a=<fake address>] [-f=<fake port>] <nickname>
+ @switches:
+ !sw: -m[=<boolean>] | --minimize[=<boolean>]
+ If the -m switch is passed, the default boolCreateMinimizedDccChat option
+ is overridden with the <boolean> parameter passed. So actually
+ by passing -m=1 will create a minimized DCC send even
+ if the [fnc]$option[/fnc](boolCreateMinimizedDccChat) returns false.[br]
+ In the same way, by passing -m=0 you will create a non minimized DCC send.
+ If no <boolean> value is specified, it defaults to 1.[br]
+
+ !sw: -n | --no-ctcp
+ Do NOT send the CTCP request to the target user, you will have to do it manually,
+ or the remote user will have to connect manually (for example by using dcc.chat -c).[br]
+
+ !sw: -c | --connect
+ Attempt to CONNECT to the remote host specified as <interface> and <port>,
+ instead of listening (active connection instead of a passive one).
+ In this case the -i and -p switches are mandatory.[br]
+ The 'c' switch takes precedence over 'n' (In fact both should
+ be mutually exclusive).[br]
+ If the 'c' and 'n' switches are missing, this commands
+ needs to be executed in a window that is bound to a connected
+ IRC context (you need a third entity to accomplish the negotiation).[br]
+
+ !sw: -i=<interface> | --ip=<interface>
+ Bind the local listening socket to the specified <interface> (which is an IP address, IPv4 or IPv6).
+ If this switch is NOT specified, the socket is bound to the interface of
+ the current IRC connection (if any) or to "127.0.0.1".[br]
+ You can also specify a local interface name to get the address from (this works only for IPv4 interfaces
+ since IPv6 ones seems to be unsupported by the system ioctl() calls at the moment (for linux at least)).[br]
+ Here go some examples:[br]
+ -i=215.243.12.12: this will bind to the IPv4 interface with the specified address.[br]
+ -i=3ffe:1001::1: this will bind to the IPv6 interface with the specified address.[br]
+ -i=ppp0: this will bind to the IPv4 address of the interface ppp0 (if supported by the underlying system).[br]
+ The -i switch parameter may serve also as a target address when the -c switch is used.[br]
+
+ !sw: -p=<port> | --port=<port>
+ Bind the local listening socket to the specified <port>.
+ If this switch is NOT specified, the port will be a "random" one choosen by the kernel.[br]
+
+ !sw: -a=<fake address> | --fake-address=<fake address>
+ Send the <fake address> as target for the remote client in the requesting CTCP message.
+ If this switch is not given, the CTCP will contain the real IP address of the listening
+ interface.[br]
+
+ !sw: -f=<fake port> | --fake-port=<fake port>
+ Send the <fake port> as target port for the remote client in the requesting CTCP message.
+ If this switch is not given, the CTCP will contain the real port of the listening socket.
+ [br][br]
+ All these switches are meant to allow maximum flexibility of the
+ DCC negotiation, earlier KVIrc releases had serious problems
+ with firewalled and/or masqueraded machines. With the -a and -f switches
+ you can work around it.[br]
+ [br]
+
+ !sw: -u | --unlimited
+ If the 'u' switch is given, the connection attempt will
+ never time out; this might be useful if you want to leave
+ a listening socket for a friend of yours while you are sleeping
+ and have the CTCP processing disabled. The 'u' switch works either
+ in active and passive mode.[br]
+
+ !sw: -s | --ssl
+ Use a Secure Socket Layer for the transfer; the whole communication will be encrypted
+ with a private key algorithm after a public key handshake.[br]
+ This option will work only if the KVIrc executable has been compiled with SSL support
+ and the remote end supports the SSL protocol too.[br]
+ Please note that this will may down the transfer somewhat.[br]
+ -s can be combined with -t.[br]
+ The CTCP negotiation will use SSEND as parameter (or eventually TSSEND).[br]
+ When requesting a SSL based DCC send to someone you probably will need a
+ certificate. If you don't have one, create it (for example with CA.pl -newcert)
+ and set it in the options dialog.
+
+ !sw: -z | --zero-port
+ Use the 0 port method. This is a dirty hack that allows you to use the CHAT
+ protocol with mIrc receiving clients.
+ @description:
+ Attempts a DCC connection to <nickname>.[br]
+ The simplest case "dcc.chat <nickname>" will work just as in all
+ the other IRC clients, but this command is really more powerful...[br]
+ Before attempting to understand the possibilities of this command,
+ be sure to know how [doc:dcc_connection]DCC negotiation and connections[/doc] work.
+ If the 'i' switch is specified, the local listening socket
+ will be bound to the specified <interface> (which is an IP address, IPv4 or IPv6),
+ otherwise it will be bound to the interface of the
+ current IRC connection.[br]
+ You can also specify a local interface name to get the address from (this works only for IPv4 interfaces
+ since IPv6 ones seem to be unsupported by the system ioctl() calls at the moment (in Linux at least)).[br]
+ Here are some examples:[br]
+ -i=215.243.12.12: This will bind to the IPv4 interface with the specified address.[br]
+ -i=3ffe:1001::1: This will bind to the IPv6 interface with the specified address.[br]
+ -i=ppp0: This will bind to the IPv4 address of the interface ppp0 (if supported by the underlying system).[br]
+ The -i switch parameter may serve also as a target address when the -c switch is used.[br]
+ If the 'p' switch is specified, the local listening socket
+ will be bound to the <port>, otherwise it will be bound to
+ a random port choosen by the kernel.[br]
+ If the 'a' switch is specified, the requesting CTCP message
+ will contain <fake address> as target for the remote user,
+ otherwise the CTCP message will contain the real IP address
+ of the listening interface.
+ If the 'f' switch is specified, the requesting CTCP message
+ will contain <fake port> as target for the remote user,
+ otherwise the CTCP message will contain the real port of the
+ listening socket.
+ All these switches are meant to allow maximum flexibility of the
+ DCC negotiation, earlier KVIrc releases had serious problems
+ with firewalled and/or masqueraded machines. With the -a and -f switches
+ you can workaround it.
+ If the 'n' switch is specified, KVIrc will NOT send the CTCP request
+ to the target user; you will have to do it manually, or the remote user
+ will have to connect manually (for example by using dcc.chat -c).
+ If the 'c' switch is specified, KVIrc will attempt to connect
+ to the remote host specified as <interface> and <port>, instead
+ of listening (active connection instead of a passive one).
+ In this case the -i and -p switches are mandatory.[br]
+ The 'c' switch takes precedence over 'n' (In fact both should
+ be mutually exclusive).[br]
+ If the 'c' and 'n' switches are missing, this commands
+ needs to be executed in a window that is bound to a connected
+ IRC context (you need a third entity to accomplish the negotiation).[br]
+ If the 'u' switch is given, the connection attempt will
+ never time out; this might be useful if you want to leave
+ a listening socket for a friend of yours while you are sleeping
+ and have the CTCP processing disabled. The 'u' switch works either
+ in active and passive mode.[br]
+ If the -m switch is passed, the default boolCreateMinimizedDccChat option
+ is overridden with the <boolean> parameter passed. So actually
+ by passing -m=1 will create a minimized DCC chat even
+ if the [fnc]$option[/fnc](boolCreateMinimizedDccChat) returns false.[br]
+ In the same way, by passing -m=0 you will create a non minimized DCC chat.
+ If no <boolean> value is specified, it defaults to 1.[br]
+ -s will cause the DCC chat to be attempted in Secure Sockets Layer mode:
+ the connection will be encrypted with a private key algorithm after a
+ public key handshake. -s will work only if the KVIrc executable was compiled
+ with SSL support enabled and if the remote end supports it.
+ The eventual DCC request will contain the string SCHAT instead of CHAT.[br]
+ When requesting a SSL based DCC chat to someone you probably will need a
+ certificate. If you don't have one, create it (for example with CA.pl -newcert)
+ and set it in the options dialog.
+ @examples:
+ Simple examples:
+ [example]
+ # Simple DCC chat to Pragma
+ dcc.chat Pragma
+ # DCC chat to Pragma, listen on address 127.0.0.1
+ dcc.chat -i=127.0.0.1 Pragma
+ # DCC chat to Pragma, listen on address 168.0.0.1 and port 1025
+ dcc.chat -i=168.0.0.1 -p=1025 Pragma
+ [/example]
+ More tricky ones:
+ [example]
+ # DCC chat to Pragma, listen on address 127.0.0.1 and port 1080
+ # but tell him to connect to address 212.134.22.11 port 1080
+ dcc.chat -i=127.0.0.1 -p=1080 -a=212.134.22.11 Pragma
+ # DCC chat to Pragma, listen on address 127.0.0.1 and port 1080
+ # but tell him to connect to address 212.134.22.11 port 1090
+ dcc.chat -i=127.0.0.1 -p=1080 -a=212.134.22.11 -f=1090 Pragma
+ [/example]
+ Now run completely out of bounds. Use dcc.chat connections
+ to do various things:
+ [example]
+ # Tricky: simulate a HTTP server
+ dcc.chat -n -i=127.0.0.1 -p=80 Netscape
+ # Now open http://127.0.0.1 with netscape
+ # and type "<html><body>Hello!</body></html>" :)
+ #
+ # Tricky 2: simulate the ident daemon (if you have none)
+ dcc.chat -n -i=127.0.0.1 -p=113 Client
+ #
+ # Now a self-DCC connection without the IRC negotiation
+ # Src: Setup a listening socket awaiting the "Destination" user connection
+ dcc.chat -n -i=127.0.0.1 -p=1080 Dst
+ # Dst: Connect to the listening socket at addr 127.0.0.1 and port 1080
+ dcc.chat -c -i=127.0.0.1 -p=1080 Src
+ # The above example will mess you a bit...
+ # Try to guess why in both windows YOU have the same nickname
+ # that is probably not Dst nor Src... :)
+ [/example]
+ Using the shell ftp proggie is too easy:
+ we're [b]real hackers[/b] and want to do complicated things...
+ [example]
+ # Connect to the local ftp server and get the list of contents
+ /dcc.chat -c -i=127.0.0.1 -p=21 FtpServer
+ # Now login, type in the new window (the following lines are NOT commands):
+ USER youruser
+ PASS yourpass
+ # Now enter passive mode
+ PASV
+ # And watch the line that you have received...sth like
+ # 227 Entering passive mode (127,0,0,1,210,195)
+ /dcc.chat -c -i=127.0.0.1 -p=$((210 * 256) + 195) FtpList
+ # (Change the port numbers accordingly)
+ # And then type in the FtpServer window (this is NOT a KVIrc command):
+ LIST
+ # Then watch the ls output in the FtpList window. :)
+ # In this way you can also read ascii files by ftp:
+ # Assume that in the previous ls output you have seen
+ # a README file.
+ # In the FtpServer window type:
+ PASV
+ # Watch the message
+ # 227 Entering passive mode (127,0,0,1,22,227)
+ /dcc.chat -c -i=127.0.0.1 -p=$((22 * 256) + 227) README
+ # In the FtpServer window type:
+ RETR README
+ # And read the file in the README window :)
+ [/example]
+*/
+
+static bool dcc_kvs_cmd_chat(KviKvsModuleCommandCall * c)
+{
+ QString szTarget;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szTarget)
+ KVSM_PARAMETERS_END(c)
+
+ KviDccDescriptor * d = new KviDccDescriptor(c->window()->console());
+
+ d->szNick = szTarget; // we always specify the nickname
+ d->szUser = __tr2qs_ctx("unknown","dcc"); // username is always unknown
+ d->szHost = d->szUser; // host is always unknown
+
+ if(!dcc_kvs_parse_default_parameters(d,c))return false;
+ dcc_module_set_dcc_type(d,"CHAT");
+
+ if(c->switches()->find('z',"zero-port"))
+ {
+ // we want to have it reversed... add a tag and send out the request
+ KviDccZeroPortTag * t = g_pDccBroker->addZeroPortTag();
+
+ d->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s chat 127.0.0.1 0 %s%c",
+ d->console()->connection()->encodeText(d->szNick).data(),
+ 0x01,
+ d->console()->connection()->encodeText(d->szType).data(),
+ d->console()->connection()->encodeText(t->m_szTag).data(),
+ 0x01);
+
+ return true;
+ }
+
+ if(c->switches()->find('c',"connect"))
+ {
+ if(!(c->switches()->find('i',"ip") && c->switches()->find('p',"port")))
+ {
+ delete d;
+ c->error(__tr2qs_ctx("-c requires -i and -p","dcc"));
+ return false;
+ }
+ d->szIp = d->szListenIp;
+ d->szPort = d->szListenPort;
+ d->szListenIp = ""; // useless
+ d->szListenPort = ""; // useless
+ d->bActive = true;
+ } else {
+ d->szIp = __tr2qs_ctx("unknown","dcc");
+ d->szPort = d->szIp;
+ d->bActive = false;
+ d->bSendRequest = !c->switches()->find('n',"no-ctcp");
+ }
+
+ //c->window()->output(0,"%Q %Q %Q",&(d->szIp),&(d->szPort),&(d->szListenIp));
+ d->triggerCreationEvent();
+ g_pDccBroker->executeChat(0,d);
+
+ return true;
+}
+
+
+/*
+ @doc: dcc.send
+ @type:
+ command
+ @title:
+ dcc.send
+ @short:
+ Sends a file
+ @syntax:
+ dcc.send [-s] [-n] [-c] [-u] [-b] [-g[=<file size>]] [-t] [-m[=<boolean>]] [-i=<interface>] [-p=<port>] [-a=<fake address>] [-f=<fake port>] <nickname> [filename]
+ @switches:
+ !sw: -g[=<file size>] | --get[=<file size>]
+ This switch is a dirty trick, you can use it to receive files from people
+ behind a firewall with masquerading enabled.[br]
+ It causes the transfer direction to be inverted; your client will receive
+ the file from the remote host instead of sending it.[br]
+ <file size> is the expected file size in bytes. This parameter can be omitted,
+ and in this case the DCC will "blindly" trust the remote end and assume
+ that the file has been transferred correctly when the remote end closes the connection.[br]
+ If you don't pass the -n option, the remote end will receive an informational DCC RECV request,
+ specifying the IP address and the port to connect to.[br]
+ -t can be used to prevent sending acknowledges to the remote end, and -u can be used
+ to avoid the listening socket to timeout.[br]
+ -a and -f can be used as well, but I see no real reason for that...[br]
+ Here is an example of usage of this option:[br]
+ spion can't accept connections (is behind a firewall with masquerading or some other reason...),
+ to his machine.[br]
+ spion wants to send the file important.jpg to Pragma.[br]
+ spion tells to Pragma that he wants to send him the file and Pragma sets up a connection in the following way:[br]
+ [b]dcc.send -g spion important.png[/b][br]
+ spion will see the informational DCC RECV request with the IP address and port that Pragma is listening on.
+ Assume that the address was 212.212.231.220 and the port 32344.[br]
+ spion will then use the following command:[br]
+ [b]dcc.send -c -i=212.212.231.220 -p=32344 Pragma /home/spion/important.jpg[/b][br]
+ Et voila!..the file is transferring.[br]
+ Pragma will see no file progress indication, since the file size is unknown on Pragma's side.[br]
+ If spion had specified the file size, Pragma could use -g=<file size> while setting up the connection,
+ to be able to see the progress indications.[br]
+ If Pragma used the the -n option, the DCC RECV indication wouldn't have been sent, in this case
+ Pragma would need to communicate the Ip address and the port "manually" to spion.[br]
+
+ !sw: -b | --blind
+ Assume that no acknowledges are sent.
+ Assume that the transfer was successful when the whole file has been sent,
+ then close the socket.[br]
+ This is called a "blind" DCC send.[br]
+
+ !sw: -t | -tdcc
+ Emulate the TDCC protocol: Use the TDCC CTCP message (DCC TSEND) for requesting the connection
+ and assume that no acknowledges are sent. Wait for the remote end to close the connection.[br]
+
+ !sw: -m[=<boolean>] | --minimize[=<boolean>]
+ If the -m switch is passed, the default boolCreateMinimizedDccSend option
+ is overridden with the <boolean> parameter passed. So actually
+ by passing -m=1 will create a minimized DCC send even
+ if the [fnc]$option[/fnc](boolCreateMinimizedDccSend) returns false.[br]
+ In the same way, by passing -m=0 you will create a non minimized DCC send.
+ If no <boolean> value is specified, it defaults to 1.[br]
+
+ !sw: -n | --no-ctcp
+ Do NOT send the CTCP request to the target user, you will have to do it manually,
+ or the remote user will have to connect manually (for example by using dcc.recv -c).[br]
+
+ !sw: -c | --connect
+ Attempt to CONNECT to the remote host specified as <interface> and <port>,
+ instead of listening (active connection instead of a passive one).
+ In this case the -i and -p switches are mandatory.[br]
+ The 'c' switch takes precedence over 'n' (In fact both should
+ be mutually exclusive).[br]
+ If the 'c' and 'n' switches are missing, this commands
+ needs to be executed in a window that is bound to a connected
+ IRC context (you need a third entity to accomplish the negotiation).[br]
+
+ !sw: -i=<interface> | --ip=<interface>
+ Bind the local listening socket to the specified <interface> (which is an IP address, IPv4 or IPv6).
+ If this switch is NOT specified, the socket is bound to the interface of
+ the current IRC connection (if any) or to "127.0.0.1".[br]
+ You can also specify a local interface name to get the address from (this works only for IPv4 interfaces
+ since IPv6 ones seems to be unsupported by the system ioctl() calls at the moment (for linux at least)).[br]
+ Here go some examples:[br]
+ -i=215.243.12.12: this will bind to the IPv4 interface with the specified address.[br]
+ -i=3ffe:1001::1: this will bind to the IPv6 interface with the specified address.[br]
+ -i=ppp0: this will bind to the IPv4 address of the interface ppp0 (if supported by the underlying system).[br]
+ The -i switch parameter may serve also as a target address when the -c switch is used.[br]
+
+ !sw: -p=<port> | --port=<port>
+ Bind the local listening socket to the specified <port>.
+ If this switch is NOT specified, the port will be a "random" one choosen by the kernel.[br]
+
+ !sw: -a=<fake address> | --fake-address=<fake address>
+ Send the <fake address> as target for the remote client in the requesting CTCP message.
+ If this switch is not given, the CTCP will contain the real IP address of the listening
+ interface.[br]
+
+ !sw: -f=<fake port> | --fake-port=<fake port>
+ Send the <fake port> as target port for the remote client in the requesting CTCP message.
+ If this switch is not given, the CTCP will contain the real port of the listening socket.
+ [br][br]
+ All these switches are meant to allow maximum flexibility of the
+ DCC negotiation, earlier KVIrc releases had serious problems
+ with firewalled and/or masqueraded machines. With the -a and -f switches
+ you can work around it.[br]
+ [br]
+
+ !sw: -u | --unlimited
+ If the 'u' switch is given, the connection attempt will
+ never time out; this might be useful if you want to leave
+ a listening socket for a friend of yours while you are sleeping
+ and have the CTCP processing disabled. The 'u' switch works either
+ in active and passive mode.[br]
+
+ !sw: -s | --ssl
+ Use a Secure Socket Layer for the transfer; the whole communication will be encrypted
+ with a private key algorithm after a public key handshake.[br]
+ This option will work only if the KVIrc executable has been compiled with SSL support
+ and the remote end supports the SSL protocol too.[br]
+ Please note that this will may down the transfer somewhat.[br]
+ -s can be combined with -t.[br]
+ The CTCP negotiation will use SSEND as parameter (or eventually TSSEND).[br]
+ When requesting a SSL based DCC send to someone you probably will need a
+ certificate. If you don't have one, create it (for example with CA.pl -newcert)
+ and set it in the options dialog.
+
+ @description:
+ Attempts to send the file <filename> to <nickname>.[br]
+ If [filename] is specified it must be an absolute file path,
+ otherwise a file selection dialog is opened.[br]
+ The simplest case "dcc.send <nickname> <filename>" will work just as in all
+ the other IRC clients, but this command is really more powerful...[br]
+ Before attempting to understand the possibilities of this command,
+ be sure to know how a [doc:dcc_connection]DCC negotiation and connection[/doc] works.[br]
+ The file will be sent as a sequence of packets which must
+ be acknowledged one by one by the active client.[br]
+ There is a special option (see $option()) called "fast send" (also known
+ as "send ahead") that makes KVIrc avoid to wait for the acknowledge
+ of the last packet before sending the next one.[br]
+ Anyway, the connection is declared as successful only
+ when the whole file (all the packets) has been acknowledged.[br]
+ If you need to send a file but you're firewalled, you might take
+ a look at the [cmd]dcc.rsend[/cmd] command. It also handles
+ the mIrc zero port protocol extension.
+ @examples:
+
+*/
+
+//#warning "Example for -r"
+//#warning "OPTION FOR NO GUI ? (this is hard...)"
+//#warning "When in IPv6 mode, should be able to use the IPv4 binding!"
+
+static bool dcc_kvs_cmd_send(KviKvsModuleCommandCall * c)
+{
+ QString szTarget,szFileName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szTarget)
+ KVSM_PARAMETER("file name",KVS_PT_NONEMPTYSTRING,KVS_PF_OPTIONAL,szFileName)
+ KVSM_PARAMETERS_END(c)
+
+ KviDccDescriptor * d = new KviDccDescriptor(c->window()->console());
+
+ d->szNick = szTarget; // we always specify the nickname
+
+ QString szTmp;
+ KviKvsVariant * pSw = 0;
+
+ if(pSw = c->switches()->find('g',"get"))
+ {
+ d->szFileName = QFileInfo(szFileName).fileName();
+
+ if(!pSw->isBoolean())
+ {
+ kvs_int_t iSize;
+ if(pSw->asInteger(iSize)) // is an integer
+ {
+ pSw->asString(szTmp);
+ // avoid sprintf as long as possibile
+ d->szFileSize = szTmp;
+ } else {
+ d->szFileSize = __tr_ctx("<unknown size>","dcc");
+ }
+ }
+ } else {
+ d->szFileName = szFileName;
+ d->szLocalFileName = szFileName;
+ }
+
+ d->szUser = __tr2qs_ctx("unknown","dcc"); // username is always unknown
+ d->szHost = d->szUser; // host is always unknown
+ d->bRecvFile = pSw != 0;
+ d->bNoAcks = c->switches()->find('b',"blind") || c->switches()->find('t',"tdcc");
+ d->bResume = false;
+ d->bAutoAccept = pSw != 0;
+ d->bIsIncomingAvatar = false;
+
+ if(!dcc_kvs_parse_default_parameters(d,c))return false;
+
+ if(c->switches()->find('c',"connect"))
+ {
+ if(!(c->switches()->find('i',"ip") && c->switches()->find('p',"port")))
+ {
+ delete d;
+ c->error(__tr2qs_ctx("-c requires -i and -p","dcc"));
+ return false;
+ }
+ d->szIp = d->szListenIp;
+ d->szPort = d->szListenPort;
+ d->szListenIp = ""; // useless
+ d->szListenPort = ""; // useless
+ d->bActive = true;
+ } else {
+ d->szIp = __tr2qs_ctx("unknown","dcc");
+ d->szPort = d->szIp;
+ d->bActive = false;
+ d->bSendRequest = !c->switches()->find('n',"no-ctcp");
+ }
+
+ if(c->switches()->find('g',"get"))
+ {
+ dcc_module_set_dcc_type(d,"RECV");
+ d->triggerCreationEvent();
+ g_pDccBroker->recvFileManage(d);
+ } else {
+ dcc_module_set_dcc_type(d,"SEND");
+ d->triggerCreationEvent();
+ if(!d->szLocalFileName.isEmpty())
+ {
+ g_pDccBroker->sendFileExecute(0,d);
+ } else {
+ g_pDccBroker->sendFileManage(d);
+ }
+ }
+
+ return true;
+}
+
+/*
+ @doc: dcc.recv
+ @type:
+ command
+ @title:
+ dcc.recv
+ @short:
+ Sets up a file receiving connection
+ @syntax:
+ dcc.recv [-s] [-t] [-u] [-b] [-n] [-c] [-i=<interface>] [-p=<port>] [-m[=<boolean>]] <nickname> <filename> <remote file size>
+ @switches:
+ !sw: -b | --blind
+ Assume that no acknowledges are sent.
+ Assume that the transfer was successful when the whole file has been sent,
+ then close the socket.[br]
+ This is called a "blind" DCC send.[br]
+
+ !sw: -t | -tdcc
+ Emulate the TDCC protocol: Use the TDCC CTCP message (DCC TSEND) for requesting the connection
+ and assume that no acknowledges are sent. Wait for the remote end to close the connection.[br]
+
+ !sw: -m[=<boolean>] | --minimize[=<boolean>]
+ If the -m switch is passed, the default boolCreateMinimizedDccSend option
+ is overridden with the <boolean> parameter passed. So actually
+ by passing -m=1 will create a minimized DCC send even
+ if the [fnc]$option[/fnc](boolCreateMinimizedDccSend) returns false.[br]
+ In the same way, by passing -m=0 you will create a non minimized DCC send.
+ If no <boolean> value is specified, it defaults to 1.[br]
+
+ !sw: -n | --no-ctcp
+ Do NOT send the CTCP request to the target user, you will have to do it manually,
+ or the remote user will have to connect manually (for example by using dcc.recv -c).[br]
+
+ !sw: -i=<interface> | --ip=<interface>
+ Bind the local listening socket to the specified <interface> (which is an IP address, IPv4 or IPv6).
+ If this switch is NOT specified, the socket is bound to the interface of
+ the current IRC connection (if any) or to "127.0.0.1".[br]
+ You can also specify a local interface name to get the address from (this works only for IPv4 interfaces
+ since IPv6 ones seems to be unsupported by the system ioctl() calls at the moment (for linux at least)).[br]
+ Here go some examples:[br]
+ -i=215.243.12.12: this will bind to the IPv4 interface with the specified address.[br]
+ -i=3ffe:1001::1: this will bind to the IPv6 interface with the specified address.[br]
+ -i=ppp0: this will bind to the IPv4 address of the interface ppp0 (if supported by the underlying system).[br]
+ The -i switch parameter may serve also as a target address when the -c switch is used.[br]
+
+ !sw: -p=<port> | --port=<port>
+ Bind the local listening socket to the specified <port>.
+ If this switch is NOT specified, the port will be a "random" one choosen by the kernel.[br]
+
+ !sw: -a=<fake address> | --fake-address=<fake address>
+ Send the <fake address> as target for the remote client in the requesting CTCP message.
+ If this switch is not given, the CTCP will contain the real IP address of the listening
+ interface.[br]
+
+ !sw: -f=<fake port> | --fake-port=<fake port>
+ Send the <fake port> as target port for the remote client in the requesting CTCP message.
+ If this switch is not given, the CTCP will contain the real port of the listening socket.
+ [br][br]
+ All these switches are meant to allow maximum flexibility of the
+ DCC negotiation, earlier KVIrc releases had serious problems
+ with firewalled and/or masqueraded machines. With the -a and -f switches
+ you can work around it.[br]
+ [br]
+
+ !sw: -u | --unlimited
+ If the 'u' switch is given, the connection attempt will
+ never time out; this might be useful if you want to leave
+ a listening socket for a friend of yours while you are sleeping
+ and have the CTCP processing disabled. The 'u' switch works either
+ in active and passive mode.[br]
+
+ !sw: -s | --ssl
+ Use a Secure Socket Layer for the transfer; the whole communication will be encrypted
+ with a private key algorithm after a public key handshake.[br]
+ This option will work only if the KVIrc executable has been compiled with SSL support
+ and the remote end supports the SSL protocol too.[br]
+ Please note that this will may down the transfer somewhat.[br]
+ -s can be combined with -t.[br]
+ The CTCP negotiation will use SSEND as parameter (or eventually TSSEND).[br]
+ When requesting a SSL based DCC send to someone you probably will need a
+ certificate. If you don't have one, create it (for example with CA.pl -newcert)
+ and set it in the options dialog.
+
+ !sw: -c | --connect
+ Accepted for compatibility: don't use it!
+ @description:
+ Sets up a connection ready to receive a file.[br]
+ In most 'common' cases you will not need this command, you might want to use [cmd]dcc.get[/cmd] instead.[br]
+ This works like dcc.send but has two main differences: The file is INCOMING, and the CTCP sent to the other side
+ is a CTCP RECV.[br]
+ This command is the counterpart of [cmd]dcc.send[/cmd] and its parameters are exactly the same, so please refer to that
+ help page for the full discussion. This help page contains only a brief resume of these parameters.[br]
+ The [doc:dcc_connection]dcc documentation[/doc] explains the DCC Recv subprotocol in detail.[br]
+ @examples:
+
+*/
+
+//#warning "ENCODE THE CTCP'S!!!!!!!"
+//#warning "DOCS FOR dcc.recv (examples!)"
+
+static bool dcc_kvs_cmd_recv(KviKvsModuleCommandCall * c)
+{
+ QString szTarget,szFileName;
+ kvs_uint_t uSize;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szTarget)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szFileName)
+ KVSM_PARAMETER("size",KVS_PT_UINT,0,uSize)
+ KVSM_PARAMETERS_END(c)
+
+ KviDccDescriptor * d = new KviDccDescriptor(c->window()->console());
+ d->szNick = szTarget;
+ d->szUser = __tr2qs_ctx("unknown","dcc");
+ d->szHost = d->szUser;
+ d->szIp = __tr2qs_ctx("unknown","dcc");
+ d->szPort = d->szIp;
+
+ // -c is senseless here...but we accept it for compatibility
+
+ if(!dcc_kvs_parse_default_parameters(d,c))return false;
+
+ d->szFileName = szFileName;
+ d->szFileSize.setNum(uSize);
+
+ d->bActive = false; // we have to listen!
+ d->bResume = false;
+ d->bRecvFile = true; // we have to receive the file!
+ d->bSendRequest = !c->switches()->find('n',"no-ctcp");
+ d->bNoAcks = d->bIsTdcc || c->switches()->find('b',"blind");
+ d->bAutoAccept = KVI_OPTION_BOOL(KviOption_boolAutoAcceptDccSend);
+ d->bIsIncomingAvatar = g_pApp->findPendingAvatarChange(d->console(),d->szNick,d->szFileName);
+
+ if(KVI_OPTION_BOOL(KviOption_boolAutoAcceptIncomingAvatars))d->bAutoAccept = d->bAutoAccept || d->bIsIncomingAvatar;
+ dcc_module_set_dcc_type(d,"RECV");
+ d->triggerCreationEvent();
+ g_pDccBroker->recvFileManage(d);
+
+ return true;
+}
+
+/*
+ @doc: dcc.rsend
+ @type:
+ command
+ @title:
+ dcc.rsend
+ @short:
+ Sends a file by using the Reverse DCC Send protocol
+ @syntax:
+ dcc.rsend [-s] [-t] <nickname> [filename]
+ @switches:
+ !sw: -t | -tdcc
+ Emulate the TDCC protocol.
+
+ !sw: -s | --ssl
+ Use a Secure Socket Layer for the transfer; the whole communication will be encrypted
+ with a private key algorithm after a public key handshake.[br]
+ This option will work only if the KVIrc executable has been compiled with SSL support
+ and the remote end supports the SSL protocol too.[br]
+ Please note that this will may down the transfer somewhat.[br]
+ -s can be combined with -t.[br]
+ The CTCP negotiation will use SSEND as parameter (or eventually TSSEND).[br]
+ When requesting a SSL based DCC send to someone you probably will need a
+ certificate. If you don't have one, create it (for example with CA.pl -newcert)
+ and set it in the options dialog.
+ !sw: -z | --zero-port
+ Use the 0 port method. This is a dirty hack that allows you to use the RSEND
+ protocol with mIrc receiving clients.
+ @description:
+ Sends a DCC RSEND request to <nickname> notifying him that you want to
+ send him the file [filename].[br]
+ The remote end may acknowledge the request by sending a DCC RECV request.
+ This command effects are similar to [cmd]dcc.send[/cmd], but will work also on machines
+ that can't accept incoming connections (firewalling or masquerading problems).[br]
+ A 120 seconds file offer is added for the specified file and mask "<nickname>!*@*".
+ @examples:
+
+*/
+
+//#warning "ENCODE THE CTCP'S!!!!!!!"
+//#warning "DOCS FOR dcc.rsend"
+
+static bool dcc_kvs_cmd_rsend(KviKvsModuleCommandCall * c)
+{
+ QString szTarget,szFileName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szTarget)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,KVS_PF_OPTIONAL,szFileName)
+ KVSM_PARAMETERS_END(c)
+
+ KVSM_REQUIRE_CONNECTION(c)
+
+ KviDccDescriptor * d = new KviDccDescriptor(c->window()->console());
+ d->szNick = szTarget;
+ d->szLocalFileName = szFileName;
+ d->bIsTdcc = c->switches()->find('t',"tdcc");
+#ifdef COMPILE_SSL_SUPPORT
+ d->bIsSSL = c->switches()->find('s',"ssl");
+#else
+ if(c->switches()->find('s',"ssl"))c->warning(__tr2qs_ctx("This executable has been built without SSL support, -s switch ignored","dcc"));
+#endif //!COMPILE_SSL_SUPPORT
+
+ if(c->switches()->find('z',"zero-port"))
+ {
+ dcc_module_set_dcc_type(d,"SEND");
+ d->setZeroPortRequestTag("nonempty"); // just to tag it
+ } else
+ dcc_module_set_dcc_type(d,"RSEND");
+ d->triggerCreationEvent();
+ g_pDccBroker->rsendManage(d);
+
+ return true;
+}
+
+
+
+
+/*
+ @doc: dcc.get
+ @type:
+ command
+ @title:
+ dcc.get
+ @short:
+ Requests a file
+ @syntax:
+ dcc.get [-s] [-t] <nickname> <filename> [filesize]
+ @description:
+ Sends a CTCP DCC GET to <nickname> requesting the file <filename>.
+ The remote end should reply with a DCC SEND request CTCP.
+ <filename> must not contain any leading path.
+ If the -t switch is given, the message is a DCC TGET, expecting
+ a TSEND reply.[br]
+ If the -s switch is given, the message will be a DCC SGET, expecting
+ a SSEND reply.[br]
+ -t and -s can be combined together to obtain a "turbo"+"SSL" extension transfer.[br]
+ -s will work only if the KVIrc executable has been compiled with SSL support and
+ the remote client supports it.[br]
+ @examples:
+
+*/
+
+//#warning "ENCODE THE CTCP'S!!!!!!!"
+//#warning "DOCS FOR dcc.get"
+
+static bool dcc_kvs_cmd_get(KviKvsModuleCommandCall * c)
+{
+ QString szTarget,szFileName;
+ kvs_uint_t uSize;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szTarget)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szFileName)
+ KVSM_PARAMETER("size",KVS_PT_UINT,KVS_PF_OPTIONAL,uSize)
+ KVSM_PARAMETERS_END(c)
+
+ KVSM_REQUIRE_CONNECTION(c)
+
+ KviQString::cutToLast(szFileName,'/');
+
+ if(szFileName.contains(' '))
+ {
+ szFileName.prepend('"');
+ szFileName.append('"');
+ }
+
+ KviStr szDCC("GET");
+#ifdef COMPILE_SSL_SUPPORT
+ if(c->switches()->find('s',"ssl"))szDCC.prepend('S');
+#else
+ if(c->switches()->find('s',"ssl"))c->warning(__tr2qs_ctx("This executable has no SSL support, -s switch ignored","dcc"));
+#endif
+ if(c->switches()->find('t',"tdcc"))szDCC.prepend('T');
+
+ if(uSize == 0)
+ {
+ c->window()->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s%c",
+ c->window()->console()->connection()->encodeText(szTarget).data(),
+ 0x01,
+ c->window()->console()->connection()->encodeText(szDCC.ptr()).data(),
+ c->window()->console()->connection()->encodeText(szFileName).data(),
+ 0x01);
+ } else {
+ c->window()->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %u%c",
+ c->window()->console()->connection()->encodeText(szTarget).data(),
+ 0x01,
+ c->window()->console()->connection()->encodeText(szDCC.ptr()).data(),
+ c->window()->console()->connection()->encodeText(szFileName).data(),
+ uSize,0x01);
+ }
+
+ return true;
+}
+
+
+
+
+// FIXME: SSL support for DCC VOICE ? (has a sense ?)
+
+/*
+ @doc: dcc.voice
+ @type:
+ command
+ @title:
+ dcc.voice
+ @short:
+ Starts a DCC Voice connection
+ @syntax:
+ dcc.voice [-g=<codec>] [-n] [-c] [-u] [-h=<sample_rate_in_hz>] [-m[=<boolean>]] [-i=<interface>] [-p=<port>] [-a=<fake address>] [-f=<fake port>] <nickname>
+ @switches:
+ !sw: -g=<codec> | --codec=<codec>
+ Use the codec specified as parameter.
+ Actually the supported codecs are "null","adpcm" and "gsm".
+
+ !sw: -h=<rate> | --sample-rate=<rate>
+ Use the sample rate specified by <rage>.
+ Valid sample rates are 8000, 11025, 22050 and 44100 Hz.
+
+ !sw: -m[=<boolean>] | --minimize[=<boolean>]
+ If the -m switch is passed, the default boolCreateMinimizedDccSend option
+ is overridden with the <boolean> parameter passed. So actually
+ by passing -m=1 will create a minimized DCC send even
+ if the [fnc]$option[/fnc](boolCreateMinimizedDccSend) returns false.[br]
+ In the same way, by passing -m=0 you will create a non minimized DCC send.
+ If no <boolean> value is specified, it defaults to 1.[br]
+
+ !sw: -n | --no-ctcp
+ Do NOT send the CTCP request to the target user, you will have to do it manually,
+ or the remote user will have to connect manually (for example by using dcc.recv -c).[br]
+
+ !sw: -c | --connect
+ Attempt to CONNECT to the remote host specified as <interface> and <port>,
+ instead of listening (active connection instead of a passive one).
+ In this case the -i and -p switches are mandatory.[br]
+ The 'c' switch takes precedence over 'n' (In fact both should
+ be mutually exclusive).[br]
+ If the 'c' and 'n' switches are missing, this commands
+ needs to be executed in a window that is bound to a connected
+ IRC context (you need a third entity to accomplish the negotiation).[br]
+
+ !sw: -i=<interface> | --ip=<interface>
+ Bind the local listening socket to the specified <interface> (which is an IP address, IPv4 or IPv6).
+ If this switch is NOT specified, the socket is bound to the interface of
+ the current IRC connection (if any) or to "127.0.0.1".[br]
+ You can also specify a local interface name to get the address from (this works only for IPv4 interfaces
+ since IPv6 ones seems to be unsupported by the system ioctl() calls at the moment (for linux at least)).[br]
+ Here go some examples:[br]
+ -i=215.243.12.12: this will bind to the IPv4 interface with the specified address.[br]
+ -i=3ffe:1001::1: this will bind to the IPv6 interface with the specified address.[br]
+ -i=ppp0: this will bind to the IPv4 address of the interface ppp0 (if supported by the underlying system).[br]
+ The -i switch parameter may serve also as a target address when the -c switch is used.[br]
+
+ !sw: -p=<port> | --port=<port>
+ Bind the local listening socket to the specified <port>.
+ If this switch is NOT specified, the port will be a "random" one choosen by the kernel.[br]
+
+ !sw: -a=<fake address> | --fake-address=<fake address>
+ Send the <fake address> as target for the remote client in the requesting CTCP message.
+ If this switch is not given, the CTCP will contain the real IP address of the listening
+ interface.[br]
+
+ !sw: -f=<fake port> | --fake-port=<fake port>
+ Send the <fake port> as target port for the remote client in the requesting CTCP message.
+ If this switch is not given, the CTCP will contain the real port of the listening socket.
+ [br][br]
+ All these switches are meant to allow maximum flexibility of the
+ DCC negotiation, earlier KVIrc releases had serious problems
+ with firewalled and/or masqueraded machines. With the -a and -f switches
+ you can work around it.[br]
+ [br]
+
+ !sw: -u | --unlimited
+ If the 'u' switch is given, the connection attempt will
+ never time out; this might be useful if you want to leave
+ a listening socket for a friend of yours while you are sleeping
+ and have the CTCP processing disabled. The 'u' switch works either
+ in active and passive mode.[br]
+
+ @description:
+ Attempts a DCC Voice connection to <nickname>.[br]
+ The -g option is used to select the GSM codec, available codecs are "gsm", "adpcm" and "null".[br]
+ The adpcm codec is the one that was used in previous KVIrc versions, it provides a 1:4 compression rate
+ and is designed for 8 KHz audio sampling rate (but will work also with other sampling rates).[br]
+ The gsm codec offers 1:10 compression at the cost of some quality and cpu time. If you have a good
+ cpu and plan to transmit voice only, use this codec.<br> The null codec
+ offers no compression and may be used to transfer plain audio data over a fast connection (usually loopback
+ connection or local networks). The null codec with 44100 sampling rate would provide CD quality audio
+ streaming, but it is practically not usable (at the time I'm writing) since requires a
+ monster bandwidth. If the -g switch is not present, the adpcm codec is used by default (for compatibility reasons).[br]
+ The -h switch is used to select the sampling rate, if not given the sampling rate defaults to 8000 Hz.
+ This switch accepts any value, but in fact the soundcards have limits on the values. Typically
+ the lowest limit is 5 KHz and the upper limit is 44.1 KHz (but some soundcards support 96 KHz).
+ It is also possible that the soundcard can't support a continous range of frequencies and
+ will select a discrete closest match instead.[br]
+ The "commonly used" sample rates are 8000, 11025, 22050 and 44100 Hz.[br]
+ The remaining parameters are equivalent to the ones used in [cmd]dcc.send[/cmd], so please refer to that
+ help page for the full discussion. This help page contains only a brief resume of these parameters.[br]
+ @examples:
+ [example]
+ [comment]# Setup a DCC VOICE connection with Pragma (IRC user)[/comment]
+ dcc.voice Pragma
+ [comment]# Setup a DCC VOICE connection with Pragma and use the gsm codec[/comment]
+ dcc.voice -g=gsm Pragma
+ [comment]# Setup a DCC VOICE connection with Pragma, use the gsm codec and 22050 Hz sampling rate[/comment]
+ dcc.voice -g=gsm -h=22050 Pragma
+ [comment]# Setup a listening socket for a DCC VOICE connection on interface 127.0.0.1 and port 8088[/comment]
+ dcc.voice -n -i=127.0.0.1 -p=8088 Pippo
+ [comment]# Connect to the socket above[/comment]
+ dcc.voice -c -i=127.0.0.1 -p=8088 Pluto
+ [comment]# Same as above but use the NULL codec with 11025 Hz sampling rate[/comment]
+ dcc.voice -g=null -h=11025 -n -i=127.0.0.1 -p=8088 Pippo
+ [comment]# Connect to the socket above[/comment]
+ dcc.voice -g=null -h=11025 -c -i=127.0.0.1 -p=8088 Pluto
+ [/example]
+*/
+
+static bool dcc_kvs_cmd_voice(KviKvsModuleCommandCall * c)
+{
+ QString szTarget;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szTarget)
+ KVSM_PARAMETERS_END(c)
+
+#ifdef COMPILE_DISABLE_DCC_VOICE
+ c->warning(__tr2qs_ctx("DCC VOICE support not enabled at compilation time","dcc"));
+ return true;
+#endif
+
+ KviDccDescriptor * d = new KviDccDescriptor(c->window()->console());
+
+ d->szNick = szTarget; // we always specify the nickname
+ d->szUser = __tr2qs_ctx("unknown","dcc"); // username is always unknown
+ d->szHost = d->szUser; // host is always unknown
+ d->iSampleRate = 8000;
+
+ if(!dcc_kvs_parse_default_parameters(d,c))return false;
+
+ if(KviKvsVariant * pSR = c->switches()->find('h',"sample-rate"))
+ {
+ kvs_int_t iSR;
+ if(!pSR->asInteger(iSR))
+ {
+ c->warning(__tr2qs_ctx("Invalid sample rate specified, defaulting to 8000","dcc"));
+ d->iSampleRate = 8000;
+ } else {
+ d->iSampleRate = iSR;
+ }
+ }
+
+ d->szCodec = "adpcm";
+
+ if(KviKvsVariant * pCodec = c->switches()->find('g',"codec"))
+ {
+ QString szCodec;
+ pCodec->asString(szCodec);
+
+ if(!kvi_dcc_voice_is_valid_codec(szCodec))
+ {
+ c->warning(__tr2qs_ctx("Invalid codec specified, defaulting to 'adpcm'","dcc"));
+ d->szCodec = "adpcm";
+ }
+ }
+
+ dcc_module_set_dcc_type(d,"VOICE");
+ if(c->switches()->find('c',"connect"))
+ {
+ if(!(c->switches()->find('i',"ip") && c->switches()->find('p',"port")))
+ {
+ delete d;
+ c->error(__tr2qs_ctx("-c requires -i and -p","dcc"));
+ return false;
+ }
+ d->szIp = d->szListenIp;
+ d->szPort = d->szListenPort;
+ d->szListenIp = ""; // useless
+ d->szListenPort = ""; // useless
+ d->bActive = true;
+
+ d->triggerCreationEvent();
+ g_pDccBroker->activeVoiceExecute(0,d);
+ } else {
+ d->szIp = __tr2qs_ctx("unknown","dcc");
+ d->szPort = d->szIp;
+ d->bActive = false;
+ d->bSendRequest = !(c->switches()->find('n',"no-ctcp"));
+
+ d->triggerCreationEvent();
+ g_pDccBroker->passiveVoiceExecute(d);
+ }
+
+ return true;
+}
+
+
+
+
+/*
+static bool dcc_module_cmd_canvas(KviModule *m,KviCommand *c)
+{
+ ENTER_STACK_FRAME(c,"dcc_module_cmd_canvas");
+
+ KviStr target;
+ if(!g_pUserParser->parseCmdFinalPart(c,target))return false;
+
+ if(target.isEmpty())return c->error(KviError_notEnoughParameters,"%s",__tr_ctx("Missing target nickname","dcc"));
+
+ KviDccDescriptor * d = new KviDccDescriptor(c->window()->console());
+
+ d->szNick = target.ptr(); // we always specify the nickname
+ d->szUser = __tr2qs_ctx("unknown","dcc"); // username is always unknown
+ d->szHost = d->szUser; // host is always unknown
+*/
+/*
+ d->bIsTdcc = c->hasSwitch('t');
+
+ d->bOverrideMinimize = c->hasSwitch('m');
+
+ if(d->bOverrideMinimize)
+ {
+ KviStr tmpVal;
+ if(!(c->getSwitchValue('m',tmpVal)))d->bShowMinimized = false;
+ else d->bShowMinimized = kvi_strEqualCI(tmpVal.ptr(),"1");
+ }
+
+
+ if(!d->console())
+ {
+ // We don't need a console with -c and -n , otherwise we need it
+ if(!(c->hasSwitch('c') || c->hasSwitch('n')))return c->noIrcContext();
+ else d->console() = c->window()->frame()->firstConsole();
+ }
+
+ __range_valid(d->console());
+
+ if(!d->console()->isConnected())
+ {
+ // We don't need a connection with -c and -n , otherwise we need it
+ if(!(c->hasSwitch('c') || c->hasSwitch('n')))return c->notConnectedToServer();
+ else {
+ // -c or -n , grab a local nick from somewhere
+ d->szLocalNick = KVI_OPTION_STRING(KviOption_stringNickname1);
+ d->szLocalNick.stripWhiteSpace();
+ if(d->szLocalNick.isEmpty())d->szLocalNick = KVI_DEFAULT_NICKNAME1;
+ d->szLocalUser = __tr("unknown"); // we can live without it
+ d->szLocalHost = d->szLocalUser; // we can live without it
+ }
+ } else {
+ // We know everything
+ d->szLocalNick = d->console()->currentNickName();
+ d->szLocalUser = d->console()->currentUserName();
+ d->szLocalHost = d->console()->currentLocalHostName();
+ }
+
+
+ if(c->hasSwitch('i'))
+ {
+ c->getSwitchValue('i',d->szListenIp);
+ if(!(d->szListenIp.contains('.') || d->szListenIp.contains(':')))
+ {
+ // This will magically work with the same buffer as source and dst!
+ if(!kvi_getInterfaceAddress(d->szListenIp.ptr(),d->szListenIp))
+ {
+ return c->error(KviError_invalidParameter,__tr("Can't get address of interface %s"),d->szListenIp.ptr());
+ }
+ }
+ } else {
+ if(d->console()->isConnected())
+ {
+ d->console()->socket()->getLocalHostIp(d->szListenIp,d->console()->isIpV6Connection());
+ } else d->szListenIp = "127.0.0.1"; // huh ? :)
+ }
+
+ if(c->hasSwitch('p'))c->getSwitchValue('p',d->szListenPort);
+ else d->szListenPort = "0"; // any port is ok
+
+ if(c->hasSwitch('a'))c->getSwitchValue('a',d->szFakeIp);
+
+ if(c->hasSwitch('f'))c->getSwitchValue('f',d->szFakePort);
+
+ d->bDoTimeout = (!c->hasSwitch('u'));
+
+*/
+/*
+ if(!dcc_module_parse_default_parameters(d,c))return false;
+ dcc_module_set_dcc_type(d,"VOICE");
+
+ if(c->hasSwitch('c'))
+ {
+ if(!(c->hasSwitch('i') && c->hasSwitch('p')))
+ {
+ delete d;
+ return c->error(KviError_notEnoughParameters,__tr_ctx("-c requires -i and -p","dcc"));
+ }
+ d->szIp = d->szListenIp;
+ d->szPort = d->szListenPort;
+ d->szListenIp = ""; // useless
+ d->szListenPort = ""; // useless
+ d->bActive = true;
+
+ d->triggerCreationEvent();
+ g_pDccBroker->activeCanvasExecute(0,d);
+ } else {
+ d->szIp = __tr2qs_ctx("unknown","dcc");
+ d->szPort = d->szIp;
+ d->bActive = false;
+ d->bSendRequest = !c->hasSwitch('n');
+
+ d->triggerCreationEvent();
+ g_pDccBroker->passiveCanvasExecute(d);
+ }
+
+ return c->leaveStackFrame();
+}
+*/
+
+
+
+
+
+/*
+ @doc: dcc_connection
+ @type:
+ generic
+ @title:
+ DCC negotiation and connection
+ @short:
+ Overview of the DCC internals
+ @keyterms:
+ DCC without IRC
+ @body:
+ [big]What is DCC?[/big][br]
+ 'DCC' stands for Direct Client Connection, it is used to exchange data
+ directly between two IRC clients (with no IRC server in the middle).[br]
+ DCC itself is not a well-defined protocol, but rather a set of
+ subprotocols with (more or less) standardized rules.[br]
+ Sub-protocols are also (historically) called [b]"DCC types"[/b]; this term often
+ leads to confusion and it will become clear later.[br]
+ Each subprotocol has two main parts: The [b]DCC negotiation[/b] and the [b]DCC transfer[/b].[br]
+ The [b]DCC negotiation[/b] part is used to request the [b]DCC transfer[/b] and define its necessary parameters,[br]
+ while the [b]DCC transfer[/b] part is the real data transfer between clients.[br]
+ The [b]DCC negotiation[/b] requires a third entity that routes the negotiation data between clients,
+ this is usually an IRC server.[br]
+ [br]
+ [big]DCC Negotiation[/big][br]
+ This part of the protocol is the most tricky and difficult one, and is different for almost every DCC subprotocol.[br]
+ The "constant" scenario of the negotiation is more or less the following:[br]
+ There are two IRC clients connected to the same IRC network and they want to exchange some data in
+ a direct client connection.[br]
+ Each client knows the other by nickname only (and eventually by the host displayed by the IRC server,
+ but this cannot be trusted for several reasons), and can send text messages to each other by using the
+ IRC network as data channel.[br]
+ To initiate a direct client connection, one of the clients must start listening on some port (this is called [b]passive client[/b])
+ and the other must connect to that port on the first client's machine (this is the [b]active client[/b]).[br]
+ Both clients must agree on who is the passive and who is the active client. The active client must also
+ know the passive client's IP address and port (in order to be able to contact it).[br]
+ Finally, both clients must agree on the transfer type that has to be initiated.[br]
+ The negotiation exchanges these informations between clients by using IRC as channel and CTCP messages
+ as encoding method.[br]
+ An example will make things clearer:[br]
+ DCC Chat is the simplest (and most widely implemented) DCC subprotocol:
+ it is used to exchange <cr><lf> separated text data between clients.[br]
+ Assume that you want to establish a DCC Chat
+ connection to 'Sarah' that is actually connected to your IRC network (so
+ she/he is an IRC user just like you).
+ All you have to do is type sth as "/dcc chat Sarah" in your IRC client.
+ The client will setup a listening socket on a random port choosen
+ usually by the kernel of your OS. In this case YOU are the [b]passive client[/b], and Sarah is the active one.[br]
+ Once the socket is ready to accept connections,
+ your client will send a [doc:ctcp_handling]CTCP message[/doc] to Sarah using the IRC connection (and protocol) as channel:[br]
+ PRIVMSG Sarah :<0x01>DCC CHAT chat <ip_address> <port><0x01>[br]
+ where <ip_address> is the address of the listening socket and <port>
+ is the port that it has been bound to (these informations are obtained
+ after the socket has been setup). Once Sarah has received the CTCP message,
+ and agreed to connect, her (active) client will attempt to connect to the
+ specified <ip_address> and <port> (eg. to your listening socket).[br]
+ Once the connection has been established, it continues using the
+ specific CHAT transfer protocol.[br]
+ Some IRC clients allow modifications of this procedure:[br]
+ First of all, the port to listen on can be specified by the user
+ and not by the kernel; this is useful when the passive client
+ is behind a firewall that "shades" some sets of ports.
+ The ip address for the listening socket
+ can be specified by the user as well (especially when the machine has more than one network interface).[br]
+ A more challenging trick is to listen on a specified ip address and port
+ and notify different ones to the remote user (eg, <ip_address> and <port>
+ parameters of the CTCP message are not the ones that the client is listening on).
+ This is especially useful with "transparent proxy" firewalls that
+ often are not transparent enough to allow the DCC connections.
+ (If you have one of these firewalls you know what I'm talking about,
+ otherwise just read on). KVIrc allows to avoid the usage of a third entity
+ for the protocol negotiation too.
+ You can setup a listening socket on a specified port and ip address
+ without notyfying anyone of this.
+ You can also manually connect to a specified port and ip address without
+ having been notified of a DCC request.[br][br][br]
+ Is everything clear ?...I don't think so... my English is really too bad...
+ [br]
+ [big]DCC Transfer[/big][br]
+ The DCC transfer part is different for every DCC subprotocol, but
+ it always happens over a direct client to client TCP connection.[br]
+ [br]
+ [big]DCC Subprotocols[/big][br]
+ There are two main standardized DCC subprotocols that are widely implemented in IRC clients:
+ [b]DCC Chat[/b] and [b]DCC Send[/b].[br]
+ DCC Chat is quite simple and the protocol is more or less completely defined.[br]
+ DCC Send is a *real mess*, the original definition was not very flexible
+ so many IRC clients tried to enchance both the negotiation and the transfer, leading
+ often to incompatible implementations. (I can remember the Turbo File Transfer implemented
+ by VIrc, the Send-Ahead enchancement implemented in many clients, the RESUME facility...)[br]
+ Many clients introduced new DCC subprotocols with non-standard implementations,
+ leading again to client incompatibility.[br]
+ Some of the notable subprotocols are DCC Voice, DCC Draw, DCC Whiteboard...[br]
+ [br]
+ [big]DCC Chat[/big][br]
+ This is the simplest and most standardized DCC subprotocol. Almost every IRC client implements it.[br]
+ It is used to exchange lines of text between the two clients.[br]
+ The negotiation is quite simple, we assume that Client A wants to establish a DCC Chat connection to Client B.
+ Client A sets up a listening socket and retrieves its adress (ip address and port).[br]
+ Once the socket is ready Client A sends a CTCP request to B, in the following form:[br]
+ [b]DCC CHAT chat <ipaddress> <port>[/b][br]
+ Where <ipaddress> is a string representing an positive integer that is the A socket's IP address
+ in network byte order, and where <port> is a string representing an positive integer that is the
+ A socket's port.[br]
+ The original purpose of the second "chat" string in the CTCP request is quite obscure, it was probably
+ introduced to have the <ipaddress> as second parameter, as in the DCC Send subprotocol.[br]
+ Client B receives the CTCP, parses it, eventually asks the user for permission and connects
+ to the specified ip address and port.
+ The transfer protocol is quite simple, both clients can send text lines separated by <cr><lf> pairs.[br]
+ Some clients use only <lf> as line terminator so the general idea is that one of <cr> <cr><lf> or <lf>
+ can be used as line terminator.[br]
+ As extension to the protocol, KVIrc allows <ipaddress> to be an IPv6 address in the standard hexadecimal
+ notation, the connection will be made over the IPv6 protocol in this case (obviously if both clients
+ support this feature).[br]
+ (It is not clear why the original DCC specification used the unsigned int format instead of a
+ standard string representation of the IP address... missing inet_aton() function on the target system?).[br]
+ KVIrc adds the Secure Sockets Layer to the DCC Chat protocol. In this case the negotiation string becomes:[br]
+ [b]DCC SCHAT chat <ipaddress> <port>[/b][br]
+ where "SCHAT" stands for Secure CHAT.[br] The external protocol is exactly the same but is built on top of a Secure Sockets Layer
+ implementation (specifically OpenSSL). The connection will be encrypted with a private key algorithm after
+ a public key handshake.[br]
+ [br]
+ [big]DCC Send[/big][br]
+ DCC Send is another standard subprotocol. Most clients implement this as well, many have tried
+ to enchance it.[br]
+ The basic DCC Send protocol allows transferring a file from the requesting client to the receiving client.[br]
+ The requesting client (the one that sends the file) is always passive and the receiving client is always active.[br]
+ This is a huge protocol limitation since firewalled clients are often unable to accept incoming connections.[br]
+ The negotiation protocol is more complex than DCC Chat; we assume that Client A wants to send the file F to Client B.[br]
+ Client A sets up a listening socket and retrieves its ip address and port.[br]
+ Client A sends a CTCP request to Client B in the following form:[br]
+ [b]DCC SEND <filename> <ipaddress> <port> <filesize>[/b][br]
+ <ipaddress> and <port> have the same semantics as in the DCC Chat subprotocol.[br]
+ <filename> is the name (without path!) of the file to be sent, and <filesize> is (yeah), the file size.[br]
+ Client B receives the CTCP, parses it, eventually asks the user for confirmation and connects to the
+ specified ip address and port; the transfer then begins.[br]
+ Client A sends blocks of data (usually 1-2 KB) and at every block awaits confirmation from the Client B,
+ that when receiving a block should reply 4 bytes containing an positive number specifying the total size
+ of the file received up to that moment.[br]
+ The transmission closes when the last acknowledge is received by Client A.[br]
+ The acknowledges were meant to include some sort of coherency check in the transmission, but in fact
+ no client can "recover" from an acknowledge error/desync, all of them just close the connection declaring the
+ transfer as failed (the situation is even worse in fact, often acknowledge errors aren't even detected!).[br]
+ Since the packet-acknowledge round trip eats a lot of time, many clients included
+ the "send-ahead" feature; the Client A does NOT wait for the acknowledge of the first packet before sending the second one.[br]
+ The acknowledges are still sent, but just a reverse independent stream.[br] This makes the DCC Send considerably faster.[br]
+ Since the acknowledge stream has non-zero bandwidth usage, no client can recover from an acknowledge error and
+ having them as an independant stream is more or less like having no acknowledges, the "Turbo" ( :) ) extension has been added:
+ Client B will send no acknowledges and will just close the connection when he has received all the expected data.[br]
+ This makes the DCC Send as fast as FTP transfers.[br]
+ The "Turbo" extension is specified during the negotiation phase, bu using TSEND as DCC message type (instead of SEND).[br]
+ The "Turbo" extension is not widely implemented.[br]
+ Later implementations have added the support for resuming interrupted DCC Send transfers:[br]
+ Client A sets up the socket and sends the CTCP request as before.[br]
+ If Client B discovers that the file has been partially received in a previous DCC Send session it sends
+ a resume request in the following form:[br]
+ [b]DCC RESUME <filename> <port> <resume position>[/b][br]
+ Where <port> is the <port> sent in the DCC SEND request and <resume position> is the position in the file
+ from where the transfer should start.[br]
+ Cilent A receives the request, parses it and eventually replies with:[br]
+ [b]DCC ACCEPT <filename> <port> <resume position>[/b][br]
+ Client B receives the ACCEPT message, connects to Client A and the transfer initiates as before.[br]
+ The "Send-ahead" and "Turbo" extensions can obviously be used also in this case (But 'T' is NOT prepended to the RESUME and ACCEPT messages).[br]
+ The IPv6 extension can be used also in this subprotocol, so <ipaddress> can be also an IPv6 address in hexadecimal notation.[br]
+ KVIrc introduces the SSL extension also to DCC Send. The protocol remains the same again but it is built on top of
+ a Secure Sockets Layer implementation just like DCC Chat.[br]
+ With SSL the negotiation string becomes:[br]
+ [b]DCC SSEND <filename> <ipaddress> <port> <filesize>[/b][br]
+ where "SSEND" stands for Secure SEND.[br]
+ The "turbo" extension can be combined with the SSL extension too. In this case the second parameter
+ of the negotiation string must be "TSSEND" or "STSEND".[br]
+ [br]
+ [big]DCC Recv[/big][br]
+ DCC Recv is the counterpart of DCC Send. This is a KVIrc extension and is not standard yet.[br]
+ The purpose of this subprotocol will not be immediately clear, but read on for an explanation.[br]
+ It is used to request a file from another client; we assume that Client A knows that Client B has
+ a specific file and is able/wants to send it.[br]
+ Client A sets up a listening socket, retrieves its address and port and then
+ sends a CTCP request to Client B in the following form:[br]
+ [b]DCC RECV <filename> <ipaddress> <port> <resume position>[/b][br]
+ where <filename> is the name of the requested file without path, <ipaddress> and <port> have the usual meaning and <resume position>
+ is the position from that the transfer should start from.[br]
+ <ipaddress> can be an IPv6 address as well.[br]
+ Client B receives the CTCP message, parses it, looks for the file to send (in some unspecified way)
+ and connects to the specified ip address and port. The transfer then begins just as in the DCC send, but in the inverse way:
+ Client B sends blocks of data to Client A and Client B sends back acknowledges.[br]
+ This subprotocol is useful in transferring data from clients that are behind a firewall and are not able to accept
+ incoming connections (this is not possible with a normal DCC Send). In this case the client that receives
+ the file is passive and the client that sends it is active (as opposite to DCC Send).[br]
+ The "Send ahead" extension can be used also in this case and the "Turbo" extension is activated by prepending a 'T' to the
+ DCC message, "TRECV" instead of "RECV". The SSL extension is activated by prepending an 'S' to the
+ DCC message, "SRECV", "STRECV" or "TSRECV".[br]
+ This subprotocol has an implicit resume capability and thus has no need for RESUME and ACCEPT messages.[br]
+ DCC Recv requires the initiating (passive) client to know that the file to be transferred is avaiable on the B's side
+ and probably also know the file size. This subprotocol does not specify how this information is obtained, but it
+ will become clear soon that it can be obtained either manually (User B can simply tell the info to User A),
+ or automatically (as in the DCC Rsend subprotocol (keep reading)).[br]
+ [br]
+ [big]DCC RSend[/big][br]
+ DCC RSend stands for Reverse Send. This is a KVIrc extension to the SEND protocol to allow firewalled clients
+ to send files.[br] In fact, this is a "half" subprotocol, since it defines only a part of the DCC negotiation;
+ the transfer is defined by another subprotocol (and specifically bu DCC Recv).[br]
+ The requesting client (the one that sends the file) is active and the receiving client is passive.[br]
+ Assume that Client A wants to send a file to Client B and that Client A cannot accept incoming connections.[br]
+ Client A sends a CTCP request to Client B in the following form:[br]
+ [b]DCC RSEND <filename> <filesize>[/b][br]
+ Client B receives the request, parses it, eventually asks the user for confirmation, sets up a listening socket, retrieves
+ its ip address and port and switches to the DCC Recv subprotocol by effectively sending the following CTCP message:[br]
+ [b]DCC RECV <filename> <ipaddress> <port> <resume position>[/b][br]
+ The rest of the transfer is defined by the DCC Recv subprotocol.[br]
+ The "Turbo" extension is again activated by prepending a 'T' to the RSEND string, so the initial CTCP will become:[br]
+ [b]DCC TRSEND <filename> <filesize>[/b][br]
+ The "SSL" extension is also activated by prepending an 'S' to the RSEND string. It can be again combined
+ with the "turbo" extension. The negotiation parameter becomes then "SRSEND","TSRSEND" or "STRSEND".[br]
+ Easy, no ? :)[br]
+ [br]
+ [big]DCC Get[/big][br]
+ This is again a "half" subprotocol in fact since it defines only a part of the negotiation for file transfers.[br]
+ It is also NON standard, since actually no client except KVIrc implements it (AFAIK).[br]
+ DCC Get is used to request a file from a remote client. Assume that Client A wants to request a file from Client B
+ (and assume that Client A knows that B has that file and wants to send it).[br]
+ Client A sends a CTCP message to Client B in the following form:[br]
+ [b]DCC GET <filename>[/b][br]
+ Where <filename> is a name of a file without path.[br]
+ Client B receives the message, parses it, looks for an association of the <filename> to a real filesystem file
+ and starts one of the two DCC File transfer subprotocols, DCC Send or DCC RSend.[br]
+ Client B should prefer the DCC Send method and choose DCC RSend only if it is not able to accept incoming connections.[br]
+ This subprotocol can be used by firewalled clients that can't accept connections but still want to request a file
+ from another client, this one can fail only if both clients are firewalled (in this case no DCC transfer is possible at all).[br]
+ This subprotocol also does not need to "magically" know the file size, the size definition
+ is found in the subprotocol that the remote client will choose.[br]
+ The association of <filename> with a real file on the B's machine is not explicitly defined by the subprotocol;
+ KVIrc uses an internal "file-offer" table with a list of files that are available for download.[br]
+ The "turbo" and "SSL" extensions are activated as usual, "TGET", "SGET", "TSGET" and "STGET" are supported.[br]
+ [br]
+ [big]DCC File Transfer[/big][br]
+ DCC Send: Send a file, sender is passive, receiver is active (not good for firewalled senders)[br]
+ DCC Recv: Receive a file, sender is active, receiver is passive (not good for firewalled receivers)[br]
+ DCC RSend: Send a file, sender is active, receiver is passive (not good for firewalled receivers)[br]
+ DCC Get: Receive a file, sender is passive if not firewalled, receiver active if sender not firewalled (will fail only if both are firewalled)[br]
+ The "turbo" extension disables the stream of acknowledges and is activated by prepending the 'T' character to the DCC subprotocol name[br]
+ The "SSL" extension causes a Secure Socket Layer to be used and is activated by prepending the 'S' character to the DCC subprotocol name[br]
+ [br]
+ [big]DCC Voice[/big][br]
+ DCC Voice is a KVIrc extension (there is a Windows client called VIrc that implements such
+ a protocol, but it is incompatible with KVIrc).[br]
+ DCC Voice allows audio level communication between two clients, the audio stream is compressed
+ with a specified codec.[br]
+ KVIrc currently supports the ADPCM (core support) and the GSM codec (if the libgsm is available on the target system).[br]
+ [b]TODO: Finish the DCC Voice doc :)[/b]
+ [big]More tricks[/big][br]
+ KVIrc supports another "hack" to the DCC negotiation, it recognizes "XDCC" as
+ a DCC negotiation CTCP parameter.[br]
+ This can be used to circumvent limitations of some IRC clients (read mIRC) that will not allow
+ you to send a /DCC GET since it is an unrecognized DCC type.[br]
+ "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)
+{
+ KviDccDescriptor * dcc = 0;
+ if(uId == 0)
+ {
+ if(c->window()->inherits("KviDccWindow"))
+ {
+ dcc = ((KviDccWindow *)(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);
+ if((!dcc) && bWarn)
+ c->warning(__tr2qs_ctx("The specified parameter is not a valid DCC identifier","dcc"));
+ return dcc;
+}
+
+
+/*
+ @doc: dcc.abort
+ @type:
+ command
+ @title:
+ dcc.abort
+ @short:
+ Aborts a dcc session
+ @syntax:
+ dcc.abort [-q] [dcc_id:uint]
+ @description:
+ Terminates the Direct Client Connection specified by <dcc_id>.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function doesn't abort anything and prints a warning unless the -q switch is used.[br]
+ If <dcc_id> refers to a file transfer then it the transfer is simply
+ terminated. If <dcc_id> refers to a dcc chat then the result
+ is equivalent to closing the related window.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+ @examples:
+*/
+
+static bool dcc_kvs_cmd_abort(KviKvsModuleCommandCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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"));
+
+ if(dcc)
+ {
+ if(dcc->transfer())dcc->transfer()->abort();
+ else if(dcc->window())dcc->window()->close();
+ }
+
+ return true;
+}
+
+/*
+ @doc: dcc.setBandwidthLimit
+ @type:
+ command
+ @title:
+ dcc.setBandwidthLimit
+ @short:
+ Set the bandwidthlimit of a dcc.send session.
+ @syntax:
+ dcc.setBandwidthLimit [-q] [dcc_id:uint]
+ @description:
+ Terminates the Direct Client Connection specified by <dcc_id>.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning unless the -q switch is used.[br]
+ If <dcc_id> does not refers to a file transfer a warning will be printing unless the -q switch is used.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+ @examples:
+*/
+static bool dcc_kvs_cmd_setBandwidthLimit(KviKvsModuleCommandCall * c)
+{
+ kvs_uint_t uDccId,uVal;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("limit_value",KVS_PT_UINT,0,uVal)
+ 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"));
+ if(dcc)
+ {
+ if (dcc->transfer())dcc->transfer()->setBandwidthLimit(uVal);
+ else if (!c->switches()->find('q',"quiet"))c->warning(__tr2qs_ctx("This DCC session is not a DCC transfer session","dcc"));
+ }
+ return true;
+}
+
+/*
+ @doc: dcc.protocol
+ @type:
+ function
+ @title:
+ $dcc.protocol
+ @short:
+ Returns the protocol of the specified DCC
+ @syntax:
+ <string> $dcc.protocol
+ <string> $dcc.protocol(<dcc_id:uint>)
+ @description:
+ Returns the string describing the protocol of the
+ Direct Client Connection specified by <dcc_id>.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_protocol(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->protocol());
+ return true;
+}
+
+
+/*
+ @doc: dcc.connectionType
+ @type:
+ function
+ @title:
+ $dcc.connectionType
+ @short:
+ Returns the connection type of the specified DCC
+ @syntax:
+ <string> $dcc.connectionType
+ <string> $dcc.connectionType(<dcc_id:uint>)
+ @description:
+ Returns the connection type of the specified DCC.[br]
+ Returns the string "ACTIVE" for active DCC connections
+ and the string "PASSIVE" for passive DCC connections.
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_connectionType(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->isActive() ? "ACTIVE" : "PASSIVE");
+ return true;
+}
+
+
+/*
+ @doc: dcc.isFileTransfer
+ @type:
+ function
+ @title:
+ $dcc.isFileTransfer
+ @short:
+ Checks if a DCC is a file transfer
+ @syntax:
+ <boolean> $dcc.isFileTransfer
+ <boolean> $dcc.isFileTransfer(<dcc_id:uint>)
+ @description:
+ Returns 1 if the specified Direct Client Connection
+ is a file transfer and 0 otherwise.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this and returns 0.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_isFileTransfer(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setBoolean(dcc->isFileTransfer());
+ return true;
+}
+
+
+/*
+ @doc: dcc.isFileUpload
+ @type:
+ function
+ @title:
+ $dcc.isFileUpload
+ @short:
+ Checks if a DCC is an upload file transfer
+ @syntax:
+ <boolean> $dcc.isFileUpload
+ <boolean> $dcc.isFileUpload(<dcc_id:uint>)
+ @description:
+ Returns 1 if the specified Direct Client Connection
+ is an upload file transfer and 0 otherwise.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns 0.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_isFileUpload(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setBoolean(dcc->isFileUpload());
+ return true;
+}
+
+
+/*
+ @doc: dcc.isFileDownload
+ @type:
+ function
+ @title:
+ $dcc.isFileDownload
+ @short:
+ Checks if a DCC is a download file transfer
+ @syntax:
+ <boolean> $dcc.isFileDownload
+ <boolean> $dcc.isFileDownload(<dcc_id:uint>)
+ @description:
+ Returns 1 if the specified Direct Client Connection
+ is a download file transfer and 0 otherwise.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns 0.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_isFileDownload(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setBoolean(dcc->isFileDownload());
+ return true;
+}
+
+
+/*
+ @doc: dcc.localNick
+ @type:
+ function
+ @title:
+ $dcc.localNick
+ @short:
+ Returns the local nickname associated to the specified DCC
+ @syntax:
+ <string> $dcc.localNick
+ <string> $dcc.localNick(<dcc_id:uint>)
+ @description:
+ Returns the local nickname associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_localNick(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->localNick());
+ return true;
+}
+
+
+/*
+ @doc: dcc.localUser
+ @type:
+ function
+ @title:
+ $dcc.localUser
+ @short:
+ Returns the local username associated to the specified DCC
+ @syntax:
+ <string> $dcc.localUser
+ <string> $dcc.localUser(<dcc_id:uint>)
+ @description:
+ Returns the local username associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_localUser(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->localUser());
+ return true;
+}
+
+/*
+ @doc: dcc.localHost
+ @type:
+ function
+ @title:
+ $dcc.localHost
+ @short:
+ Returns the local hostname associated to the specified DCC
+ @syntax:
+ <string> $dcc.localHost
+ <string> $dcc.localHost(<dcc_id:uint>)
+ @description:
+ Returns the local hostname associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_localHost(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->localHost());
+ return true;
+}
+
+
+/*
+ @doc: dcc.localIp
+ @type:
+ function
+ @title:
+ $dcc.localIp
+ @short:
+ Returns the local ip address associated to the specified DCC
+ @syntax:
+ <string> $dcc.localIp
+ <string> $dcc.localIp(<dcc_id:uint>)
+ @description:
+ Returns the local ip address associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_localIp(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->localIp());
+ return true;
+}
+
+
+/*
+ @doc: dcc.localPort
+ @type:
+ function
+ @title:
+ $dcc.localPort
+ @short:
+ Returns the local port associated to the specified DCC
+ @syntax:
+ <integer> $dcc.localPort
+ <integer> $dcc.localPort(<dcc_id:uint>)
+ @description:
+ Returns the local port associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_localPort(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->localPort());
+ return true;
+}
+
+
+/*
+ @doc: dcc.localFileName
+ @type:
+ function
+ @title:
+ $dcc.localFileName
+ @short:
+ Returns the local file name associated to the specified DCC
+ @syntax:
+ <string> $dcc.localFileName(<dcc_id:uint>)
+ @description:
+ Returns the local file name associated to the specified DCC.[br]
+ If <dcc_id> does not identify a file transfer DCC then this
+ function returns an empty string.
+ If <dcc_id> is not a valid Direct Client Connection identifier
+ then this function prints a warning and returns an empty string.
+*/
+
+static bool dcc_kvs_fnc_localFileName(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->localFileName());
+ return true;
+}
+
+
+/*
+ @doc: dcc.localFileSize
+ @type:
+ function
+ @title:
+ $dcc.localFileSize
+ @short:
+ Returns the local file size associated to the specified DCC
+ @syntax:
+ <integer> $dcc.localFileSize(<dcc_id:uint>)
+ @description:
+ Returns the local file size associated to the specified DCC.[br]
+ If <dcc_id> does not identify a file transfer DCC then this
+ function returns '0'[br]
+ If <dcc_id> is not a valid Direct Client Connection identifier
+ then this function prints a warning and returns '0'[br]
+ In upload transfers the local file size rappresents the
+ total size of the file to be transferred. In download transfers
+ the local file size is non zero only if the transfer has to resume
+ a file already existing on the local disk and it rappresents the
+ size of that file (and thus the offset that the transfer started on).
+*/
+
+static bool dcc_kvs_fnc_localFileSize(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->localFileSize().isEmpty() ? QString("0") : dcc->localFileSize());
+ return true;
+}
+
+
+/*
+ @doc: dcc.remoteNick
+ @type:
+ function
+ @title:
+ $dcc.remoteNick
+ @short:
+ Returns the remote nickname associated to the specified DCC
+ @syntax:
+ <string> $dcc.remoteNick
+ <string> $dcc.remoteNick(<dcc_id:uint>)
+ @description:
+ Returns the remote nickname associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_remoteNick(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->remoteNick());
+ return true;
+}
+
+
+/*
+ @doc: dcc.remoteUser
+ @type:
+ function
+ @title:
+ $dcc.remoteUser
+ @short:
+ Returns the remote username associated to the specified DCC
+ @syntax:
+ <string> $dcc.remoteUser
+ <string> $dcc.remoteUser(<dcc_id:uint>)
+ @description:
+ Returns the remote username associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_remoteUser(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->remoteUser());
+ return true;
+}
+
+/*
+ @doc: dcc.remoteHost
+ @type:
+ function
+ @title:
+ $dcc.remoteHost
+ @short:
+ Returns the remote hostname associated to the specified DCC
+ @syntax:
+ <string> $dcc.remoteHost
+ <string> $dcc.remoteHost(<dcc_id:uint>)
+ @description:
+ Returns the remote hostname associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_remoteHost(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->remoteHost());
+ return true;
+}
+
+/*
+ @doc: dcc.remoteIp
+ @type:
+ function
+ @title:
+ $dcc.remoteIp
+ @short:
+ Returns the remote ip address associated to the specified DCC
+ @syntax:
+ <string> $dcc.remoteIp
+ <string> $dcc.remoteIp(<dcc_id:uint>)
+ @description:
+ Returns the remote ip address associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_remoteIp(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->remoteIp());
+ return true;
+}
+
+
+/*
+ @doc: dcc.remotePort
+ @type:
+ function
+ @title:
+ $dcc.remotePort
+ @short:
+ Returns the remote port associated to the specified DCC
+ @syntax:
+ <integer> $dcc.remotePort
+ <integer> $dcc.remotePort(<dcc_id:uint>)
+ @description:
+ Returns the remote port associated to the specified DCC.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_remotePort(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->remotePort());
+ return true;
+}
+
+
+/*
+ @doc: dcc.remoteFileName
+ @type:
+ function
+ @title:
+ $dcc.remoteFileName
+ @short:
+ Returns the remote file name associated to the specified DCC
+ @syntax:
+ <string> $dcc.remoteFileName(<dcc_id:uint>)
+ @description:
+ Returns the remote file name associated to the specified DCC.[br]
+ If <dcc_id> does not identify a file transfer DCC then this
+ function returns an empty string.
+ If <dcc_id> is not a valid Direct Client Connection identifier
+ then this function prints a warning and returns an empty string.
+*/
+
+static bool dcc_kvs_fnc_remoteFileName(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->remoteFileName());
+ return true;
+}
+
+
+/*
+ @doc: dcc.remoteFileSize
+ @type:
+ function
+ @title:
+ $dcc.remoteFileSize
+ @short:
+ Returns the remote file size associated to the specified DCC
+ @syntax:
+ <integer> $dcc.remoteFileSize(<dcc_id:uint>)
+ @description:
+ Returns the remote file size associated to the specified DCC.[br]
+ If <dcc_id> does not identify a file transfer DCC then this
+ function returns '0'[br]
+ If <dcc_id> is not a valid Direct Client Connection identifier
+ then this function prints a warning and returns '0'[br]
+ In download transfers the remote file size rappresents the
+ total size of the file to be transferred (advertished by the remote end).[br]
+ In upload transfers the remote file size is non zero only if the
+ remote user has issued a resume request and is rappresents the requested offset
+ in bytes from which the transfer has started.
+*/
+
+static bool dcc_kvs_fnc_remoteFileSize(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setString(dcc->remoteFileSize().isEmpty() ? QString("0") : dcc->remoteFileSize());
+ return true;
+}
+
+
+/*
+ @doc: dcc.ircContext
+ @type:
+ function
+ @title:
+ $dcc.ircContext
+ @short:
+ Returns the ircContext from which this DCC has originated
+ @syntax:
+ <integer> $dcc.ircContext
+ <integer> $dcc.ircContext(<dcc_id:uint>)
+ @description:
+ Returns the identifier of the irc context from which
+ the specified DCC has been originated.[br]
+ When the DCC is not originated from an IRC context
+ then this function returns '0' : an invalid irc context id.
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns 0.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_ircContext(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)c->returnValue()->setInteger(dcc->console()->context()->id());
+ return true;
+}
+
+
+
+/*
+ @doc: dcc.transferStatus
+ @type:
+ function
+ @title:
+ $dcc.transferStatus
+ @short:
+ Returns the current status of a dcc file transfer
+ @syntax:
+ <string> $dcc.transferStatus
+ <string> $dcc.transferStatus(<dcc_id:uint>)
+ @description:
+ Returns the status in the specified DCC session.[br]
+ The status is one of the strings "connecting", "transferring", "success" and "failure".
+ "success" and "failure" are reported when the transfer is terminated.
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ If the DCC session does not refer to a file transfer then
+ this function returns "".[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_transferStatus(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)
+ {
+ if(dcc->transfer())
+ {
+ QString tmp;
+ dcc->transfer()->fillStatusString(tmp);
+ c->returnValue()->setString(tmp);
+ }
+ }
+ return true;
+}
+
+
+/*
+ @doc: dcc.transferredBytes
+ @type:
+ function
+ @title:
+ $dcc.transferredBytes
+ @short:
+ Returns the number of transferred bytes in a dcc file transfer
+ @syntax:
+ <integer> $dcc.transferredBytes
+ <integer> $dcc.transferredBytes(<dcc_id:uint>)
+ @description:
+ Returns the number of transferred bytes in the specified DCC session.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ If the DCC session does not refer to a file transfer then
+ this function returns 0.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_transferredBytes(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)
+ {
+ if(dcc->transfer())
+ {
+ c->returnValue()->setInteger(dcc->transfer()->transferredBytes());
+ } else {
+ c->returnValue()->setInteger(0);
+ }
+ }
+ return true;
+}
+
+
+
+/*
+ @doc: dcc.averageSpeed
+ @type:
+ function
+ @title:
+ $dcc.averageSpeed
+ @short:
+ Returns the average speed of a dcc file transfer
+ @syntax:
+ $dcc.averageSpeed
+ $dcc.averageSpeed(<dcc_id>)
+ @description:
+ Returns the average speed (in bytes/sec) of the specified DCC session.[br]
+ If <dcc_id> is omitted then the DCC Session associated
+ to the current window is assumed.[br]
+ If <dcc_id> is not a valid DCC session identifier (or it is omitted
+ and the current window has no associated DCC session) then
+ this function prints a warning and returns an empty sting.[br]
+ If the DCC session does not refer to a file transfer then
+ this function returns 0.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_averageSpeed(KviKvsModuleFunctionCall * c)
+{
+ kvs_uint_t uDccId;
+ KVSM_PARAMETERS_BEGIN(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);
+
+ if(dcc)
+ {
+ if(dcc->transfer())
+ {
+ c->returnValue()->setInteger(dcc->transfer()->averageSpeed());
+ } else {
+ c->returnValue()->setInteger(0);
+ }
+ }
+ return true;
+}
+
+
+
+/*
+ @doc: dcc.session
+ @type:
+ function
+ @title:
+ $dcc.session
+ @short:
+ Returns the DCC session identifier associated to a window
+ @syntax:
+ <uint> $dcc.session
+ <uint> $dcc.session(<window_id>)
+ @description:
+ Returns the DCC session identifier associated to the DCC window specified
+ by <window_id>. If <window_id> is omitted then the DCC session identifier
+ associated to the current window is returned. If the specified window
+ has no associated DCC session then a warning is printed and 0 is returned.[br]
+*/
+
+static bool dcc_kvs_fnc_session(KviKvsModuleFunctionCall * c)
+{
+ QString szWinId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWinId)
+ KVSM_PARAMETERS_END(c)
+
+ KviDccDescriptor * dcc = 0;
+ if(szWinId.isEmpty())
+ {
+ if(c->window()->inherits("KviDccWindow"))
+ dcc = ((KviDccWindow *)(c->window()))->descriptor();
+ if(!dcc)
+ {
+ c->warning(__tr2qs_ctx("The current window has no associated DCC session","dcc"));
+ c->returnValue()->setInteger(0);
+ } else {
+ c->returnValue()->setInteger(dcc->id());
+ }
+ return true;
+ }
+
+ KviWindow * pWnd = g_pApp->findWindow(szWinId);
+ if(!pWnd)
+ {
+ c->warning(__tr2qs_ctx("The specified window identifier is not valid","dcc"));
+ c->returnValue()->setInteger(0);
+ return true;
+ }
+
+ if(pWnd->inherits("KviDccWindow"))
+ dcc = ((KviDccWindow *)pWnd)->descriptor();
+ if(!dcc)
+ {
+ c->warning(__tr2qs_ctx("The current window has no associated DCC session","dcc"));
+ c->returnValue()->setInteger(0);
+ } else {
+ c->returnValue()->setInteger(dcc->id());
+ }
+ return true;
+}
+
+
+/*
+ @doc: dcc.sessionList
+ @type:
+ function
+ @title:
+ $dcc.sessionList
+ @short:
+ List the existing dcc session identifiers
+ @syntax:
+ <array> $dcc.sessionList
+ <array> $dcc.sessionList(<filter:string>)
+ @description:
+ The first form returns an array with all the currently existing dcc session
+ identifiers. The second form returns an array with the session types specified
+ in <filter> which may be a combination of the flags 'u' (for file upload),
+ 'd' (for file download) and 'c' (for dcc chat). To select all the file transfers
+ please use the combination 'ud'.[br]
+ See the [module:dcc]dcc module[/module] documentation for more informations.[br]
+*/
+
+static bool dcc_kvs_fnc_sessionList(KviKvsModuleFunctionCall * c)
+{
+ QString szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filter",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray * a = new KviKvsArray();
+ c->returnValue()->setArray(a);
+
+ KviPointerHashTable<int,KviDccDescriptor> * dict = KviDccDescriptor::descriptorDict();
+ if(!dict)return true;
+
+ KviPointerHashTableIterator<int,KviDccDescriptor> it(*dict);
+
+ int idx = 0;
+
+ if(szFlags.isEmpty())
+ {
+ // all
+ while(KviDccDescriptor * dcc = it.current())
+ {
+ a->set(idx++,new KviKvsVariant((kvs_int_t)(dcc->id())));
+ ++it;
+ }
+ } else {
+ bool bWantFileUploads = szFlags.find('u',false) != -1;
+ bool bWantFileDownloads = szFlags.contains('d',false) != -1;
+ bool bWantChats = szFlags.contains('c',false) != -1;
+
+ while(KviDccDescriptor * dcc = it.current())
+ {
+ if((dcc->isFileUpload() && bWantFileUploads) ||
+ (dcc->isFileDownload() && bWantFileDownloads) ||
+ (dcc->isDccChat() && bWantChats))
+ {
+ a->set(idx++,new KviKvsVariant((kvs_int_t)(dcc->id())));
+ }
+ ++it;
+ }
+ }
+
+ return true;
+}
+
+
+/*
+ @doc: dcc
+ @type:
+ module
+ @short:
+ Direct Client Connections
+ @title:
+ The DCC module
+ @body:
+ [big]Overview[/big][br]
+ The DCC module handles the Direct Client Connection
+ protocol layer and all it's sub-protocols.[br]
+ The sub-protocols include the standard CHAT
+ the standard SEND and its variants plus several
+ KVIrc extensions like RECV,RSEND,GET and VOICE.[br]
+ [br]
+ [big]Initiating a DCC negotiation[/big][br]
+ The following commands initiate a specific DCC session
+ with a remote client:[br]
+ [cmd]dcc.chat[/cmd][br]
+ [cmd]dcc.send[/cmd][br]
+ [cmd]dcc.rsend[/cmd][br]
+ [cmd]dcc.recv[/cmd][br]
+ [cmd]dcc.get[/cmd][br]
+ [cmd]dcc.voice[/cmd][br]
+ [br]
+ [big]Handling the DCC events[/big][br]
+ Each DCC session has an associated unique identifier (&lt;dcc_id&gt;).[br]
+ You can interact with the session by using several commands
+ and functions exported by this module and by passing the above session
+ id as parameter.[br]
+ The session related commands and functions are the following:[br]
+ [fnc]$dcc.sessionList[/fnc][br]
+ [fnc]$dcc.protocol[/fnc][br]
+ [fnc]$dcc.connectionType[/fnc][br]
+ [fnc]$dcc.transferStatus[/fnc][br]
+ [fnc]$dcc.isFileTransfer[/fnc][br]
+ [fnc]$dcc.isFileUpload[/fnc][br]
+ [fnc]$dcc.isFileDownload[/fnc][br]
+ [fnc]$dcc.localNick[/fnc][br]
+ [fnc]$dcc.localUser[/fnc][br]
+ [fnc]$dcc.localHost[/fnc][br]
+ [fnc]$dcc.localIp[/fnc][br]
+ [fnc]$dcc.localPort[/fnc][br]
+ [fnc]$dcc.localFileName[/fnc][br]
+ [fnc]$dcc.localFileSize[/fnc][br]
+ [fnc]$dcc.remoteNick[/fnc][br]
+ [fnc]$dcc.remoteUser[/fnc][br]
+ [fnc]$dcc.remoteHost[/fnc][br]
+ [fnc]$dcc.remoteIp[/fnc][br]
+ [fnc]$dcc.remotePort[/fnc][br]
+ [fnc]$dcc.remoteFileName[/fnc][br]
+ [fnc]$dcc.remoteFileSize[/fnc][br]
+ [fnc]$dcc.ircContext[/fnc][br]
+ [fnc]$dcc.session[/fnc][br]
+*/
+
+
+static bool dcc_module_init(KviModule * m)
+{
+ g_pDccBroker = new KviDccBroker();
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"send",dcc_kvs_cmd_send);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"chat",dcc_kvs_cmd_chat);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"voice",dcc_kvs_cmd_voice);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"recv",dcc_kvs_cmd_recv);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"rsend",dcc_kvs_cmd_rsend);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"get",dcc_kvs_cmd_get);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"abort",dcc_kvs_cmd_abort);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setBandwidthLimit",dcc_kvs_cmd_setBandwidthLimit);
+
+
+ // FIXME: file upload / download state ?
+
+ KVSM_REGISTER_FUNCTION(m,"transferStatus",dcc_kvs_fnc_transferStatus);
+ KVSM_REGISTER_FUNCTION(m,"protocol",dcc_kvs_fnc_protocol);
+ KVSM_REGISTER_FUNCTION(m,"connectionType",dcc_kvs_fnc_connectionType);
+ KVSM_REGISTER_FUNCTION(m,"isFileTransfer",dcc_kvs_fnc_isFileTransfer);
+ KVSM_REGISTER_FUNCTION(m,"isFileUpload",dcc_kvs_fnc_isFileUpload);
+ KVSM_REGISTER_FUNCTION(m,"isFileDownload",dcc_kvs_fnc_isFileDownload);
+ KVSM_REGISTER_FUNCTION(m,"localNick",dcc_kvs_fnc_localNick);
+ KVSM_REGISTER_FUNCTION(m,"localUser",dcc_kvs_fnc_localUser);
+ KVSM_REGISTER_FUNCTION(m,"localHost",dcc_kvs_fnc_localHost);
+ KVSM_REGISTER_FUNCTION(m,"localIp",dcc_kvs_fnc_localIp);
+ KVSM_REGISTER_FUNCTION(m,"localPort",dcc_kvs_fnc_localPort);
+ KVSM_REGISTER_FUNCTION(m,"localFileName",dcc_kvs_fnc_localFileName);
+ KVSM_REGISTER_FUNCTION(m,"localFileSize",dcc_kvs_fnc_localFileSize);
+ KVSM_REGISTER_FUNCTION(m,"remoteNick",dcc_kvs_fnc_remoteNick);
+ KVSM_REGISTER_FUNCTION(m,"remoteUser",dcc_kvs_fnc_remoteUser);
+ KVSM_REGISTER_FUNCTION(m,"remoteHost",dcc_kvs_fnc_remoteHost);
+ KVSM_REGISTER_FUNCTION(m,"remoteIp",dcc_kvs_fnc_remoteIp);
+ KVSM_REGISTER_FUNCTION(m,"remotePort",dcc_kvs_fnc_remotePort);
+ KVSM_REGISTER_FUNCTION(m,"remoteFileName",dcc_kvs_fnc_remoteFileName);
+ KVSM_REGISTER_FUNCTION(m,"remoteFileSize",dcc_kvs_fnc_remoteFileSize);
+ KVSM_REGISTER_FUNCTION(m,"averageSpeed",dcc_kvs_fnc_averageSpeed);
+ KVSM_REGISTER_FUNCTION(m,"transferredBytes",dcc_kvs_fnc_transferredBytes);
+ KVSM_REGISTER_FUNCTION(m,"ircContext",dcc_kvs_fnc_ircContext);
+ KVSM_REGISTER_FUNCTION(m,"session",dcc_kvs_fnc_session);
+ KVSM_REGISTER_FUNCTION(m,"sessionList",dcc_kvs_fnc_sessionList);
+
+ return true;
+}
+
+static bool dcc_module_cleanup(KviModule *m)
+{
+ delete g_pDccBroker;
+ g_pDccBroker = 0;
+#ifdef COMPILE_USE_GSM
+ kvi_gsm_codec_done();
+#endif
+
+ return true;
+}
+
+static bool dcc_module_can_unload(KviModule *m)
+{
+ return g_pDccBroker ? g_pDccBroker->canUnload() : true;
+}
+
+KVIRC_MODULE(
+ "Dcc",
+ "1.0.0",
+ "Copyright (C) 2000-2004:\n" \
+ " Szymon Stefanek (pragma at kvirc dot net)\n",
+ "DCC extension for KVIrc\n",
+ dcc_module_init,
+ dcc_module_can_unload,
+ 0,
+ dcc_module_cleanup
+)
diff --git a/src/modules/dcc/marshal.cpp b/src/modules/dcc/marshal.cpp
new file mode 100644
index 00000000..9aedec41
--- /dev/null
+++ b/src/modules/dcc/marshal.cpp
@@ -0,0 +1,647 @@
+//
+// 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) 1999-2000 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 "kvi_netutils.h"
+#include "kvi_error.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_memmove.h"
+#include "kvi_socket.h"
+#include "kvi_fileutils.h"
+
+
+#include <stdlib.h> //for exit()
+
+
+
+
+KviDccMarshal::KviDccMarshal(KviDccMarshalOutputContext * ctx)
+: QObject(0,"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
+// debug("MARSHAL RESETTING (SSL=%d)",m_pSSL);
+ if(m_pSSL)
+ {
+// debug("MARSHAL CLEARING THE SSL");
+ KviSSLMaster::freeSSL(m_pSSL);
+ m_pSSL = 0;
+ }
+#endif
+ if(m_pTimeoutTimer)
+ {
+ delete m_pTimeoutTimer;
+ m_pTimeoutTimer = 0;
+ }
+ m_bIpV6 = false;
+}
+
+int 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;
+
+#ifdef COMPILE_SSL_SUPPORT
+ m_bUseSSL = bUseSSL;
+#else
+ if(bUseSSL)return KviError_noSSLSupport;
+#endif
+
+ if(m_pTimeoutTimer)delete m_pTimeoutTimer;
+ m_pTimeoutTimer = new QTimer();
+ connect(m_pTimeoutTimer,SIGNAL(timeout()),this,SLOT(doListen()));
+ m_pTimeoutTimer->start(100,true);
+
+ return KviError_success;
+}
+
+void KviDccMarshal::doListen()
+{
+ if(m_pTimeoutTimer)
+ {
+ delete m_pTimeoutTimer;
+ m_pTimeoutTimer = 0;
+ }
+
+ // Check the address type
+ if(!kvi_isValidStringIp(m_szIp))
+ {
+#ifdef COMPILE_IPV6_SUPPORT
+ if(!kvi_isValidStringIp_V6(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,m_uPort,m_bIpV6);
+#else
+ KviSockaddr sa(m_szIp,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,m_uPort,m_bIpV6);
+#else
+ KviSockaddr sa(m_szIp,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))
+ {
+// debug("GETSOCKNAMEOK");
+ m_szPort.setNum(sareal.port());
+ m_uPort = sareal.port();
+// debug("REALPORT %u",m_uPort);
+ } else {
+// debug("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_bUseTimeout)
+ {
+ m_pTimeoutTimer = new QTimer();
+ connect(m_pTimeoutTimer,SIGNAL(timeout()),this,SLOT(connectionTimedOut()));
+ m_pTimeoutTimer->start(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000,true);
+ }
+ // and wait for connect
+
+ emit inProgress();
+}
+
+int 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
+
+ if(m_pTimeoutTimer)delete m_pTimeoutTimer;
+ m_pTimeoutTimer = new QTimer();
+ connect(m_pTimeoutTimer,SIGNAL(timeout()),this,SLOT(doConnect()));
+ m_pTimeoutTimer->start(100,true);
+
+ return KviError_success;
+}
+
+void KviDccMarshal::doConnect()
+{
+ if(m_pTimeoutTimer)
+ {
+ delete m_pTimeoutTimer;
+ m_pTimeoutTimer = 0;
+ }
+
+ // Check the address type
+ if(!kvi_isValidStringIp(m_szIp))
+ {
+#ifdef COMPILE_IPV6_SUPPORT
+ if(!kvi_isValidStringIp_V6(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,m_uPort,m_bIpV6);
+#else
+ KviSockaddr sa(m_szIp,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_bUseTimeout)
+ {
+ m_pTimeoutTimer = new QTimer();
+ connect(m_pTimeoutTimer,SIGNAL(timeout()),this,SLOT(connectionTimedOut()));
+ m_pTimeoutTimer->start(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000,true);
+ }
+
+ // 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(!kvi_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(!kvi_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(!kvi_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(!kvi_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
+// debug("DO SSL HANDSHAKE");
+ if(m_pSn)
+ {
+ delete m_pSn;
+ m_pSn = 0;
+ }
+
+ if(!m_pSSL)
+ {
+ debug("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!
+// debug("EMITTING CONNECTED");
+ emit connected();
+// debug("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:
+ {
+ KviStr buffer;
+ while(m_pSSL->getLastErrorString(buffer))emit sslError(buffer.ptr());
+ reset();
+ emit error(KviError_SSLError);
+ }
+ break;
+ }
+#else //!COMPILE_SSL_SUPPORT
+ debug("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);
+}
+
+
+#include "m_marshal.moc"
diff --git a/src/modules/dcc/marshal.h b/src/modules/dcc/marshal.h
new file mode 100644
index 00000000..9665e09a
--- /dev/null
+++ b/src/modules/dcc/marshal.h
@@ -0,0 +1,112 @@
+#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) 1999-2000 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_string.h"
+#include "kvi_sockettype.h"
+#include <qobject.h>
+#include <qsocketnotifier.h>
+#include <qtimer.h>
+#include "kvi_inttypes.h"
+
+class KviWindow;
+
+#ifdef COMPILE_SSL_SUPPORT
+ #include "kvi_sslmaster.h"
+#endif
+
+class KviDccMarshal;
+
+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;
+ QTimer * m_pTimeoutTimer;
+ bool m_bUseTimeout;
+#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; };
+ int dccListen(const QString &ip,const QString &port,bool bUseTimeout,bool bUseSSL = false);
+ int 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
new file mode 100644
index 00000000..e1e18143
--- /dev/null
+++ b/src/modules/dcc/requests.cpp
@@ -0,0 +1,1154 @@
+//=============================================================================
+//
+// File : requests.cpp
+// Creation date : Tue Jul 23 02:44:38 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)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under 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 "kvi_settings.h"
+#include "kvi_string.h"
+#include "kvi_module.h"
+#include "kvi_sparser.h"
+#include "kvi_locale.h"
+#include "kvi_out.h"
+#include "kvi_console.h"
+#include "kvi_netutils.h"
+#include "kvi_frame.h"
+#include "kvi_console.h"
+
+#include "kvi_error.h"
+#include "kvi_options.h"
+#include "kvi_defaults.h"
+#include "kvi_sharedfiles.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_app.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+
+#include "gsmcodec.h"
+#include "broker.h"
+#include "voice.h"
+#include "utils.h"
+#include "send.h"
+
+#include <qfileinfo.h>
+
+#ifdef COMPILE_ON_WINDOWS
+ // Ugly Windoze compiler...
+ #include "dialogs.h"
+#endif
+
+//#warning "KviOption_boolIgnoreDccChat and other types too"
+
+extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager;
+extern KviDccBroker * g_pDccBroker;
+
+static void dcc_module_reply_errmsg(KviDccRequest * dcc,const QString& errText)
+{
+ dcc->ctcpMsg->msg->console()->connection()->sendFmtData(
+ "NOTICE %s :%cERRMSG %s%c",
+ dcc->ctcpMsg->msg->console()->connection()->encodeText(dcc->ctcpMsg->pSource->nick()).data(),0x01,
+ dcc->ctcpMsg->msg->console()->connection()->encodeText(errText).data()
+ ,0x01);
+}
+
+static void dcc_module_request_error(KviDccRequest * dcc,const QString& errText)
+{
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCERROR,
+ __tr2qs_ctx("Unable to process the above request: %Q, %Q","dcc"),
+ &errText,
+ KVI_OPTION_BOOL(KviOption_boolNotifyFailedDccHandshakes) ? &(__tr2qs_ctx("Ignoring and notifying failure","dcc")) : &(__tr2qs_ctx("Ignoring","dcc")));
+
+ if(KVI_OPTION_BOOL(KviOption_boolNotifyFailedDccHandshakes))
+ {
+ QString szError = QString("Sorry, your DCC %1 request can't be satisfied: %2").arg(dcc->szType.ptr()).arg(errText);
+ dcc_module_reply_errmsg(dcc,szError);
+ }
+}
+
+static bool dcc_module_check_concurrent_transfers_limit(KviDccRequest * dcc)
+{
+ if(KVI_OPTION_UINT(KviOption_uintMaxDccSendTransfers) > 0)
+ {
+ unsigned int uTransfers = KviDccFileTransfer::runningTransfersCount();
+ if(uTransfers >= KVI_OPTION_UINT(KviOption_uintMaxDccSendTransfers))
+ {
+ KviStr szError(KviStr::Format,__tr2qs_ctx("Concurrent transfer limit reached (%u of %u transfers running)","dcc"),
+ uTransfers,KVI_OPTION_UINT(KviOption_uintMaxDccSendTransfers));
+ dcc_module_request_error(dcc,szError.ptr());
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool dcc_module_check_limits(KviDccRequest * dcc)
+{
+ if(KVI_OPTION_UINT(KviOption_uintMaxDccSlots) > 0)
+ {
+ unsigned int uWindows = g_pDccBroker->dccWindowsCount();
+ if(uWindows >= KVI_OPTION_UINT(KviOption_uintMaxDccSlots))
+ {
+ KviStr szError(KviStr::Format,__tr2qs_ctx("Slot limit reached (%u slots of %u)","dcc"),
+ uWindows,KVI_OPTION_UINT(KviOption_uintMaxDccSlots));
+ dcc_module_request_error(dcc,szError.ptr());
+ return false;
+ }
+ }
+ if(g_pDccBroker->dccBoxCount() >= 32)
+ {
+ // there are too many pending dcc requests: the user isn't watching....
+ dcc_module_request_error(dcc,__tr2qs_ctx("Too many pending connections","dcc"));
+ return false;
+ }
+ return true;
+}
+
+static void dcc_fill_local_nick_user_host(KviDccDescriptor * d,KviDccRequest * dcc)
+{
+ if(dcc->pConsole->connection())
+ {
+ d->szLocalNick = dcc->pConsole->connection()->userInfo()->nickName();
+ d->szLocalUser = dcc->pConsole->connection()->userInfo()->userName();
+ d->szLocalHost = dcc->pConsole->connection()->userInfo()->hostName();
+ } else {
+ d->szLocalNick = __tr_ctx("unknown","dcc");
+ d->szLocalUser = __tr2qs_ctx("unknown","dcc");
+ d->szLocalHost = __tr2qs_ctx("unknown","dcc");
+ }
+}
+
+static void dcc_module_set_dcc_type(KviDccDescriptor * d,const char * szBaseType)
+{
+ d->szType = szBaseType;
+#ifdef COMPILE_SSL_SUPPORT
+ if(d->bIsSSL)d->szType.prepend('S');
+#endif
+ if(d->bIsTdcc)d->szType.prepend('T');
+}
+
+
+static bool dcc_module_normalize_target_data(KviDccRequest * dcc,KviStr &ipaddr,KviStr &port)
+{
+ if(!port.isUnsignedNum())
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ KviStr szError(KviStr::Format,__tr2qs_ctx("Invalid port number %s","dcc"),port.ptr());
+ dcc_module_request_error(dcc,szError.ptr());
+ }
+ return false;
+ }
+
+ struct in_addr addr;
+
+ if(ipaddr.isUnsignedNum())
+ {
+ addr.s_addr = htonl((unsigned long)ipaddr.toULong());
+ QString tmp;
+ if(!kvi_binaryIpToStringIp(addr,tmp))
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ KviStr szError(KviStr::Format,__tr2qs_ctx("Invalid IP address in old format %s","dcc"),ipaddr.ptr());
+ dcc_module_request_error(dcc,szError.ptr());
+ }
+ return false;
+ }
+ ipaddr = tmp;
+ } else {
+ if(!kvi_stringIpToBinaryIp(ipaddr,&addr))
+ {
+#ifdef COMPILE_IPV6_SUPPORT
+ struct in6_addr addr6;
+ if(kvi_stringIpToBinaryIp_V6(ipaddr,&addr6))
+ {
+ dcc->bIpV6 = true;
+ return true; // IPV6 address.
+ }
+#endif
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ KviStr szError(KviStr::Format,__tr2qs_ctx("Invalid IP address %s","dcc"),ipaddr.ptr());
+ dcc_module_request_error(dcc,szError.ptr());
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// CHAT
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void dccModuleParseDccChat(KviDccRequest *dcc)
+{
+ //
+ // We have received a DCC CHAT request in the following form:
+ //
+ // DCC CHAT chat <ipaddress> <port>
+ //
+ // This means that we're requested to setup an ACTIVE chat connection
+ // ... Easy task :)
+ //
+ // Anybody understands the meaning of the secondo "chat" in there ?
+ // It was meant to simplify the parsing ? :DDD
+ //
+ // There is a mIrc extension that allows <port> to be 0
+ // and adds a last parameter that seems to be a random number (thnx YaP :)
+ // that is used to keep track of the connection.
+ // This extension is used by firewalled machines to initiate a DCC CHAT:
+ // the receiving side should respond with a DCC CHAT offer
+ // with the same random number appended, and then should listen for a connection.
+ //
+ // when a zero port request is initiated by another party we get
+ //
+ // DCC CHAT chat <fakeipaddress> 0 <tag>
+ //
+ // and we reply with
+ //
+ // DCC CHAT chat <ourip> <ourport> <tag>
+ //
+ // when a zero port request is initiated by us we send out
+ //
+ // DCC CHAT chat <fakeipaddress> 0 <tag>
+ //
+ // and we get
+ //
+ // DCC CHAT chat <remoteip> <remoteport> <tag>
+ //
+ // Thus if there is a <tag> and the port is 0, then the remote party
+ // wanted to estabilish a dcc with us and wants us to listen, but if the port is nonzero then
+ // we have sent out a zero port request and the remote party acked it
+ // thus we have to connect instead!
+ //
+
+ // First of all we check the dcc slot limits
+ if(!dcc_module_check_limits(dcc))return;
+
+ // Then we check the target host data
+ if(!dcc_module_normalize_target_data(dcc,dcc->szParam2,dcc->szParam3))return;
+
+ if(!kvi_strEqualCI(dcc->szParam1.ptr(),"chat"))
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The above request is broken: The second parameter is '%s' and should be 'chat', trying to continue","dcc"),dcc->szParam1.ptr());
+ }
+ }
+
+ KviStr szExtensions = dcc->szType;
+ szExtensions.cutRight(4); // cut off CHAT
+
+#ifdef COMPILE_SSL_SUPPORT
+ bool bSSLExtension = szExtensions.contains('S',false);
+#else //!COMPILE_SSL_SUPPORT
+ if(szExtensions.contains('S',false))
+ {
+ dcc_module_request_error(dcc,__tr2qs_ctx("This executable has been compiled without SSL support, the SSL extension to DCC CHAT is not available","dcc"));
+ return;
+ }
+#endif //!COMPILE_SSL_SUPPORT
+
+ KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole);
+
+ d->szNick = dcc->ctcpMsg->pSource->nick();
+ d->szUser = dcc->ctcpMsg->pSource->username();
+ d->szHost = dcc->ctcpMsg->pSource->host();
+
+ dcc_fill_local_nick_user_host(d,dcc);
+
+ d->szIp = dcc->szParam2.ptr();
+ d->szPort = dcc->szParam3.ptr();
+
+
+ if(dcc->szParam4.hasData())
+ {
+ // zero port tag ?
+ if(d->szPort == "0")
+ {
+ // zero port request
+ if(KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault))
+ {
+ d->szFakeIp = KVI_OPTION_STRING(KviOption_stringDefaultDccFakeAddress);
+ if(d->szFakeIp.isEmpty())KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault) = false;
+ }
+ d->setZeroPortRequestTag(dcc->szParam4.ptr());
+ QString tmp;
+ if(!dcc_kvs_get_listen_ip_address(0,d->console(),tmp))d->szListenIp = "0.0.0.0";
+ else d->szListenIp=tmp;
+ d->szListenPort = "0"; // any port is OK
+ d->bAutoAccept = KVI_OPTION_BOOL(KviOption_boolAutoAcceptDccChat);
+ d->bActive = false; // we must listen then...
+ } else {
+ // zero port acknowledge
+ // check if this is a tag that we have sent out
+ QString szTag = QString(dcc->szParam4.ptr());
+ KviDccZeroPortTag * t = g_pDccBroker->findZeroPortTag(szTag);
+ if(!t)
+ {
+ // hum.. not our tag
+
+ // FIXME: As segnaled by PRAEDO, ezbounce seems to send a fourth parameter in response to /quote ezb log
+ // Pragma: That's a bug in ezbounce, it sends the filesize of the log as a DCC CHAT parameter...
+ // The author probably copied and pasted the CTCP line from DCC SEND and forgot to remove the filesize.
+ // We *could* add an option to ignore the last parameter and treat it as a standard dcc chat
+ // request, but since we don't encourage bugs, we don't do it :D
+ // Mail me at pragma at kvirc dot net if you really think it's necessary.
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The above request is broken: it looks like a zero port tag acknowledge but I have either never seen this tag or it was sent more than 120 seconds ago","dcc"));
+ dcc_module_request_error(dcc,__tr2qs_ctx("It seems that I haven't requested this dcc chat","dcc"));
+ delete d;
+ return;
+ } else {
+ g_pDccBroker->removeZeroPortTag(szTag);
+ }
+
+ d->bAutoAccept = true; // auto-accept it (we have sent it out)
+ d->bActive = true;
+ }
+ } else {
+ d->bAutoAccept = KVI_OPTION_BOOL(KviOption_boolAutoAcceptDccChat);
+ d->bActive = true; // we have to connct (standard active chat)
+ }
+
+#ifdef COMPILE_SSL_SUPPORT
+ d->bIsSSL = bSSLExtension;
+#endif
+
+ dcc_module_set_dcc_type(d,"CHAT");
+ d->triggerCreationEvent();
+
+ g_pDccBroker->handleChatRequest(d);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// SEND
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void dccModuleParseDccRecv(KviDccRequest * dcc);
+
+static void dccModuleParseDccSend(KviDccRequest *dcc)
+{
+//#warning "Ignore files depending on file type ? (MediaType ?)"
+ //
+ // We have received a DCC SEND request in the following form
+ //
+ // DCC [ST]SEND <filename> <ipaddress> <port> <filesize>
+ //
+ // Now the things are a bit tricky... we eventually can
+ // reply with a DCC RESUME and receive a DCC ACCEPT then
+ // The format of these requests is:
+ //
+ // DCC RESUME <filename> <port> <resumepos>
+ // ACCEPT <filename> <port> <resumepos>
+ //
+ // There is a mIrc extension that allows <port> to be 0
+ // and adds a last parameter that seems to be a random number (thnx YaP :)
+ // that is used to keep track of the connection.
+ // This extension is used by firewalled machines to initiate a DCC SEND:
+ // the receiving side should respond with a DCC SEND offer
+ // with the same random number appended, listen for a connection, and receive the file
+ // instead of sending it.
+ //
+ // when a zero port request is initiated by another party we get
+ // DCC SEND <filename> <fakeipaddress> 0 <filesize> <tag>
+ // if (and only if) we want to resume we reply with
+ // DCC RESUME <filename> 0 <resumesize> <tag>
+ // in this case the remote part replies again with
+ // DCC ACCEPT <filename> 0 <resumesize> <tag>
+ // and we finally reply with
+ // DCC SEND <filename> <ourip> <ourport> <filesize> <tag>
+ //
+ // when a zero port request is initiated by us we send out
+ // DCC SEND <filename> <fakeipaddress> 0 <filesize> <tag>
+ // and if the remote party wants to resume then we get
+ // DCC RESUME <filename> 0 <resumesize> <tag>
+ // and we eventually reply with
+ // DCC ACCEPT <filename> 0 <resumesize> <tag>
+ // and we finally get
+ // DCC SEND <filename> <remoteip> <remoteport> <filesize> <tag>
+ //
+ // Thus if there is a <tag> and the port is 0, then the remote party
+ // is trying to send a file to us, but if the port is nonzero then
+ // we have sent out a zero port request and the remote party acked it
+ //
+
+ if((!kvi_strEqualCS(dcc->szParam3.ptr(),"0")) && dcc->szParam5.hasData())
+ {
+ // DCC SEND <filename> <remoteip> <remoteport> <filesize> <tag>
+ // zero port acknowledge: treat as a RECV that should look like
+ // DCC [TS]RECV <filename> <remoteip> <remoteport> <resume-filesize>
+ // but since we have stored the sharedfile with the name <tag>
+ // we do exchange the params :)
+
+ KviDccZeroPortTag * t = g_pDccBroker->findZeroPortTag(dcc->szParam5.ptr());
+ if(t)
+ {
+ dcc->szParam4.sprintf("%u",t->m_uResumePosition);
+ g_pDccBroker->removeZeroPortTag(dcc->szParam5.ptr());
+ } else {
+ // this should never happen since we always add
+ // a zero port tag for out outgoing requests
+ // but well... maybe the user did something behing our back...
+ dcc->szParam4 = "0"; // no resume possible in this case
+ }
+
+ // swap the tag and the filename (we have added a fileoffer with this tag)
+ dcc->szParam1 = dcc->szParam5;
+ dcc->szParam5 = "";
+
+ dccModuleParseDccRecv(dcc);
+ return;
+ }
+
+ // First of all we check the transfer limits
+ dcc->szParam1=dcc->pConsole->decodeText(dcc->szParam1);
+ if(!dcc_module_check_limits(dcc))return;
+ if(!dcc_module_check_concurrent_transfers_limit(dcc))return;
+
+ // Then we ensure that the data that the remote end has sent are valid
+ if(!dcc_module_normalize_target_data(dcc,dcc->szParam2,dcc->szParam3))return;
+
+ if(!(dcc->szParam4.isUnsignedNum()))
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The above request is broken: The fourth parameter should be the file size but does not appear to be an unsigned number, trying to continue","dcc"),dcc->szParam4.ptr());
+ }
+ dcc->szParam4 = __tr2qs_ctx("<unknown size>","dcc");
+ }
+
+ if(dcc->szParam1.contains('/'))
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The above request is broken: The filename contains path components, stripping the leading path and trying to continue","dcc"),dcc->szParam1.ptr());
+ }
+ dcc->szParam1.cutToLast('/');
+ }
+
+ KviStr szExtensions = dcc->szType;
+ szExtensions.cutRight(4); // cut off SEND
+
+ bool bTurboExtension = szExtensions.contains('T',false);
+#ifdef COMPILE_SSL_SUPPORT
+ bool bSSLExtension = szExtensions.contains('S',false);
+#else //!COMPILE_SSL_SUPPORT
+ if(szExtensions.contains('S',false))
+ {
+ dcc_module_request_error(dcc,__tr2qs_ctx("This executable has been compiled without SSL support, the SSL extension to DCC SEND is not available","dcc"));
+ return;
+ }
+#endif //!COMPILE_SSL_SUPPORT
+
+ KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole);
+ d->szNick = dcc->ctcpMsg->pSource->nick();
+ d->szUser = dcc->ctcpMsg->pSource->username();
+ d->szHost = dcc->ctcpMsg->pSource->host();
+ dcc_fill_local_nick_user_host(d,dcc);
+
+ d->szIp = dcc->szParam2.ptr();
+ d->szPort = dcc->szParam3.ptr();
+ d->szFileName = dcc->szParam1.ptr();
+ d->szFileSize = dcc->szParam4.ptr();
+
+ if(d->szPort=="0" && dcc->szParam5.hasData())
+ {
+ if(KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault))
+ {
+ d->szFakeIp = KVI_OPTION_STRING(KviOption_stringDefaultDccFakeAddress);
+ if(d->szFakeIp.isEmpty())KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault) = false;
+ }
+ d->setZeroPortRequestTag(dcc->szParam5.ptr());
+ QString tmp;
+ if(!dcc_kvs_get_listen_ip_address(0,d->console(),tmp))d->szListenIp = "0.0.0.0";
+ else d->szListenIp=QString(tmp);
+ d->szListenPort = "0"; // any port is OK
+ d->bSendRequest = true;
+ d->szLocalFileSize = d->szFileSize;
+ }
+
+ d->bActive = !d->isZeroPortRequest(); // we have to connect unless it is a zero port request
+
+ d->bResume = false;
+ d->bRecvFile = true;
+ d->bIsTdcc = bTurboExtension;
+ d->bNoAcks = d->bIsTdcc;
+#ifdef COMPILE_SSL_SUPPORT
+ d->bIsSSL = bSSLExtension;
+#endif
+ d->bOverrideMinimize = false;
+ d->bAutoAccept = KVI_OPTION_BOOL(KviOption_boolAutoAcceptDccSend);
+
+ d->bIsIncomingAvatar = g_pApp->findPendingAvatarChange(dcc->pConsole,d->szNick,d->szFileName);
+ dcc_module_set_dcc_type(d,"RECV");
+ if(KVI_OPTION_BOOL(KviOption_boolAutoAcceptIncomingAvatars))d->bAutoAccept = d->bAutoAccept || d->bIsIncomingAvatar;
+ d->triggerCreationEvent();
+
+ g_pDccBroker->recvFileManage(d);
+}
+
+static void dccModuleParseDccAccept(KviDccRequest *dcc)
+{
+ // this is usually DCC ACCEPT <filename> <port> <resumesize>
+ // but may be also
+ // DCC ACCEPT <filename> 0 <resumesize> <tag>
+ if(!g_pDccBroker->handleResumeAccepted(dcc->szParam1.ptr(),dcc->szParam2.ptr(),dcc->szParam4.ptr()))
+ {
+//#warning "IF KviOption_boolReplyCtcpErrmsgOnInvalidAccept..."
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ KviStr szError(KviStr::Format,__tr2qs_ctx("Can't proceed with DCC RECV: Transfer not initiated for file %s on port %s","dcc"),dcc->szParam1.ptr(),dcc->szParam2.ptr());
+ dcc_module_request_error(dcc,szError.ptr());
+ }
+ }
+}
+
+static void dccModuleParseDccResume(KviDccRequest *dcc)
+{
+ // This is usually RESUME <filename> <port> <resumesize>
+
+ // when a zero port request is initiated by us we send out
+ // DCC SEND <filename> <fakeipaddress> 0 <filesize> <tag>
+ // and if the remote party wants to resume then we get
+ // DCC RESUME <filename> 0 <resumesize> <tag>
+ // and we eventually reply with
+ // DCC ACCEPT <filename> 0 <resumesize> <tag>
+ // and we finally get
+ // DCC SEND <filename> <remoteip> <remoteport> <filesize> <tag>
+
+ bool bOk;
+ unsigned int filePos = dcc->szParam3.toUInt(&bOk);
+ if(!bOk)
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ KviStr szError(KviStr::Format,__tr2qs_ctx("Invalid resume position argument '%s'","dcc"),dcc->szParam3.ptr());
+ dcc_module_request_error(dcc,szError.ptr());
+ }
+ return;
+ }
+
+ if(!g_pDccBroker->handleResumeRequest(dcc,dcc->szParam1.ptr(),dcc->szParam2.ptr(),filePos,dcc->szParam4.ptr()))
+ {
+//#warning "IF KviOption_boolReplyCtcpErrmsgOnInvalidResume..."
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ KviStr szError(KviStr::Format,
+ __tr2qs_ctx("Can't proceed with DCC SEND: Transfer not initiated for file %s on port %s, or invalid resume size","dcc"),
+ dcc->szParam1.ptr(),dcc->szParam2.ptr());
+ dcc_module_request_error(dcc,szError.ptr());
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// RECV
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void dccModuleParseDccRecv(KviDccRequest * dcc)
+{
+ // DCC [TS]RECV <filename> <ipaddr> <port> <resume-filesize>
+ if(!dcc_module_check_limits(dcc))return;
+ if(!dcc_module_check_concurrent_transfers_limit(dcc))return;
+
+ if(!dcc_module_normalize_target_data(dcc,dcc->szParam2,dcc->szParam3))return;
+
+ if(!(dcc->szParam4.isUnsignedNum()))
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->outputNoFmt(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The above request has resume file size missing, assuming a resume file size of 0","dcc"));
+ }
+ dcc->szParam4 = "0";
+ }
+
+ if(dcc->szParam1.contains('/'))
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The above request is broken: The filename contains path components, stripping the leading path and trying to continue","dcc"),dcc->szParam1.ptr());
+ }
+ dcc->szParam1.cutToLast('/');
+ }
+
+ KviStr szExtensions = dcc->szType;
+ szExtensions.cutRight(4); // cut off RECV
+
+ bool bTurboExtension = szExtensions.contains('T',false);
+#ifdef COMPILE_SSL_SUPPORT
+ bool bSSLExtension = szExtensions.contains('S',false);
+#else //!COMPILE_SSL_SUPPORT
+ if(szExtensions.contains('S',false))
+ {
+ dcc_module_request_error(dcc,__tr2qs_ctx("This executable has been compiled without SSL support, the SSL extension to DCC RECV is not available","dcc"));
+ return;
+ }
+#endif //!COMPILE_SSL_SUPPORT
+
+ // If we have a file offer for this...do it automatically
+ KviSharedFile * o = g_pSharedFilesManager->lookupSharedFile(dcc->szParam1.ptr(),dcc->ctcpMsg->pSource,0);
+ if(o)
+ {
+
+ unsigned int uResumeSize = dcc->szParam4.toUInt(); // this will NEVER fail
+ if(uResumeSize >= o->fileSize())
+ {
+ // senseless request
+ KviStr szError(KviStr::Format,
+ __tr2qs_ctx("Invalid RECV request: Position %u is is larger than file size","dcc"),uResumeSize);
+ dcc_module_request_error(dcc,szError.ptr());
+ return;
+ }
+
+ // ok...we have requested this send
+// #warning "Maybe remove this file offer now ?"
+ KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole);
+
+ d->szNick = dcc->ctcpMsg->pSource->nick();
+ d->szUser = dcc->ctcpMsg->pSource->user();
+ d->szHost = dcc->ctcpMsg->pSource->host();
+
+ d->szFileName = dcc->szParam1.ptr();
+ d->szFileSize = dcc->szParam4.ptr();
+
+ //d->bResume = false; // This is actually useless
+
+ d->szLocalFileName = o->absFilePath();
+ d->szLocalFileSize.setNum(o->fileSize()); // Should we look it up again ?
+
+
+ d->bRecvFile = false;
+ d->bNoAcks = bTurboExtension;
+
+ d->bAutoAccept = true;
+ d->bIsIncomingAvatar = false;
+
+ d->bIsTdcc = bTurboExtension;
+#ifdef COMPILE_SSL_SUPPORT
+ d->bIsSSL = bSSLExtension;
+#endif
+
+ d->bOverrideMinimize = false;
+
+ // We know everything
+ dcc_fill_local_nick_user_host(d,dcc);
+
+
+ d->bDoTimeout = true;
+
+ d->szIp = dcc->szParam2.ptr();
+ d->szPort = dcc->szParam3.ptr();
+
+ d->bActive = true;
+ dcc_module_set_dcc_type(d,"SEND");
+ d->triggerCreationEvent();
+ g_pDccBroker->sendFileExecute(0,d);
+
+ return;
+
+ } else {
+
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("%Q [%Q@%Q] is ready to receive the file \"%s\"","dcc"),
+ &(dcc->ctcpMsg->pSource->nick()),
+ &(dcc->ctcpMsg->pSource->username()),
+ &(dcc->ctcpMsg->pSource->host()),
+ dcc->szParam1.ptr());
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The remote client is listening on interface %s and port %s","dcc"),dcc->szParam2.ptr(),dcc->szParam3.ptr());
+ KviStr szSwitches = "-c";
+ if(bTurboExtension)szSwitches.prepend("-t ");
+#ifdef COMPILE_SSL_SUPPORT
+ if(bSSLExtension)szSwitches.prepend("-s ");
+#endif
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("Use %c\r![!dbl]dcc.send %s -i=%s -p=%s %Q\r/dcc.send %s -i=%s -p=%s %Q\r%c to send the file (or double-click on the socket)","dcc"),
+ KVI_TEXT_BOLD,
+ szSwitches.ptr(),
+ dcc->szParam2.ptr(),dcc->szParam3.ptr(),&(dcc->ctcpMsg->pSource->nick()),
+ szSwitches.ptr(),
+ dcc->szParam2.ptr(),dcc->szParam3.ptr(),&(dcc->ctcpMsg->pSource->nick()),
+ KVI_TEXT_BOLD);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// RSEND
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void dccModuleParseDccRSend(KviDccRequest *dcc)
+{
+ // DCC RSEND <filename> <filesize>
+//#warning "Ignore files depending on file type ? (MediaType ?)"
+ //
+ // We have received a DCC RSEND request in the following form
+ //
+ // DCC [ST]RSEND <filename> <filesize>
+ //
+ dcc->szParam1 = dcc->pConsole->decodeText(dcc->szParam1);
+ if(!dcc_module_check_limits(dcc))return;
+ if(!dcc_module_check_concurrent_transfers_limit(dcc))return;
+
+ if(!(dcc->szParam2.isUnsignedNum()))
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The above request is broken: The fourth parameter should be the file size but does not appear to be an unsigned number; trying to continue","dcc"),dcc->szParam2.ptr());
+ }
+ dcc->szParam2 = __tr_ctx("<unknown size>","dcc");
+ }
+
+ if(dcc->szParam1.contains('/'))
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The above request is broken: The filename contains path components, stripping the leading path and trying to continue","dcc"),dcc->szParam1.ptr());
+ }
+ dcc->szParam1.cutToLast('/');
+ }
+
+ KviStr szExtensions = dcc->szType;
+ szExtensions.cutRight(4); // cut off SEND
+
+ bool bTurboExtension = szExtensions.contains('T',false);
+#ifdef COMPILE_SSL_SUPPORT
+ bool bSSLExtension = szExtensions.contains('S',false);
+#else //!COMPILE_SSL_SUPPORT
+ if(szExtensions.contains('S',false))
+ {
+ dcc_module_request_error(dcc,__tr2qs_ctx("This executable has been compiled without SSL support, the SSL extension to DCC RSEND is not available","dcc"));
+ return;
+ }
+#endif //!COMPILE_SSL_SUPPORT
+
+//#warning "When behind a firewall, we should reply an error message and avoid setting up the listening connection"
+
+ KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole);
+ d->szNick = dcc->ctcpMsg->pSource->nick();
+ d->szUser = dcc->ctcpMsg->pSource->username();
+ d->szHost = dcc->ctcpMsg->pSource->host();
+ d->szIp = __tr2qs_ctx("(unknown)","dcc");
+ d->szPort = d->szIp;
+ QString tmp;
+ if(!dcc_kvs_get_listen_ip_address(0,d->console(),tmp))
+ {
+ d->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("No suitable interface to listen on, trying to continue anyway...","dcc"));
+ d->szListenIp = "0.0.0.0";
+ } else
+ d->szListenIp=QString(tmp);
+
+ d->szListenPort = "0";
+ dcc_fill_local_nick_user_host(d,dcc);
+
+
+ d->szFileName = dcc->szParam1.ptr();
+ d->szFileSize = dcc->szParam2.ptr();
+ d->bActive = false; // we have to listen!
+ d->bResume = false;
+ d->bRecvFile = true; // we have to receive the file!
+
+#ifdef COMPILE_SSL_SUPPORT
+ d->bIsSSL = bSSLExtension;
+#endif
+ d->bIsTdcc = bTurboExtension;
+ d->bSendRequest = true; // we have to send the [ST]RECV request back
+ d->bNoAcks = d->bIsTdcc;
+ d->bOverrideMinimize = false;
+ d->bAutoAccept = KVI_OPTION_BOOL(KviOption_boolAutoAcceptDccSend);
+ d->bIsIncomingAvatar = g_pApp->findPendingAvatarChange(dcc->pConsole,d->szNick.utf8().data(),d->szFileName.utf8().data());
+
+ if(KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault))
+ {
+ d->szFakeIp = KVI_OPTION_STRING(KviOption_stringDefaultDccFakeAddress);
+ if(d->szFakeIp.isEmpty())KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault) = false;
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolAutoAcceptIncomingAvatars))d->bAutoAccept = d->bAutoAccept || d->bIsIncomingAvatar;
+
+ dcc_module_set_dcc_type(d,"RECV");
+ d->triggerCreationEvent();
+ g_pDccBroker->recvFileManage(d);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// GET
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void dccModuleParseDccGet(KviDccRequest *dcc)
+{
+ // DCC [TS]GET <filename> [filesize]
+ // -> DCC [TS]SEND <filename> <ipaddr> <port> <filesize>
+ // ...
+ dcc->szParam1=dcc->pConsole->decodeText(dcc->szParam1);
+ bool bOk;
+ unsigned int uSize = dcc->szParam2.toUInt(&bOk);
+ if(!bOk)uSize = 0;
+
+ if(!dcc_module_check_limits(dcc))return;
+ if(!dcc_module_check_concurrent_transfers_limit(dcc))return;
+
+ KviStr szExtensions = dcc->szType;
+ szExtensions.cutRight(3); // cut off GET
+
+ bool bTurboExtension = szExtensions.contains('T',false);
+#ifdef COMPILE_SSL_SUPPORT
+ bool bSSLExtension = szExtensions.contains('S',false);
+#else //!COMPILE_SSL_SUPPORT
+ if(szExtensions.contains('S',false))
+ {
+ dcc_module_request_error(dcc,__tr2qs_ctx("This executable has been compiled without SSL support, the SSL extension to DCC GET is not available","dcc"));
+ return;
+ }
+#endif //!COMPILE_SSL_SUPPORT
+
+ KviSharedFile * o = g_pSharedFilesManager->lookupSharedFile(dcc->szParam1.ptr(),dcc->ctcpMsg->pSource,uSize);
+ if(!o)
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ KviStr szError(KviStr::Format,
+ __tr2qs_ctx("No file offer named '%s' (with size %s) available for %Q [%Q@%Q]","dcc"),
+ dcc->szParam1.ptr(),uSize > 0 ? dcc->szParam2.ptr() : __tr_ctx("\"any\"","dcc"),
+ &(dcc->ctcpMsg->pSource->nick()),
+ &(dcc->ctcpMsg->pSource->username()),
+ &(dcc->ctcpMsg->pSource->host()));
+ dcc_module_request_error(dcc,szError.ptr());
+ }
+ return;
+ }
+
+//#warning "IF NOT IGNORE DCC GET!"
+
+//#warning "CREATE IT MINIMIZED ETC..."
+//#warning "MAYBE USE A DIALOG TO ACCEPT THE REQUEST ?"
+//#warning "DO NOT ACCEPT /etc/* requests..."
+
+ if(KVI_OPTION_BOOL(KviOption_boolCantAcceptIncomingDccConnections))
+ {
+ // we have to use DCC RSEND , otherwise it will not work
+ KviStr szSubproto("RSEND");
+ szSubproto.prepend(szExtensions);
+
+
+ QString szFileName = QFileInfo(o->absFilePath()).fileName();
+ if(o->name() != szFileName)
+ {
+ // BUG
+ // If the file offer was added with a name that is senseless (like "mediaXYZ" for an *.mp3 file)
+ // then we would be going to RSEND that name here: the remote user woulnd't be
+ // able to recognize the file.
+ // Here we add another temporary offer with the right filename.
+
+ // now add a file offer , so he we will accept it automatically
+ // 120 secs is a reasonable timeout
+ QString szMask;
+ dcc->ctcpMsg->pSource->mask(szMask,KviIrcMask::NickUserHost);
+
+ KviSharedFile * pOld = o;
+ o = g_pSharedFilesManager->addSharedFile(szFileName,o->absFilePath(),szMask,120);
+ if(!o)o = pOld; // give up (FIXME: should we notify that ?)
+ }
+
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("Accepting file request from %Q [%Q@%Q] for '%s' (real file: %Q), offering DCC %s since we can't accept incoming connections (user option)","dcc"),
+ &(dcc->ctcpMsg->pSource->nick()),
+ &(dcc->ctcpMsg->pSource->username()),
+ &(dcc->ctcpMsg->pSource->host()),dcc->szParam1.ptr(),
+ &(o->absFilePath()),szSubproto.ptr());
+ }
+
+ dcc->pConsole->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %u%c",
+ dcc->pConsole->connection()->encodeText(dcc->ctcpMsg->pSource->nick()).data(),
+ 0x01,szSubproto.ptr(),
+ dcc->pConsole->connection()->encodeText(dcc->szParam1.ptr()).data(),o->fileSize(),0x01);
+ return;
+ }
+
+
+ KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole);
+ d->szNick = dcc->ctcpMsg->pSource->nick();
+ d->szLocalFileName = o->absFilePath();
+ d->szUser = dcc->ctcpMsg->pSource->username();
+ d->szHost = dcc->ctcpMsg->pSource->host();
+ d->bRecvFile = false;
+ dcc_fill_local_nick_user_host(d,dcc);
+
+ QString tmp;
+ if(!dcc_kvs_get_listen_ip_address(0,d->console(),tmp))
+ {
+ d->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("No suitable interface to listen on, trying to continue anyway...","dcc"));
+ d->szListenIp = "0.0.0.0";
+ } else
+ d->szListenIp=QString(tmp);
+//#warning "DO STH WITH THIS PORT (HOW TO SPECIFY IT ?)"
+ d->szListenPort = "0"; // any port is ok
+
+ if(KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault))
+ {
+ d->szFakeIp = KVI_OPTION_STRING(KviOption_stringDefaultDccFakeAddress);
+ if(d->szFakeIp.isEmpty())KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault) = false;
+ }
+
+ d->bDoTimeout = true;
+ d->szIp = __tr2qs_ctx("(unknown)","dcc");
+ d->szPort = d->szIp;
+ d->bActive = false;
+ d->bSendRequest = true;
+ d->bIsTdcc = bTurboExtension;
+#ifdef COMPILE_SSL_SUPPORT
+ d->bIsSSL = bSSLExtension;
+#endif
+ d->bNoAcks = d->bIsTdcc;
+ d->bOverrideMinimize = false;
+
+ dcc_module_set_dcc_type(d,"SEND");
+
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("Accepting file request from %Q [%Q@%Q] for '%s' (real file: %Q), offering DCC %Q","dcc"),
+ &(dcc->ctcpMsg->pSource->nick()),
+ &(dcc->ctcpMsg->pSource->username()),
+ &(dcc->ctcpMsg->pSource->host()),
+ dcc->szParam1.ptr(),
+ &(o->absFilePath()),&(d->szType));
+ }
+ d->triggerCreationEvent();
+ g_pDccBroker->sendFileExecute(0,d);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// VOICE
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void dccModuleParseDccVoice(KviDccRequest *dcc)
+{
+ //
+ // We have received a DCC VOICE request in the following form:
+ //
+ // DCC VOICE codec <ipaddress> <port> <sample-rate>
+ //
+ // This means that we're requested to setup an ACTIVE voice connection
+ // ... Easy task :)
+ //
+
+ if(!dcc_module_check_limits(dcc))return;
+
+ if(!dcc_module_normalize_target_data(dcc,dcc->szParam2,dcc->szParam3))return;
+
+#ifdef COMPILE_DISABLE_DCC_VOICE
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCERROR,
+ __tr2qs_ctx("The above request cannot be accepted: DCC VOICE support not enabled at compilation time ","dcc"));
+ return;
+ }
+#endif
+ // Actually unused parameter
+ if(!kvi_dcc_voice_is_valid_codec(dcc->szParam1.ptr()))
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCERROR,
+ __tr2qs_ctx("The above request cannot be accepted: Unsupported codec '%s'","dcc"),dcc->szParam1.ptr());
+ return;
+ }
+ }
+
+ bool bOk;
+
+ int iSampleRate = dcc->szParam4.toInt(&bOk);
+ if(!bOk)
+ {
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+ __tr2qs_ctx("The above request appears to be broken: Invalid sample-rate '%s', defaulting to 8000","dcc"),dcc->szParam4.ptr());
+ }
+ iSampleRate = 8000;
+ }
+
+
+ KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole);
+ d->szNick = dcc->ctcpMsg->pSource->nick();
+ d->szUser = dcc->ctcpMsg->pSource->username();
+ d->szHost = dcc->ctcpMsg->pSource->host();
+ dcc_fill_local_nick_user_host(d,dcc);
+
+
+ d->szIp = dcc->szParam2.ptr();
+ d->szPort = dcc->szParam3.ptr();
+ d->bActive = true; // we have to connect
+ d->bIsTdcc = false;
+ d->bNoAcks = false; // this has no meaning in voice
+ d->szCodec = dcc->szParam1;
+ d->iSampleRate = iSampleRate;
+ d->bOverrideMinimize = false;
+ d->bAutoAccept = KVI_OPTION_BOOL(KviOption_boolAutoAcceptDccVoice);
+ dcc_module_set_dcc_type(d,"VOICE");
+ d->triggerCreationEvent();
+ g_pDccBroker->activeVoiceManage(d);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// CANVAS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void dccModuleParseDccCanvas(KviDccRequest *dcc)
+{
+ //
+ // We have received a DCC CANVAS request in the following form:
+ //
+ // DCC CANVAS unused <ipaddress> <port>
+ //
+ // This means that we're requested to setup an ACTIVE canvas connection
+ // ... Easy task :)
+ //
+ if(!dcc_module_check_limits(dcc))return;
+
+ if(!dcc_module_normalize_target_data(dcc,dcc->szParam2,dcc->szParam3))return;
+
+// Actually unused parameter
+// if(!(kvi_strEqualCI("canvas",dcc->szParam1.ptr())))
+// {
+// if(!dcc->ctcpMsg->msg->haltOutput())
+// {
+// dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
+// __tr("The above request is broken: the second parameter is '%s' and shoud be 'chat'; trying to continue"),dcc->szParam1.ptr());
+// }
+// }
+#ifdef COMPILE_DCC_CANVAS
+ KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole);
+ d->szNick = dcc->ctcpMsg->pSource->nick();
+ d->szUser = dcc->ctcpMsg->pSource->username();
+ d->szHost = dcc->ctcpMsg->pSource->host();
+ dcc_fill_local_nick_user_host(d,dcc);
+
+
+ d->szIp = dcc->szParam2.ptr();
+ d->szPort = dcc->szParam3.ptr();
+ d->bActive = true; // we have to connect
+ d->bIsTdcc = false;
+ d->bNoAcks = false; // this has no meaning in canvas
+ d->bOverrideMinimize = false;
+ d->bAutoAccept = KVI_OPTION_BOOL(KviOption_boolAutoAcceptDccCanvas);
+ dcc_module_set_dcc_type(d,"CANVAS");
+ d->triggerCreationEvent();
+ g_pDccBroker->activeCanvasManage(d);
+#endif
+}
+
+
+static void dccModuleParseDccList(KviDccRequest *dcc)
+{
+ // DCC LIST <mask> <ipaddr> <port>
+ // FIXME!
+}
+
+
+
+typedef void (*dccParseProc)(KviDccRequest *);
+typedef struct _dccParseProcEntry
+{
+ const char * type;
+ dccParseProc proc;
+} dccParseProcEntry;
+
+#define KVI_NUM_KNOWN_DCC_TYPES 27
+
+static dccParseProcEntry dccParseProcTable[KVI_NUM_KNOWN_DCC_TYPES]=
+{
+ { "CHAT" , dccModuleParseDccChat },
+ { "SCHAT" , dccModuleParseDccChat },
+ { "SEND" , dccModuleParseDccSend },
+ { "TSEND" , dccModuleParseDccSend },
+ { "SSEND" , dccModuleParseDccSend },
+ { "TSSEND" , dccModuleParseDccSend },
+ { "STSEND" , dccModuleParseDccSend },
+ { "GET" , dccModuleParseDccGet },
+ { "SGET" , dccModuleParseDccGet },
+ { "TGET" , dccModuleParseDccGet },
+ { "STGET" , dccModuleParseDccGet },
+ { "TSGET" , dccModuleParseDccGet },
+ { "LIST" , dccModuleParseDccList },
+ { "ACCEPT" , dccModuleParseDccAccept },
+ { "RESUME" , dccModuleParseDccResume },
+ { "RECV" , dccModuleParseDccRecv },
+ { "SRECV" , dccModuleParseDccRecv },
+ { "TRECV" , dccModuleParseDccRecv },
+ { "TSRECV" , dccModuleParseDccRecv },
+ { "STRECV" , dccModuleParseDccRecv },
+ { "RSEND" , dccModuleParseDccRSend },
+ { "SRSEND" , dccModuleParseDccRSend },
+ { "TRSEND" , dccModuleParseDccRSend },
+ { "STRSEND", dccModuleParseDccRSend },
+ { "TSRSEND", dccModuleParseDccRSend },
+ { "CANVAS" , dccModuleParseDccCanvas },
+ { "VOICE" , dccModuleParseDccVoice }
+};
+
+
+
+// We want C linkage on this one: we want to be able to dlsym() it with a simple name
+// FIXME: Is this portable enough ? Or is better to have a table entry ?
+
+KVIMODULEEXPORTFUNC void dccModuleCtcpDccParseRoutine(KviDccRequest *dcc)
+{
+ dcc->szType.toUpper();
+
+ for(int i=0;i<KVI_NUM_KNOWN_DCC_TYPES;i++)
+ {
+ if(kvi_strEqualCS(dccParseProcTable[i].type,dcc->szType.ptr()))
+ {
+ (dccParseProcTable[i].proc)(dcc);
+ return;
+ }
+ }
+ // ops...we don't know this dcc type
+ if(!dcc->ctcpMsg->msg->haltOutput())
+ {
+ KviStr szError(KviStr::Format,
+ __tr2qs_ctx("Unknown DCC type '%s'","dcc"),dcc->szType.ptr());
+ dcc_module_request_error(dcc,szError.ptr());
+ }
+}
diff --git a/src/modules/dcc/send.cpp b/src/modules/dcc/send.cpp
new file mode 100644
index 00000000..c6cc1182
--- /dev/null
+++ b/src/modules/dcc/send.cpp
@@ -0,0 +1,1898 @@
+//=============================================================================
+//
+// 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-2005 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 "send.h"
+#include "broker.h"
+#include "marshal.h"
+#include "broker.h"
+#include "window.h"
+#include "kvi_styled_controls.h"
+
+#ifdef COMPILE_ON_WINDOWS
+ // Ugly Windoze compiler...
+ #include "dialogs.h"
+#endif
+
+#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_ircview.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+#include "kvi_error.h"
+#include "kvi_out.h"
+#include "kvi_netutils.h"
+#include "kvi_console.h"
+#include "kvi_frame.h"
+#include "kvi_malloc.h"
+#include "kvi_memmove.h"
+#include "kvi_thread.h"
+#include "kvi_ircsocket.h"
+
+#include "kvi_mediatype.h"
+#include "kvi_socket.h"
+#include "kvi_kvs_eventtriggers.h"
+#include "kvi_parameterlist.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_sparser.h"
+#include "kvi_kvs_script.h"
+
+#include <qevent.h>
+#include <qfile.h>
+#include <qpainter.h>
+#include <qdatetime.h>
+#include <qglobal.h>
+#include <qcheckbox.h>
+#include <qspinbox.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+
+#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
+
+//#include <unistd.h> //close()
+
+// FIXME: SSL Support here!
+// FIXME: The events OnDCCConnect etc are in wrong places here...!
+
+extern KviDccBroker * g_pDccBroker;
+
+extern KVIRC_API KviMediaManager * g_pMediaManager; // kvi_app.cpp
+
+
+static KviPointerList<KviDccFileTransfer> * g_pDccFileTransfers = 0;
+static QPixmap * g_pDccFileTransferIcon = 0;
+
+//#warning "The events that have a KviStr 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_iAverageSpeed = -1;
+ m_iInstantSpeed = -1;
+ m_iFilePosition = 0;
+
+ m_iTotalReceivedBytes = 0;
+ m_iInstantReceivedBytes = 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)
+{
+ int size = htonl(filePos);
+ if(kvi_socket_send(m_fd,(void *)(&size),4) != 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_iFilePosition = m_pFile->at();
+ m_iAverageSpeed = m_iTotalReceivedBytes / 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_iInstantSpeed = (m_iInstantReceivedBytes * 1000) / m_uInstantSpeedInterval;
+ m_iInstantReceivedBytes = 0;
+ m_uInstantSpeedInterval = uMSecsOfTheNextInterval;
+ } else {
+ if(uElapsedTime <= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS)
+ m_iInstantSpeed = m_iAverageSpeed;
+ }
+ m_pMutex->unlock();
+}
+
+void KviDccRecvThread::postMessageEvent(const char * m)
+{
+ KviThreadDataEvent<KviStr> * e = new KviThreadDataEvent<KviStr>(KVI_DCC_THREAD_EVENT_MESSAGE);
+ e->setData(new KviStr(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(IO_WriteOnly | IO_Append))
+ {
+ postErrorEvent(KviError_cantOpenFileForAppending);
+ goto exit_dcc;
+ } // else pFile is already at end
+ } else {
+ if(!m_pFile->open(IO_WriteOnly))
+ {
+ postErrorEvent(KviError_cantOpenFileForWriting);
+ goto exit_dcc;
+ }
+ }
+
+ if(m_pOpt->bSendZeroAck && (!m_pOpt->bNoAcks))
+ {
+ if(!sendAck(m_pFile->at()))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 > ((unsigned int)(m_iInstantReceivedBytes)) ? uMaxPossible - m_iInstantReceivedBytes : 0;
+ if(uToRead > KVI_DCC_RECV_BLOCK_SIZE)uToRead = KVI_DCC_RECV_BLOCK_SIZE;
+
+ if(uToRead > 0)
+ {
+ int readLen = kvi_socket_recv(m_fd,buffer,uToRead);
+
+ if(readLen > 0)
+ {
+ // Readed something useful...write back
+ if((m_pOpt->iTotalFileSize > -1) && ((readLen + (int)m_pFile->at()) > m_pOpt->iTotalFileSize))
+ {
+ postMessageEvent(__tr2qs_ctx("WARNING: The peer is sending garbage data past the end of the file","dcc"));
+ postMessageEvent(__tr2qs_ctx("WARNING: Ignoring data past the declared end of file and closing the connection","dcc"));
+
+ readLen = m_pOpt->iTotalFileSize - m_pFile->at();
+ if(readLen > 0)
+ {
+ if(m_pFile->writeBlock(buffer,readLen) != readLen)
+ postErrorEvent(KviError_fileIOError);
+ }
+ break;
+
+ } else {
+ if(m_pFile->writeBlock(buffer,readLen) != readLen)
+ {
+ postErrorEvent(KviError_fileIOError);
+ break;
+ }
+ }
+
+ // Update stats
+ m_iTotalReceivedBytes += readLen;
+ m_iInstantReceivedBytes += readLen;
+
+ updateStats();
+ // Now send the ack
+ if(m_pOpt->bNoAcks)
+ {
+ // No acks...
+ // Interrupt if the whole file has been received
+ if(m_pOpt->iTotalFileSize > 0)
+ {
+ if(((int)(m_pFile->at())) == m_pOpt->iTotalFileSize)
+ {
+ // 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->at()))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...
+
+ if(readLen == 0)
+ {
+ // readed EOF..
+ if((((int)(m_pFile->at())) == m_pOpt->iTotalFileSize) || (m_pOpt->iTotalFileSize < 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(((int)(m_pFile->at())) == m_pOpt->iTotalFileSize)
+ {
+ // Wait for the peer to close the connection
+ if(iProbableTerminationTime == 0)
+ {
+ iProbableTerminationTime = (int)kvi_unixTime();
+ m_pFile->flush();
+ postMessageEvent(__tr2qs_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(__tr2qs_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)
+ {
+ debug("LOOP: artificial delay");
+ 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;
+ }
+ 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_iAverageSpeed = -1;
+ m_iInstantSpeed = -1;
+ m_iFilePosition = 0;
+ m_iTotalSentBytes = 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_iAverageSpeed = m_iTotalSentBytes / uElapsedTime;
+ } else {
+ // acknowledges : we compute the avg bandwidth based on the acks we receive
+ m_iAverageSpeed = (m_iAckedBytes - m_pOpt->iStartPosition) / 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_iInstantSpeed = (m_iInstantSentBytes * 1000) / m_uInstantSpeedInterval;
+ m_uInstantSpeedInterval = uMSecsOfNextPeriodUsed;
+ m_iInstantSentBytes = 0;
+ } else {
+ if(uElapsedTime <= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS)
+ m_iInstantSpeed = m_iAverageSpeed;
+ }
+ m_pMutex->unlock();
+}
+
+void KviDccSendThread::run()
+{
+ m_pTimeInterval->mark();
+ m_pMutex->lock();
+ m_uStartTime = m_pTimeInterval->secondsCounter();
+ m_pMutex->unlock();
+
+ m_iTotalSentBytes = 0;
+ m_iInstantSentBytes = 0;
+ int iFailedSelects = 0;
+ char ackbuffer[4];
+ int iBytesInAckBuffer = 0;
+ Q_UINT32 iLastAck = 0;
+
+ if(m_pOpt->iPacketSize < 32)m_pOpt->iPacketSize = 32;
+ char * buffer = (char *)kvi_malloc(m_pOpt->iPacketSize * sizeof(char));
+
+ QFile * pFile = new QFile(QString::fromUtf8(m_pOpt->szFileName.ptr()));
+
+ if(!pFile->open(IO_ReadOnly))
+ {
+ postErrorEvent(KviError_cantOpenFileForReading);
+ goto exit_dcc;
+ }
+
+ if(pFile->size() < 1)
+ {
+ postErrorEvent(KviError_cantSendAZeroSizeFile);
+ goto exit_dcc;
+ }
+
+ if(m_pOpt->iStartPosition > 0)
+ {
+ // seek
+ if(!(pFile->at(m_pOpt->iStartPosition)))
+ {
+ postErrorEvent(KviError_fileIOError);
+ goto exit_dcc;
+ }
+ }
+
+ iLastAck = m_pOpt->iStartPosition;
+
+ 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 = kvi_socket_recv(m_fd,(void *)(ackbuffer + iBytesInAckBuffer),iAckBytesToRead);
+ if(readLen > 0)
+ {
+ iBytesInAckBuffer += readLen;
+ if(iBytesInAckBuffer == 4)
+ {
+ Q_UINT32 iNewAck = ntohl(*((Q_UINT32 *)ackbuffer));
+ if((iNewAck > pFile->at()) || (iNewAck < iLastAck))
+ {
+ // the peer is drunk or is trying to fool us
+ postErrorEvent(KviError_acknowledgeError);
+ break;
+ }
+ iLastAck = iNewAck;
+ iBytesInAckBuffer = 0;
+ }
+ } else {
+ if(!handleInvalidSocketRead(readLen))break;
+ }
+
+ // update stats
+ m_pMutex->lock(); // is this really necessary ?
+ m_iAckedBytes = iLastAck;
+ m_pMutex->unlock();
+
+ if(iLastAck >= 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 = kvi_socket_recv(m_fd,(void *)&iAck,4);
+ if(readLen == 0)
+ {
+ // done...success
+ updateStats();
+ KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS);
+ postEvent(parent(),e);
+ break;
+ } else {
+ if(readLen < 0)
+ {
+ if(!handleInvalidSocketRead(readLen))break;
+ } else {
+ KviThreadDataEvent<KviStr> * e = new KviThreadDataEvent<KviStr>(KVI_DCC_THREAD_EVENT_MESSAGE);
+ e->setData(new KviStr(__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 || (iLastAck == pFile->at()))
+ {
+ // maximum readable size
+ int toRead = pFile->size() - pFile->at();
+ // the max number of bytes we can send in this interval (bandwidth limit)
+ m_pMutex->lock(); // FIXME: how to remove this lock ?
+ int iMaxPossible = 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(iMaxPossible < m_iInstantSentBytes)toRead = 0; // already sent too much!
+ else {
+ iMaxPossible -= m_iInstantSentBytes;
+ if(toRead > iMaxPossible)toRead = iMaxPossible;
+ }
+ // limit to packet size
+ if(toRead > m_pOpt->iPacketSize)toRead = m_pOpt->iPacketSize;
+
+ int written = 0;
+ if(toRead > 0)
+ {
+ // read data
+ int readed = pFile->readBlock(buffer,toRead);
+ if(readed < toRead)
+ {
+ postErrorEvent(KviError_fileIOError);
+ break;
+ }
+ // send it out
+ written = kvi_socket_send(m_fd,buffer,toRead);
+ if(written < toRead)
+ {
+ if(written < 0)
+ {
+ // error ?
+ if(!handleInvalidSocketRead(written))break;
+ } else {
+ // seek back to the right position
+ pFile->at(pFile->at() - (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_iTotalSentBytes += written;
+ m_iInstantSentBytes += written;
+ m_iFilePosition = pFile->at();
+ 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:
+ kvi_free(buffer);
+ pFile->close();
+ delete pFile;
+ pFile = 0;
+ 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->bIsTdcc ? (dcc->bRecvFile ? "TRECV" : "TSEND") : (dcc->bRecvFile ? "RECV" : "SEND");
+
+ 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.toUInt(&bOk) : dcc->szLocalFileSize.toUInt(&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;
+ KviServerParser::encodeCtcpParameter(m_pDescriptor->szFileName.utf8().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.utf8().data(),
+ m_pDescriptor->szLocalFileSize.utf8().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.utf8().data(),
+ m_pDescriptor->szLocalFileSize.utf8().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->start(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000,true);
+ } else {
+ listenOrConnect();
+ }
+
+ displayUpdate();
+}
+
+void KviDccFileTransfer::listenOrConnect()
+{
+ if(!(m_pDescriptor->bActive))
+ {
+ int ret = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout);
+ if(ret != KviError_success)handleMarshalError(ret);
+ } else {
+ int ret = m_pMarshal->dccConnect(m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data(),m_pDescriptor->bDoTimeout);
+ if(ret != KviError_success)handleMarshalError(ret);
+ }
+
+ 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.utf8().data();
+}
+
+void KviDccFileTransfer::die()
+{
+ delete this;
+}
+
+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.utf8().data(),m_pDescriptor->szLocalFileName.utf8().data(),m_pDescriptor->szNick.utf8().data(),__tr_ctx("Aborted","dcc"));
+
+ KviStr 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"),QString(tmp.ptr()),m_pDescriptor->idString());
+
+ outputAndLog(KVI_OUT_DCCERROR,m_szStatusString);
+ displayUpdate();
+}
+
+
+void KviDccFileTransfer::fillContextPopup(KviTalPopupMenu * m,int column)
+{
+ 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()));
+ /* FIX ME credo che il problema sia che se riavvio un trasferimento, a sua volta gia'
+ avviato, questo non ha irc contex, perche' la finestra "in cui e' nato"e' sta
+ quella della dcc. Conservarsi l'id della finestra? */
+ 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;
+ szId.setNum(m_pDescriptor->id());
+ 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;
+ szId.setNum(m_pDescriptor->id());
+ 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;
+ szId.setNum(m_pDescriptor->id());
+ 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 iAvgBandwidth = 0;
+ if(m_pDescriptor->bRecvFile)
+ {
+ if(m_pSlaveRecvThread)
+ {
+ m_pSlaveRecvThread->initGetInfo();
+ iAvgBandwidth = (unsigned int)m_pSlaveRecvThread->averageSpeed();
+ m_pSlaveRecvThread->doneGetInfo();
+ }
+ } else {
+ if(m_pSlaveSendThread)
+ {
+ m_pSlaveSendThread->initGetInfo();
+ iAvgBandwidth = (unsigned int)m_pSlaveSendThread->averageSpeed();
+ m_pSlaveSendThread->doneGetInfo();
+ }
+ }
+ return iAvgBandwidth;
+}
+
+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,int width,int height)
+{
+
+ QString txt;
+ bool bIsTerminated = ((m_eGeneralStatus == Success) || (m_eGeneralStatus == Failure));
+
+ switch(column)
+ {
+ case COLUMN_TRANSFERTYPE:
+ {
+ 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(3,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 = 4;
+
+ p->setPen(Qt::black);
+
+ KviStr szRemote(KviStr::Format,"dcc://%s@%s:%s/%s",m_pDescriptor->szNick.utf8().data(),m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data(),
+ m_pDescriptor->szFileName.utf8().data());
+
+ p->drawText(4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,
+ m_pDescriptor->bRecvFile ? szRemote.ptr() : m_pDescriptor->szLocalFileName.utf8().data());
+ iY += iLineSpacing;
+
+ p->drawText(4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,
+ m_pDescriptor->bRecvFile ? m_pDescriptor->szLocalFileName.utf8().data() : szRemote.ptr());
+ iY += iLineSpacing;
+
+
+ p->setPen(Qt::darkGray);
+
+ p->drawText(4,4,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szFrom);
+ p->drawText(4,4 + iLineSpacing,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szTo);
+
+
+ p->setPen(QColor(180,180,200));
+
+ iLineSpacing += 2;
+
+ p->drawRect(4,height - (iLineSpacing + 4),width - 8,iLineSpacing);
+ p->fillRect(5,height - (iLineSpacing + 3),width - 10,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240));
+
+ p->setPen(Qt::black);
+
+ p->drawText(7,height - (iLineSpacing + 4),width - 14,iLineSpacing,Qt::AlignVCenter | Qt::AlignLeft,m_szStatusString);
+
+ }
+ break;
+ case COLUMN_PROGRESS:
+ {
+
+ QFontMetrics fm(p->font());
+
+ int iW = width - 8;
+ int iAvgBandwidth = -1;
+ int iInstantSpeed = -1;
+ int iAckedBytes = -1;
+
+ int iEta = -1;
+
+ unsigned int uTransferred = 0;
+
+ if(m_pDescriptor->bRecvFile)
+ {
+ if(m_pSlaveRecvThread)
+ {
+ m_pSlaveRecvThread->initGetInfo();
+ iAvgBandwidth = m_pSlaveRecvThread->averageSpeed();
+ iInstantSpeed = m_pSlaveRecvThread->instantSpeed();
+ uTransferred = m_pSlaveRecvThread->filePosition();
+ m_pSlaveRecvThread->doneGetInfo();
+ }
+ } else {
+ if(m_pSlaveSendThread)
+ {
+ m_pSlaveSendThread->initGetInfo();
+ iAvgBandwidth = m_pSlaveSendThread->averageSpeed();
+ iInstantSpeed = m_pSlaveSendThread->instantSpeed();
+ uTransferred = m_pSlaveSendThread->filePosition();
+ iAckedBytes = m_pSlaveSendThread->ackedBytes();
+ m_pSlaveSendThread->doneGetInfo();
+ }
+ }
+
+ p->setPen(bIsTerminated ? Qt::lightGray : QColor(210,210,240));
+ p->drawRect(4,4,iW,12);
+
+ iW -= 2;
+
+ if(m_uTotalFileSize > 0)
+ {
+ if(iAvgBandwidth > 0)
+ {
+ unsigned int uRemaining = m_uTotalFileSize - uTransferred;
+ iEta = uRemaining / iAvgBandwidth;
+ }
+
+ if(!m_pDescriptor->bNoAcks && (iAckedBytes > 0) && (iAckedBytes < ((int)(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)iAckedBytes) * 100.0) / (double)m_uTotalFileSize;
+ int iL2 = (int) ((((double)iW) * dPerc2) / 100.0);
+ int iW2 = iL1 - iL2;
+ if(iW2 > 0)p->fillRect(5 + iL2,5,iW2,10,bIsTerminated ? QColor(150,130,110) : QColor(220,170,100));
+ p->fillRect(5,5,iL2,10,bIsTerminated ? QColor(140,110,110) : QColor(200,100,100));
+
+ txt = QString(__tr2qs_ctx("%1 of %2 (%3%)","dcc")).arg(KviQString::makeSizeReadable(iAckedBytes)).arg(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(5,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)).arg(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(4,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 += " ";
+ if(iInstantSpeed >= 0)
+ {
+ QString tmpisp;
+ KviNetUtils::formatNetworkBandwidthString(tmpisp,iInstantSpeed);
+ txt += tmpisp;
+ } else {
+ txt += "? B/s";
+ }
+ txt += " [";
+ } else {
+ txt = "";
+ }
+
+ txt += __tr2qs_ctx("Avg:","dcc");
+ txt += " ";
+ if(iAvgBandwidth >= 0)
+ {
+ QString tmpspd;
+ KviNetUtils::formatNetworkBandwidthString(tmpspd,iAvgBandwidth);
+ txt += tmpspd;
+ } else {
+ txt += "? B/s";
+ }
+
+ if(!bIsTerminated)
+ {
+ txt += "]";
+ }
+
+ int iDaH = height - (iLineSpacing + 4);
+
+ p->setPen(QColor(180,180,200));
+ p->drawRect(4,iDaH,iLeftHalf,iLineSpacing);
+ p->fillRect(5,iDaH + 1,iLeftHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240));
+ p->setPen(bIsTerminated ? Qt::darkGray : Qt::black);
+ p->drawText(6,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(width - (4 + iRightHalf),iDaH,iRightHalf,iLineSpacing);
+ p->fillRect(width - (3 + iRightHalf),iDaH + 1,iRightHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240));
+ p->setPen(bIsTerminated ? Qt::darkGray : Qt::black);
+ p->drawText(width - (2 + iRightHalf),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("<table><tr><td bgcolor=\"#000000\"><font color=\"#FFFFFF\"><b>DCC %1 (ID %2)</b></font></td></tr>").arg(m_szDccType.ptr()).arg(id());
+
+ s += "<tr><td bgcolor=\"#404040\"><font color=\"#FFFFFF\">";
+ s += __tr2qs_ctx("Transfer Log","dcc");
+ s += "</font></td></tr>";
+ s += "<tr><td bgcolor=\"#C0C0C0\">";
+ s += m_szTransferLog;
+ s += "</td></tr>";
+ s += "<table>";
+
+ return s;
+}
+
+void KviDccFileTransfer::init()
+{
+ if(g_pDccFileTransfers)return;
+ g_pDccFileTransfers = new KviPointerList<KviDccFileTransfer>;
+ g_pDccFileTransfers->setAutoDelete(false);
+
+ QPixmap * pix = g_pIconManager->getImage("kvi_dccfiletransfericons.png");
+ if(pix)g_pDccFileTransferIcon = new QPixmap(*pix);
+ else g_pDccFileTransferIcon = new QPixmap(192,128);
+}
+
+void KviDccFileTransfer::done()
+{
+ if(!g_pDccFileTransfers)return;
+ while(KviDccFileTransfer * t = g_pDccFileTransfers->first())
+ delete t;
+ delete g_pDccFileTransfers;
+ g_pDccFileTransfers = 0;
+ 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())
+ {
+#ifdef COMPILE_ON_WINDOWS
+ // on windows the file names are case insensitive
+ if(t->localFileName().lower() == szLocalFileName.lower())
+#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,unsigned int 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 += "<br>";
+}
+
+
+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).arg(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()).arg(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"));
+ }
+ }
+ }
+ }
+
+ KviStr 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(" ","_");
+
+ KviServerParser::encodeCtcpParameter(tmp.utf8().data(),fName);
+ // Zero port requests want DCC SEND as back-request
+ KviStr szReq;
+
+ if(m_pDescriptor->isZeroPortRequest())
+ {
+ szReq = "SEND";
+ 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.utf8().data(),port.ptr(),
+ m_pDescriptor->szFileSize.utf8().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.utf8().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()).arg(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:
+ {
+ int * err = ((KviThreadDataEvent<int> *)e)->getData();
+ QString szErrorString = KviError::getDescription(*err);
+ delete err;
+ if(m_pDescriptor->bRecvFile)
+ g_pApp->fileDownloadTerminated(false,m_pDescriptor->szFileName.utf8().data(),m_pDescriptor->szLocalFileName.utf8().data(),m_pDescriptor->szNick.utf8().data(),szErrorString.utf8().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))
+ {
+ KviConsole *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,30);
+ }
+ */
+ if(m_pDescriptor->bRecvFile)g_pApp->fileDownloadTerminated(true,m_pDescriptor->szFileName.utf8().data(),m_pDescriptor->szLocalFileName.utf8().data(),m_pDescriptor->szNick.utf8().data());
+ m_szStatusString = __tr2qs_ctx("Transfer completed","dcc");
+ outputAndLog(m_szStatusString);
+ m_eGeneralStatus = Success;
+ m_tTransferEndTime = kvi_unixTime();
+
+ 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:
+ {
+ KviStr * str = ((KviThreadDataEvent<KviStr> *)e)->getData();
+ outputAndLog(QString(__tr_no_xgettext_ctx(str->ptr(),"dcc")));
+ delete str;
+ return true;
+ }
+ break;
+ default:
+ debug("Invalid event type %d received",((KviThreadEvent *)e)->id());
+ break;
+ }
+ }
+//#warning "Remove this!"
+// if(e->type() == QEvent::Close)debug("Close event received");
+ return KviFileTransfer::event(e);
+}
+
+void KviDccFileTransfer::handleMarshalError(int err)
+{
+ QString szErr = KviError::getDescription(err);
+ 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()).arg(m_pMarshal->remotePort()));
+ outputAndLog(__tr2qs_ctx("Local end is %1:%2","dcc").arg(m_pMarshal->localIp()).arg(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.utf8().data();
+ bool bOk;
+ o->iTotalFileSize = m_pDescriptor->szFileSize.toInt(&bOk);
+ if(!bOk)o->iTotalFileSize = -1;
+ 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);
+ m_pSlaveRecvThread->start();
+ } else {
+ KviDccSendThreadOptions * o = new KviDccSendThreadOptions;
+ o->szFileName = m_pDescriptor->szLocalFileName.utf8().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->iStartPosition = m_pDescriptor->szFileSize.toInt(&bOk);
+ if(!bOk || (o->iStartPosition < 0))o->iStartPosition = 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);
+ 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.utf8().data()) || KVI_OPTION_BOOL(KviOption_boolAcceptBrokenFileNameDccResumeRequests)))
+ return false;
+
+ if(!(kvi_strEqualCI(port,m_pDescriptor->szPort.utf8().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.utf8().data(),
+ m_pDescriptor->szPort.utf8().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).arg(m_pDescriptor->szPort);
+ outputAndLog(m_szStatusString);
+ displayUpdate();
+ }
+ */
+
+ return true;
+}
+
+bool KviDccFileTransfer::doResume(const char * filename,const char * port,unsigned int filePos)
+{
+ if(KviQString::equalCI(port,m_pMarshal->dccPort()) &&
+ (!m_pSlaveRecvThread) && (!m_pDescriptor->bRecvFile))
+ {
+ if(KviQString::equalCI(filename,m_pDescriptor->szFileName) || KVI_OPTION_BOOL(KviOption_boolAcceptBrokenFileNameDccResumeRequests))
+ {
+ bool bOk;
+ unsigned int iLocalFileSize = m_pDescriptor->szLocalFileSize.toUInt(&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);
+
+
+ KviStr szBuffy;
+ KviServerParser::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;
+ }
+ }
+ return false;
+}
+
+
+
+
+
+
+KviDccFileTransferBandwidthDialog::KviDccFileTransferBandwidthDialog(QWidget * pParent,KviDccFileTransfer * t)
+: QDialog(pParent)
+{
+ QGridLayout * g = new QGridLayout(this,3,3,4,4);
+
+ m_pTransfer = t;
+ int iVal = m_pTransfer->bandwidthLimit();
+
+ QString szText = __tr2qs_ctx("Configure bandwidth for DCC transfer %1","dcc").arg(t->id());
+ setCaption(szText);
+
+ szText = t->isFileUpload() ? __tr2qs_ctx("Limit upload bandwidth to","dcc") : __tr2qs_ctx("Limit download bandwidth to","dcc");
+
+ m_pEnableLimitCheck = new KviStyledCheckBox(szText,this);
+ g->addWidget(m_pEnableLimitCheck,0,0);
+
+ m_pEnableLimitCheck->setChecked((iVal >= 0) && (iVal < MAX_DCC_BANDWIDTH_LIMIT));
+
+ m_pLimitBox = new QSpinBox(0,MAX_DCC_BANDWIDTH_LIMIT-1,1,this);
+ m_pLimitBox->setEnabled((iVal >= 0) && (iVal < MAX_DCC_BANDWIDTH_LIMIT));
+ connect(m_pEnableLimitCheck,SIGNAL(toggled(bool)),m_pLimitBox,SLOT(setEnabled(bool)));
+ g->addMultiCellWidget(m_pLimitBox,0,0,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->setColStretch(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;
+}
+
+
+
+
+#include "m_send.moc"
diff --git a/src/modules/dcc/send.h b/src/modules/dcc/send.h
new file mode 100644
index 00000000..636f2b3b
--- /dev/null
+++ b/src/modules/dcc/send.h
@@ -0,0 +1,260 @@
+#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-2005 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_window.h"
+#include "kvi_string.h"
+
+#include "descriptor.h"
+#include "window.h"
+#include "thread.h"
+
+#include "kvi_sockettype.h"
+
+#include "kvi_pointerlist.h"
+#include <qlabel.h>
+#include <qprogressbar.h>
+#include "kvi_tal_popupmenu.h"
+#include "kvi_tal_hbox.h"
+#include "kvi_tal_vbox.h"
+#include <qfile.h>
+#include <qdialog.h>
+
+#include "kvi_filetransfer.h"
+#include "kvi_time.h"
+
+
+typedef struct _KviDccSendThreadOptions
+{
+ KviStr szFileName;
+ int iStartPosition;
+ 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!!!
+ int m_iAverageSpeed;
+ int m_iInstantSpeed;
+ int m_iFilePosition;
+ int m_iAckedBytes;
+ int m_iTotalSentBytes;
+ // internal
+ unsigned long m_uStartTime;
+ unsigned long m_uInstantSpeedInterval;
+ int m_iInstantSentBytes;
+ KviDccSendThreadOptions * m_pOpt;
+ KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth but not only
+public:
+ void initGetInfo();
+ int averageSpeed(){ return m_iAverageSpeed; };
+ int instantSpeed(){ return m_iInstantSpeed; };
+ int filePosition(){ return m_iFilePosition; };
+ // sent ONLY in this session
+ int sentBytes(){ return m_iTotalSentBytes; };
+ int ackedBytes(){ return m_iAckedBytes; };
+ 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;
+ KviStr szFileName;
+ int iTotalFileSize;
+ 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!
+ int m_iAverageSpeed;
+ int m_iInstantSpeed;
+ int m_iFilePosition;
+ int m_iTotalReceivedBytes;
+
+ // internal
+ unsigned long m_uStartTime;
+ KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth
+ int m_iInstantReceivedBytes;
+ unsigned long m_uInstantSpeedInterval;
+ QFile * m_pFile;
+public:
+ void initGetInfo();
+ int averageSpeed(){ return m_iAverageSpeed; };
+ int instantSpeed(){ return m_iInstantSpeed; };
+ int filePosition(){ return m_iFilePosition; };
+ // received ONLY in this session
+ int receivedBytes(){ return m_iTotalReceivedBytes; };
+ 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 KviDccFileTransfer;
+class QSpinBox;
+class QTimer;
+
+#include "kvi_styled_controls.h"
+
+class KviDccFileTransferBandwidthDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviDccFileTransferBandwidthDialog(QWidget * pParent,KviDccFileTransfer * t);
+ ~KviDccFileTransferBandwidthDialog();
+protected:
+ KviDccFileTransfer * m_pTransfer;
+ KviStyledCheckBox * m_pEnableLimitCheck;
+ QSpinBox * m_pLimitBox;
+protected:
+ virtual void closeEvent(QCloseEvent *e);
+protected slots:
+ void okClicked();
+ void cancelClicked();
+};
+
+
+class KviDccMarshal;
+class QPainter;
+class KviTalPopupMenu;
+
+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;
+
+ KviStr m_szTarget;
+ KviStr 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
+ unsigned int 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,unsigned int 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,unsigned int filePos);
+
+ virtual bool event(QEvent *e);
+
+ virtual KviWindow * dccMarshalOutputWindow();
+ virtual const char * dccMarshalOutputContextString();
+
+ virtual void displayPaint(QPainter * p,int column,int width,int height);
+ virtual int displayHeight(int iLineSpacing);
+ virtual void fillContextPopup(KviTalPopupMenu * m,int column);
+ virtual void fillStatusString(QString &szBuffer);
+ virtual bool active();
+ virtual void die();
+ virtual QString tipText();
+ virtual QString localFileName();
+
+ bool isFileUpload(){ return m_pDescriptor->isFileUpload(); };
+
+ unsigned int averageSpeed();
+ unsigned int transferredBytes();
+
+ int bandwidthLimit();
+ void setBandwidthLimit(int iVal);
+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(int err);
+ 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
new file mode 100644
index 00000000..7ae38bbe
--- /dev/null
+++ b/src/modules/dcc/thread.cpp
@@ -0,0 +1,111 @@
+//
+// 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) 1999-2000 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"
+#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+#include "kvi_window.h"
+#include "kvi_error.h"
+#include "kvi_memmove.h"
+#include "kvi_malloc.h"
+#include "kvi_netutils.h"
+#include "kvi_socket.h"
+#ifdef COMPILE_SSL_SUPPORT
+ #include "kvi_sslmaster.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
+// debug("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);
+ __range_invalid(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)
+{
+ __range_valid(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()
+{
+ KviStr buffer;
+ while(m_pSSL->getLastErrorString(buffer))
+ {
+ KviStr msg(KviStr::Format,"[SSL ERROR]: %s",buffer.ptr());
+ postMessageEvent(msg.ptr());
+ }
+}
+#endif
+
+void KviDccThread::postErrorEvent(int err)
+{
+ KviThreadDataEvent<int> * e = new KviThreadDataEvent<int>(KVI_DCC_THREAD_EVENT_ERROR);
+ e->setData(new int(err));
+ postEvent(m_pParent,e);
+}
+
+void KviDccThread::postMessageEvent(const char * message)
+{
+ KviThreadDataEvent<KviStr> * e = new KviThreadDataEvent<KviStr>(KVI_DCC_THREAD_EVENT_MESSAGE);
+ e->setData(new KviStr(message));
+ postEvent(m_pParent,e);
+}
diff --git a/src/modules/dcc/thread.h b/src/modules/dcc/thread.h
new file mode 100644
index 00000000..3d56661d
--- /dev/null
+++ b/src/modules/dcc/thread.h
@@ -0,0 +1,79 @@
+#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) 1999-2000 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 "kvi_thread.h"
+#include "kvi_sockettype.h"
+
+#include "kvi_pointerlist.h"
+
+#include <qobject.h>
+
+#ifdef COMPILE_SSL_SUPPORT
+ #include "kvi_ssl.h"
+#endif
+
+// KviThreadDataEvent<int>
+#define KVI_DCC_THREAD_EVENT_ERROR (KVI_THREAD_USER_EVENT_BASE + 1)
+// KviThreadDataEvent<KviStr>
+#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<KviStr>
+#define KVI_DCC_THREAD_EVENT_MESSAGE (KVI_THREAD_USER_EVENT_BASE + 4)
+// KviThreadDataEvent<int>
+#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);
+#endif
+};
+
+#endif //_THREAD_H_
diff --git a/src/modules/dcc/utils.cpp b/src/modules/dcc/utils.cpp
new file mode 100644
index 00000000..8d3229e7
--- /dev/null
+++ b/src/modules/dcc/utils.cpp
@@ -0,0 +1,169 @@
+//
+// 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 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 "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_netutils.h"
+#include "kvi_ircsocket.h"
+#include "kvi_qstring.h"
+
+/*
+bool dcc_module_get_listen_ip_address(KviCommand *c,KviConsole * 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).stripWhiteSpace();
+ if(!KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).isEmpty())
+ {
+ if(kvi_isValidStringIp(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).utf8().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).utf8().data());
+ return false;
+ }
+ } else {
+ szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface);
+ }
+ return true;
+ }
+#ifdef COMPILE_IPV6_SUPPORT
+ if(kvi_isValidStringIp_V6(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).utf8().data()))
+ {
+ szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface);
+ } else {
+#endif
+ if(!kvi_getInterfaceAddress(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).utf8().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).utf8().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,KviConsole * 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).stripWhiteSpace();
+ if(!KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).isEmpty())
+ {
+ if(kvi_isValidStringIp(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).utf8().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).utf8().data());
+ return false;
+ }
+ } else {
+ szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface);
+ }
+ return true;
+ }
+#ifdef COMPILE_IPV6_SUPPORT
+ if(kvi_isValidStringIp_V6(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).utf8().data()))
+ {
+ szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface);
+ } else {
+#endif
+ if(!kvi_getInterfaceAddress(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).utf8().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).utf8().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;
+}
+
diff --git a/src/modules/dcc/utils.h b/src/modules/dcc/utils.h
new file mode 100644
index 00000000..992814f2
--- /dev/null
+++ b/src/modules/dcc/utils.h
@@ -0,0 +1,34 @@
+#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 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 "kvi_string.h"
+#include "kvi_console.h"
+#include "kvi_kvs_moduleinterface.h"
+
+#ifndef _UTILS_CPP_
+ extern bool dcc_kvs_get_listen_ip_address(KviKvsModuleCommandCall *c,KviConsole * pConsole,QString &szListenIp);
+#endif
+
+#endif //_UTILS_H_
diff --git a/src/modules/dcc/voice.cpp b/src/modules/dcc/voice.cpp
new file mode 100644
index 00000000..2e34df2f
--- /dev/null
+++ b/src/modules/dcc/voice.cpp
@@ -0,0 +1,1041 @@
+//
+// 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 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 "kvi_settings.h"
+#include "kvi_iconmanager.h"
+#include "kvi_ircview.h"
+#include "kvi_locale.h"
+#include "kvi_out.h"
+#include "kvi_error.h"
+#include "kvi_netutils.h"
+#include "kvi_options.h"
+#include "kvi_console.h"
+#include "kvi_malloc.h"
+#include "kvi_socket.h"
+#include "kvi_ircconnection.h"
+
+#include "adpcmcodec.h"
+#include "gsmcodec.h"
+
+#include <qframe.h>
+#include <qsplitter.h>
+#include "kvi_tal_vbox.h"
+#include <qslider.h>
+#include <qtooltip.h>
+
+#ifndef COMPILE_ON_WINDOWS
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <errno.h>
+ #include <fcntl.h>
+//#include "kvi_error.h"
+
+#include <sys/stat.h> // for open()
+#include <sys/ioctl.h> // for ioctl()
+#endif //!COMPILE_ON_WIDNOWS
+
+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 <linux/soundcard.h>
+ #else
+ #ifdef HAVE_SYS_SOUNDCARD_H
+ #include <sys/soundcard.h>
+ #else
+ #ifdef HAVE_SOUNDCARD_H
+ #include <soundcard.h>
+ #else
+ //CAN NOT COMPILE :(
+ #define COMPILE_DISABLE_DCC_VOICE
+ #ifndef COMPILE_ON_WINDOWS
+ #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"));
+ 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"));
+ }
+
+ 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)
+ {
+ KviStr tmp(KviStr::Format,__tr2qs_ctx("WARNING: failed to set the requested sample rate (%d): the device used closest match (%d)","dcc"),
+ 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"));
+ }
+ } // 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)
+ {
+ debug("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;
+ //debug("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)
+ {
+ debug("Ispace failed");
+ info.fragments = 0; // dummy...
+ info.bytes = 0;
+ }
+
+ //debug("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);
+ }
+ }
+ }
+/*
+ debug("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");
+ }
+ debug("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
+ //debug("Start recording");
+ if(m_bRecording)return; // already started
+ if(openSoundcardForReading())
+ {
+// debug("Posting event");
+ KviThreadDataEvent<int> * e = new KviThreadDataEvent<int>(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
+ //debug("Stop recording");
+ m_bRecordingRequestPending = false;
+ if(!m_bRecording)return; // already stopped
+
+ KviThreadDataEvent<int> * e = new KviThreadDataEvent<int>(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
+ //debug("Start playing");
+ if(m_bPlaying)return;
+
+ if(openSoundcardForWriting())
+ {
+ KviThreadDataEvent<int> * e = new KviThreadDataEvent<int>(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
+ //debug("Stop playing");
+ if(!m_bPlaying)return;
+
+ KviThreadDataEvent<int> * e = new KviThreadDataEvent<int>(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<int> *)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(KviFrame *pFrm,KviDccDescriptor * dcc,const char * name)
+: KviDccWindow(KVI_WINDOW_TYPE_DCCVOICE,pFrm,name,dcc)
+{
+ m_pDescriptor = dcc;
+ m_pSlaveThread = 0;
+
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"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->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->setToggleButton(true);
+#if QT_VERSION >= 300
+ QIconSet iset;
+ iset.setPixmap(*(g_pIconManager->getBigIcon(KVI_BIGICON_DISCONNECTED)),QIconSet::Large,QIconSet::Normal,QIconSet::Off);
+ iset.setPixmap(*(g_pIconManager->getBigIcon(KVI_BIGICON_CONNECTED)),QIconSet::Large,QIconSet::Normal,QIconSet::On);
+ m_pTalkButton->setIconSet(iset);
+#else
+ m_pTalkButton->setOffIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_DISCONNECTED)));
+ m_pTalkButton->setOnIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_CONNECTED)));
+#endif
+ m_pTalkButton->setUsesBigPixmap(true);
+
+ 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"));
+ int ret = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout);
+ if(ret != KviError_success)handleMarshalError(ret);
+ } else {
+ // ACTIVE CONNECTION
+ output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC VOICE connection","dcc"));
+ int ret = m_pMarshal->dccConnect(m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data(),m_pDescriptor->bDoTimeout);
+ if(ret != KviError_success)handleMarshalError(ret);
+ }
+}
+
+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)
+ {
+ KviStr ip = !m_pDescriptor->szFakeIp.isEmpty() ? m_pDescriptor->szFakeIp : m_pDescriptor->szListenIp;
+ KviStr 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(kvi_stringIpToBinaryIp(ip.ptr(),&a))ip.setNum(htonl(a.s_addr));
+
+ m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC VOICE %s %s %s %d%c",
+ m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(),
+ 0x01,m_pDescriptor->szCodec.ptr(),
+ ip.ptr(),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.utf8().data(),m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data());
+ return m_szTarget;
+}
+
+void KviDccVoice::getBaseLogFileName(KviStr &buffer)
+{
+ buffer.sprintf("dccvoice_%s_%s_%s",m_pDescriptor->szNick.utf8().data(),m_pDescriptor->szLocalFileName.utf8().data(),m_pDescriptor->szPort.utf8().data());
+}
+
+void KviDccVoice::fillCaptionBuffers()
+{
+ KviStr tmp(KviStr::Format,"DCC Voice %s@%s:%s %s",
+ m_pDescriptor->szNick.utf8().data(),m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data(),
+ m_pDescriptor->szLocalFileName.utf8().data());
+
+ m_szPlainTextCaption = tmp;
+
+ m_szHtmlActiveCaption.sprintf("<nobr><font color=\"%s\"><b>%s</b></font></nobr>",
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(),tmp.ptr());
+ m_szHtmlInactiveCaption.sprintf("<nobr><font color=\"%s\"><b>%s</b></font></nobr>",
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(),tmp.ptr());
+}
+
+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:
+ {
+ int * err = ((KviThreadDataEvent<int> *)e)->getData();
+ QString ssss = KviError::getDescription(*err);
+ output(KVI_OUT_DCCERROR,__tr2qs_ctx("ERROR: %Q","dcc"),&(ssss));
+ delete err;
+ 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:
+ {
+ KviStr * str = ((KviThreadDataEvent<KviStr> *)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<int> *)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:
+ debug("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();
+ KviStr tmp(KviStr::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 *e)
+{
+ 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(int err)
+{
+ QString ssss = KviError::getDescription(err);
+ output(KVI_OUT_DCCERROR,__tr2qs_ctx("DCC Failed: %Q","dcc"),&ssss);
+ m_pTalkButton->setEnabled(false);
+ m_pTalkButton->setOn(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).utf8().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<int> * e = new KviThreadDataEvent<int>(KVI_DCC_THREAD_EVENT_ACTION);
+ e->setData(new int(0));
+ m_pSlaveThread->enqueueEvent(e);
+}
+
+void KviDccVoice::startTalking()
+{
+ KviThreadDataEvent<int> * e = new KviThreadDataEvent<int>(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).utf8().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).utf8().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);
+
+ QString s;
+ s.sprintf(__tr_ctx("Volume: %i","dcc"), -vol);
+ QToolTip::add(m_pVolumeSlider, s);
+#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)
+{
+// debug("focusInEvent()");
+ m_pVolumeSlider->setValue(getMixerVolume());
+ setMixerVolume(m_pVolumeSlider->value());
+
+ KviWindow::focusInEvent(e);
+}
+
+#include "m_voice.moc"
diff --git a/src/modules/dcc/voice.h b/src/modules/dcc/voice.h
new file mode 100644
index 00000000..c74c677c
--- /dev/null
+++ b/src/modules/dcc/voice.h
@@ -0,0 +1,440 @@
+#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 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_window.h"
+
+#include "kvi_databuffer.h"
+#include "kvi_sockettype.h"
+
+#include "codec.h"
+#include "descriptor.h"
+#include "thread.h"
+#include "window.h"
+
+#include "kvi_tal_hbox.h"
+#include <qlabel.h>
+#include <qtoolbutton.h>
+#include <qtimer.h>
+
+#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;
+ KviStr 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 KviDccMarshal;
+class QSlider;
+
+class KviDccVoice : public KviDccWindow
+{
+ Q_OBJECT
+public:
+ KviDccVoice(KviFrame *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(KviStr &buffer);
+ void startTalking();
+ void stopTalking();
+ void startConnection();
+ int getMixerVolume(void) const;
+protected slots:
+ void handleMarshalError(int err);
+ 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
+
+ <rate>:<bits>:<endianness>:<compressor>
+
+ 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<KviVoiceParty> * 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<KviVoiceParty>;
+ 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<KviVoiceLink> * m_pLinks;
+ KviPointerHashTable<QString,KviVoiceLink> *
+ 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<KviVoiceLink>;
+ 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: <local id for the remote end> (CID)
+// <-- YOURIDIS: <local id for the remote end> (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:
+
+// <magic byte>: byte
+// <magic byte>: byte
+// <local id>: word
+// <payload len>: word
+// <payload>
+
+
+// Payload format:
+
+// <codec id>: word
+// <ordinal in a chunk>: 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
new file mode 100644
index 00000000..4abd7f99
--- /dev/null
+++ b/src/modules/dcc/window.cpp
@@ -0,0 +1,53 @@
+//
+// 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 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 "kvi_tal_hbox.h"
+
+KviDccWindow::KviDccWindow(int type,KviFrame * lpFrm,const char * name,KviDccDescriptor * d)
+: KviWindow(type,lpFrm,name)
+{
+ 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;
+}
+
+#include "m_window.moc"
diff --git a/src/modules/dcc/window.h b/src/modules/dcc/window.h
new file mode 100644
index 00000000..b4bfa43d
--- /dev/null
+++ b/src/modules/dcc/window.h
@@ -0,0 +1,49 @@
+#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 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_window.h"
+
+#include "descriptor.h"
+#include "marshal.h"
+
+class KviDccWindow : public KviWindow , public KviDccMarshalOutputContext
+{
+ Q_OBJECT
+public:
+ KviDccWindow(int type,KviFrame * 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 KviWindow * dccMarshalOutputWindow();
+ virtual const char * dccMarshalOutputContextString();
+};
+
+
+
+#endif //_WINDOW_H_
diff --git a/src/modules/dialog/Makefile.am b/src/modules/dialog/Makefile.am
new file mode 100644
index 00000000..06018a14
--- /dev/null
+++ b/src/modules/dialog/Makefile.am
@@ -0,0 +1,21 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvidialog.la
+
+libkvidialog_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvidialog_la_SOURCES = libkvidialog.cpp
+
+libkvidialog_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= libkvidialog.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkvidialog.cpp: libkvidialog.moc
diff --git a/src/modules/dialog/libkvidialog.cpp b/src/modules/dialog/libkvidialog.cpp
new file mode 100644
index 00000000..dd7cf391
--- /dev/null
+++ b/src/modules/dialog/libkvidialog.cpp
@@ -0,0 +1,920 @@
+//=============================================================================
+//
+// File : libkvidialog.cpp
+// Creation date : Sat Sep 15 2001 01:13:25 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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 "libkvidialog.h"
+
+#include <qmessagebox.h>
+#include <qlayout.h>
+#include "kvi_tal_hbox.h"
+#include <qlineedit.h>
+#ifdef COMPILE_USE_QT4
+ #include <q3multilineedit.h>
+ #define QMultiLineEdit Q3MultiLineEdit
+ #include <qdesktopwidget.h>
+#else
+ #include <qmultilineedit.h>
+#endif
+#include <qevent.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+
+#include "kvi_locale.h"
+#include "kvi_module.h"
+#include "kvi_modulemanager.h"
+#include "kvi_error.h"
+#include "kvi_app.h"
+#include "kvi_iconmanager.h"
+#include "kvi_console.h"
+#include "kvi_iconmanager.h"
+#include "kvi_kvs_script.h"
+#include "kvi_msgbox.h"
+
+static KviPointerList<QWidget> * g_pDialogModuleDialogList;
+
+KviKvsCallbackMessageBox::KviKvsCallbackMessageBox(
+ const QString &szCaption,
+ const QString &szText,
+ const QString &szIcon,
+ const QString &szButton0,
+ const QString &szButton1,
+ const QString &szButton2,
+ const QString &szCode,
+ KviKvsVariantList * pMagicParams,
+ KviWindow * pWindow,bool modal)
+: QMessageBox(
+ szCaption,
+ szText,
+ QMessageBox::NoIcon,
+ szButton0.isEmpty() ? QMessageBox::NoButton : QMessageBox::Ok | QMessageBox::Default,
+ szButton1.isEmpty() ? QMessageBox::NoButton : (szButton2.isEmpty() ? QMessageBox::No | QMessageBox::Escape : QMessageBox::No),
+ szButton2.isEmpty() ? QMessageBox::NoButton : QMessageBox::Cancel | QMessageBox::Escape,
+ 0,0,modal) ,
+ KviKvsCallbackObject("dialog.message",pWindow,szCode,pMagicParams,0)
+{
+ g_pDialogModuleDialogList->append(this);
+#ifndef COMPILE_USE_QT4
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)));
+#endif
+
+ QPixmap * pix = g_pIconManager->getImage(szIcon);
+
+ if(pix)setIconPixmap(*pix);
+ else {
+ if(KviQString::equalCI(szIcon,"information"))setIcon(QMessageBox::Information);
+ else if(KviQString::equalCI(szIcon,"warning"))setIcon(QMessageBox::Warning);
+ else if(KviQString::equalCI(szIcon,"critical"))setIcon(QMessageBox::Critical);
+ }
+ if(!szButton0.isEmpty())setButtonText(QMessageBox::Ok,szButton0);
+ if(!szButton1.isEmpty())setButtonText(QMessageBox::No,szButton1);
+ if(!szButton2.isEmpty())setButtonText(QMessageBox::Cancel,szButton2);
+}
+
+KviKvsCallbackMessageBox::~KviKvsCallbackMessageBox()
+{
+ g_pDialogModuleDialogList->removeRef(this);
+}
+
+void KviKvsCallbackMessageBox::done(int code)
+{
+ QMessageBox::done(code);
+
+ kvs_int_t iVal = 0;
+
+ switch(code)
+ {
+ case QMessageBox::No: iVal = 1; break;
+ case QMessageBox::Cancel: iVal = 2; break;
+ }
+
+ KviKvsVariantList params;
+ params.append(new KviKvsVariant(iVal));
+
+ execute(&params);
+
+ delete this;
+}
+
+
+/*
+ @doc: dialog.message
+ @type:
+ command
+ @title:
+ dialog.message
+ @short:
+ Shows a message box
+ @syntax:
+ dialog.message [-b] (<caption>,<message_text>,<icon>,<button0>[,<button1>[,<button2>[,<magic1>[,<magic2>[...]]]]])
+ {
+ <callback_command>
+ }
+ @description:
+ Shows a message dialog box with the specified <caption> , <message_text> , <icon> and
+ buttons.[br]
+ <caption> is a text string that will appear in the caption of the dialog box.[br]
+ <message_text> is a text string that will appear in the dialog box and can contain HTML formatting.[br]
+ <icon> is an [doc:image_id]image identifier[/doc] that defines an icon to be placed in the dialog box.
+ <icon> can be a relative or absolute path to an image file , a signed number (in that case it defines
+ an internal KVIrc image) or one of the special strings "critical", "information" and "warning".[br]
+ <button0> is the text of the first button (on the left).[br]
+ <button1> is the text of the second button (if empty or not given at all, only one button will appear in the dialog).[br]
+ <button2> is the text of the third button (if empty or not given, only two buttons will appear in the dialog).[br]
+ The first button is always the default button: it is activated when the user presses the
+ enter key. The thirs, or the second if the third is not present, is the escape button
+ and is activated when the user presses the Esc key.[br]
+ <magic1>,<magic2>... are the magic parameters: evaluated at dialog.message call time and passed
+ to the <callback_command> as positional parameters.[br]
+ If the -b or -modal switch is specified the dialog will have non-blocking modal behaviour:
+ it will appear above its parent widget and block its input until it's closed.[br]
+ Once the dialog has been shown , the user will click one of the buttons. At this point the dialog
+ is hidden and the <callback_command> is executed passing the number of the button clicked
+ as $0 and the magic parameters as positional parameters $1 , $2 , $3....[br]
+ Please note that if the user closes the window with the window manager close button ,
+ the action is interpreted as a button2 click (that is usually sth as "Cancel").[br]
+ @examples:
+ [example]
+ [comment]# Just a warning dialog[/comment]
+ dialog.message("Warning","You're being <b>warned</b>",warning,"Ok"){ echo The user clicked OK; }
+ [comment]# A question[/comment]
+ dialog.message("And now ?","What do you want to do ?",information,"Go home","Watch TV","Scream")
+ {
+ if($0 == 0)echo "The user want's to go home"
+ else if($0 == 1)echo "The user want's to watch TV"
+ else echo "The user wants to scream!"
+ }
+ [/example]
+*/
+
+static bool dialog_kvs_cmd_message(KviKvsModuleCallbackCommandCall * c)
+{
+ QString szCaption,szMessage,szIcon,szButton0,szButton1,szButton2;
+ KviKvsVariantList params;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
+ KVSM_PARAMETER("message",KVS_PT_STRING,0,szMessage)
+ KVSM_PARAMETER("icon",KVS_PT_STRING,0,szIcon)
+ KVSM_PARAMETER("button0",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton0)
+ KVSM_PARAMETER("button1",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton1)
+ KVSM_PARAMETER("button2",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton2)
+ KVSM_PARAMETER("magic",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,params)
+ KVSM_PARAMETERS_END(c)
+ bool modal;
+ if(c->hasSwitch('b',"modal")) modal=true;
+ else modal=false;
+ QString szCmd = c->callback()->code();
+
+ KviKvsCallbackMessageBox * box = new KviKvsCallbackMessageBox(
+ szCaption,szMessage,szIcon,szButton0,szButton1,szButton2,szCmd,&params,c->window(),modal);
+ box->show();
+
+ return true;
+}
+
+
+
+KviKvsCallbackTextInput::KviKvsCallbackTextInput(
+ const QString &szCaption,
+ const QString &szLabel,
+ const QString &szDefaultText,
+ const QString &szIcon,
+ bool bMultiLine,
+ const QString &szButton0,
+ const QString &szButton1,
+ const QString &szButton2,
+ const QString &szCode,
+ KviKvsVariantList * pMagicParams,
+ KviWindow * pWindow,bool modal)
+ : QDialog(), KviKvsCallbackObject("dialog.textinput",pWindow,szCode,pMagicParams,0)
+{
+ g_pDialogModuleDialogList->append(this);
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)));
+ setModal(modal);
+ setCaption(szCaption);
+
+ QGridLayout * g = new QGridLayout(this,2,3,5,5);
+
+ QPixmap * pix = g_pIconManager->getImage(szIcon);
+
+ if(pix)
+ {
+ QLabel * il = new QLabel(this);
+ il->setPixmap(*pix);
+ il->setAlignment(Qt::AlignCenter);
+ g->addWidget(il,0,0);
+ QLabel * tl = new QLabel(szLabel,this);
+ g->addWidget(tl,0,1);
+ } else {
+ QLabel * tl = new QLabel(szLabel,this);
+ g->addMultiCellWidget(tl,0,0,0,1);
+ }
+
+ g->setColStretch(1,1);
+
+ m_bMultiLine = bMultiLine;
+
+ if(m_bMultiLine)
+ {
+ m_pEdit = new QMultiLineEdit(this);
+ ((QMultiLineEdit *)m_pEdit)->setText(szDefaultText);
+ } else {
+ m_pEdit = new QLineEdit(this);
+ ((QLineEdit *)m_pEdit)->setText(szDefaultText);
+ }
+
+ g->addMultiCellWidget(m_pEdit,1,1,0,1);
+
+ KviTalHBox * box = new KviTalHBox(this);
+ g->addMultiCellWidget(box,2,2,0,1);
+
+ m_iEscapeButton = 0;
+ m_iDefaultButton = 0;
+
+ if(!szButton0.isEmpty())
+ {
+ QString szB = szButton0;
+ bool bDef = false;
+ if(KviQString::equalCIN(szB,"default=",8))
+ {
+ bDef = true;
+ szB.remove(0,8);
+ m_iDefaultButton = 0;
+ } else if(KviQString::equalCIN(szB,"escape=",7))
+ {
+ szB.remove(0,7);
+ m_iEscapeButton = 0;
+ }
+ QPushButton * pb1 = new QPushButton(szB,box);
+ if(bDef)pb1->setDefault(true);
+ connect(pb1,SIGNAL(clicked()),this,SLOT(b0Clicked()));
+ }
+
+ if(!szButton1.isEmpty())
+ {
+ QString szB = szButton1;
+ bool bDef = false;
+ if(KviQString::equalCIN(szB,"default=",8))
+ {
+ bDef = true;
+ szB.remove(0,8);
+ m_iDefaultButton = 1;
+ } else if(KviQString::equalCIN(szB,"escape=",7))
+ {
+ szB.remove(0,7);
+ m_iEscapeButton = 1;
+ }
+ QPushButton * pb2 = new QPushButton(szB,box);
+ if(bDef)pb2->setDefault(true);
+ connect(pb2,SIGNAL(clicked()),this,SLOT(b1Clicked()));
+ }
+
+ if(!szButton2.isEmpty())
+ {
+ QString szB = szButton2;
+ bool bDef = false;
+ if(KviQString::equalCIN(szB,"default=",8))
+ {
+ bDef = true;
+ szB.remove(0,8);
+ m_iDefaultButton = 2;
+ } else if(KviQString::equalCIN(szB,"escape=",7))
+ {
+ szB.remove(0,7);
+ m_iEscapeButton = 2;
+ }
+ QPushButton * pb3 = new QPushButton(szB,box);
+ if(bDef)pb3->setDefault(true);
+ connect(pb3,SIGNAL(clicked()),this,SLOT(b2Clicked()));
+ }
+
+}
+
+KviKvsCallbackTextInput::~KviKvsCallbackTextInput()
+{
+ g_pDialogModuleDialogList->removeRef(this);
+}
+
+void KviKvsCallbackTextInput::b0Clicked()
+{
+ done(0+10);
+}
+
+void KviKvsCallbackTextInput::b1Clicked()
+{
+ done(1+10);
+}
+
+void KviKvsCallbackTextInput::b2Clicked()
+{
+ done(2+10);
+}
+
+void KviKvsCallbackTextInput::closeEvent(QCloseEvent *e)
+{
+ e->ignore();
+ done(m_iEscapeButton+10);
+}
+
+void KviKvsCallbackTextInput::done(int code)
+{
+ if(code >= 10)
+ {
+ code -= 10;
+ } else {
+ switch(code)
+ {
+ case QDialog::Accepted:
+ code = m_iDefaultButton;
+ break;
+ default:
+ code = m_iEscapeButton;
+ break;
+ }
+ }
+
+ QString txt;
+
+ if(m_bMultiLine)
+ {
+ txt = ((QMultiLineEdit *)m_pEdit)->text();
+ } else {
+ txt = ((QLineEdit *)m_pEdit)->text();
+ }
+
+ KviKvsVariantList params;
+ params.append(new KviKvsVariant((kvs_int_t)code));
+ params.append(new KviKvsVariant(txt));
+
+ execute(&params);
+
+ //QDialog::done(code);
+
+ delete this;
+}
+
+void KviKvsCallbackTextInput::showEvent(QShowEvent *e)
+{
+ move((g_pApp->desktop()->width() - width())/2,(g_pApp->desktop()->height() - height()) / 2);
+ QDialog::showEvent(e);
+}
+
+
+
+/*
+ @doc: dialog.textinput
+ @type:
+ command
+ @title:
+ dialog.textinput
+ @short:
+ Shows a dialog that accepts user input as text
+ @syntax:
+ dialog.textinput [-d=<default text>] [-i=<icon>] [-m] [-b] (<caption>,<info_text>,<button0>[,<button1>[,<button2>[,<magic1>[,<magic2>[...]]]]])
+ {
+ <callback_command>
+ }
+ @switches:
+ !sw: -d=<default_text> | --default=<default_text>
+ Set the initial text input value to <default_text>
+ !sw: -i=<icon> | --icon=<icon>
+ Display the specified icon, just of the left of the informational text
+ !sw: -m | --multiline
+ Input multiline text instead of single line
+ @description:
+ Shows a text input dialog box with the specified <caption> , <info_text> , <icon> and
+ buttons.[br]
+ <caption> is a text string that will appear in the caption of the dialog box.[br]
+ <info_text> is a fixed text string that will appear in the dialog box and can contain HTML formatting.[br]
+ <button0> is the text of the first button (on the left).[br]
+ <button1> is the text of the second button (if empty or not given at all, only one button will appear in the dialog).[br]
+ <button2> is the text of the third button (if empty or not given, only two buttons will appear in the dialog).[br]
+ If one of the text strings starts with a "default=" prefix then the button is assumed
+ to be the default button of the dialog and will be also activated when the user presses enter.
+ If the -m switch is used , the dialog will be a multi-line text input, otherwise the user will be able to
+ input only a single line of text.[br]
+ If the -d switch is used , the initial text input value is set to <default text>.[br]
+ If the -i switch is used , the dialog displays also the icon <icon> , just on the left ot the <info_text>[br]
+ If the -b or -modal switch is specified the dialog will have non-blocking modal behaviour:
+ it will appear above its parent widget and block its input until it's closed.[br]
+ In that case <icon> is an [doc:image_id]image identifier[/doc] (can be a relative or absolute
+ path to an image file or a signed number (in that case it defines an internal KVIrc image).[br]
+ <magic1>,<magic2>... are the magic parameters: evaluated at dialog.textinput call time and passed
+ to the <callback_command> as positional parameters.[br]
+ Once the dialog has been shown , the user will click one of the buttons. At this point the dialog
+ is hidden and the <callback_command> is executed passing the text input value in $1, the number of the button clicked
+ as $0, and the magic parameters as positional parameters $2 , $3 , $4....[br]
+ Please note that if the user closes the window with the window manager close button ,
+ the action is interpreted as a button2 click (that is usually sth as "Cancel").[br]
+ @examples:
+ [example]
+ [comment]# We need a single line "reason"[/comment]
+ dialog.textinput -d="Working !" (Away,<center>Please enter the <h1>away message</h1></center>,"Ok","Cancel")
+ {
+ switch($0)
+ {
+ case(0):
+ away $1-
+ break;
+ default:
+ # Cancelled
+ break;
+ }
+ }
+ [/example]
+*/
+
+static bool dialog_kvs_cmd_textinput(KviKvsModuleCallbackCommandCall * c)
+{
+ QString szCaption,szInfoText,szIcon,szDefaultText,szButton0,szButton1,szButton2;
+ KviKvsVariantList params;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
+ KVSM_PARAMETER("info_text",KVS_PT_STRING,0,szInfoText)
+ KVSM_PARAMETER("button0",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton0)
+ KVSM_PARAMETER("button1",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton1)
+ KVSM_PARAMETER("button2",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton2)
+ KVSM_PARAMETER("magic",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,params)
+ KVSM_PARAMETERS_END(c)
+
+ QString szCmd = c->callback()->code();
+
+ c->switches()->getAsStringIfExisting('i',"icon",szIcon);
+ c->switches()->getAsStringIfExisting('d',"default",szDefaultText);
+ bool modal;
+ if(c->hasSwitch('b',"modal")) modal=true;
+ else modal=false;
+ KviKvsCallbackTextInput * box = new KviKvsCallbackTextInput(
+ szCaption,szInfoText,szDefaultText,szIcon,c->switches()->find('m',"multiline"),
+ szButton0,szButton1,szButton2,szCmd,&params,c->window(),modal);
+ box->show();
+
+ return true;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// New KVS
+KviKvsCallbackFileDialog::KviKvsCallbackFileDialog(
+ const QString &szCaption,
+ const QString &szInitialSelection,
+ const QString &szFilter,
+ const QString &szCode,
+ KviKvsVariantList * pMagicParams,
+ KviWindow * pWindow,bool modal)
+ : KviFileDialog(szInitialSelection,szFilter,0,0,modal), KviKvsCallbackObject("dialog.file",pWindow,szCode,pMagicParams,0)
+{
+ g_pDialogModuleDialogList->append(this);
+ setCaption(szCaption);
+}
+
+KviKvsCallbackFileDialog::~KviKvsCallbackFileDialog()
+{
+ g_pDialogModuleDialogList->removeRef(this);
+}
+
+void KviKvsCallbackFileDialog::done(int code)
+{
+ KviFileDialog::done(code);
+ KviKvsVariantList params;
+
+ if(code == QDialog::Accepted)
+ {
+#ifdef COMPILE_KDE_SUPPORT
+ if(mode() == KFile::ExistingOnly)
+#else
+ if(mode() == QFileDialog::ExistingFiles)
+#endif
+ {
+ KviKvsArray * a = new KviKvsArray();
+ QStringList sl = selectedFiles();
+ int idx = 0;
+ for(QStringList::Iterator it = sl.begin();it != sl.end();++it)
+ {
+ a->set(idx,new KviKvsVariant(*it));
+ idx++;
+ }
+ params.append(new KviKvsVariant(a));
+ } else {
+ params.append(new KviKvsVariant(selectedFile()));
+ }
+ } else {
+ params.append(new KviKvsVariant(QString("")));
+ }
+
+ hide(); // ensure we're hidden
+
+ // ugly workaround for the Qt filedialog "destructive accept() before this reference" bug
+ // we can't delete ourselves in this moment.... :(((
+ // ...so skip out of this call stack and ask KviApp to destroy us just
+ // when the control returns to the main loop.
+ // If the module is unloaded then , KviApp will notice it and will NOT delete the dialog
+ g_pApp->collectGarbage(this);
+
+ // calling dialog.unload here WILL lead to a sigsegv (this is SURE
+ // with a lot of qt versions that have the ugly file dialog "accept before this reference" bug)
+ // to avoid it, we can execute the callback triggered by a timer...
+ // ... umpf ...
+ execute(&params);
+}
+
+/*
+ @doc: dialog.file
+ @type:
+ command
+ @title:
+ dialog.file
+ @short:
+ Shows a file dialog
+ @syntax:
+ dialog.file [-b] (<mode>,<caption>[,<initial_selection[,<file_filter>[,<magic1>[,<magic2>[...]]]]]])
+ {
+ <callback_command>
+ }
+ @description:
+ Shows an openfile dialog box with the specified <caption> , <initial_selection> , and <file_filter>.[br]
+ <mode> can be "open" , "openm" , "save" or "dir":[br]
+ "open" causes the dialog to return an existing file[br]
+ "openm" is similar to open but allows returning multiple files as a comma separated list[br]
+ "save" causes the dialog to return any file name (no overwrite confirmation is built in the dialog!)[br]
+ "dir" causes the dialog to return an existing directory name[br]
+ <mode> defaults to "open".[br]
+ <caption> is a text string that will appear in the caption of the dialog box.[br]
+ <initial_selection> can be a directory or filename that will be initially selected in the dialog.[br]
+ Only files matching <file_filter> are selectable. If filter is an empty string, all files are selectable.[br]
+ In the filter string multiple filters can be specified separated by either two semicolons next to each
+ other or separated by newlines. To add two filters, one to show all C++ files and one to show all
+ header files, the filter string could look like "C++ Files (*.cpp *.cc *.C *.cxx *.c++);;Header Files (*.h *.hxx *.h++)"
+ <magic1>,<magic2>... are the magic parameters: evaluated at dialog.message call time and passed
+ to the <callback_command> as positional parameters.[br]
+ If the -b or -modal switch is specified the dialog will have non-blocking modal behaviour:
+ it will appear above its parent widget and block its input until it's closed.[br]
+ Once the dialog has been shown , the user will select an EXISTING file and click either
+ Ok or Cancel. At this point the dialog is hidden and the <callback_command> is executed passing the selected file(s) as $0
+ and the magic parameters as positional parameters $1 , $2 , $3....[br]
+ If the user clicks "Cancel" or does not select any file the positional parameter $0 will be empty.[br]
+ @examples:
+ [example]
+ dialog.file(open,Choose an audio file,/home/pragma/TheAudio.au,"Audio files (*.au *.wav *.snd)")
+ {
+ if("$0" != "")run play $0
+ }
+ [/example]
+*/
+
+//#warning "Examples for these dialogs!"
+
+
+static bool dialog_kvs_cmd_file(KviKvsModuleCallbackCommandCall * c)
+{
+ QString szMode,szCaption,szInitialSelection,szFilter;
+ KviKvsVariantList params;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mode",KVS_PT_STRING,0,szMode)
+ KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
+ KVSM_PARAMETER("initial_selection",KVS_PT_STRING,KVS_PF_OPTIONAL,szInitialSelection)
+ KVSM_PARAMETER("filter",KVS_PT_STRING,KVS_PF_OPTIONAL,szFilter)
+ KVSM_PARAMETER("magic",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,params)
+ KVSM_PARAMETERS_END(c)
+ bool modal;
+ if(c->hasSwitch('b',"modal")) modal=true;
+ else modal=false;
+ QString szCmd = c->callback()->code();
+
+ KviKvsCallbackFileDialog * box = new KviKvsCallbackFileDialog(szCaption,szInitialSelection,szFilter,szCmd,&params,c->window(),modal);
+
+ KviFileDialog::FileMode md = KviFileDialog::ExistingFile;
+
+ if(KviQString::equalCI(szMode,"openm"))md = KviFileDialog::ExistingFiles;
+ else if(KviQString::equalCI(szMode,"save"))md = KviFileDialog::AnyFile;
+ else if(KviQString::equalCI(szMode,"dir"))md = KviFileDialog::DirectoryOnly;
+
+ box->setFileMode(md);
+
+ box->show();
+
+ return true;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// New KVS
+KviKvsCallbackImageDialog::KviKvsCallbackImageDialog(
+ const QString &szCaption,
+ const QString &szInitialSelection,
+ int iType,
+ int iMaxSize,
+ const QString &szCode,
+ KviKvsVariantList * pMagicParams,
+ KviWindow * pWindow,bool modal)
+ : KviImageDialog(0,szCaption,iType,0,szInitialSelection,iMaxSize,modal), KviKvsCallbackObject("dialog.image",pWindow,szCode,pMagicParams,0)
+{
+ g_pDialogModuleDialogList->append(this);
+}
+
+KviKvsCallbackImageDialog::~KviKvsCallbackImageDialog()
+{
+ g_pDialogModuleDialogList->removeRef(this);
+}
+
+void KviKvsCallbackImageDialog::done(int code)
+{
+ KviImageDialog::done(code);
+ KviKvsVariantList params;
+
+ if(code == QDialog::Accepted)
+ {
+ params.append(new KviKvsVariant(selectedImage()));
+ } else {
+ params.append(new KviKvsVariant(QString("")));
+ }
+
+ hide(); // ensure we're hidden
+
+ // ugly workaround for the Qt filedialog "destructive accept() before this reference" bug
+ // we can't delete ourselves in this moment.... :(((
+ // ...so skip out of this call stack and ask KviApp to destroy us just
+ // when the control returns to the main loop.
+ // If the module is unloaded then , KviApp will notice it and will NOT delete the dialog
+ g_pApp->collectGarbage(this);
+
+ // calling dialog.unload here WILL lead to a sigsegv (this is SURE
+ // with a lot of qt versions that have the ugly file dialog "accept before this reference" bug)
+ // to avoid it, we can execute the callback triggered by a timer...
+ // ... umpf ...
+ execute(&params);
+}
+
+
+/*
+ @doc: dialog.image
+ @type:
+ command
+ @title:
+ dialog.image
+ @short:
+ Shows a image dialog
+ @syntax:
+ dialog.image [-b] (<type>,<caption>,<initial_directory>,[<maxsize>,[,<magic1>[,<magic2>[...]]]]]])
+ {
+ <callback_command>
+ }
+ @description:
+ Shows a dialog that allows selecting an [doc:image_id]image_id[doc].
+ The <type> parameter must be a combination of the following flags:<br>
+ 's' : allow selecting from the KVIrc builtin small icons<br>
+ 'f' : allow browsing the local directories<br>
+ 'a' : all of the above<br>
+ The default for <type> is 'a'.<br>
+ <caption> is the caption string for the dialog.<br>
+ <initial_directory> makes sense only if 'f' is specified (if <initial_directory> is empty
+ then the last path used by the image dialog will be used).<br>
+ <maxsize> is the maximum size of the images for that the preview will be generated:
+ this is 256000 bytes by default (if unspecified). Don't make it a lot bigger : it can take a lot to make
+ the thumbnails for bigger images (and it can eat a considerable amount of memory).<br>
+ <magic1>,<magic2>... are the magic parameters: evaluated at dialog.image call time and passed
+ to the <callback_command> as positional parameters.[br]
+ If the -b or -modal switch is specified the dialog will have non-blocking modal behaviour:
+ it will appear above its parent widget and block its input until it's closed.[br]
+ Once the dialog has been shown , the user will select an EXISTING file and click either
+ Ok or Cancel. At this point the dialog is hidden and the <callback_command> is executed passing the selected file(s) as $0
+ and the magic parameters as positional parameters $1 , $2 , $3....[br]
+ If the user clicks "Cancel" or does not select any image the positional parameter $0 will be empty.[br]
+ @examples:
+ [example]
+ dialog.image(f,Choose an image file,/home/pragma/,"256000")
+ {
+ if("$0" != "")run kview $0
+ }
+ [/example]
+*/
+
+//#warning "Examples for these dialogs!"
+
+
+static bool dialog_kvs_cmd_image(KviKvsModuleCallbackCommandCall * c)
+{
+ QString szType,szCaption,szInitialSelection;
+ kvs_uint_t iMaxSize;
+ KviKvsVariantList params;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mode",KVS_PT_STRING,0,szType)
+ KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
+ KVSM_PARAMETER("initial_directory",KVS_PT_STRING,0,szInitialSelection)
+ KVSM_PARAMETER("maxsize",KVS_PT_UINT,KVS_PF_OPTIONAL,iMaxSize)
+ KVSM_PARAMETER("magic",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,params)
+ KVSM_PARAMETERS_END(c)
+ bool modal;
+ if(c->hasSwitch('b',"modal")) modal=true;
+ else modal=false;
+ QString szCmd = c->callback()->code();
+
+ int iType = 0;
+
+ if(szType.contains('s'))iType |= KID_TYPE_BUILTIN_IMAGES_SMALL;
+ if(szType.contains('f'))iType |= KID_TYPE_FULL_PATH;
+ if(szType.isEmpty())iType = KID_TYPE_ALL;
+
+ if(iMaxSize < 1)iMaxSize = 256000;
+
+ KviKvsCallbackImageDialog * box = new KviKvsCallbackImageDialog(szCaption,szInitialSelection,iType,iMaxSize,szCmd,&params,c->window(),modal);
+
+ box->show();
+
+ return true;
+}
+
+/*
+ @doc: dialog.yesno
+ @type:
+ function
+ @title:
+ $dialog.yesno
+ @short:
+ Shows a simple yes/no dialog
+ @syntax:
+ $dialog.yesno(<caption:string>,<szText:string>)
+ @description:
+ Shows a simple yes/no dialog. Returns 1 if user clicks "Yes" and 0 if (s)he clicks "No".
+ Please note that this dialog is BLOCKING: it blocks execution of the script
+ until the user has selected either YES or NO.
+ @examples:
+ @seealso:
+*/
+
+static bool dialog_kvs_fnc_yesno(KviKvsModuleFunctionCall * c)
+{
+ QString szCaption;
+ QString szText;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
+ KVSM_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSM_PARAMETERS_END(c)
+
+ c->enterBlockingSection();
+ bool yes=KviMessageBox::yesNo(szCaption,szText); // this will happily crash on quit ?
+ if(!c->leaveBlockingSection())return true; // just die
+ c->returnValue()->setBoolean(yes);
+ return true;
+}
+
+/*
+
+static int g_iLocalEventLoops = 0;
+
+static bool dialog_module_cmd_unload(KviModule *m,KviCommand *c)
+{
+ // We use local loops in this module: we must FORBID explicit unloading of the
+ // module while local even loops are running
+ ENTER_STACK_FRAME(c,"dialog_module_cmd_unload");
+ c->warning(__tr("The dialog module can't be explicitly unloaded: a modal dialog is currently open"));
+ return c->leaveStackFrame();
+}
+
+static void dialog_module_entering_local_loop(KviModule * m)
+{
+ // Replace unload
+ g_iLocalEventLoops++;
+ if(g_iLocalEventLoops == 1)m->registerCommand("unload",dialog_module_cmd_unload);
+}
+
+static void dialog_module_exiting_local_loop(KviModule * m)
+{
+ g_pModuleManager->registerDefaultCommands(m);
+ g_iLocalEventLoops--;
+}
+
+static bool dialog_module_fnc_textline(KviModule *m,KviCommand *c,KviParameterList * parms,KviStr &buffer)
+{
+ ENTER_STACK_FRAME(c,"dialog_module_fnc_textline");
+
+ KviStr caption = parms->safeFirstParam();
+ KviStr info = parms->safeNextParam();
+ KviStr initial = parms->safeNextParam();
+
+ dialog_module_entering_local_loop(m);
+ QMessageBox::information(0,caption.ptr(),info.ptr(),QMessageBox::Ok);
+ dialog_module_exiting_local_loop(m);
+
+ // It might be that the current window is no longer available!!!
+
+ return c->leaveStackFrame();
+}
+
+*/
+
+/*
+ @doc: noblockingdialogs
+ @type:
+ generic
+ @title:
+ Why there are no blocking dialogs in KVIrc ?
+ @short:
+ Tecnical answer
+ @description:
+ Why there are no blocking dialogs in KVIrc ?[br]
+ The answer is simple: because they're more confusing and tricky than it seems.[br]
+ Blocking the entire program control flow while showing a dialog is
+ rather a bad idea since we have to deal with external entities (servers and other users)
+ that are NOT blocked. This means that the blocking dialogs must block only the
+ script control-flow but let the rest of the application running.
+ Such blocking dialogs actually seem to simplify scripting because
+ the programmer "feels" that the control is always left in the script snippet that he is writing.
+ This is actually confusing: the control IS in the script snippet but while the dialog
+ is open the whole world can change: you can return from the dialog call and discover
+ that the server connection no longer exists and the application is about to quit.[br]
+ This may happen even with non-blocking dialogs ,but in non-blocking mode you have
+ a way to handle this event. Consider the following snippet of code:[br]
+ [example]
+ echo My name is $?
+ [/example]
+ Where $? stands for a blocking input dialog that asks the user for some text.[br]
+ When the input dialog returns the window that the echo was directed to no longer
+ exists and you have no way to stop the echo! (Well...I could add extra code
+ in the executable to handle all these situations but that would be really too expensive).[br]
+ With object scripting this is actually dangerous: you might use a blocking dialog
+ in an object signal handler and when returning discover that this object has been deleted!
+ (The example refers to a simple object , but think about a complex hierarchy of objects
+ where one random gets deleted...).[br]
+ This is why the dialogs in KVIrc are non-blocking :)[br]
+ That's REAL programming.
+*/
+
+
+
+
+
+
+
+static bool dialog_module_init(KviModule * m)
+{
+ g_pDialogModuleDialogList = new KviPointerList<QWidget>;
+ g_pDialogModuleDialogList->setAutoDelete(false);
+
+ KVSM_REGISTER_CALLBACK_COMMAND(m,"message",dialog_kvs_cmd_message);
+ KVSM_REGISTER_CALLBACK_COMMAND(m,"textinput",dialog_kvs_cmd_textinput);
+ KVSM_REGISTER_CALLBACK_COMMAND(m,"file",dialog_kvs_cmd_file);
+ KVSM_REGISTER_CALLBACK_COMMAND(m,"image",dialog_kvs_cmd_image);
+
+ KVSM_REGISTER_FUNCTION(m,"yesno",dialog_kvs_fnc_yesno);
+
+ return true;
+}
+
+static bool dialog_module_cleanup(KviModule *m)
+{
+ // Here we get a tragedy if g_iLocalEventLoops > 0!
+ while(g_pDialogModuleDialogList->first())delete g_pDialogModuleDialogList->first();
+ delete g_pDialogModuleDialogList;
+ g_pDialogModuleDialogList = 0;
+ return true;
+}
+
+static bool dialog_module_can_unload(KviModule *m)
+{
+ return g_pDialogModuleDialogList->isEmpty();
+}
+
+
+KVIRC_MODULE(
+ "KVIrc script dialogs",
+ "1.0.0",
+ "Szymon Stefanek <pragma at kvirc dot net>" ,
+ "Adds the /dialog.* commands functionality\n",
+ dialog_module_init ,
+ dialog_module_can_unload,
+ 0,
+ dialog_module_cleanup
+)
+
+#include "libkvidialog.moc"
diff --git a/src/modules/dialog/libkvidialog.h b/src/modules/dialog/libkvidialog.h
new file mode 100644
index 00000000..43b1510f
--- /dev/null
+++ b/src/modules/dialog/libkvidialog.h
@@ -0,0 +1,133 @@
+#ifndef _KVI_DIALOG_H_
+#define _KVI_DIALOG_H_
+//=============================================================================
+//
+// File : libkvidialog.cpp
+// Creation date : Sat Sep 15 2001 01:13:25 by Szymon Stefanek
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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_window.h"
+#include "kvi_string.h"
+#include "kvi_parameterlist.h"
+#include "kvi_filedialog.h"
+#include "kvi_imagedialog.h"
+
+#include "kvi_kvs_callbackobject.h"
+
+#include <qmessagebox.h>
+#include <qdialog.h>
+
+
+
+// New KVS
+class KviKvsCallbackMessageBox : public QMessageBox, public KviKvsCallbackObject
+{
+ Q_OBJECT
+public:
+ KviKvsCallbackMessageBox(
+ const QString &szCaption,
+ const QString &szText,
+ const QString &szIcon,
+ const QString &szButton0,
+ const QString &szButton1,
+ const QString &szButton2,
+ const QString &szCode,
+ KviKvsVariantList * pMagicParams,
+ KviWindow * pWindow, bool modal=false);
+ ~KviKvsCallbackMessageBox();
+protected slots:
+ virtual void done(int code);
+};
+
+
+
+
+// New KVS
+class KviKvsCallbackTextInput : public QDialog, public KviKvsCallbackObject
+{
+ Q_OBJECT
+public:
+ KviKvsCallbackTextInput(
+ const QString &szCaption,
+ const QString &szLabel,
+ const QString &szDefaultText,
+ const QString &szIcon,
+ bool bMultiLine,
+ const QString &szButton0,
+ const QString &szButton1,
+ const QString &szButton2,
+ const QString &szCode,
+ KviKvsVariantList * pMagicParams,
+ KviWindow * pWindow, bool modal=false);
+ ~KviKvsCallbackTextInput();
+protected:
+ bool m_bMultiLine;
+ QWidget * m_pEdit;
+ int m_iEscapeButton;
+ int m_iDefaultButton;
+protected:
+ virtual void closeEvent(QCloseEvent *e);
+ virtual void showEvent(QShowEvent *e);
+protected slots:
+ void b0Clicked();
+ void b1Clicked();
+ void b2Clicked();
+ virtual void done(int code);
+};
+
+
+
+// New KVS
+class KviKvsCallbackFileDialog : public KviFileDialog, public KviKvsCallbackObject
+{
+ Q_OBJECT
+public:
+ KviKvsCallbackFileDialog(
+ const QString &szCaption,
+ const QString &szInitialSelection,
+ const QString &szFilter,
+ const QString &szCode,
+ KviKvsVariantList * pMagicParams,
+ KviWindow * pWindow, bool modal=false);
+ ~KviKvsCallbackFileDialog();
+protected:
+ virtual void done(int code);
+};
+
+
+// New KVS
+class KviKvsCallbackImageDialog : public KviImageDialog, public KviKvsCallbackObject
+{
+ Q_OBJECT
+public:
+ KviKvsCallbackImageDialog(
+ const QString &szCaption,
+ const QString &szInitialSelection,
+ int iType,
+ int iMaxSize,
+ const QString &szCode,
+ KviKvsVariantList * pMagicParams,
+ KviWindow * pWindow,bool modal=false);
+ ~KviKvsCallbackImageDialog();
+protected:
+ virtual void done(int code);
+};
+
+#endif //_KVI_DIALOG_H_
diff --git a/src/modules/dockwidget/Makefile.am b/src/modules/dockwidget/Makefile.am
new file mode 100644
index 00000000..71a2f023
--- /dev/null
+++ b/src/modules/dockwidget/Makefile.am
@@ -0,0 +1,33 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvidockwidget.la
+
+libkvidockwidget_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvidockwidget_la_SOURCES = libkvidockwidget_qt3.cpp libkvidockwidget_qt4.cpp
+
+#nodist_libkvidockwidget_la_SOURCES = moc_trayicon.cpp
+
+libkvidockwidget_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= libkvidockwidget.h libkvidockwidget_qt4.h libkvidockwidget_qt3.h
+
+tmpdir = $(picsdir)
+
+tmp_DATA = kvi_dock.png kvi_dock_part-0.png kvi_dock_part-1.png kvi_dock_part-2.png
+
+EXTRA_DIST = $(tmp_DATA)
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+moc_%.cpp: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkvidockwidget_qt3.cpp: libkvidockwidget_qt3.moc
+libkvidockwidget_qt4.cpp: libkvidockwidget_qt4.moc
diff --git a/src/modules/dockwidget/kvi_dock.png b/src/modules/dockwidget/kvi_dock.png
new file mode 100644
index 00000000..3ac1a3ce
--- /dev/null
+++ b/src/modules/dockwidget/kvi_dock.png
Binary files differ
diff --git a/src/modules/dockwidget/kvi_dock_part-0.png b/src/modules/dockwidget/kvi_dock_part-0.png
new file mode 100644
index 00000000..80bdbb0a
--- /dev/null
+++ b/src/modules/dockwidget/kvi_dock_part-0.png
Binary files differ
diff --git a/src/modules/dockwidget/kvi_dock_part-1.png b/src/modules/dockwidget/kvi_dock_part-1.png
new file mode 100644
index 00000000..b0acff09
--- /dev/null
+++ b/src/modules/dockwidget/kvi_dock_part-1.png
Binary files differ
diff --git a/src/modules/dockwidget/kvi_dock_part-2.png b/src/modules/dockwidget/kvi_dock_part-2.png
new file mode 100644
index 00000000..5229a74e
--- /dev/null
+++ b/src/modules/dockwidget/kvi_dock_part-2.png
Binary files differ
diff --git a/src/modules/dockwidget/libkvidockwidget.h b/src/modules/dockwidget/libkvidockwidget.h
new file mode 100644
index 00000000..89b99a47
--- /dev/null
+++ b/src/modules/dockwidget/libkvidockwidget.h
@@ -0,0 +1,34 @@
+#ifndef _KVI_TAL_DOCK_H_
+#define _KVI_TAL_DOCK_H_
+
+//
+// File : libkvidockwidget.h
+// Creation date : Sun Jun 18 2000 12:53:08 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_QT4
+ #include "libkvidockwidget_qt4.h"
+#else
+ #include "libkvidockwidget_qt3.h"
+#endif
+
+#endif // _KVI_TAL_DOCK_H_
diff --git a/src/modules/dockwidget/libkvidockwidget_qt3.cpp b/src/modules/dockwidget/libkvidockwidget_qt3.cpp
new file mode 100644
index 00000000..60003853
--- /dev/null
+++ b/src/modules/dockwidget/libkvidockwidget_qt3.cpp
@@ -0,0 +1,858 @@
+//
+// File : libkvidockwidget.cpp
+// Creation date : Tue Jan 02 20001 14:34:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-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_settings.h"
+#ifndef COMPILE_USE_QT4
+
+#include "kvi_app.h"
+#include "kvi_module.h"
+#include "kvi_locale.h"
+#include "kvi_memmove.h"
+#include "kvi_taskbar.h"
+#include "kvi_window.h"
+#include "kvi_dynamictooltip.h"
+#include "kvi_iconmanager.h"
+#include "kvi_internalcmd.h"
+#include "kvi_console.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_imagelib.h"
+#include "kvi_options.h"
+#include "kvi_ircview.h"
+
+#include "libkvidockwidget.h"
+#include "kvi_doublebuffer.h"
+
+#ifdef COMPILE_KDE_SUPPORT
+ #include <kwin.h>
+ #include <kpopupmenu.h>
+#else
+ #include <qlabel.h>
+#endif
+
+#include "kvi_tal_popupmenu.h"
+
+
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qtimer.h>
+#include <qevent.h>
+#include <qregexp.h>
+
+#include <stdlib.h>
+#include <time.h>
+
+#ifdef COMPILE_ON_WINDOWS
+ #include <windows.h>
+
+ #include <qbitmap.h>
+ #include <qcursor.h>
+
+ #define ID_DOCKWIDGET_TASKBAR_ICON 0xdeadbeef
+ #define WM_KVIRC_NOTIFY_ICON_MESSAGE (WM_USER + 0xbeef)
+
+ static UINT WM_KVIRC_TASKBAR_CREATED = 0;
+#else
+#ifndef Q_OS_MACX
+ #include <X11/Xlib.h>
+
+ //const int XFocusOut = FocusOut;
+ const int XFocusIn = FocusIn;
+ #undef FocusOut
+ #undef FocusIn
+ #undef KeyPress
+ #undef KeyRelease
+
+ //#warning "Later remove this stuff and use a wrapper for #include <X11/Xlib.h>"
+ #ifdef Bool
+ #undef Bool
+ #endif
+#endif
+#endif
+
+extern KVIRC_API KviPointerHashTable<const char *,KviWindow> * g_pGlobalWindowDict;
+static KviPointerList<KviDockWidget> * g_pDockWidgetList = 0;
+
+static QPixmap * g_pDock1 = 0;
+static QPixmap * g_pDock2 = 0;
+static QPixmap * g_pDock3 = 0;
+
+#ifdef COMPILE_ON_WINDOWS
+ static HICON g_pCurrentIcon = 0;
+ static QPixmap * g_pCurrentPixmap = 0;
+#endif
+
+
+KviDockWidget::KviDockWidget(KviFrame * frm,const char * name)
+: QWidget(0,name)
+{
+ m_iConsoles = 0;
+ m_iChannels = 0;
+ m_iQueries = 0;
+ m_iOther = 0;
+
+ m_pFlashingTimer = new QTimer(this,"flashing_timer");
+ connect( m_pFlashingTimer, SIGNAL(timeout()), this, SLOT(flashingTimerShot()) );
+ m_bFlashed=0;
+ g_pDockWidgetList->append(this);
+ m_pFrm = frm;
+ m_pFrm->setDockExtension(this);
+
+#ifdef COMPILE_ON_WINDOWS
+ // kode54
+ if(!WM_KVIRC_TASKBAR_CREATED)WM_KVIRC_TASKBAR_CREATED = RegisterWindowMessage(TEXT("TaskbarCreated"));
+ createTaskbarIcon();
+#else //!COMPILE_ON_WINDOWS
+ setMinimumSize(22,22);
+ #ifndef COMPILE_USE_QT4
+ setBackgroundMode(X11ParentRelative);
+ #endif
+ #ifdef COMPILE_KDE_SUPPORT
+ KWin::setSystemTrayWindowFor(winId(),frm->winId());
+ #endif
+#endif //!COMPILE_ON_WINDOWS
+
+#ifdef COMPILE_USE_QT4
+ m_pSysTrayIcon = new QSystemTrayIcon(m_pFrm);
+#endif
+
+ m_pTip = new KviDynamicToolTip(this,"dock_tooltip");
+ connect(m_pTip,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &)));
+
+ m_pAwayPopup = new KviTalPopupMenu(this);
+
+#ifdef COMPILE_KDE_SUPPORT
+ m_pContextPopup = new KPopupMenu(this);
+ m_pContextPopup->insertTitle(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)),__tr2qs("KVIrc"));
+#else
+ m_pContextPopup = new KviTalPopupMenu(this);
+#ifndef COMPILE_USE_QT4
+ QLabel * l = new QLabel(__tr2qs("KVIrc"),m_pContextPopup);
+ l->setFrameStyle(QFrame::Raised | QFrame::StyledPanel);
+ m_pContextPopup->insertItem(l);
+#endif
+#endif
+ m_pContextPopup->setCaption(__tr2qs("Context"));
+ m_iAwayMenuId = m_pContextPopup->insertItem ( __tr2qs("Away"), m_pAwayPopup);
+ m_pContextPopup->changeItem(m_iAwayMenuId,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_AWAY)),__tr2qs("Away"));
+
+ int id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_OPTIONS)),__tr2qs("&Configure KVIrc..."),m_pFrm,SLOT(executeInternalCommand(int)));
+ m_pContextPopup->setItemParameter(id,KVI_INTERNALCOMMAND_OPTIONS_DIALOG);
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)),__tr2qs("&About KVIrc"),m_pFrm,SLOT(executeInternalCommand(int)));
+ m_pContextPopup->setItemParameter(id,KVI_INTERNALCOMMAND_ABOUT_ABOUTKVIRC);
+ m_pContextPopup->insertSeparator();
+ m_iToggleFrame = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RAW)),QString(""),this,SLOT(toggleParentFrame()));
+ m_pContextPopup->insertSeparator();
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DOCKWIDGET)),__tr2qs("Un&dock"),m_pFrm,SLOT(executeInternalCommand(int)));
+ m_pContextPopup->setItemParameter(id,KVI_INTERNALCOMMAND_DOCKWIDGET_HIDE);
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUITAPP)),__tr2qs("&Quit"),g_pApp,SLOT(quit()));
+ m_pContextPopup->setAccel(__tr2qs("Ctrl+Q"),id);
+ connect(m_pContextPopup,SIGNAL(aboutToShow()),this,SLOT(fillContextPopup()));
+}
+
+
+KviDockWidget::~KviDockWidget()
+{
+#ifdef COMPILE_ON_WINDOWS
+ destroyTaskbarIcon();
+#endif
+ m_pFrm->setDockExtension(0);
+ g_pDockWidgetList->removeRef(this);
+}
+
+void KviDockWidget::die()
+{
+ delete this;
+}
+void KviDockWidget::flashingTimerShot()
+{
+ m_bFlashed=!m_bFlashed;
+#ifdef COMPILE_ON_WINDOWS
+ updateTaskbarIcon();
+#else
+ update();
+#endif
+}
+
+#ifdef COMPILE_ON_WINDOWS
+void KviDockWidget::createTaskbarIcon()
+{
+ ICONINFO inf;
+ g_pCurrentPixmap=new QPixmap(*g_pDock1);
+ inf.hbmColor = g_pCurrentPixmap->hbm();
+ if(!g_pCurrentPixmap->mask())g_pCurrentPixmap->setMask(g_pCurrentPixmap->createHeuristicMask());
+ inf.hbmMask = g_pCurrentPixmap->mask()->hbm();
+ g_pCurrentIcon=CreateIconIndirect(&inf);
+
+ NOTIFYICONDATA nid;
+ nid.cbSize = sizeof(nid);
+ nid.hWnd = winId();
+ nid.uID = ID_DOCKWIDGET_TASKBAR_ICON;
+ nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
+ nid.uCallbackMessage = WM_KVIRC_NOTIFY_ICON_MESSAGE;
+ kvi_memmove(nid.szTip,"KVIrc",6);
+ nid.hIcon = g_pCurrentIcon;
+ Shell_NotifyIcon(NIM_ADD,&nid);
+}
+
+void KviDockWidget::destroyTaskbarIcon()
+{
+ NOTIFYICONDATA nid;
+ nid.cbSize = sizeof(nid);
+ nid.hWnd = winId();
+ nid.uID = ID_DOCKWIDGET_TASKBAR_ICON;
+ nid.uFlags = 0;
+ Shell_NotifyIcon(NIM_DELETE,&nid);
+}
+
+void KviDockWidget::updateTaskbarIcon()
+{
+ ICONINFO inf;
+ QPixmap* pix = m_bFlashed ? g_pIconManager->getSmallIcon(KVI_SMALLICON_MESSAGE) : g_pCurrentPixmap;
+ inf.hbmColor = pix->hbm();
+ if(!pix->mask())pix->setMask(pix->createHeuristicMask());
+ inf.hbmMask = pix->mask()->hbm();
+ HICON hIcon=CreateIconIndirect(&inf);
+
+ NOTIFYICONDATA nid;
+ nid.cbSize = sizeof(nid);
+ nid.hWnd = winId();
+ nid.uID = ID_DOCKWIDGET_TASKBAR_ICON;
+ nid.uFlags = NIF_ICON;
+ nid.hIcon = hIcon;
+ Shell_NotifyIcon(NIM_MODIFY,&nid);
+ DestroyIcon(g_pCurrentIcon);
+ g_pCurrentIcon=hIcon;
+}
+
+bool KviDockWidget::winEvent(MSG * m)
+{
+ if(m->message == WM_KVIRC_NOTIFY_ICON_MESSAGE)
+ {
+ if(m->wParam == ID_DOCKWIDGET_TASKBAR_ICON)
+ {
+ switch(m->lParam)
+ {
+ case WM_MOUSEMOVE:
+ tipRequest(m_pTip,QCursor::pos());
+ break;
+ case WM_LBUTTONDOWN:
+ toggleParentFrame();
+ break;
+ case WM_RBUTTONDOWN:
+ m_pContextPopup->popup(QCursor::pos());
+ break;
+ }
+ return true;
+ }
+ } else if(m->message == WM_KVIRC_TASKBAR_CREATED)
+ {
+ // kode54 : when the window shell dies and is restarted
+ // it sends the "TaskbarCreated" message to all the toplevel windows
+ // We recreate the taskbar icon then
+ createTaskbarIcon();
+ refresh();
+ }
+ return false;
+}
+
+#endif
+
+#define NIDLEMSGS 18
+
+static const char * idlemsgs[NIDLEMSGS]=
+{
+ __tr("Nothing is happening...") ,
+ __tr("Just idling...") ,
+ __tr("Dum de dum de dum...") ,
+ __tr("Hey man... do something!") ,
+ __tr("Umpf!") ,
+ __tr("Silence speaking") ,
+ __tr("Are ya here?") ,
+ __tr("The world has stopped?") ,
+ __tr("Everything is all right") ,
+ __tr("idle()") ,
+ __tr("It's so cold here...") ,
+ __tr("Do not disturb... watching TV") ,
+ __tr("Just vegetating") ,
+ __tr("Hey... are ya sure that your network is up?") ,
+ __tr("Seems like the world has stopped spinning") ,
+ __tr("This silence is freaking me out!") ,
+ __tr("Mieeeeeowww!") ,
+ __tr("idle idle idle idle!")
+};
+
+#ifdef COMPILE_KDE_SUPPORT
+ extern Time qt_x_time;
+#endif
+
+void KviDockWidget::enterEvent( QEvent* )
+{
+#ifdef COMPILE_KDE_SUPPORT
+ if(!g_pApp->focusWidget())
+ {
+ XEvent ev;
+ kvi_memset(&ev, 0, sizeof(ev));
+ ev.xfocus.display = qt_xdisplay();
+ ev.xfocus.type = XFocusIn;
+ ev.xfocus.window = winId();
+ ev.xfocus.mode = NotifyNormal;
+ ev.xfocus.detail = NotifyAncestor;
+ Time time = qt_x_time;
+ qt_x_time = 1;
+ g_pApp->x11ProcessEvent( &ev );
+ qt_x_time = time;
+ }
+#endif
+}
+
+void KviDockWidget::tipRequest(KviDynamicToolTip *tip,const QPoint &pnt)
+{
+ QString tmp;
+
+ KviTaskBarBase * t = m_pFrm->taskBar();
+
+ QString line;
+
+ for(KviTaskBarItem * b = t->firstItem();b;b = t->nextItem())
+ {
+
+ if(b->kviWindow()->view())
+ {
+ if(b->kviWindow()->view()->haveUnreadedMessages())
+ {
+ line = b->kviWindow()->lastMessageText();
+ if(!line.isEmpty())
+ {
+ line.replace(QChar('&'),"&amp;");
+ line.replace(QChar('<'),"&lt;");
+ line.replace(QChar('>'),"&gt;");
+ tmp += "<b>";
+ tmp += b->kviWindow()->plainTextCaption();
+ tmp += "</b><br>";
+ tmp += line;
+ tmp += "<br><br>\n";
+ }
+ }
+ }
+ }
+
+
+ srand(time(0));
+
+ // We use the bad way to generate random numbers :)))))
+
+ if(tmp.isEmpty())tmp = __tr2qs_no_xgettext(idlemsgs[(int)(rand() % NIDLEMSGS)]);
+
+#ifdef COMPILE_ON_WINDOWS
+
+#else
+ m_pTip->tip(rect(),tmp);
+#endif
+}
+
+//int KviDockWidget::message(int,void *)
+//{
+// debug("Message");
+// update();
+// return 0;
+//}
+
+void KviDockWidget::mousePressEvent(QMouseEvent *e)
+{
+ if(e->button() & Qt::LeftButton)toggleParentFrame();
+ else if(e->button() & Qt::RightButton)
+ m_pContextPopup->popup(mapToGlobal(e->pos()));
+}
+
+void KviDockWidget::doAway(int id)
+{
+ if(id<0)
+ {
+ KviPointerHashTableIterator<const char *,KviWindow> it(*g_pGlobalWindowDict);
+ while(KviWindow * wnd = it.current())
+ {
+ if(wnd->type()==KVI_WINDOW_TYPE_CONSOLE)
+ {
+ KviConsole* pConsole=(KviConsole*)wnd;
+ if(pConsole->isConnected())
+ if(id==-2)
+ pConsole->connection()->sendFmtData("AWAY");
+ else
+ pConsole->connection()->sendFmtData("AWAY :%s",
+ pConsole->connection()->encodeText(KVI_OPTION_STRING(KviOption_stringAwayMessage)).data()
+ );
+ }
+ ++it;
+ }
+ } else {
+ KviConsole* pConsole=g_pApp->findConsole((unsigned int)id);
+ if(pConsole)
+ if(pConsole->isConnected())
+ if(pConsole->connection()->userInfo()->isAway())
+ pConsole->connection()->sendFmtData("AWAY");
+ else
+ pConsole->connection()->sendFmtData("AWAY :%s",
+ pConsole->connection()->encodeText(KVI_OPTION_STRING(KviOption_stringAwayMessage)).data()
+ );
+ }
+}
+
+void KviDockWidget::fillContextPopup()
+{
+ m_pContextPopup->changeItem(m_iToggleFrame,m_pFrm->isVisible() ? __tr2qs("Hide Window") : __tr2qs("Show Window"));
+ if(g_pApp->topmostConnectedConsole())
+ {
+ m_pContextPopup->setItemVisible(m_iAwayMenuId,true);
+ m_pAwayPopup->clear();
+
+ int iAllAway=m_pAwayPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)),__tr2qs("Away on all"),this,SLOT(doAway(int)));
+ m_pAwayPopup->setItemParameter(iAllAway,-1);
+
+ int iAllUnaway=m_pAwayPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)),__tr2qs("Back on all"),this,SLOT(doAway(int)));
+ m_pAwayPopup->setItemParameter(iAllUnaway,-2);
+
+ int iSeparator=m_pAwayPopup->insertSeparator();
+
+ KviPointerHashTableIterator<const char *,KviWindow> it(*g_pGlobalWindowDict);
+ bool bAllAway=1;
+ bool bAllUnaway=1;
+ int iNetCount=0;
+ while(KviWindow * wnd = it.current())
+ {
+ if(wnd->type()==KVI_WINDOW_TYPE_CONSOLE)
+ {
+ KviConsole* pConsole=(KviConsole*)wnd;
+ if(pConsole->isConnected())
+ {
+ int id;
+ if(pConsole->connection()->userInfo()->isAway())
+ {
+ id=m_pAwayPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)),__tr2qs("Back on %1").arg(pConsole->currentNetworkName()),this,SLOT(doAway(int)));
+ bAllUnaway=0;
+ } else {
+ id=m_pAwayPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)),__tr2qs("Away on %1").arg(pConsole->currentNetworkName()),this,SLOT(doAway(int)));
+ bAllAway=0;
+ }
+ m_pAwayPopup->setItemParameter(id,pConsole->ircContextId());
+ iNetCount++;
+ }
+ }
+ ++it;
+ }
+ if(iNetCount==1)
+ {
+ m_pAwayPopup->setItemVisible(iAllAway,false);
+ m_pAwayPopup->setItemVisible(iAllUnaway,false);
+ m_pAwayPopup->setItemVisible(iSeparator,false);
+ } else {
+ m_pAwayPopup->setItemVisible(iAllAway,!bAllAway);
+ m_pAwayPopup->setItemVisible(iAllUnaway,!bAllUnaway);
+ }
+ } else {
+ m_pContextPopup->setItemVisible(m_iAwayMenuId,false);
+ }
+}
+
+void KviDockWidget::toggleParentFrame()
+{
+ QWidget *top_widget = m_pFrm->topLevelWidget();
+
+ if(m_pFrm->isVisible()) {
+ m_pFrm->hide();
+ } else {
+ top_widget->show();
+ top_widget->raise();
+ top_widget->setActiveWindow();
+ if(g_pActiveWindow) g_pActiveWindow->setFocus();
+ if(m_pFrm->isMinimized())
+ m_pFrm->showNormal();
+ else
+ m_pFrm->show();
+ }
+}
+
+void KviDockWidget::refresh()
+{
+ grabActivityInfo();
+
+#ifdef COMPILE_ON_WINDOWS
+ // how to copy transparency????
+ delete g_pCurrentPixmap;
+ g_pCurrentPixmap=new QPixmap(16,16);
+ bitBlt(g_pCurrentPixmap,0,0,m_iOther ? ((m_iOther == 2) ? g_pDock3 : g_pDock2) : g_pDock1,0,0,8,8,Qt::ClearROP);
+ bitBlt(g_pCurrentPixmap,0,8,m_iConsoles ? ((m_iConsoles == 2) ? g_pDock3 : g_pDock2) : g_pDock1,0,8,8,8,Qt::ClearROP);
+ bitBlt(g_pCurrentPixmap,8,0,m_iQueries ? ((m_iQueries == 2) ? g_pDock3 : g_pDock2) : g_pDock1,8,0,8,8,Qt::ClearROP);
+ bitBlt(g_pCurrentPixmap,8,8,m_iChannels ? ((m_iChannels == 2) ? g_pDock3 : g_pDock2) : g_pDock1,8,8,8,8,Qt::ClearROP);
+#endif
+
+ if( (m_iChannels == 2) || (m_iQueries == 2) )
+ {
+ if(!m_pFlashingTimer->isActive() && KVI_OPTION_BOOL(KviOption_boolEnableTrayIconFlashing) ) m_pFlashingTimer->start(1000);
+ } else {
+ if(m_pFlashingTimer->isActive()) m_pFlashingTimer->stop();
+ m_bFlashed=false;
+ }
+
+#ifdef COMPILE_ON_WINDOWS
+ updateTaskbarIcon();
+#else
+ update();
+#endif
+}
+
+void KviDockWidget::grabActivityInfo()
+{
+ KviTaskBarBase * t = m_pFrm->taskBar();
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseLevelBasedTrayNotification))
+ {
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)>5) KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)=5;
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)>5) KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)=5;
+
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)<1) KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)=1;
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)<1) KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)=1;
+
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)<KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage))
+ KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)=KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage);
+ }
+
+ m_iConsoles = 0;
+ m_iChannels = 0;
+ m_iQueries = 0;
+ m_iOther = 0;
+
+ for(KviTaskBarItem * b = t->firstItem();b;b = t->nextItem())
+ {
+ if(KVI_OPTION_BOOL(KviOption_boolUseLevelBasedTrayNotification))
+ {
+ int iLevel = b->highlightLevel();
+ switch(b->kviWindow()->type())
+ {
+ case KVI_WINDOW_TYPE_CONSOLE:
+ if(m_iConsoles < iLevel) m_iConsoles = iLevel;
+ break;
+ case KVI_WINDOW_TYPE_CHANNEL:
+ if(m_iChannels < iLevel) m_iChannels = iLevel;
+ break;
+ case KVI_WINDOW_TYPE_QUERY:
+ if(m_iQueries < iLevel) m_iQueries = iLevel;
+ break;
+ default:
+ if(m_iOther < iLevel) m_iOther = iLevel;
+ break;
+ }
+ } else {
+ int iLevel=0;
+ if(b->kviWindow()->view())
+ {
+ if(b->kviWindow()->view()->haveUnreadedHighlightedMessages())
+ {
+ iLevel=2;
+ } else if(b->kviWindow()->view()->haveUnreadedMessages())
+ {
+ iLevel=1;
+ }
+ if(iLevel>0)
+ switch(b->kviWindow()->type())
+ {
+ case KVI_WINDOW_TYPE_CONSOLE:
+ if(m_iConsoles < iLevel) m_iConsoles = iLevel;
+ break;
+ case KVI_WINDOW_TYPE_CHANNEL:
+ if(m_iChannels < iLevel) m_iChannels = iLevel;
+ break;
+ case KVI_WINDOW_TYPE_QUERY:
+ if(m_iQueries < iLevel) m_iQueries = iLevel;
+ break;
+ default:
+ if(m_iOther < iLevel) m_iOther = iLevel;
+ break;
+ }
+ }
+ }
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseLevelBasedTrayNotification))
+ {
+ if(m_iConsoles >= KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)) m_iConsoles=2;
+ else if(m_iConsoles >= KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)) m_iConsoles=1;
+ else m_iConsoles=0;
+
+ if(m_iChannels >= KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)) m_iChannels=2;
+ else if(m_iChannels >= KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)) m_iChannels=1;
+ else m_iChannels=0;
+
+ if(m_iQueries >= KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)) m_iQueries=2;
+ else if(m_iQueries >= KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)) m_iQueries=1;
+ else m_iQueries=0;
+
+ if(m_iOther >= KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)) m_iOther=2;
+ else if(m_iOther >= KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)) m_iOther=1;
+ else m_iOther=0;
+ }
+}
+
+void KviDockWidget::paintEvent(QPaintEvent * event)
+{
+#ifdef COMPILE_USE_QT4
+ QPainter thisRestrictionOfQt4IsNotNice(this);
+ if(m_bFlashed)
+ {
+ erase();
+ thisRestrictionOfQt4IsNotNice.drawPixmap(4,4,16,16,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MESSAGE)),0,0,16,16);
+ } else {
+ thisRestrictionOfQt4IsNotNice.drawPixmap(0,0,12,12,m_iOther ? ((m_iOther == 2) ? *g_pDock3 : *g_pDock2) : *g_pDock1,0,0,12,12);
+ thisRestrictionOfQt4IsNotNice.drawPixmap(0,12,12,12,m_iConsoles ? ((m_iConsoles == 2) ? *g_pDock3 : *g_pDock2) : *g_pDock1,0,12,12,12);
+ thisRestrictionOfQt4IsNotNice.drawPixmap(12,0,12,12,m_iQueries ? ((m_iQueries == 2) ? *g_pDock3 : *g_pDock2) : *g_pDock1,12,0,12,12);
+ thisRestrictionOfQt4IsNotNice.drawPixmap(12,12,12,12,m_iChannels ? ((m_iChannels == 2) ? *g_pDock3 : *g_pDock2) : *g_pDock1,12,12,12,12);
+ }
+#else
+ if(m_bFlashed)
+ {
+ erase();
+ bitBlt(this,4,4,g_pIconManager->getSmallIcon(KVI_SMALLICON_MESSAGE),0,0,16,16);
+ } else {
+ bitBlt(this,0,0,m_iOther ? ((m_iOther == 2) ? g_pDock3 : g_pDock2) : g_pDock1,0,0,12,12,Qt::CopyROP,false);
+ bitBlt(this,0,12,m_iConsoles ? ((m_iConsoles == 2) ? g_pDock3 : g_pDock2) : g_pDock1,0,12,12,12,Qt::CopyROP,false);
+ bitBlt(this,12,0,m_iQueries ? ((m_iQueries == 2) ? g_pDock3 : g_pDock2) : g_pDock1,12,0,12,12,Qt::CopyROP,false);
+ bitBlt(this,12,12,m_iChannels ? ((m_iChannels == 2) ? g_pDock3 : g_pDock2) : g_pDock1,12,12,12,12,Qt::CopyROP,false);
+ }
+#endif
+}
+
+
+static KviDockWidget * dockwidget_find(KviFrame *f)
+{
+ if(!g_pDockWidgetList)return 0;
+ for(KviDockWidget * w = g_pDockWidgetList->first();w;w = g_pDockWidgetList->next())
+ {
+ if(w->frame() == f)return w;
+ }
+ return 0;
+}
+
+/*
+ @doc: dockwidget.show
+ @type:
+ command
+ @title:
+ dockwidget.show
+ @short:
+ Shows the dock widget for the current frame window
+ @keyterms:
+ dock widget , system tray
+ @syntax:
+ dockwidget.show
+ @description:
+ Shows the dock widget for the current frame window.[br]
+ The dock widget is a small widget that docks in the KDE panel.[br]
+ It shows a small icon of the earth and eventually displays four squares
+ that cover this icon: the bottom left square appears when there is some new
+ text in any console window, the square becomes red if the text is highlighted.[br]
+ The bottom right square appears when there is some new text in any channel window,
+ and it becomes red when the text is highlighted.[br] The upper right square refers to
+ query windows and the upper left one to any other kind of window (dcc , links...).[br]
+ If you move the mouse over the dock widget a tooltip will show you the last lines
+ of the "new" text in all these windows.[br]
+ This is useful when you keep the main KVIrc window minimized and you're working on something else:
+ if the dock widget shows nothing but the earth icon , nothing is happening in the main KVIrc window.
+ If the dock widget shows one or more white (or red) squares , you can move the mouse over
+ and check what's happened exactly and eventually bring up the main KVIrc window by clicking on the widget.[br]
+ [big]tecnical details[/big]
+ The dock widget is currently working in KDE compilation mode only:
+ it relies on the KWin implementation of the Window Manager interaction protocol.
+ @seealso:
+ [cmd]dockwidget.hide[/cmd]
+*/
+
+static bool dockwidget_kvs_cmd_show(KviKvsModuleCommandCall * c)
+{
+ if(!(dockwidget_find(c->window()->frame())))
+ {
+ KviDockWidget * w = new KviDockWidget(c->window()->frame(),"dock_widget");
+#ifndef COMPILE_ON_WINDOWS
+ w->show();
+#else
+ w->hide();
+#endif
+ }
+ return true;
+}
+
+/*
+ @doc: dockwidget.hide
+ @type:
+ command
+ @title:
+ dockwidget.hide
+ @short:
+ Hides the dock widget for the current frame window
+ @syntax:
+ dockwidget.hide
+ @description:
+ Hides the dock widget for the current frame window
+ @seealso:
+ [cmd]dockwidget.show[/cmd]
+*/
+
+static bool dockwidget_kvs_cmd_hide(KviKvsModuleCommandCall * c)
+{
+ KviDockWidget * w= dockwidget_find(c->window()->frame());
+ if(w)delete w;
+ // show the parent frame.. otherwise there will be no way to get it back
+ if(!c->window()->frame()->isVisible())
+ {
+ c->window()->frame()->show();
+ }
+ return true;
+}
+
+/*
+ @doc: dockwidget.hidewindow
+ @type:
+ command
+ @title:
+ dockwidget.hidewindow
+ @short:
+ Returns the state of the dock widget
+ @syntax:
+ dockwidget.hidewindow
+ @description:
+ Hides the window, assotiated with dockwidget
+ @seealso:
+ [cmd]dockwidget.show[/cmd], [cmd]dockwidget.hide[/cmd]
+*/
+
+static bool dockwidget_kvs_cmd_hidewindow(KviKvsModuleCommandCall * c)
+{
+ KviDockWidget * w= dockwidget_find(c->window()->frame());
+ if(w)
+ {
+#if QT_VERSION > 0x030201
+ w->setPrevWindowState(c->window()->frame()->windowState());
+#endif
+ c->window()->frame()->hide();
+ }
+ return true;
+}
+
+/*
+ @doc: dockwidget.isVisible
+ @type:
+ function
+ @title:
+ $dockwidget.isVisible
+ @short:
+ Returns the state of the dock widget
+ @syntax:
+ $reguser.isVisible()
+ @description:
+ Returns 1 if the dock widget is actually visible , 0 otherwise.
+ @seealso:
+ [cmd]dockwidget.show[/cmd]
+*/
+
+static bool dockwidget_kvs_fnc_isvisible(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setBoolean(dockwidget_find(c->window()->frame()));
+ return true;
+}
+
+
+
+// =======================================
+// init routine
+// =======================================
+static bool dockwidget_module_init(KviModule * m)
+{
+ KviStr buffer;
+#ifdef COMPILE_ON_WINDOWS
+ g_pApp->findImage(buffer,"kvi_dock_win32.png");
+ KviImageLibrary l1(buffer.ptr(),16,16);
+#else
+ g_pApp->findImage(buffer,"kvi_dock.png");
+ KviImageLibrary l1(buffer.ptr(),22,22);
+#endif
+ g_pDock1 = new QPixmap(l1.getImage(0));
+ g_pDock2 = new QPixmap(l1.getImage(1));
+ g_pDock3 = new QPixmap(l1.getImage(2));
+
+#ifdef COMPILE_ON_WINDOWS
+
+#endif
+
+
+ g_pDockWidgetList = new KviPointerList<KviDockWidget>;
+ g_pDockWidgetList->setAutoDelete(false);
+
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"hide",dockwidget_kvs_cmd_hide);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"hidewindow",dockwidget_kvs_cmd_hidewindow);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"show",dockwidget_kvs_cmd_show);
+ KVSM_REGISTER_FUNCTION(m,"isVisible",dockwidget_kvs_fnc_isvisible);
+
+ return true;
+}
+
+static bool dockwidget_module_cleanup(KviModule *m)
+{
+ while(g_pDockWidgetList->first())delete g_pDockWidgetList->first();
+ delete g_pDockWidgetList;
+ g_pDockWidgetList = 0;
+
+#ifdef COMPILE_ON_WINDOWS
+ DestroyIcon(g_pCurrentIcon);
+#endif
+
+ delete g_pDock1;
+ g_pDock1 = 0;
+ delete g_pDock2;
+ g_pDock2 = 0;
+ delete g_pDock3;
+ g_pDock3 = 0;
+
+ return true;
+}
+
+static bool dockwidget_module_can_unload(KviModule *)
+{
+ return g_pDockWidgetList->isEmpty();
+}
+
+// =======================================
+// plugin definition structure
+// =======================================
+KVIRC_MODULE(
+ "KVIrc dock widget implementation",
+ "1.0.0",
+ "Szymon Stefanek <pragma at kvirc dot net>" ,
+ "exports the /dockwidget.* interface\n",
+ dockwidget_module_init ,
+ dockwidget_module_can_unload,
+ 0,
+ dockwidget_module_cleanup
+)
+
+#include "libkvidockwidget_qt3.moc"
+
+#endif \ No newline at end of file
diff --git a/src/modules/dockwidget/libkvidockwidget_qt3.h b/src/modules/dockwidget/libkvidockwidget_qt3.h
new file mode 100644
index 00000000..1721c28b
--- /dev/null
+++ b/src/modules/dockwidget/libkvidockwidget_qt3.h
@@ -0,0 +1,95 @@
+#ifndef _KVI_DOCKWIDGET_H_
+#define _KVI_DOCKWIDGET_H_
+//
+// This file is part of the KVirc irc client distribution
+// Creation date : Tue 02 Jan 2001 14:28:25 by Szymon Stefanek
+// Copyright (C) 2000-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_frame.h"
+
+#ifdef COMPILE_KDE_SUPPORT
+ class KPopupMenu;
+#else
+ class KviTalPopupMenu;
+#endif
+
+
+
+
+class QPixmap;
+class QTimer;
+
+//class KviFrame;
+class KviDynamicToolTip;
+
+class KviDockWidget : public QWidget , public KviDockExtension
+{
+ Q_OBJECT
+public:
+ KviDockWidget(KviFrame * win,const char * name);
+ ~KviDockWidget();
+protected:
+ KviFrame * m_pFrm;
+ KviDynamicToolTip * m_pTip;
+#ifdef COMPILE_KDE_SUPPORT
+ KPopupMenu * m_pContextPopup;
+#else
+ KviTalPopupMenu * m_pContextPopup;
+#endif
+ KviTalPopupMenu * m_pAwayPopup;
+ int m_iToggleFrame;
+ int m_iAwayMenuId;
+
+ bool m_bFlashed;
+
+ QTimer* m_pFlashingTimer;
+ int m_iConsoles;
+ int m_iChannels;
+ int m_iQueries;
+ int m_iOther;
+public:
+ KviFrame * frame(){ return m_pFrm; };
+public:
+// virtual int message(int msgtype,void * data);
+ virtual void enterEvent(QEvent *);
+ virtual void refresh();
+ virtual void die();
+protected:
+ virtual void paintEvent(QPaintEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ void grabActivityInfo();
+
+#ifdef COMPILE_ON_WINDOWS
+private:
+ void createTaskbarIcon();
+ void destroyTaskbarIcon();
+ void updateTaskbarIcon();
+protected:
+ bool winEvent(MSG * m);
+#endif
+
+protected slots:
+ void fillContextPopup();
+ void toggleParentFrame();
+ void tipRequest(KviDynamicToolTip *tip,const QPoint &pnt);
+ void doAway(int);
+ void flashingTimerShot();
+};
+
+#endif //_KVI_DOCKWIDGET_H_
diff --git a/src/modules/dockwidget/libkvidockwidget_qt4.cpp b/src/modules/dockwidget/libkvidockwidget_qt4.cpp
new file mode 100644
index 00000000..73a21998
--- /dev/null
+++ b/src/modules/dockwidget/libkvidockwidget_qt4.cpp
@@ -0,0 +1,691 @@
+//
+// File : libkvidockwidget.cpp
+// Creation date : Tue Jan 02 20001 14:34:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-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_settings.h"
+
+#ifdef COMPILE_USE_QT4
+
+#ifdef COMPILE_ON_WINDOWS
+ #define ICON_SIZE 16
+#else
+ #define ICON_SIZE 22
+#endif
+
+#include "kvi_app.h"
+#include "kvi_module.h"
+#include "kvi_locale.h"
+#include "kvi_memmove.h"
+#include "kvi_taskbar.h"
+#include "kvi_window.h"
+#include "kvi_dynamictooltip.h"
+#include "kvi_iconmanager.h"
+#include "kvi_internalcmd.h"
+#include "kvi_console.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_imagelib.h"
+#include "kvi_options.h"
+#include "kvi_ircview.h"
+
+#include "libkvidockwidget.h"
+#include "kvi_doublebuffer.h"
+
+#include <qlabel.h>
+
+#include "kvi_tal_popupmenu.h"
+
+
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qtimer.h>
+#include <qevent.h>
+#include <qregexp.h>
+
+#include <stdlib.h>
+#include <time.h>
+
+
+extern KVIRC_API KviPointerHashTable<const char *,KviWindow> * g_pGlobalWindowDict;
+static KviPointerList<KviDockWidget> * g_pDockWidgetList = 0;
+
+static QPixmap * g_pDock1 = 0;
+static QPixmap * g_pDock2 = 0;
+static QPixmap * g_pDock3 = 0;
+
+KviDockWidget::KviDockWidget(KviFrame * frm)
+: QSystemTrayIcon(frm), m_CurrentPixmap(ICON_SIZE,ICON_SIZE)
+{
+ m_pContextPopup = new KviTalPopupMenu(0);
+ setContextMenu(m_pContextPopup);
+
+ m_iConsoles = 0;
+ m_iChannels = 0;
+ m_iQueries = 0;
+ m_iOther = 0;
+
+ m_pFlashingTimer = new QTimer(this,"flashing_timer");
+ connect( m_pFlashingTimer, SIGNAL(timeout()), this, SLOT(flashingTimerShot()) );
+ m_bFlashed=0;
+ g_pDockWidgetList->append(this);
+ m_pFrm = frm;
+ m_pFrm->setDockExtension(this);
+
+ m_pTip = new KviDynamicToolTip(frm,"dock_tooltip");
+ m_pAwayPopup = new KviTalPopupMenu(0);
+
+ QLabel * l = new QLabel(__tr2qs("KVIrc"),m_pContextPopup);
+ l->setFrameStyle(QFrame::Raised | QFrame::StyledPanel);
+ m_pContextPopup->insertItem(l);
+ m_pContextPopup->setCaption(__tr2qs("Context"));
+ m_iAwayMenuId = m_pContextPopup->insertItem ( __tr2qs("Away"), m_pAwayPopup);
+ m_pContextPopup->changeItem(m_iAwayMenuId,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_AWAY)),__tr2qs("Away"));
+
+ int id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_OPTIONS)),__tr2qs("&Configure KVIrc..."),m_pFrm,SLOT(executeInternalCommand(int)));
+ m_pContextPopup->setItemParameter(id,KVI_INTERNALCOMMAND_OPTIONS_DIALOG);
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)),__tr2qs("&About KVIrc"),m_pFrm,SLOT(executeInternalCommand(int)));
+ m_pContextPopup->setItemParameter(id,KVI_INTERNALCOMMAND_ABOUT_ABOUTKVIRC);
+ m_pContextPopup->insertSeparator();
+ m_iToggleFrame = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RAW)),QString(""),this,SLOT(toggleParentFrame()));
+ m_pContextPopup->insertSeparator();
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DOCKWIDGET)),__tr2qs("Un&dock"),m_pFrm,SLOT(executeInternalCommand(int)));
+ m_pContextPopup->setItemParameter(id,KVI_INTERNALCOMMAND_DOCKWIDGET_HIDE);
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUITAPP)),__tr2qs("&Quit"),g_pApp,SLOT(quit()));
+ m_pContextPopup->setAccel(__tr2qs("Ctrl+Q"),id);
+ connect(m_pContextPopup,SIGNAL(aboutToShow()),this,SLOT(fillContextPopup()));
+
+ QIcon icon(*g_pDock1);
+ setIcon(icon);
+
+ connect(this,SIGNAL(activated ( QSystemTrayIcon::ActivationReason )),this,SLOT(activatedSlot ( QSystemTrayIcon::ActivationReason )));
+}
+
+
+KviDockWidget::~KviDockWidget()
+{
+ m_pFrm->setDockExtension(0);
+ g_pDockWidgetList->removeRef(this);
+}
+
+void KviDockWidget::die()
+{
+ delete this;
+}
+
+void KviDockWidget::flashingTimerShot()
+{
+ m_bFlashed=!m_bFlashed;
+ refresh();
+}
+
+#define NIDLEMSGS 18
+
+static const char * idlemsgs[NIDLEMSGS]=
+{
+ __tr("Nothing is happening...") ,
+ __tr("Just idling...") ,
+ __tr("Dum de dum de dum...") ,
+ __tr("Hey man... do something!") ,
+ __tr("Umpf!") ,
+ __tr("Silence speaking") ,
+ __tr("Are ya here?") ,
+ __tr("The world has stopped?") ,
+ __tr("Everything is all right") ,
+ __tr("idle()") ,
+ __tr("It's so cold here...") ,
+ __tr("Do not disturb... watching TV") ,
+ __tr("Just vegetating") ,
+ __tr("Hey... are ya sure that your network is up?") ,
+ __tr("Seems like the world has stopped spinning") ,
+ __tr("This silence is freaking me out!") ,
+ __tr("Mieeeeeowww!") ,
+ __tr("idle idle idle idle!")
+};
+
+void KviDockWidget::tipRequest(KviDynamicToolTip *tip,const QPoint &pnt)
+{
+ QString tmp;
+
+ KviTaskBarBase * t = m_pFrm->taskBar();
+
+ QString line;
+
+ for(KviTaskBarItem * b = t->firstItem();b;b = t->nextItem())
+ {
+
+ if(b->kviWindow()->view())
+ {
+ if(b->kviWindow()->view()->haveUnreadedMessages())
+ {
+ line = b->kviWindow()->lastMessageText();
+ if(!line.isEmpty())
+ {
+ line.replace(QChar('&'),"&amp;");
+ line.replace(QChar('<'),"&lt;");
+ line.replace(QChar('>'),"&gt;");
+ tmp += "<b>";
+ tmp += b->kviWindow()->plainTextCaption();
+ tmp += "</b><br>";
+ tmp += line;
+ tmp += "<br><br>\n";
+ }
+ }
+ }
+ }
+
+
+ srand(time(0));
+
+ // We use the bad way to generate random numbers :)))))
+
+ if(tmp.isEmpty())tmp = __tr2qs_no_xgettext(idlemsgs[(int)(rand() % NIDLEMSGS)]);
+
+ //m_pTip->tip(rect(),tmp);
+}
+
+//int KviDockWidget::message(int,void *)
+//{
+// debug("Message");
+// update();
+// return 0;
+//}
+
+//FIXME: Qt4 port
+/*void KviDockWidget::mousePressEvent(QMouseEvent *e)
+{
+ if(e->button() & Qt::LeftButton)toggleParentFrame();
+ else if(e->button() & Qt::RightButton)
+ m_pContextPopup->popup(mapToGlobal(e->pos()));
+}*/
+
+void KviDockWidget::doAway(int id)
+{
+ if(id<0)
+ {
+ KviPointerHashTableIterator<const char *,KviWindow> it(*g_pGlobalWindowDict);
+ while(KviWindow * wnd = it.current())
+ {
+ if(wnd->type()==KVI_WINDOW_TYPE_CONSOLE)
+ {
+ KviConsole* pConsole=(KviConsole*)wnd;
+ if(pConsole->isConnected())
+ if(id==-2)
+ pConsole->connection()->sendFmtData("AWAY");
+ else
+ pConsole->connection()->sendFmtData("AWAY :%s",
+ pConsole->connection()->encodeText(KVI_OPTION_STRING(KviOption_stringAwayMessage)).data()
+ );
+ }
+ ++it;
+ }
+ } else {
+ KviConsole* pConsole=g_pApp->findConsole((unsigned int)id);
+ if(pConsole)
+ if(pConsole->isConnected())
+ if(pConsole->connection()->userInfo()->isAway())
+ pConsole->connection()->sendFmtData("AWAY");
+ else
+ pConsole->connection()->sendFmtData("AWAY :%s",
+ pConsole->connection()->encodeText(KVI_OPTION_STRING(KviOption_stringAwayMessage)).data()
+ );
+ }
+}
+
+void KviDockWidget::fillContextPopup()
+{
+ m_pContextPopup->changeItem(m_iToggleFrame,m_pFrm->isVisible() ? __tr2qs("Hide Window") : __tr2qs("Show Window"));
+ if(g_pApp->topmostConnectedConsole())
+ {
+ m_pContextPopup->setItemVisible(m_iAwayMenuId,true);
+ m_pAwayPopup->clear();
+
+ int iAllAway=m_pAwayPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)),__tr2qs("Away on all"),this,SLOT(doAway(int)));
+ m_pAwayPopup->setItemParameter(iAllAway,-1);
+
+ int iAllUnaway=m_pAwayPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)),__tr2qs("Back on all"),this,SLOT(doAway(int)));
+ m_pAwayPopup->setItemParameter(iAllUnaway,-2);
+
+ int iSeparator=m_pAwayPopup->insertSeparator();
+
+ KviPointerHashTableIterator<const char *,KviWindow> it(*g_pGlobalWindowDict);
+ bool bAllAway=1;
+ bool bAllUnaway=1;
+ int iNetCount=0;
+ while(KviWindow * wnd = it.current())
+ {
+ if(wnd->type()==KVI_WINDOW_TYPE_CONSOLE)
+ {
+ KviConsole* pConsole=(KviConsole*)wnd;
+ if(pConsole->isConnected())
+ {
+ int id;
+ if(pConsole->connection()->userInfo()->isAway())
+ {
+ id=m_pAwayPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)),__tr2qs("Back on %1").arg(pConsole->currentNetworkName()),this,SLOT(doAway(int)));
+ bAllUnaway=0;
+ } else {
+ id=m_pAwayPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)),__tr2qs("Away on %1").arg(pConsole->currentNetworkName()),this,SLOT(doAway(int)));
+ bAllAway=0;
+ }
+ m_pAwayPopup->setItemParameter(id,pConsole->ircContextId());
+ iNetCount++;
+ }
+ }
+ ++it;
+ }
+ if(iNetCount==1)
+ {
+ m_pAwayPopup->setItemVisible(iAllAway,false);
+ m_pAwayPopup->setItemVisible(iAllUnaway,false);
+ m_pAwayPopup->setItemVisible(iSeparator,false);
+ } else {
+ m_pAwayPopup->setItemVisible(iAllAway,!bAllAway);
+ m_pAwayPopup->setItemVisible(iAllUnaway,!bAllUnaway);
+ }
+ } else {
+ m_pContextPopup->setItemVisible(m_iAwayMenuId,false);
+ }
+}
+
+void KviDockWidget::toggleParentFrame()
+{
+ QWidget *top_widget = m_pFrm->topLevelWidget();
+
+ if(m_pFrm->isVisible()) {
+ m_pFrm->hide();
+ } else {
+ top_widget->show();
+ top_widget->raise();
+ top_widget->setActiveWindow();
+ if(g_pActiveWindow) g_pActiveWindow->setFocus();
+ if(m_pFrm->isMinimized())
+ m_pFrm->showNormal();
+ else
+ m_pFrm->show();
+ }
+}
+
+void KviDockWidget::refresh()
+{
+ grabActivityInfo();
+
+ if( (m_iChannels == 2) || (m_iQueries == 2) )
+ {
+ if(!m_pFlashingTimer->isActive() && KVI_OPTION_BOOL(KviOption_boolEnableTrayIconFlashing) )
+ m_pFlashingTimer->start(1000);
+ } else {
+ if(m_pFlashingTimer->isActive()) m_pFlashingTimer->stop();
+ m_bFlashed=false;
+ }
+
+ m_CurrentPixmap.fill(Qt::transparent);
+ QPainter thisRestrictionOfQt4IsNotNice(&m_CurrentPixmap);
+ //thisRestrictionOfQt4IsNotNice.drawPixmap(0,0,22,22,*g_pDock1,0,0,22,22);
+
+ if(m_bFlashed)
+ {
+ thisRestrictionOfQt4IsNotNice.drawPixmap((ICON_SIZE-16)/2,(ICON_SIZE-16)/2,16,16,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MESSAGE)),0,0,16,16);
+ } else {
+ thisRestrictionOfQt4IsNotNice.drawPixmap(0,0,ICON_SIZE/2,ICON_SIZE/2,
+ m_iOther ?
+ ((m_iOther == 2) ? *g_pDock3 : *g_pDock2)
+ : *g_pDock1,0,0,ICON_SIZE/2,ICON_SIZE/2);
+
+ thisRestrictionOfQt4IsNotNice.drawPixmap(0,ICON_SIZE/2,ICON_SIZE/2,ICON_SIZE/2,
+ m_iConsoles ?
+ ((m_iConsoles == 2) ? *g_pDock3 : *g_pDock2)
+ : *g_pDock1,0,ICON_SIZE/2,ICON_SIZE/2,ICON_SIZE/2);
+
+ thisRestrictionOfQt4IsNotNice.drawPixmap(ICON_SIZE/2,0,ICON_SIZE/2,ICON_SIZE/2,
+ m_iQueries ?
+ ((m_iQueries == 2)
+ ? *g_pDock3 : *g_pDock2)
+ : *g_pDock1,ICON_SIZE/2,0,ICON_SIZE/2,ICON_SIZE/2);
+
+ thisRestrictionOfQt4IsNotNice.drawPixmap(ICON_SIZE/2,ICON_SIZE/2,ICON_SIZE/2,ICON_SIZE/2,
+ m_iChannels ?
+ ((m_iChannels == 2) ? *g_pDock3 : *g_pDock2)
+ : *g_pDock1
+ ,ICON_SIZE/2,ICON_SIZE/2,ICON_SIZE/2,ICON_SIZE/2);
+
+ }
+ updateIcon();
+}
+
+void KviDockWidget::activatedSlot( QSystemTrayIcon::ActivationReason reason )
+{
+ if(reason==QSystemTrayIcon::Trigger)
+ {
+ toggleParentFrame();
+ }
+}
+
+void KviDockWidget::grabActivityInfo()
+{
+ KviTaskBarBase * t = m_pFrm->taskBar();
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseLevelBasedTrayNotification))
+ {
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)>5) KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)=5;
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)>5) KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)=5;
+
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)<1) KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)=1;
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)<1) KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)=1;
+
+ if(KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)<KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage))
+ KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)=KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage);
+ }
+
+ m_iConsoles = 0;
+ m_iChannels = 0;
+ m_iQueries = 0;
+ m_iOther = 0;
+
+ for(KviTaskBarItem * b = t->firstItem();b;b = t->nextItem())
+ {
+ if(KVI_OPTION_BOOL(KviOption_boolUseLevelBasedTrayNotification))
+ {
+ int iLevel = b->highlightLevel();
+ switch(b->kviWindow()->type())
+ {
+ case KVI_WINDOW_TYPE_CONSOLE:
+ if(m_iConsoles < iLevel) m_iConsoles = iLevel;
+ break;
+ case KVI_WINDOW_TYPE_CHANNEL:
+ if(m_iChannels < iLevel) m_iChannels = iLevel;
+ break;
+ case KVI_WINDOW_TYPE_QUERY:
+ if(m_iQueries < iLevel) m_iQueries = iLevel;
+ break;
+ default:
+ if(m_iOther < iLevel) m_iOther = iLevel;
+ break;
+ }
+ } else {
+ int iLevel=0;
+ if(b->kviWindow()->view())
+ {
+ if(b->kviWindow()->view()->haveUnreadedHighlightedMessages())
+ {
+ iLevel=2;
+ } else if(b->kviWindow()->view()->haveUnreadedMessages())
+ {
+ iLevel=1;
+ }
+ if(iLevel>0)
+ switch(b->kviWindow()->type())
+ {
+ case KVI_WINDOW_TYPE_CONSOLE:
+ if(m_iConsoles < iLevel) m_iConsoles = iLevel;
+ break;
+ case KVI_WINDOW_TYPE_CHANNEL:
+ if(m_iChannels < iLevel) m_iChannels = iLevel;
+ break;
+ case KVI_WINDOW_TYPE_QUERY:
+ if(m_iQueries < iLevel) m_iQueries = iLevel;
+ break;
+ default:
+ if(m_iOther < iLevel) m_iOther = iLevel;
+ break;
+ }
+ }
+ }
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseLevelBasedTrayNotification))
+ {
+ if(m_iConsoles >= KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)) m_iConsoles=2;
+ else if(m_iConsoles >= KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)) m_iConsoles=1;
+ else m_iConsoles=0;
+
+ if(m_iChannels >= KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)) m_iChannels=2;
+ else if(m_iChannels >= KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)) m_iChannels=1;
+ else m_iChannels=0;
+
+ if(m_iQueries >= KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)) m_iQueries=2;
+ else if(m_iQueries >= KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)) m_iQueries=1;
+ else m_iQueries=0;
+
+ if(m_iOther >= KVI_OPTION_UINT(KviOption_uintMinTrayHighLevelMessage)) m_iOther=2;
+ else if(m_iOther >= KVI_OPTION_UINT(KviOption_uintMinTrayLowLevelMessage)) m_iOther=1;
+ else m_iOther=0;
+ }
+}
+
+void KviDockWidget::updateIcon()
+{
+ setIcon(QIcon(m_CurrentPixmap));
+}
+
+
+static KviDockWidget * dockwidget_find(KviFrame *f)
+{
+ if(!g_pDockWidgetList)return 0;
+ for(KviDockWidget * w = g_pDockWidgetList->first();w;w = g_pDockWidgetList->next())
+ {
+ if(w->frame() == f)return w;
+ }
+ return 0;
+}
+
+/*
+ @doc: dockwidget.show
+ @type:
+ command
+ @title:
+ dockwidget.show
+ @short:
+ Shows the dock widget for the current frame window
+ @keyterms:
+ dock widget , system tray
+ @syntax:
+ dockwidget.show
+ @description:
+ Shows the dock widget for the current frame window.[br]
+ The dock widget is a small widget that docks in the KDE panel.[br]
+ It shows a small icon of the earth and eventually displays four squares
+ that cover this icon: the bottom left square appears when there is some new
+ text in any console window, the square becomes red if the text is highlighted.[br]
+ The bottom right square appears when there is some new text in any channel window,
+ and it becomes red when the text is highlighted.[br] The upper right square refers to
+ query windows and the upper left one to any other kind of window (dcc , links...).[br]
+ If you move the mouse over the dock widget a tooltip will show you the last lines
+ of the "new" text in all these windows.[br]
+ This is useful when you keep the main KVIrc window minimized and you're working on something else:
+ if the dock widget shows nothing but the earth icon , nothing is happening in the main KVIrc window.
+ If the dock widget shows one or more white (or red) squares , you can move the mouse over
+ and check what's happened exactly and eventually bring up the main KVIrc window by clicking on the widget.[br]
+ [big]tecnical details[/big]
+ The dock widget is currently working in KDE compilation mode only:
+ it relies on the KWin implementation of the Window Manager interaction protocol.
+ @seealso:
+ [cmd]dockwidget.hide[/cmd]
+*/
+
+static bool dockwidget_kvs_cmd_show(KviKvsModuleCommandCall * c)
+{
+ if(!(dockwidget_find(c->window()->frame())))
+ {
+ KviDockWidget * w = new KviDockWidget(c->window()->frame());
+ w->show();
+ }
+ return true;
+}
+
+/*
+ @doc: dockwidget.hide
+ @type:
+ command
+ @title:
+ dockwidget.hide
+ @short:
+ Hides the dock widget for the current frame window
+ @syntax:
+ dockwidget.hide
+ @description:
+ Hides the dock widget for the current frame window
+ @seealso:
+ [cmd]dockwidget.show[/cmd]
+*/
+
+static bool dockwidget_kvs_cmd_hide(KviKvsModuleCommandCall * c)
+{
+ KviDockWidget * w= dockwidget_find(c->window()->frame());
+ if(w)delete w;
+ // show the parent frame.. otherwise there will be no way to get it back
+ if(!c->window()->frame()->isVisible())
+ {
+ c->window()->frame()->show();
+ }
+ return true;
+}
+
+/*
+ @doc: dockwidget.hidewindow
+ @type:
+ command
+ @title:
+ dockwidget.hidewindow
+ @short:
+ Returns the state of the dock widget
+ @syntax:
+ dockwidget.hidewindow
+ @description:
+ Hides the window, assotiated with dockwidget
+ @seealso:
+ [cmd]dockwidget.show[/cmd], [cmd]dockwidget.hide[/cmd]
+*/
+
+static bool dockwidget_kvs_cmd_hidewindow(KviKvsModuleCommandCall * c)
+{
+ KviDockWidget * w= dockwidget_find(c->window()->frame());
+ if(w)
+ {
+ c->window()->frame()->hide();
+ }
+ return true;
+}
+
+/*
+ @doc: dockwidget.isVisible
+ @type:
+ function
+ @title:
+ $dockwidget.isVisible
+ @short:
+ Returns the state of the dock widget
+ @syntax:
+ $reguser.isVisible()
+ @description:
+ Returns 1 if the dock widget is actually visible , 0 otherwise.
+ @seealso:
+ [cmd]dockwidget.show[/cmd]
+*/
+
+static bool dockwidget_kvs_fnc_isvisible(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setBoolean(dockwidget_find(c->window()->frame()));
+ return true;
+}
+
+
+
+// =======================================
+// init routine
+// =======================================
+static bool dockwidget_module_init(KviModule * m)
+{
+ QString buffer;
+#ifdef COMPILE_ON_WINDOWS
+ g_pApp->findImage(buffer,"kvi_dock_win32-0.png");
+#else
+ g_pApp->findImage(buffer,"kvi_dock_part-0.png");
+#endif
+ g_pDock1 = new QPixmap(buffer);
+
+#ifdef COMPILE_ON_WINDOWS
+ g_pApp->findImage(buffer,"kvi_dock_win32-1.png");
+#else
+ g_pApp->findImage(buffer,"kvi_dock_part-1.png");
+#endif
+ g_pDock2 = new QPixmap(buffer);
+
+#ifdef COMPILE_ON_WINDOWS
+ g_pApp->findImage(buffer,"kvi_dock_win32-2.png");
+#else
+ g_pApp->findImage(buffer,"kvi_dock_part-2.png");
+#endif
+
+ g_pDock3 = new QPixmap(buffer);
+
+
+ g_pDockWidgetList = new KviPointerList<KviDockWidget>;
+ g_pDockWidgetList->setAutoDelete(false);
+
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"hide",dockwidget_kvs_cmd_hide);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"hidewindow",dockwidget_kvs_cmd_hidewindow);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"show",dockwidget_kvs_cmd_show);
+ KVSM_REGISTER_FUNCTION(m,"isVisible",dockwidget_kvs_fnc_isvisible);
+
+ return true;
+}
+
+static bool dockwidget_module_cleanup(KviModule *m)
+{
+ while(g_pDockWidgetList->first())delete g_pDockWidgetList->first();
+ delete g_pDockWidgetList;
+ g_pDockWidgetList = 0;
+
+ delete g_pDock1;
+ g_pDock1 = 0;
+
+ delete g_pDock2;
+ g_pDock2 = 0;
+
+ delete g_pDock3;
+ g_pDock3 = 0;
+
+ return true;
+}
+
+static bool dockwidget_module_can_unload(KviModule *)
+{
+ return g_pDockWidgetList->isEmpty();
+}
+
+// =======================================
+// plugin definition structure
+// =======================================
+KVIRC_MODULE(
+ "KVIrc dock widget implementation",
+ "2.0.0",
+ "Szymon Stefanek <pragma at kvirc dot net> and Alexey Uzhva <alexey at kvirc dot ru>" ,
+ "exports the /dockwidget.* interface\n",
+ dockwidget_module_init ,
+ dockwidget_module_can_unload,
+ 0,
+ dockwidget_module_cleanup
+)
+
+#include "libkvidockwidget_qt4.moc"
+
+#endif
diff --git a/src/modules/dockwidget/libkvidockwidget_qt4.h b/src/modules/dockwidget/libkvidockwidget_qt4.h
new file mode 100644
index 00000000..9d9e87bc
--- /dev/null
+++ b/src/modules/dockwidget/libkvidockwidget_qt4.h
@@ -0,0 +1,81 @@
+#ifndef _KVI_DOCKWIDGET_QT4_H_
+#define _KVI_DOCKWIDGET_QT4_H_
+//
+// This file is part of the KVirc irc client distribution
+// Creation date : Tue 02 Jan 2001 14:28:25 by Szymon Stefanek
+// Copyright (C) 2000-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_settings.h"
+//#ifdef COMPILE_USE_QT4
+
+#include "kvi_frame.h"
+
+class KviTalPopupMenu;
+#include <QSystemTrayIcon>
+
+class QPixmap;
+class QTimer;
+
+//class KviFrame;
+class KviDynamicToolTip;
+
+class KviDockWidget : public QSystemTrayIcon, public KviDockExtension
+{
+ Q_OBJECT
+public:
+ KviDockWidget(KviFrame * win);
+ ~KviDockWidget();
+protected:
+ KviFrame * m_pFrm;
+ KviDynamicToolTip * m_pTip;
+ KviTalPopupMenu * m_pContextPopup;
+ KviTalPopupMenu * m_pAwayPopup;
+
+ int m_iToggleFrame;
+ int m_iAwayMenuId;
+
+ bool m_bFlashed;
+
+ QPixmap m_CurrentPixmap;
+ QTimer* m_pFlashingTimer;
+ int m_iConsoles;
+ int m_iChannels;
+ int m_iQueries;
+ int m_iOther;
+public:
+ KviFrame * frame(){ return m_pFrm; };
+public:
+ virtual void refresh();
+ virtual void die();
+ void updateIcon();
+protected:
+ void grabActivityInfo();
+
+protected slots:
+ void fillContextPopup();
+ void toggleParentFrame();
+ void tipRequest(KviDynamicToolTip *tip,const QPoint &pnt);
+ void doAway(int);
+ void flashingTimerShot();
+
+ void activatedSlot( QSystemTrayIcon::ActivationReason reason );
+};
+
+//#endif
+
+#endif //_KVI_DOCKWIDGET_QT4_H_
diff --git a/src/modules/editor/Makefile.am b/src/modules/editor/Makefile.am
new file mode 100644
index 00000000..beb22541
--- /dev/null
+++ b/src/modules/editor/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\" -DKVIRC_SSEX
+
+pluglib_LTLIBRARIES = libkvieditor.la
+
+libkvieditor_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+nodist_libkvieditor_la_SOURCES = moc_scripteditor.cpp
+libkvieditor_la_SOURCES = libkvieditor.cpp scripteditor.cpp
+libkvieditor_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= scripteditor.h
+
+moc_%.cpp: %.h
+ $(SS_QT_MOC) $< -o $@
+
diff --git a/src/modules/editor/libkvieditor.cpp b/src/modules/editor/libkvieditor.cpp
new file mode 100644
index 00000000..14ad53b3
--- /dev/null
+++ b/src/modules/editor/libkvieditor.cpp
@@ -0,0 +1,94 @@
+//
+// File : libkvieditor.cpp
+// Creation date : Mon Sep 11 2000 12:19:00 by Szymon Stefanek
+//
+// Copyright (C) 1999-2000 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_module.h"
+
+#include "kvi_window.h"
+
+#include "scripteditor.h"
+
+KviModule * g_pEditorModulePointer = 0;
+
+KviPointerList<KviScriptEditorImplementation> * g_pScriptEditorWindowList = 0;
+
+static bool editor_module_init(KviModule * m)
+{
+ g_pScriptEditorWindowList = new KviPointerList<KviScriptEditorImplementation>;
+ g_pScriptEditorWindowList->setAutoDelete(false);
+
+ g_pEditorModulePointer = m;
+
+ return true;
+}
+
+static bool editor_module_cleanup(KviModule *m)
+{
+ while(g_pScriptEditorWindowList->first())
+ {
+ QObject * w = g_pScriptEditorWindowList->first()->parent();;
+ while(w)
+ {
+ //debug("%s %s %i %s",__FILE__,__FUNCTION__,__LINE__,w->className());
+ if(w->inherits("KviWindow"))
+ {
+ // debug("%s %s %i",__FILE__,__FUNCTION__,__LINE__);
+ ((KviWindow *)w)->close();
+ // debug("%s %s %i",__FILE__,__FUNCTION__,__LINE__);
+ break;
+ }
+ w = w->parent();
+ }
+ delete g_pScriptEditorWindowList->first();
+ }
+ delete g_pScriptEditorWindowList;
+ g_pScriptEditorWindowList = 0;
+
+ return true;
+}
+
+static bool editor_module_can_unload(KviModule *m)
+{
+ return ((g_pScriptEditorWindowList == 0) || (g_pScriptEditorWindowList->count() == 0));
+}
+
+KVIRC_MODULE(
+ "Editor", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Text editor extension",
+ editor_module_init,
+ editor_module_can_unload,
+ 0,
+ editor_module_cleanup
+)
+
+// We want C linkage on this one: we want to be able to dlsym() it with a simple name
+// FIXME: Is this portable enough ? Or is better to have a table entry ?
+
+KVIMODULEEXPORTFUNC KviScriptEditor * editor_module_createScriptEditor(QWidget * par)
+{
+ return new KviScriptEditorImplementation(par);
+}
+
+KVIMODULEEXPORTFUNC void editor_module_destroyScriptEditor(KviScriptEditor * e)
+{
+ delete ((KviScriptEditorImplementation *)e);
+}
diff --git a/src/modules/editor/scripteditor.cpp b/src/modules/editor/scripteditor.cpp
new file mode 100644
index 00000000..06023a7c
--- /dev/null
+++ b/src/modules/editor/scripteditor.cpp
@@ -0,0 +1,1224 @@
+//=============================================================================
+//
+// File : scripteditor.cpp
+// Created on Sun Mar 28 1999 16:11:48 CEST by Szymon Stefanek
+// Code improvements by Carbone Alessandro & Tonino Imbesi
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 1999-2004 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 "scripteditor.h"
+
+#include <qlayout.h>
+#include <qtoolbutton.h>
+#include <kvi_tal_groupbox.h>
+#include "kvi_tal_popupmenu.h"
+#include "kvi_tal_scrollview.h"
+#include <qmessagebox.h>
+#include <qtimer.h>
+#ifdef COMPILE_USE_QT4
+ //#define QSyntaxHighlighter Q3SyntaxHighlighter
+#else
+ #include <qobjectlist.h>
+#endif
+#include <qcursor.h>
+#include <qfont.h>
+#include <qrect.h>
+
+#include "kvi_fileutils.h"
+#include "kvi_locale.h"
+#include "kvi_filedialog.h"
+#include "kvi_qstring.h"
+#include "kvi_config.h"
+#include "kvi_module.h"
+#include "kvi_pointerlist.h"
+//
+#include "kvi_app.h"
+#include "kvi_console.h"
+#include "kvi_window.h"
+#include "kvi_iconmanager.h"
+#include "kvi_kvs_kernel.h"
+
+#include <qlayout.h>
+
+
+extern KviPointerList<KviScriptEditorImplementation> * g_pScriptEditorWindowList;
+extern KviModule * g_pEditorModulePointer;
+
+
+static QColor g_clrBackground(255,255,255);
+static QColor g_clrNormalText(0,0,0);
+static QColor g_clrBracket(255,0,0);
+static QColor g_clrComment(0,120,0);
+static QColor g_clrFunction(0,17,255);
+static QColor g_clrKeyword(85,85,255);
+static QColor g_clrVariable(255,0,0);
+static QColor g_clrPunctuation(180,180,0);
+static QColor g_clrFind(0,0,0);
+
+static QFont g_fntNormal("Courier New",8);
+
+KviCompletionBox::KviCompletionBox(QWidget * parent = 0)
+: KviTalListBox(parent)
+{
+ setPaletteForegroundColor(QColor(0,0,0));
+ setPaletteBackgroundColor(QColor(255,255,255));
+#ifdef COMPILE_USE_QT4
+ setHScrollBarMode(KviTalListBox::AlwaysOff);
+#else
+ setHScrollBarMode(QScrollView::AlwaysOff);
+#endif
+ QFont listfont=font();
+ listfont.setPointSize(8);
+ setFont(listfont);
+ setVariableWidth(false);
+ setFixedWidth(200);
+ //completelistbox->setColumnMode(KviTalListBox::Variable);
+ hide();
+}
+
+void KviCompletionBox::updateContents(QString buffer)
+{
+ buffer=buffer.stripWhiteSpace();
+ KviPointerList<QString> list;
+ clear();
+
+ QString szModule;
+ QChar* pCur = (QChar *)buffer.ucs2();
+
+ int pos=buffer.find('.');
+
+ if(pos>0)
+ {
+ szModule=buffer.left(pos);
+ if(szModule[0].unicode()=='$')
+ szModule.remove(0,1);
+ }
+
+ if(pCur->unicode() == '$')
+ {
+ buffer.remove(0,1);
+ if(!buffer.isEmpty())
+ {
+ if(szModule.isEmpty())
+ KviKvsKernel::instance()->completeFunction(buffer,&list);
+ else
+ debug("we need a module completion!");
+ for ( QString* szCurrent = list.first(); szCurrent; szCurrent = list.next() )
+ {
+ szCurrent->prepend('$');
+ //szCurrent->append('(');
+ insertItem(*szCurrent);
+ }
+ }
+ }
+ else
+ {
+ if(szModule.isEmpty())
+ KviKvsKernel::instance()->completeCommand(buffer,&list);
+ else
+ debug("we need a module completion!");
+ for ( QString* szCurrent = list.first(); szCurrent; szCurrent = list.next() )
+ {
+ szCurrent->append(' ');
+ insertItem(*szCurrent);
+ }
+ }
+// debug("%s %s %i %i",__FILE__,__FUNCTION__,__LINE__,count());
+}
+
+void KviCompletionBox::keyPressEvent(QKeyEvent * e)
+{
+// debug("%s %s %i %x",__FILE__,__FUNCTION__,__LINE__,e->key());
+ switch(e->key())
+ {
+ case Qt::Key_Escape:
+ hide();
+ setFocus();
+ break;
+ case Qt::Key_Return:
+ break;
+ default:
+ if(!e->text().isEmpty())
+ {
+ e->ignore();
+ }
+
+ }
+ KviTalListBox::keyPressEvent(e);
+}
+
+KviScriptEditorWidgetColorOptions::KviScriptEditorWidgetColorOptions(QWidget * pParent)
+: QDialog(pParent)
+{
+ m_pSelectorInterfaceList = new KviPointerList<KviSelectorInterface>;
+ m_pSelectorInterfaceList->setAutoDelete(false);
+ setCaption(__tr2qs_ctx("Preferences","editor"));
+ QGridLayout * g = new QGridLayout(this,3,3,4,4);
+
+ KviFontSelector * f = new KviFontSelector(this,__tr2qs_ctx("Font:","editor"),&g_fntNormal,true);
+ g->addMultiCellWidget(f,0,0,0,2);
+ m_pSelectorInterfaceList->append(f);
+ KviTalGroupBox * gbox = new KviTalGroupBox(1,Qt::Horizontal,__tr2qs("Colors" ),this);
+ g->addMultiCellWidget(gbox,1,1,0,2);
+ KviColorSelector * s = addColorSelector(gbox,__tr2qs_ctx("Background:","editor"),&g_clrBackground,true);
+ s = addColorSelector(gbox,__tr2qs_ctx("Normal text:","editor"),&g_clrNormalText,true);
+ s = addColorSelector(gbox,__tr2qs_ctx("Brackets:","editor"),&g_clrBracket,true);
+ s = addColorSelector(gbox,__tr2qs_ctx("Comments:","editor"),&g_clrComment,true);
+ s = addColorSelector(gbox,__tr2qs_ctx("Functions:","editor"),&g_clrFunction,true);
+ s = addColorSelector(gbox,__tr2qs_ctx("Keywords:","editor"),&g_clrKeyword,true);
+ s = addColorSelector(gbox,__tr2qs_ctx("Variables:","editor"),&g_clrVariable,true);
+ s = addColorSelector(gbox,__tr2qs_ctx("Punctuation:","editor"),&g_clrPunctuation,true);
+ s = addColorSelector(gbox,__tr2qs_ctx("Find:","editor"),&g_clrFind,true);
+
+ QPushButton * b = new QPushButton(__tr2qs_ctx("&OK","editor"),this);
+ b->setDefault(true);
+ connect(b,SIGNAL(clicked()),this,SLOT(okClicked()));
+ g->addWidget(b,2,1);
+
+ b = new QPushButton(__tr2qs_ctx("Cancel","editor"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(reject()));
+ g->addWidget(b,2,2);
+
+
+ g->setRowStretch(0,1);
+ g->setColStretch(0,1);
+}
+
+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();
+}
+
+
+KviScriptEditorWidget::KviScriptEditorWidget(QWidget * pParent)
+: KviTalTextEdit(pParent)
+{
+ setWordWrap(KviTalTextEdit::NoWrap);
+ m_pParent=pParent;
+ m_szHelp="Nothing";
+ updateOptions();
+ m_szFind="";
+ completelistbox=new KviCompletionBox(this);
+ connect (completelistbox,SIGNAL(selected(const QString &)),this,SLOT(slotComplete(const QString &)));
+}
+
+KviScriptEditorWidget::~KviScriptEditorWidget()
+{
+
+}
+
+#ifdef COMPILE_USE_QT4
+Q3PopupMenu * KviScriptEditorWidget::createPopupMenu( const QPoint& pos )
+#else
+QPopupMenu * KviScriptEditorWidget::createPopupMenu( const QPoint& pos )
+#endif
+{
+#ifdef COMPILE_USE_QT4
+ Q3PopupMenu *pop=KviTalTextEdit::createPopupMenu(pos);
+#else
+ QPopupMenu *pop=KviTalTextEdit::createPopupMenu(pos);
+#endif
+ pop->insertItem(__tr2qs("Context sensitive help"),this,SLOT(slotHelp()),Qt::CTRL+Qt::Key_H);
+ pop->insertItem(__tr2qs("&Replace"),this,SLOT(slotReplace()),Qt::CTRL+Qt::Key_R);
+ return pop;
+}
+
+void KviScriptEditorWidget::slotFind()
+{
+ m_szFind=((KviScriptEditorImplementation*)m_pParent)->getFindlineedit()->text();
+ setText(text());
+}
+
+void KviScriptEditorWidget::slotReplace()
+{
+ KviScriptEditorReplaceDialog *dialog=new KviScriptEditorReplaceDialog(this,tr("Find & Repalce"));
+ connect (dialog,SIGNAL(replaceAll(const QString &,const QString &)),m_pParent,SLOT(slotReplaceAll(const QString &,const QString &)));
+ connect (dialog,SIGNAL(initFind()),m_pParent,SLOT(slotInitFind()));
+ connect (dialog,SIGNAL(nextFind(const QString &)),m_pParent,SLOT(slotNextFind(const QString &)));
+ if(dialog->exec()){};
+
+}
+void KviScriptEditorWidget::slotHelp()
+{
+ contextSensitiveHelp();
+}
+
+
+void KviScriptEditorWidget::updateOptions()
+{
+ setPaper(QBrush(g_clrBackground));
+ setFont(g_fntNormal);
+ setColor(g_clrNormalText);
+
+ QPalette p = palette();
+ p.setColor(QColorGroup::Text,g_clrNormalText);
+ setPalette(p);
+
+#ifdef COMPILE_USE_QT4
+ setTextFormat(Qt::PlainText);
+#else
+ setTextFormat(KviTalTextEdit::PlainText);
+#endif
+
+ // this will rehighlight everything
+ setText(text()); // an "hack" to ensure Update all in the editor
+ KviScriptSyntaxHighlighter *h = new KviScriptSyntaxHighlighter(this);
+ (void)h;
+ ((KviScriptEditorImplementation*)m_pParent)->getFindlineedit()->setPaletteForegroundColor(g_clrFind);
+}
+
+void KviScriptEditorWidget::keyPressEvent(QKeyEvent * e)
+{
+ if(e->state() == Qt::ControlButton)
+ {
+ switch(e->key())
+ {
+ case Qt::Key_B:
+ insert("$b");
+ return;
+ case Qt::Key_K:
+ insert("$k");
+ return;
+ case Qt::Key_O:
+ insert("$o");
+ return;
+ case Qt::Key_U:
+ insert("$u");
+ return;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_Backspace:
+ case Qt::Key_PageUp:
+ e->ignore(); // allow the parent to process it
+ return;
+ break;
+ }
+ }
+
+ if(e->state() == Qt::ShiftButton)
+ {
+ if (e->key() == Qt::Key_Insert)
+ {
+ completition();
+ return;
+ }
+ }
+ switch(e->key())
+ {
+ case Qt::Key_Period:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if(!completelistbox->isVisible()) completition(0);
+ break;
+ case Qt::Key_Up:
+ case Qt::Key_Escape:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_End:
+ case Qt::Key_Home:
+ if(completelistbox->isVisible()) completelistbox->hide();
+ break;
+ case Qt::Key_Down:
+ if(completelistbox->isVisible())
+ {
+ completelistbox->setFocus();
+ completelistbox->setCurrentItem(0);
+ return;
+ }
+ break;
+ case Qt::Key_Return:
+ KviTalTextEdit::keyPressEvent(e);
+ int para,pos;
+ getCursorPosition(&para,&pos);
+ if(para > 0)
+ {
+ QString szPrev=text(para-1);
+ if(!szPrev.isEmpty())
+ {
+ if(szPrev.at(szPrev.length() - 1).unicode() == ' ')
+ szPrev.remove(szPrev.length() - 1,1);
+ QString szCur;
+ const QChar * pCur = (const QChar *)szPrev.ucs2();
+ if(pCur)
+ {
+ while(pCur->unicode() && pCur->isSpace())
+ {
+ szCur.append(*pCur);
+ pCur++;
+ }
+ }
+ insertAt(szCur,para,0);
+ setCursorPosition(para,szCur.length()+pos);
+ }
+// debug("|%i|",pos);
+ }
+ return;
+ default:
+ setFocus();
+ break;
+ }
+ KviTalTextEdit::keyPressEvent(e);
+ emit keyPressed();
+ if(completelistbox->isVisible())
+ completition(0);
+}
+
+void KviScriptEditorWidget::contentsMousePressEvent(QMouseEvent *e)
+{
+ completelistbox->hide();
+ if (e->button() == Qt::RightButton)
+ {
+// bool bIsFirstWordInLine;
+ QString buffer;
+ int para = paragraphAt(e->pos());
+ int index=charAt(e->pos(),&para);
+ buffer=this->text(para);
+ getWordOnCursor(buffer,index);
+ QString tmp=buffer;
+ KviPointerList<QString> l;
+ if (tmp.left(1) == "$")
+ {
+ tmp.remove(0,1);
+ KviKvsKernel::instance()->completeFunction(tmp,&l);
+ if (l.count() != 1) buffer="";
+ else buffer=*(l.at(0));
+ }
+ else
+ {
+ KviKvsKernel::instance()->completeCommand(tmp,&l);
+ if (l.count() != 1) buffer="";
+ else buffer=*(l.at(0));
+ }
+ //debug (buffer);
+ m_szHelp=buffer;
+ }
+ KviTalTextEdit::contentsMousePressEvent(e);
+
+}
+
+bool KviScriptEditorWidget::contextSensitiveHelp() const
+{
+ QString buffer;
+ int para,index;
+ getCursorPosition(&para,&index);
+ buffer=text(para);
+
+ getWordOnCursor(buffer,index);
+
+ /*
+ QString tmp=buffer;
+ KviPointerList<QString> * l;
+ if(tmp.left(1) == "$")
+ {
+ tmp.remove(0,1);
+ l = g_pUserParser->completeFunctionAllocateResult(tmp);
+ } else {
+ l = g_pUserParser->completeCommandAllocateResult(tmp);
+ }
+
+ bool bOk = false;
+ if(l)
+ {
+ for(QString * s = l->first();s;s = l->next())
+ {
+ if(KviQString::equalCI(*s,buffer))
+ {
+ l->last();
+ bOk = true;
+ }
+ }
+ }
+ g_pUserParser->freeCompletionResult(l);
+ if(!bOk)return false;
+ */
+
+ QString parse;
+ KviQString::sprintf(parse,"timer -s (help,0){ help -s %Q; }",&buffer);
+ debug ("parsing %s",parse.latin1());
+ KviKvsScript::run(parse,(KviWindow*)g_pApp->activeConsole());
+
+ return true;
+}
+
+
+void KviScriptEditorWidget::getWordOnCursor(QString &buffer,int index) const
+{
+ QRegExp re("[ \t=,\\(\\)\"}{\\[\\]\r\n+-*><;@!]");
+ //debug("BUFFER IS %s",buffer.utf8().data());
+ int start = buffer.findRev(re,index);
+ int end = buffer.find(re,index);
+
+ QString tmp;
+ if(start!=end)
+ {
+ if(start<0)start=0;
+ else start++;
+ if(end<0)end=index;
+ tmp = buffer.mid(start,end-start);
+ }
+ buffer = tmp;
+ //debug("BUFFER NOW IS %s",buffer.utf8().data());
+}
+
+void KviScriptEditorWidget::completition(bool bCanComplete)
+{
+ int line,index;
+ QString buffer;
+ QString word;
+ getCursorPosition(&line,&index);
+ buffer=this->text(line);
+ bool bIsFirstWordInLine;
+ getWordBeforeCursor(buffer,index,&bIsFirstWordInLine);
+ if(!buffer.isEmpty())
+ completelistbox->updateContents(buffer);
+ if (completelistbox->count() == 1) word=completelistbox->text(0);
+ if (!word.isEmpty() && bCanComplete)
+ {
+ insert(word);
+ completelistbox->hide();
+ }
+ if( completelistbox->count() == 0 )
+ completelistbox->hide();
+ else if(!completelistbox->isVisible())
+ {
+ if (completelistbox->count() <6) completelistbox->resize(completelistbox->width(),(completelistbox->count()*completelistbox->fontMetrics().height()+20));
+ else completelistbox->resize(completelistbox->width(),6*completelistbox->fontMetrics().height()+20);
+ int posy=paragraphRect(line).bottom();
+ int posx=fontMetrics().width(this->text(line).left(index));
+ completelistbox->move(posx,posy);
+ completelistbox->show();
+ }
+}
+
+void KviScriptEditorWidget::getWordBeforeCursor(QString &buffer,int index,bool *bIsFirstWordInLine)
+{
+ QString tmp = buffer.left(index);
+ buffer=tmp;
+ int idx = buffer.findRev(' ');
+ int idx1 = buffer.findRev("=");
+ int idx2 = buffer.findRev(',');
+ int idx3 = buffer.findRev('(');
+ int idx4 = buffer.findRev('"');
+ if(idx1 > idx) idx= idx1;
+ if(idx2 > idx)idx = idx2;
+ if(idx3 > idx)idx = idx3;
+ if(idx4 > idx)idx = idx4;
+ *bIsFirstWordInLine = false;
+ if(idx > -1)buffer.remove(0,idx);
+ else
+ {
+ *bIsFirstWordInLine = true;
+ buffer.insert(0," ");
+ }
+
+}
+
+void KviScriptEditorWidget::slotComplete(const QString &str)
+{
+ QString complete=str;
+ int line,index;
+ getCursorPosition(&line,&index);
+ QString buffer;
+ buffer=this->text(line);
+ bool bIsFirstWordInLine;
+ getWordBeforeCursor(buffer,index,&bIsFirstWordInLine);
+ int len=buffer.length();
+// if (buffer[1].unicode() == '$') len --;
+ complete.remove(0,len-1);
+ if (buffer[1].unicode() == '$') complete.append("(");
+ else complete.append(" ");
+ insert (complete);
+ completelistbox->hide();
+ setFocus();
+}
+
+KviScriptSyntaxHighlighter::KviScriptSyntaxHighlighter(KviScriptEditorWidget * pWidget)
+: QSyntaxHighlighter(pWidget)
+{
+}
+
+KviScriptSyntaxHighlighter::~KviScriptSyntaxHighlighter()
+{
+}
+
+#define IN_COMMENT 1
+#define IN_LINE 2
+#define IN_STRING 4
+
+int KviScriptSyntaxHighlighter::highlightParagraph(const QString &text,int endStateOfLastPara)
+
+{
+ const QChar * pBuf = (const QChar *)text.ucs2();
+ const QChar * c = pBuf;
+ if(!c)return endStateOfLastPara;
+
+ if(endStateOfLastPara < 0)endStateOfLastPara = 0;
+
+ bool bNewCommand = !(endStateOfLastPara & IN_LINE);
+ bool bInComment = endStateOfLastPara & IN_COMMENT;
+ bool bInString = endStateOfLastPara & IN_STRING;
+
+ const QChar * pBegin;
+
+
+ while(c->unicode())
+ {
+ if(bInComment)
+ {
+ pBegin = c;
+ while(c->unicode() && (c->unicode() != '*'))c++;
+ if(!c->unicode())
+ {
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrComment);
+ return IN_COMMENT;
+ }
+ c++;
+ if(c->unicode() == '/')
+ {
+ // end of the comment!
+ c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrComment);
+ bInComment = false;
+ bNewCommand = true;
+ }
+ continue;
+ }
+
+ if(c->isSpace())
+ {
+ while(c->unicode() && c->isSpace())c++;
+ if(!c->unicode())continue;
+ }
+
+ pBegin = c;
+
+ // this does not break the bNewCommand flag
+ if((c->unicode() == '{') || (c->unicode() == '}'))
+ {
+ c++;
+ setFormat(pBegin - pBuf,1,g_fntNormal,g_clrBracket);
+ continue;
+ }
+
+
+ if(bNewCommand)
+ {
+ bNewCommand = false;
+
+ if(c->unicode() == '#')
+ {
+ if(c > pBuf)
+ {
+ const QChar * prev = c - 1;
+ if((prev->unicode() == ']') || (prev->unicode() == '}'))
+ {
+ // array or hash count
+ c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrPunctuation);
+ continue;
+ }
+ }
+ // comment until the end of the line
+ while(c->unicode())c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrComment);
+ continue;
+ }
+ if(c->unicode() == '/')
+ {
+ c++;
+ if(c->unicode() == '/')
+ {
+ while(c->unicode())c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrComment);
+ continue;
+ } else if(c->unicode() == '*')
+ {
+ c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrComment);
+ bInComment = true;
+ continue;
+ }
+ c--;
+ }
+ if(c->unicode() && (c->isLetterOrNumber() || (c->unicode() == '_')))
+ {
+ c++;
+ while(c->unicode() && (c->isLetterOrNumber() || (c->unicode() == '.') || (c->unicode() == '_') || (c->unicode() == ':')))c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrKeyword);
+ // special processing for callbacks and magic commands
+ if(pBegin->unicode() == 'e')
+ {
+ if(c - pBegin == 4)
+ {
+ // might be "else"
+ QString tmp(pBegin,4);
+ if(tmp.lower() == "else")bNewCommand = true;
+ continue;
+ }
+ }
+ else
+ if(pBegin->unicode() == 'f')
+ {
+ if(c - pBegin == 8)
+ {
+ // might be "function"
+ QString tmp(pBegin,8);
+ if(tmp.lower() == "function")bNewCommand = true;
+ continue;
+ }
+ }
+
+ if(pBegin->unicode() == 'i')
+ {
+ if(c - pBegin == 8)
+ {
+ // might be "internal"
+ QString tmp(pBegin,8);
+ if(tmp.lower() == "internal")bNewCommand = true;
+ continue;
+ }
+ }
+
+ // not an else or special command function... FIXME: should check for callbacks.. but that's prolly too difficult :)
+ continue;
+ }
+ }
+ if(c->unicode() == '$')
+ {
+ c++;
+ if(c->unicode() == '$')
+ {
+ c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrKeyword);
+ } else {
+ while(c->unicode() && (c->isLetterOrNumber() || (c->unicode() == '.') || (c->unicode() == '_') || (c->unicode() == ':')))c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrFunction);
+ }
+ continue;
+ }
+
+ if(c->unicode() == '-')
+ {
+ QChar * pTmp =(QChar *) c;
+ c++;
+ if(c->unicode() == '-') c++;
+ if(c->isLetter())
+ {
+ while(c->unicode() && (c->isLetterOrNumber() || (c->unicode() == '_')))c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrKeyword);
+ continue;
+ } else {
+ while(c!=pTmp) c--;
+ }
+ }
+
+ if(c->unicode() == '%')
+ {
+ c++;
+ if(c->unicode() && (c->isLetterOrNumber() || (c->unicode() == ':') || (c->unicode() == '_')))
+ {
+ while(c->unicode() && (c->isLetterOrNumber() || (c->unicode() == ':') || (c->unicode() == '_')))c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrVariable);
+ continue;
+ }
+ c--;
+ }
+
+ if(!c->unicode())continue;
+
+ if(c->isLetterOrNumber() || c->unicode() == '_')
+ {
+ c++;
+ while(c->unicode() && c->isLetterOrNumber() || (c->unicode() == '_'))c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrNormalText);
+ continue;
+ }
+
+ if(c->unicode() == '\\')
+ {
+ c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrPunctuation);
+ // the next char is to be interpreted as normal text
+ pBegin = c;
+ if(c->unicode() && (c->unicode() != '\n'))
+ {
+ c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrNormalText);
+ continue;
+ }
+ // this is never returned since Qt sux in string processing
+ // it sets the newlines to spaces and we have no secure way to undestand that this was the end of a line
+ return IN_LINE;
+ }
+
+ if(c->unicode() == '"')
+ {
+ bInString = !bInString;
+ c++;
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrPunctuation);
+ continue;
+ } else if(c->unicode() == ';')
+ {
+ if(!bInString) bNewCommand = true; // the next will be a new command
+ }
+
+ c++;
+ if(bInString)
+ {
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrNormalText);
+ } else {
+ setFormat(pBegin - pBuf,c - pBegin,g_fntNormal,g_clrPunctuation);
+ }
+ }
+
+ bool i=TRUE;
+ QString szFind=((KviScriptEditorWidget *)textEdit())->m_szFind;
+ if (!szFind.isEmpty())
+ {
+ int index=0;
+ while (i)
+ {
+ index=text.find(szFind,index,false);
+ if (index != -1)
+ {
+ setFormat(index,szFind.length(),g_clrFind);
+ index += szFind.length();
+ }
+ else i=false;
+ }
+ }
+ if(bInString)
+ return IN_LINE | IN_STRING;
+ else
+ return 0;
+}
+
+// 22.02.2005 :: 00:01
+// valgrind --leak-check=yes --num-callers=10 -v kvirc -f
+//
+//==30299== Warning: SIGSEGV not in user code; either from syscall kill()
+//==30299== or possible Valgrind bug. This message is only shown 3 times.
+//==30299== Warning: SIGSEGV not in user code; either from syscall kill()
+//==30299== or possible Valgrind bug. This message is only shown 3 times.
+//==30299== Warning: SIGSEGV not in user code; either from syscall kill()
+//==30299== or possible Valgrind bug. This message is only shown 3 times.
+
+
+KviScriptEditorImplementation::KviScriptEditorImplementation(QWidget * par)
+:KviScriptEditor(par)
+{
+ if(g_pScriptEditorWindowList->isEmpty())loadOptions();
+ g_pScriptEditorWindowList->append(this);
+ m_lastCursorPos=QPoint(0,0);
+ QGridLayout * g = new QGridLayout(this,2,3,0,0);
+
+ m_pFindLineedit = new QLineEdit(" ",this);
+#ifndef COMPILE_USE_QT4
+ m_pFindLineedit->setFrameStyle(QFrame::Sunken | QFrame::Panel);
+#endif
+ m_pFindLineedit->setText("");
+ m_pFindLineedit->setPaletteForegroundColor(g_clrFind);
+
+ m_pEditor = new KviScriptEditorWidget(this);
+ g->addMultiCellWidget(m_pEditor,0,0,0,3);
+ g->setRowStretch(0,1);
+
+#ifdef COMPILE_USE_QT4
+ QToolButton * b = new QToolButton(Qt::DownArrow,this,"dsa2");
+#else
+ QToolButton * b = new QToolButton(DownArrow,this);
+#endif
+ 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->setPopup(pop);
+ b->setPopupDelay(1);
+
+ g->setColStretch(1,1);
+ g->setColStretch(2,10);
+ g->addWidget(m_pFindLineedit,1,2);
+ QLabel *lab= new QLabel("find",this);
+ lab->setText(tr("Find"));
+
+ g->addWidget(lab,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(keyPressed()),this,SLOT(updateRowColLabel()));
+ connect(m_pEditor,SIGNAL(textChanged()),this,SLOT(updateRowColLabel()));
+ connect(m_pEditor,SIGNAL(selectionChanged()),this,SLOT(updateRowColLabel()));
+ m_lastCursorPos = QPoint(-1,-1);
+}
+
+KviScriptEditorImplementation::~KviScriptEditorImplementation()
+{
+ g_pScriptEditorWindowList->removeRef(this);
+ if(g_pScriptEditorWindowList->isEmpty())saveOptions();
+}
+
+void KviScriptEditorImplementation::loadOptions()
+{
+ QString tmp;
+ g_pEditorModulePointer->getDefaultConfigFileName(tmp);
+
+ KviConfig cfg(tmp,KviConfig::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("Fixed",12));
+}
+
+bool KviScriptEditorImplementation::isModified()
+{
+ return m_pEditor->isModified();
+}
+
+void KviScriptEditorImplementation::slotFind()
+{
+ emit find(m_pFindLineedit->text());
+
+}
+void KviScriptEditorImplementation::slotNextFind(const QString &text)
+{
+// emit nextFind(const QString &text);
+
+}void KviScriptEditorImplementation::slotInitFind()
+{
+ emit initFind();
+
+}
+void KviScriptEditorImplementation::slotReplaceAll(const QString &txt,const QString &txt1)
+{
+ emit replaceAll(txt,txt1);
+}
+void KviScriptEditorImplementation::saveOptions()
+{
+ QString tmp;
+ g_pEditorModulePointer->getDefaultConfigFileName(tmp);
+
+ KviConfig cfg(tmp,KviConfig::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 fName;
+ if(KviFileDialog::askForSaveFileName(fName,
+ __tr2qs_ctx("Choose a Filename - KVIrc","editor"),
+ QString::null,
+ QString::null,false,true,true))
+ {
+ QString buffer = m_pEditor->text();
+
+ //if(tmp.isEmpty())tmp = "";
+ //KviStr buffer = tmp.utf8().data();
+ if(!KviFileUtils::writeFile(fName,buffer))
+ {
+ QString tmp;
+ QMessageBox::warning(this,
+ __tr2qs_ctx("Save Failed - KVIrc","editor"),
+ KviQString::sprintf(tmp,__tr2qs_ctx("Can't open the file %s for writing.","editor"),&fName));
+ }
+ }
+}
+
+void KviScriptEditorImplementation::setText(const KviQCString &txt)
+{
+ m_pEditor->setText(txt.data());
+#ifdef COMPILE_USE_QT4
+ m_pEditor->setTextFormat(Qt::PlainText);
+#else
+ m_pEditor->setTextFormat(KviTalTextEdit::PlainText);
+#endif
+ m_pEditor->moveCursor(KviTalTextEdit::MoveEnd,false);
+ m_pEditor->setModified(false);
+ updateRowColLabel();
+}
+
+void KviScriptEditorImplementation::getText(KviQCString &txt)
+{
+ txt = m_pEditor->text();
+}
+QLineEdit * KviScriptEditorImplementation::getFindlineedit()
+{
+ return m_pFindLineedit;
+}
+void KviScriptEditorImplementation::setText(const QString &txt)
+{
+ m_pEditor->setText(txt);
+#ifdef COMPILE_USE_QT4
+ m_pEditor->setTextFormat(Qt::PlainText);
+#else
+ m_pEditor->setTextFormat(KviTalTextEdit::PlainText);
+#endif
+ m_pEditor->moveCursor(KviTalTextEdit::MoveEnd,false);
+ m_pEditor->setModified(false);
+ updateRowColLabel();
+}
+
+void KviScriptEditorImplementation::getText(QString &txt)
+{
+ txt = m_pEditor->text();
+}
+void KviScriptEditorImplementation::setFindText(const QString &txt)
+{
+ m_pFindLineedit->setText(txt);
+ m_pEditor->slotFind();
+
+}
+
+void KviScriptEditorImplementation::setFindLineeditReadOnly(bool b)
+{
+ m_pFindLineedit->setReadOnly(b);
+
+}
+
+
+void KviScriptEditorImplementation::updateRowColLabel()
+{
+ int iRow,iCol;
+ m_pEditor->getCursorPosition(&iRow,&iCol);
+ if(iRow != m_lastCursorPos.x() || iCol != m_lastCursorPos.y())
+ {
+ m_lastCursorPos = QPoint(iRow,iCol);
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs_ctx("Row: %d Col: %d","editor"),iRow,iCol);
+ m_pRowColLabel->setText(tmp);
+ }
+}
+
+QPoint KviScriptEditorImplementation::getCursor()
+{
+ return m_lastCursorPos;
+}
+void KviScriptEditorImplementation::setCursorPosition(QPoint pos)
+{
+ m_pEditor->setCursorPosition(pos.x(),pos.y());
+ m_pEditor->setFocus();
+ m_pEditor->ensureCursorVisible();
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs_ctx("Row: %d Col: %d","editor"),pos.x(),pos.y());
+ m_pRowColLabel->setText(tmp);
+
+ m_lastCursorPos=pos;
+}
+
+void KviScriptEditorImplementation::loadFromFile()
+{
+ QString fName;
+ if(KviFileDialog::askForOpenFileName(fName,
+ __tr2qs_ctx("Load Script File - KVIrc","editor"),
+ QString::null,
+ QString::null,false,true))
+ {
+ QString buffer;
+ if(KviFileUtils::loadFile(fName,buffer))
+ {
+ m_pEditor->setText(buffer);
+ m_pEditor->moveCursor(KviTalTextEdit::MoveEnd,false);
+ updateRowColLabel();
+ } else {
+ QString tmp;
+ QMessageBox::warning(this,
+ __tr2qs_ctx("Open Failed - KVIrc","editor"),
+ KviQString::sprintf(tmp,__tr2qs_ctx("Can't open the file %s for reading.","editor"),&fName));
+ }
+ }
+}
+
+void KviScriptEditorImplementation::configureColors()
+{
+ KviScriptEditorWidgetColorOptions dlg(this);
+ if(dlg.exec() == QDialog::Accepted)
+
+ {
+ m_pEditor->updateOptions();
+ saveOptions();
+ }
+}
+KviScriptEditorReplaceDialog::KviScriptEditorReplaceDialog( QWidget* parent, const char* name)
+ : QDialog( parent)
+{
+ m_pParent=parent;
+ emit initFind();
+ setPaletteForegroundColor( QColor( 0, 0, 0 ) );
+ setPaletteBackgroundColor( QColor( 236, 233, 216 ) );
+ QGridLayout *layout = new QGridLayout( this, 1, 1, 11, 6, "replace layout");
+
+ m_pFindlineedit = new QLineEdit( this, "findlineedit" );
+#ifndef COMPILE_USE_QT4
+ m_pFindlineedit->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, 0, 0, m_pFindlineedit->sizePolicy().hasHeightForWidth() ) );
+ m_pFindlineedit->setFrameShape( QLineEdit::LineEditPanel );
+ m_pFindlineedit->setFrameShadow( QLineEdit::Sunken );
+#endif
+
+ layout->addMultiCellWidget( m_pFindlineedit, 2, 2, 1, 2 );
+
+ m_pReplacelineedit = new QLineEdit( this, "replacelineedit" );
+#ifndef COMPILE_USE_QT4
+ m_pReplacelineedit->setFrameShape( QLineEdit::LineEditPanel );
+ m_pReplacelineedit->setFrameShadow( QLineEdit::Sunken );
+#endif
+ layout->addMultiCellWidget( m_pReplacelineedit, 3, 3, 1, 2 );
+
+ m_pFindlineedit->setFocus();
+
+ QLabel *findlabel = new QLabel( this, "findlabel" );
+ findlabel->setText(tr("Word to Find"));
+#ifndef COMPILE_USE_QT4
+ findlabel->setAutoResize(true);
+#endif
+
+ layout->addWidget( findlabel, 2, 0 );
+
+ QLabel *replacelabel = new QLabel( this, "replacelabel" );
+ replacelabel->setText(tr("Replace with"));
+#ifndef COMPILE_USE_QT4
+ replacelabel->setAutoResize(true);
+#endif
+ layout->addWidget( replacelabel, 3, 0 );
+
+ QPushButton *cancelbutton = new QPushButton( this, "cancelButton" );
+ cancelbutton->setText(tr("&Cancel"));
+ layout->addWidget( cancelbutton, 5, 2 );
+
+ replacebutton = new QPushButton( this, "replacebutton" );
+ replacebutton->setText(tr("&Replace"));
+ replacebutton->setEnabled( FALSE );
+ layout->addWidget( replacebutton, 5, 0 );
+
+ checkReplaceAll = new KviStyledCheckBox( this, "replaceAll" );
+ checkReplaceAll->setText(tr("&Replace in all Aliases"));
+ layout->addWidget( checkReplaceAll, 4, 0 );
+
+ findNext = new QPushButton(this, "findNext(WIP)" );
+ findNext->setText(tr("&Findnext"));
+ layout->addWidget( findNext, 2, 3 );
+ findNext->setEnabled(false);
+
+ replace = new QPushButton(this, "replace" );
+ replace->setText(tr("&Replace(WIP)"));
+ layout->addWidget( replace, 3, 3 );
+ replace->setEnabled(false);
+
+#ifndef COMPILE_USE_QT4
+ clearWState( WState_Polished );
+ setTabOrder(m_pFindlineedit,m_pReplacelineedit);
+#endif
+ // signals and slots connections
+ connect( replacebutton, SIGNAL( clicked() ), this, SLOT( slotReplace() ) );
+ connect( findNext, SIGNAL( clicked() ),this,SLOT( slotNextFind()));
+ connect( cancelbutton, SIGNAL( clicked() ), this, SLOT( reject() ) );
+ connect( m_pFindlineedit, SIGNAL( textChanged(const QString &)), this, SLOT( textChanged(const QString &)));
+
+}
+
+
+KviScriptEditorReplaceDialog::~KviScriptEditorReplaceDialog()
+{
+}
+
+void KviScriptEditorReplaceDialog::textChanged(const QString &txt)
+{
+ if (!txt.isEmpty()) replacebutton->setEnabled(TRUE);
+ else replacebutton->setEnabled(FALSE);
+
+}
+void KviScriptEditorReplaceDialog::slotReplace()
+{
+ QString txt=((KviScriptEditorWidget *)m_pParent)->text();
+ if (checkReplaceAll->isChecked()) emit replaceAll(m_pFindlineedit->text(),m_pReplacelineedit->text());
+ txt.replace(m_pFindlineedit->text(),m_pReplacelineedit->text(),false);
+ ((KviScriptEditorWidget *)m_pParent)->setText(txt);
+ ((KviScriptEditorWidget *)m_pParent)->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
new file mode 100644
index 00000000..d7bc435f
--- /dev/null
+++ b/src/modules/editor/scripteditor.h
@@ -0,0 +1,200 @@
+#ifndef _SCRIPTEDITOR_H_
+#define _SCRIPTEDITOR_H_
+
+//=============================================================================
+//
+// File : scripteditor.h
+// Created on Sun Mar 28 1999 16:11:48 CEST by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 1999-2004 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_scripteditor.h"
+
+#include <qlabel.h>
+#include <kvi_tal_textedit.h>
+#include <qsyntaxhighlighter.h>
+#include <qdialog.h>
+#include <qcheckbox.h>
+#include "kvi_tal_listbox.h"
+#include <qevent.h>
+#include "kvi_qcstring.h"
+
+#include "kvi_tal_popupmenu.h"
+
+#include "kvi_pointerlist.h"
+#include "kvi_selectors.h"
+typedef KviPointerList<int> ColumnList;
+
+class KviCompletionBox: public KviTalListBox
+{
+ Q_OBJECT
+public:
+ KviCompletionBox(QWidget * parent);
+ ~KviCompletionBox(){};
+
+ void updateContents(QString word);
+protected:
+ virtual void keyPressEvent(QKeyEvent * e);
+};
+
+class KviScriptEditorWidget : public KviTalTextEdit
+{
+ Q_OBJECT
+ Q_PROPERTY(bool contextSensitiveHelp READ contextSensitiveHelp)
+public:
+ KviScriptEditorWidget(QWidget * pParent);
+ virtual ~KviScriptEditorWidget();
+public:
+ void updateOptions();
+ void find1();
+ QString m_szFind;
+ KviCompletionBox *completelistbox;
+ void completition(bool bCanComplete = 1);
+ void getWordBeforeCursor(QString &buffer,int index,bool *);
+ void getWordOnCursor(QString &buffer,int index) const;
+ bool contextSensitiveHelp() const;
+public slots:
+ void slotFind();
+ void slotHelp();
+ void slotReplace();
+ void slotComplete(const QString &str);
+
+signals:
+ void keyPressed();
+protected:
+ virtual void keyPressEvent(QKeyEvent * e);
+ void contentsMousePressEvent(QMouseEvent *);
+#ifdef COMPILE_USE_QT4
+ Q3PopupMenu *createPopupMenu( const QPoint& pos );
+#else
+ QPopupMenu *createPopupMenu( const QPoint& pos );
+#endif
+ QWidget *m_pParent;
+ QString m_szHelp;
+
+};
+
+#ifdef COMPILE_USE_QT4
+ #include <q3syntaxhighlighter.h>
+ #define QSyntaxHighlighter Q3SyntaxHighlighter
+#else
+ #include <qobjectlist.h>
+#endif
+class KviScriptSyntaxHighlighter : public QSyntaxHighlighter
+{
+public:
+ KviScriptSyntaxHighlighter(KviScriptEditorWidget * pWidget);
+ virtual ~KviScriptSyntaxHighlighter();
+public:
+ virtual int highlightParagraph(const QString & text,int endStateOfLastPara);
+};
+
+class KviScriptEditorWidgetColorOptions : public QDialog
+{
+ Q_OBJECT
+public:
+ KviScriptEditorWidgetColorOptions(QWidget * pParent);
+ ~KviScriptEditorWidgetColorOptions();
+private:
+ KviPointerList<KviSelectorInterface> * m_pSelectorInterfaceList;
+protected:
+ KviColorSelector * addColorSelector(QWidget * pParent,const QString & txt,QColor * pOption,bool bEnabled);
+
+protected slots:
+ void okClicked();
+};
+
+class QTimer;
+
+class KviScriptEditorImplementation : public KviScriptEditor
+{
+ Q_OBJECT
+public:
+ KviScriptEditorImplementation(QWidget * par);
+ virtual ~KviScriptEditorImplementation();
+protected:
+ KviScriptEditorWidget * m_pEditor;
+ QLabel * m_pRowColLabel;
+ QPoint m_lastCursorPos;
+public:
+ virtual void setText(const QString &txt);
+ virtual void getText(QString &txt);
+ virtual void setText(const KviQCString &txt);
+ virtual void getText(KviQCString &txt);
+ virtual void setFindText(const QString & text);
+ virtual void setEnabled(bool bEnabled);
+ virtual void setFocus();
+ virtual bool isModified();
+ void setFindLineeditReadOnly(bool b);
+ void setCursorPosition(QPoint);
+ QPoint getCursor();
+ QLineEdit *m_pFindlineedit;
+ QLineEdit * getFindlineedit();
+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 &,const QString &);
+ void slotInitFind();
+ void slotNextFind(const QString &);
+signals:
+ void find( const QString &);
+ void replaceAll( const QString &, const QString &);
+ void initFind();
+ void nextFind(const QString &);
+};
+
+class KviScriptEditorReplaceDialog: public QDialog
+{
+ Q_OBJECT
+public:
+ KviScriptEditorReplaceDialog( QWidget* parent = 0, const char* name = 0);
+ ~KviScriptEditorReplaceDialog();
+ QLineEdit *m_pFindlineedit;
+ QLineEdit *m_pReplacelineedit;
+protected:
+ QLabel *findlabel;
+ QLabel *replacelabel;
+ QPushButton *replacebutton;
+ QPushButton *replace;
+ QPushButton *findNext;
+
+// QPushButton *cancelbutton;
+ KviStyledCheckBox *checkReplaceAll;
+ 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/Makefile.am b/src/modules/eventeditor/Makefile.am
new file mode 100644
index 00000000..ceb7541a
--- /dev/null
+++ b/src/modules/eventeditor/Makefile.am
@@ -0,0 +1,21 @@
+###############################################################################
+# KVirc IRC client Makeeventeditor - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvieventeditor.la
+
+libkvieventeditor_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvieventeditor_la_SOURCES = libkvieventeditor.cpp eventeditor.cpp
+nodist_libkvieventeditor_la_SOURCES = moc_eventeditor.cpp
+
+noinst_HEADERS = eventeditor.h
+libkvieventeditor_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+moc_eventeditor.cpp: eventeditor.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/eventeditor/eventeditor.cpp b/src/modules/eventeditor/eventeditor.cpp
new file mode 100644
index 00000000..bedeca5f
--- /dev/null
+++ b/src/modules/eventeditor/eventeditor.cpp
@@ -0,0 +1,536 @@
+//
+// 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 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 "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_imagedialog.h"
+#include "kvi_config.h"
+#include "kvi_filedialog.h"
+#include "kvi_fileutils.h"
+#include "kvi_scripteditor.h"
+#include "kvi_debug.h"
+//#include "kvi_event.h"
+#include "kvi_app.h"
+#include "kvi_cmdformatter.h"
+//#include "kvi_eventhandler.h"
+#include "kvi_qstring.h"
+#include "kvi_filedialog.h"
+
+#include "kvi_kvs_eventmanager.h"
+
+#include <qmessagebox.h>
+
+#include <qsplitter.h>
+#include <qlayout.h>
+#include "kvi_tal_vbox.h"
+#include "kvi_tal_popupmenu.h"
+#include <qtooltip.h>
+#include <qpushbutton.h>
+#include <qevent.h>
+
+extern KviEventEditorWindow * g_pEventEditorWindow;
+
+
+
+const QPixmap * KviEventListViewItem::pixmap(int col) const
+{
+ return g_pIconManager->getSmallIcon(firstChild() ? KVI_SMALLICON_EVENT : KVI_SMALLICON_EVENTNOHANDLERS);
+}
+
+const QPixmap * KviEventHandlerListViewItem::pixmap(int col) const
+{
+ return g_pIconManager->getSmallIcon(m_bEnabled ? KVI_SMALLICON_HANDLER : KVI_SMALLICON_HANDLERDISABLED);
+}
+
+
+
+KviEventEditor::KviEventEditor(QWidget * par)
+: QWidget(par,"event_editor")
+{
+ QGridLayout * l = new QGridLayout(this,1,1,2,2);
+
+ QSplitter * spl = new QSplitter(Qt::Horizontal,this);
+ spl->setOpaqueResize(false);
+
+ l->addWidget(spl,0,0);
+
+ KviTalVBox * boxi = new KviTalVBox(spl);
+ m_pListView = new KviTalListView(boxi);
+ m_pListView->addColumn(__tr2qs("Event"));
+ m_pListView->setMultiSelection(false);
+ m_pListView->setShowSortIndicator(true);
+ m_pListView->setRootIsDecorated(true);
+
+ QPushButton * pb = new QPushButton(__tr2qs("&Export All To..."),boxi);
+ connect(pb,SIGNAL(clicked()),this,SLOT(exportAllEvents()));
+
+ KviTalVBox * box = new KviTalVBox(spl);
+ m_pNameEditor = new QLineEdit(box);
+ QToolTip::add(m_pNameEditor,__tr2qs("Edit the event handler name."));
+ 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;
+
+ KviEventListViewItem * it;
+ KviEventHandlerListViewItem * ch;
+
+ for(unsigned int i = 0;i < KVI_KVS_NUM_APP_EVENTS;i++)
+ {
+ KviKvsEvent * e = KviKvsEventManager::instance()->appEvent(i);
+ it = new KviEventListViewItem(m_pListView,i,e->name(),e->parameterDescription());
+ if(KviPointerList<KviKvsEventHandler> * l = e->handlers())
+ {
+ for(KviKvsEventHandler * s = l->first();s;s = l->next())
+ {
+ if(s->type() == KviKvsEventHandler::Script)
+ {
+ ch = new KviEventHandlerListViewItem(it,((KviKvsScriptEventHandler *)s)->name(),
+ ((KviKvsScriptEventHandler *)s)->code(),((KviKvsScriptEventHandler *)s)->isEnabled());
+ }
+ }
+ it->setOpen(true);
+ }
+ }
+
+
+ m_pContextPopup = new KviTalPopupMenu(this);
+
+ connect(m_pListView,SIGNAL(selectionChanged(KviTalListViewItem *)),this,SLOT(selectionChanged(KviTalListViewItem *)));
+ connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),
+ this,SLOT(itemPressed(KviTalListViewItem *,const QPoint &,int)));
+}
+
+void KviEventEditor::itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ __range_valid(m_bOneTimeSetupDone);
+
+ if(it)
+ {
+ m_pContextPopup->clear();
+ if(it->parent())
+ {
+ QString tmp;
+ if(!(((KviEventHandlerListViewItem *)it)->m_bEnabled))
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLER)),
+ __tr2qs("&Enable Handler"),this,SLOT(toggleCurrentHandlerEnabled()));
+ else
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLERDISABLED)),
+ __tr2qs("&Disable Handler"),this,SLOT(toggleCurrentHandlerEnabled()));
+
+ //m_pContextPopup->setItemChecked(id,((KviEventHandlerListViewItem *)it)->m_bEnabled);
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),
+ __tr2qs("Re&move Handler"),
+ this,SLOT(removeCurrentHandler()));
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)),
+ __tr2qs("&Export Handler To..."),
+ this,SLOT(exportCurrentHandler()));
+ } else {
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLER)),
+ __tr2qs("&New Handler"),
+ this,SLOT(addHandlerForCurrentEvent()));
+ }
+
+ m_pContextPopup->popup(pnt);
+ }
+}
+
+void KviEventEditor::getUniqueHandlerName(KviEventListViewItem *it,QString &buffer)
+{
+ __range_valid(m_bOneTimeSetupDone);
+
+ QString newName = buffer;
+ if(newName.isEmpty())newName = __tr2qs("unnamed");
+
+ bool bFound = true;
+ int idx = 1;
+
+ while(bFound)
+ {
+ bFound = false;
+
+ for(KviEventHandlerListViewItem * ch = (KviEventHandlerListViewItem *)(it->firstChild());ch;ch = (KviEventHandlerListViewItem *)ch->nextSibling())
+ {
+ if(KviQString::equalCI(newName,ch->m_szName))
+ {
+ bFound = true;
+ KviQString::sprintf(newName,"%Q_%d",&buffer,idx);
+ idx++;
+ break;
+ }
+ }
+ }
+
+ buffer = newName;
+}
+
+void KviEventEditor::addHandlerForCurrentEvent()
+{
+ __range_valid(m_pOneTimeSetupDone);
+
+ KviTalListViewItem * it = m_pListView->selectedItem();
+ if(it)
+ {
+ if(it->parent() == 0)
+ {
+ QString buffer = __tr2qs("default");
+ getUniqueHandlerName((KviEventListViewItem *)it,buffer);
+ KviTalListViewItem * ch = new KviEventHandlerListViewItem(it,buffer,"",true);
+ it->setOpen(true);
+ m_pListView->setSelected(ch,true);
+ }
+ }
+}
+
+void KviEventEditor::removeCurrentHandler()
+{
+ __range_valid(m_pOneTimeSetupDone);
+ if(m_pLastEditedItem)
+ {
+ KviTalListViewItem * it = m_pLastEditedItem;
+ m_pLastEditedItem = 0;
+ delete it;
+ m_pEditor->setEnabled(false);
+ m_pNameEditor->setEnabled(false);
+ }
+}
+
+void KviEventEditor::toggleCurrentHandlerEnabled()
+{
+ __range_valid(m_pOneTimeSetupDone);
+ if(m_pLastEditedItem)
+ {
+ m_pLastEditedItem->m_bEnabled = !(m_pLastEditedItem->m_bEnabled);
+ m_pListView->repaintItem(m_pLastEditedItem);
+ selectionChanged(m_pLastEditedItem);
+ }
+}
+
+void KviEventEditor::commit()
+{
+ if(!m_bOneTimeSetupDone)return; // nothing to commit
+
+ saveLastEditedItem();
+ KviKvsEventManager::instance()->removeAllScriptAppHandlers();
+ for(KviTalListViewItem * it = m_pListView->firstChild();it;it = it->nextSibling())
+ {
+ if(it->firstChild())
+ {
+ QString szContext;
+
+ for(KviTalListViewItem * ch = it->firstChild();ch;ch = ch->nextSibling())
+ {
+ KviQString::sprintf(szContext,"%Q::%Q",&(((KviEventListViewItem *)it)->m_szName),&(((KviEventHandlerListViewItem *)ch)->m_szName));
+
+ KviKvsScriptEventHandler * s = KviKvsScriptEventHandler::createInstance( // msvc workaround
+ ((KviEventHandlerListViewItem *)ch)->m_szName,
+ szContext,
+ ((KviEventHandlerListViewItem *)ch)->m_szBuffer,
+ ((KviEventHandlerListViewItem *)ch)->m_bEnabled
+ );
+
+ KviKvsEventManager::instance()->addAppHandler(((KviEventListViewItem *)it)->m_uEventIdx,s);
+ }
+ }
+ }
+
+ g_pApp->saveAppEvents();
+}
+
+void KviEventEditor::saveLastEditedItem()
+{
+ __range_valid(m_bOneTimeSetupDone);
+ if(!m_pLastEditedItem)return;
+
+ QString buffer = m_pNameEditor->text();
+ if(!KviQString::equalCI(buffer,m_pLastEditedItem->m_szName))
+ {
+ getUniqueHandlerName((KviEventListViewItem *)(m_pLastEditedItem->parent()),buffer);
+ }
+
+ m_pLastEditedItem->m_szName = buffer;
+ QString tmp;
+ m_pEditor->getText(tmp);
+
+ m_pLastEditedItem->m_szBuffer = tmp;
+}
+
+void KviEventEditor::selectionChanged(KviTalListViewItem * it)
+{
+ __range_valid(m_bOneTimeSetupDone);
+ saveLastEditedItem();
+ if(it->parent())
+ {
+ m_pLastEditedItem = (KviEventHandlerListViewItem *)it;
+ m_pNameEditor->setEnabled(true);
+ m_pNameEditor->setText(it->text(0));
+ m_pEditor->setEnabled(true);
+ m_pEditor->setText(((KviEventHandlerListViewItem *)it)->m_szBuffer);
+ } else {
+ m_pLastEditedItem = 0;
+ m_pNameEditor->setEnabled(false);
+ m_pNameEditor->setText("");
+ m_pEditor->setEnabled(false);
+ QString parms = ((KviEventListViewItem *)it)->m_szParams;
+ if(parms.isEmpty())parms = __tr2qs("none");
+ KviCommandFormatter::indent(parms);
+ KviCommandFormatter::indent(parms);
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("\n\n Event:\n %s\n\n Parameters:\n%s"),
+ ((KviEventListViewItem *)it)->m_szName.utf8().data(),parms.utf8().data());
+ m_pEditor->setText(tmp);
+ }
+}
+
+void KviEventEditor::showEvent(QShowEvent *e)
+{
+ oneTimeSetup();
+ QWidget::showEvent(e);
+}
+
+
+void KviEventEditor::getExportEventBuffer(QString &buffer,KviEventHandlerListViewItem * it)
+{
+ if(!it->parent())return;
+
+ QString szBuf = it->m_szBuffer;
+
+ KviCommandFormatter::blockFromBuffer(szBuf);
+
+ buffer = "event(";
+ buffer += ((KviEventListViewItem *)(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 += ((KviEventListViewItem *)(it->parent()))->m_szName;
+ buffer += " ";
+ buffer += it->m_szName;
+ }
+}
+
+void KviEventEditor::exportCurrentHandler()
+{
+ if(!m_pLastEditedItem)return;
+ saveLastEditedItem();
+ if(!m_pLastEditedItem)return;
+
+ QString szName = QDir::homeDirPath();
+ if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR;
+ szName += ((KviEventListViewItem *)(m_pLastEditedItem->parent()))->m_szName;
+ szName += ".";
+ szName += m_pLastEditedItem->m_szName;
+ szName += ".kvs";
+
+ QString szFile;
+
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose a Filename - KVIrc"),szName,"*.kvs",true,true,true))return;
+
+ QString szOut;
+ getExportEventBuffer(szOut,m_pLastEditedItem);
+
+ if(!KviFileUtils::writeFile(szFile,szOut))
+ {
+ QMessageBox::warning(this,__tr2qs("Write Failed - KVIrc"),__tr2qs("Unable to write to the event file."),__tr2qs("&OK"));
+ }
+}
+
+void KviEventEditor::exportAllEvents()
+{
+ saveLastEditedItem();
+
+ KviEventListViewItem * it = (KviEventListViewItem *)m_pListView->firstChild();
+
+ QString out;
+
+ while(it)
+ {
+ KviEventHandlerListViewItem * item = (KviEventHandlerListViewItem *)it->firstChild();
+ while(item)
+ {
+ QString tmp;
+ getExportEventBuffer(tmp,item);
+ out += tmp;
+ out += "\n";
+ item = (KviEventHandlerListViewItem *)item->nextSibling();
+ }
+ it = (KviEventListViewItem *)it->nextSibling();
+ }
+
+ QString szName = QDir::homeDirPath();
+ if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR;
+ szName += "events.kvs";
+
+ QString szFile;
+
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose a Filename - KVIrc"),szName,QString::null,true,true))return;
+
+ if(!KviFileUtils::writeFile(szFile,out))
+ {
+ QMessageBox::warning(this,__tr2qs("Write Failed - KVIrc"),__tr2qs("Unable to write to the events file."),__tr2qs("Ok"));
+ }
+}
+
+
+
+
+KviEventEditorWindow::KviEventEditorWindow(KviFrame * lpFrm)
+: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"eventeditor",0)
+{
+ g_pEventEditorWindow = this;
+
+ m_pEditor = new KviEventEditor(this);
+
+ m_pBase = new QWidget(this);
+ QGridLayout * g = new QGridLayout(m_pBase,1,4,4,4);
+
+ QPushButton * btn = new QPushButton(__tr2qs("&OK"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(okClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,1);
+
+ btn = new QPushButton(__tr2qs("&Apply"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,2);
+
+ btn = new QPushButton(__tr2qs("Cancel"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ g->addWidget(btn,0,3);
+
+ g->setColStretch(0,1);
+}
+
+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::resizeEvent(QResizeEvent *e)
+{
+ int hght = m_pBase->sizeHint().height();
+ m_pEditor->setGeometry(0,0,width(),height()- hght);
+ m_pBase->setGeometry(0,height() - hght,width(),hght);
+}
+
+void KviEventEditorWindow::fillCaptionBuffers()
+{
+ m_szPlainTextCaption = __tr2qs("Event Editor");
+
+ static QString p1("<nobr><font color=\"");
+ static QString p2("\"><b>");
+ static QString p3("</b></font></nobr>");
+
+ m_szHtmlActiveCaption = p1;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += p2;
+ m_szHtmlActiveCaption += m_szPlainTextCaption;
+ m_szHtmlActiveCaption += p3;
+
+ m_szHtmlInactiveCaption = p1;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += p2;
+ m_szHtmlInactiveCaption += m_szPlainTextCaption;
+ m_szHtmlInactiveCaption += p3;
+}
+
+
+void KviEventEditorWindow::getConfigGroupName(KviStr &szName)
+{
+ szName = "eventeditor";
+}
+
+
+void KviEventEditorWindow::saveProperties(KviConfig *cfg)
+{
+/*
+#ifdef COMPILE_SCRIPTTOOLBAR
+ cfg->writeEntry("Sizes",m_pEditor->sizes());
+ cfg->writeEntry("LastEvent",m_pEditor->lastEditedEvent().ptr());
+ //debug("LAST EDITED=%s",m_pEditor->lastEditedEvent().ptr());
+#endif // COMPILE_SCRIPTTOOLBAR
+*/
+}
+
+void KviEventEditorWindow::loadProperties(KviConfig *cfg)
+{
+/*
+#ifdef COMPILE_SCRIPTTOOLBAR
+ QValueList<int> def;
+ def.append(20);
+ def.append(80);
+ m_pEditor->setSizes(cfg->readIntListEntry("Sizes",def));
+ KviStr tmp = cfg->readEntry("LastEvent","");
+ m_pEditor->editEvent(tmp);
+ //debug("LAST EDITED WAS %s",tmp.ptr());
+#endif // COMPILE_SCRIPTTOOLBAR
+*/
+}
diff --git a/src/modules/eventeditor/eventeditor.h b/src/modules/eventeditor/eventeditor.h
new file mode 100644
index 00000000..d94a07cc
--- /dev/null
+++ b/src/modules/eventeditor/eventeditor.h
@@ -0,0 +1,120 @@
+#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 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 "kvi_window.h"
+#include "kvi_string.h"
+
+#include <qwidget.h>
+#include "kvi_tal_listview.h"
+#include <qlineedit.h>
+
+class KviScriptEditor;
+
+class KviEventListViewItem : public KviTalListViewItem
+{
+public:
+ unsigned int m_uEventIdx;
+ QString m_szName;
+ QString m_szParams;
+public:
+ KviEventListViewItem(KviTalListView * par,unsigned int uEvIdx,const QString &name,const QString &params)
+ : KviTalListViewItem(par), m_uEventIdx(uEvIdx), m_szName(name), m_szParams(params) {};
+ ~KviEventListViewItem() {};
+public:
+ virtual QString text(int col) const { return m_szName; };
+ virtual const QPixmap * pixmap(int col) const;
+};
+
+class KviEventHandlerListViewItem : public KviTalListViewItem
+{
+public:
+ QString m_szName;
+ QString m_szBuffer;
+ bool m_bEnabled;
+public:
+ KviEventHandlerListViewItem(KviTalListViewItem * par,const QString &name,const QString &buffer,bool bEnabled)
+ : KviTalListViewItem(par), m_szName(name) , m_szBuffer(buffer) , m_bEnabled(bEnabled) {};
+ ~KviEventHandlerListViewItem() {};
+public:
+ virtual QString text(int col) const { return m_szName; };
+ virtual const QPixmap * pixmap(int col) const;
+};
+
+class KviTalPopupMenu;
+
+class KviEventEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ KviEventEditor(QWidget * par);
+ ~KviEventEditor();
+public:
+ KviScriptEditor * m_pEditor;
+ KviTalListView * m_pListView;
+ QLineEdit * m_pNameEditor;
+ KviTalPopupMenu * m_pContextPopup;
+ KviEventHandlerListViewItem * m_pLastEditedItem;
+ bool m_bOneTimeSetupDone;
+public:
+ void commit();
+ void saveLastEditedItem();
+ void getUniqueHandlerName(KviEventListViewItem *it,QString &buffer);
+ void getExportEventBuffer(QString &szBuffer,KviEventHandlerListViewItem * it);
+protected slots:
+ void selectionChanged(KviTalListViewItem *it);
+ void itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col);
+ void toggleCurrentHandlerEnabled();
+ void removeCurrentHandler();
+ void addHandlerForCurrentEvent();
+ void exportAllEvents();
+ void exportCurrentHandler();
+protected:
+ void showEvent(QShowEvent *e);
+private:
+ void oneTimeSetup();
+};
+
+class KviEventEditorWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviEventEditorWindow(KviFrame * lpFrm);
+ ~KviEventEditorWindow();
+protected:
+ KviEventEditor * m_pEditor;
+ QWidget * m_pBase;
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void getConfigGroupName(KviStr &szName);
+ virtual void saveProperties(KviConfig *);
+ virtual void loadProperties(KviConfig *);
+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
new file mode 100644
index 00000000..62111cad
--- /dev/null
+++ b/src/modules/eventeditor/libkvieventeditor.cpp
@@ -0,0 +1,88 @@
+//
+// File : libkvieventeditor.cpp
+// Creation date : Mon 23 Dec 2002 20:23:59 2002 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2002 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_module.h"
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+
+#include "eventeditor.h"
+
+KviEventEditorWindow * g_pEventEditorWindow = 0;
+
+
+/*
+ @doc: eventeditor.open
+ @type:
+ command
+ @title:
+ eventeditor.open
+ @short:
+ Shows the event editor
+ @syntax:
+ toolbareditor.open
+ @description:
+ Opens the script event editor dialog.
+*/
+
+static bool eventeditor_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ if(!g_pEventEditorWindow)
+ {
+ g_pEventEditorWindow = new KviEventEditorWindow(c->window()->frame());
+ c->window()->frame()->addWindow(g_pEventEditorWindow);
+ }
+
+ g_pEventEditorWindow->setFocus();
+ return true;
+}
+
+static bool eventeditor_module_init(KviModule * m)
+{
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",eventeditor_kvs_cmd_open);
+
+ g_pEventEditorWindow = 0;
+ return true;
+}
+
+static bool eventeditor_module_can_unload(KviModule * m)
+{
+ return (g_pEventEditorWindow == 0);
+}
+
+static bool eventeditor_module_cleanup(KviModule *m)
+{
+ if(g_pEventEditorWindow)delete g_pEventEditorWindow;
+ g_pEventEditorWindow = 0;
+ return true;
+}
+
+KVIRC_MODULE(
+ "EventEditor", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Editor for the script events",
+ eventeditor_module_init,
+ eventeditor_module_can_unload,
+ 0,
+ eventeditor_module_cleanup
+)
diff --git a/src/modules/file/Makefile.am b/src/modules/file/Makefile.am
new file mode 100644
index 00000000..1545a63a
--- /dev/null
+++ b/src/modules/file/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvifile.la
+
+libkvifile_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvifile_la_SOURCES = libkvifile.cpp
+libkvifile_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/file/libkvifile.cpp b/src/modules/file/libkvifile.cpp
new file mode 100644
index 00000000..8b8dd9ec
--- /dev/null
+++ b/src/modules/file/libkvifile.cpp
@@ -0,0 +1,1260 @@
+//=============================================================================
+//
+// File : libkvifile.cpp
+// Creation date : Fri Nov 9 03:27:59 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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_module.h"
+#include "kvi_fileutils.h"
+#include "kvi_locale.h"
+#include "kvi_malloc.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_qcstring.h"
+
+#include "kvi_kvs_arraycast.h"
+
+#include <qfileinfo.h>
+#include "kvi_file.h"
+#include <qdir.h>
+#include <qtextstream.h>
+
+/*
+ @doc: file.copy
+ @type:
+ command
+ @title:
+ file.copy
+ @keyterms:
+ copying files
+ @short:
+ Makes a copy of a file
+ @syntax:
+ file.copy [-o] <source:string> <destination:string>
+ @switches:
+ !sw: -o | --overwrite
+ Overwrites the file even if it already exists.
+ @description:
+ Makes a copy of the <source> file as <destination>.[br]
+ If the [-o] switch is used , the <destination> file is overwritten , if already exists.[br]
+ With no [-o] switch , this command does not overwrite files.[br]
+ The destination path must be already existing: if you want to ensure this, use [fnc]$file.mkdir[/fnc] first.[br]
+ The paths (<source> and <destination>) are adjusted according to the system that KVIrc
+ is running on so you don't have to bother about portability: it *should* be automatically
+ guaranteed. Just use UNIX style paths for them.[br]
+ @seealso:
+ [cmd]file.rename[/cmd], [fnc]$file.exists[/fnc]
+*/
+
+static bool file_kvs_cmd_copy(KviKvsModuleCommandCall * c)
+{
+ QString szSrc,szDst;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("source",KVS_PT_NONEMPTYSTRING,0,szSrc)
+ KVSM_PARAMETER("destination",KVS_PT_NONEMPTYSTRING,0,szDst)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szSrc);
+ KviFileUtils::adjustFilePath(szDst);
+ if(KviFileUtils::fileExists(szDst) && !c->switches()->find('o',"overwrite"))
+ {
+ c->warning(__tr2qs("Destinaion file exists: no copy made"));
+ return true;
+ }
+ if(!KviFileUtils::copyFile(szSrc,szDst))
+ {
+ c->warning(__tr2qs("Failed to copy from %Q to %Q"),&szSrc,&szDst);
+ c->warning(__tr2qs("Either the source doesn't exist or the destination can not be created"));
+ }
+ return true;
+}
+
+
+/*
+ @doc: file.addimagepath
+ @type:
+ command
+ @title:
+ file.addimagepath
+ @short:
+ Adds an image search path
+ @syntax:
+ file.addimagepath <path:string>
+ @description:
+ Adds <path> to the image search path list.[br]
+ KVIrc will look for images files (also) in that path (when a relative image file name is used).[br]
+ Yes, this function is a bit misplaced...
+ @seealso:
+ [cmd]file.delimagepath[/cmd]
+*/
+
+static bool file_kvs_cmd_addimagepath(KviKvsModuleCommandCall * c)
+{
+ QString szDst;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("path",KVS_PT_NONEMPTYSTRING,0,szDst)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szDst);
+
+ QStringList::Iterator it = KVI_OPTION_STRINGLIST(KviOption_stringlistImageSearchPaths).find(szDst);
+ if(it == KVI_OPTION_STRINGLIST(KviOption_stringlistImageSearchPaths).end())
+ KVI_OPTION_STRINGLIST(KviOption_stringlistImageSearchPaths).append(szDst);
+ return true;
+}
+
+
+
+/*
+ @doc: file.delimagepath
+ @type:
+ command
+ @title:
+ file.delimagepath
+ @short:
+ Removes an image search path
+ @syntax:
+ file.delimagepath <path:string>
+ @description:
+ Removes <path> from the image search path list.[br]
+ Yes, this function is a bit misplaced...
+ @seealso:
+ [cmd]file.addimagepath[/cmd]
+*/
+
+static bool file_kvs_cmd_delimagepath(KviKvsModuleCommandCall * c)
+{
+ QString szDst;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("path",KVS_PT_NONEMPTYSTRING,0,szDst)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szDst);
+
+ QStringList::Iterator it = KVI_OPTION_STRINGLIST(KviOption_stringlistImageSearchPaths).find(szDst);
+ if(it == KVI_OPTION_STRINGLIST(KviOption_stringlistImageSearchPaths).end())
+ KVI_OPTION_STRINGLIST(KviOption_stringlistImageSearchPaths).remove(szDst);
+ return true;
+}
+
+
+/*
+ @doc: file.write
+ @type:
+ command
+ @title:
+ file.write
+ @keyterms:
+ writing data to files
+ @short:
+ Writes an ascii data string to a file
+ @syntax:
+ file.write [-a] [-l] <filename:string> <data:string>
+ @switches:
+ !sw: -a | --append
+ If the file already exists, append the data instead of overwriting the original contents.
+ !sw: -l | --local-8-bit
+ Causes the file to be written in the local 8 bit character set instead of the
+ default utf8.
+ @description:
+ Writes <data> (which is an ASCII string) to the file <filename>.[br]
+ It does NOT append a traling LF character: if you want it you must explicitly specify it in the <data> parameter.[br]
+ -a causes the command to append the <data> to the file instead of overwriting the entire file.[br]
+ The path is adjusted according to the system that KVIrc
+ is running on so you don't have to bother about portability: it *should* be automatically
+ guaranteed. Just use UNIX style paths for them.[br]
+ The file is saved in utf8 unless the -l switch is specified (in that case the local 8 bit encoding is used).
+ Please note that uf8 is the only character set that preserves ALL the possible characters.
+ @seealso:
+ [cmd]file.rename[/cmd], [fnc]$file.exists[/fnc]
+*/
+
+static bool file_kvs_cmd_write(KviKvsModuleCommandCall * c)
+{
+ QString szFileName,szData;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szFileName)
+ KVSM_PARAMETER("data",KVS_PT_NONEMPTYSTRING,0,szData)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szFileName);
+
+ bool bRet;
+ if(c->switches()->find('l',"local-8-bit"))
+ bRet = KviFileUtils::writeFileLocal8Bit(szFileName,szData,c->switches()->find('a',"append"));
+ else
+ bRet = KviFileUtils::writeFile(szFileName,szData,c->switches()->find('a',"append"));
+
+ if(!bRet)
+ c->warning(__tr2qs("Failed to write to file %Q: the destination couldn't be opened"),&szFileName);
+
+ return true;
+}
+
+
+/*
+ @doc: file.rename
+ @type:
+ command
+ @title:
+ file.rename
+ @keyterms:
+ copying files
+ @short:
+ Makes a copy of a file
+ @syntax:
+ file.rename <oldname:string> <newname:string>
+ @description:
+ Renames a file from <oldname> to <newname>.[br]
+ This command can also rename directories.[br]
+ If the <newname> file already exists , this command fails.[br]
+ The paths (<oldname> and <newname>) are adjusted according to the system that KVIrc
+ is running on so you don't have to bother about portability: it *should* be automatically
+ guaranteed.Just use UNIX style paths for them.[br]
+ @seealso:
+ [cmd]file.copy[/cmd], [fnc]$file.exists[/fnc]
+*/
+
+static bool file_kvs_cmd_rename(KviKvsModuleCommandCall * c)
+{
+ QString szOld,szNew;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("oldname",KVS_PT_NONEMPTYSTRING,0,szOld)
+ KVSM_PARAMETER("newname",KVS_PT_NONEMPTYSTRING,0,szNew)
+ KVSM_PARAMETERS_END(c)
+
+ KviFileUtils::adjustFilePath(szOld);
+ KviFileUtils::adjustFilePath(szNew);
+
+ if(KviFileUtils::fileExists(szNew))
+ c->warning(__tr2qs("Destination file exists: file not renamed"));
+
+ if(!KviFileUtils::renameFile(szOld,szNew))
+ c->warning(__tr2qs("Failed to rename %Q to %Q"),&szOld,&szNew);
+ return true;
+}
+
+
+/*
+ @doc: file.mkdir
+ @type:
+ command
+ @title:
+ file.mkdir
+ @keyterms:
+ creating directories
+ @short:
+ Creates a directory
+ @syntax:
+ file.mkdir <directory:string>
+ @description:
+ Creates the <directory>.[br]
+ The path is adjusted according to the system that KVIrc
+ is running on so you don't have to bother about portability: it *should* be automatically
+ guaranteed. Just use an UNIX style path.[br]
+ @seealso:
+ [fnc]$file.exists[/fnc]
+*/
+
+static bool file_kvs_cmd_mkdir(KviKvsModuleCommandCall * c)
+{
+ QString szDir;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("directory",KVS_PT_NONEMPTYSTRING,0,szDir)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szDir);
+ if(!KviFileUtils::makeDir(szDir))
+ c->warning(__tr2qs("Failed to make the directory %Q"),&szDir);
+ return true;
+}
+
+
+
+/*
+ @doc: file.remove
+ @type:
+ command
+ @title:
+ file.remove
+ @keyterms:
+ removing files
+ @short:
+ Removes a file
+ @syntax:
+ file.remove [-q] <name:string>
+ @switches:
+ !sw: -q | --quiet
+ Suppresses any warning message
+ @description:
+ Removes the file <name>.[br]
+ -q suppresses any warning message (about non existing file , for example).[br]
+ The path is adjusted according to the system that KVIrc
+ is running on so you don't have to bother about portability: it *should* be automatically
+ guaranteed. Just use an UNIX style path.[br]
+ @seealso:
+ [fnc]$file.exists[/fnc]
+*/
+
+static bool file_kvs_cmd_remove(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szName);
+ if(!KviFileUtils::removeFile(szName))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("Failed to remove the file %Q"),&szName);
+ }
+ return true;
+}
+
+
+/*
+ @doc: file.rmdir
+ @type:
+ command
+ @title:
+ file.rmdir
+ @keyterms:
+ removing directories
+ @short:
+ Removes a directory
+ @syntax:
+ file.rmdir [-q] <name:string>
+ @switches:
+ !sw: -q | --quiet
+ Suppresses any warning message
+ @description:
+ Removes the directory <name>.[br]
+ The directory must be empty for this command to success.[br]
+ -q suppresses any warning message (about non existing directory , for example).[br]
+ The path is adjusted according to the system that KVIrc
+ is running on so you don't have to bother about portability: it *should* be automatically
+ guaranteed. Just use an UNIX style path.[br]
+ @seealso:
+ [fnc]$file.exists[/fnc]
+ [cmd]file.remove[/cmd]
+*/
+
+static bool file_kvs_cmd_rmdir(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szName);
+ if(!KviFileUtils::removeDir(szName))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("Failed to remove the directory %Q"),&szName);
+ }
+ return true;
+}
+
+
+/*
+ @doc: file.exists
+ @type:
+ function
+ @title:
+ $file.exists
+ @short:
+ Check if a file exists
+ @syntax:
+ <boolean> $file.exists(<filename:string>)
+ @description:
+ Returns true if the file <filename> exists (this is also valid for directories!).[br]
+ The <filename> should be an unix-style file path and is adjusted according to the system that KVIrc is running on.[br]
+*/
+
+static bool file_kvs_fnc_exists(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szName);
+ QFileInfo f(szName);
+ c->returnValue()->setBoolean(f.exists());
+ return true;
+}
+
+
+/*
+ @doc: file.type
+ @type:
+ function
+ @title:
+ $file.type
+ @short:
+ Checks the type of a path
+ @syntax:
+ <string> $file.type(<filename:string>)
+ @description:
+ Returns "f" if the <filename> points to a real file , "d" if <filename>
+ is the name of a directory or "l" if it is a symbolic link.[br]
+ The <filename> should be an unix-style file path and is adjusted according to the system that KVIrc is running on.[br]
+*/
+
+static bool file_kvs_fnc_type(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szName);
+ QFileInfo f(szName);
+ if(f.isFile())c->returnValue()->setString("f");
+ else if(f.isDir())c->returnValue()->setString("d");
+ else if(f.isSymLink())c->returnValue()->setString("l");
+ return true;
+}
+
+
+/*
+ @doc: file.size
+ @type:
+ function
+ @title:
+ $file.size
+ @short:
+ Returns the size of a file
+ @syntax:
+ <integer> $file.size(<filename:string>)
+ @description:
+ Returns the size of the file pointed by <filename>.[br]
+ If the file does not exist , this function returns 0.[br]
+ The <filename> should be an unix-style file path and is adjusted according to the system that KVIrc is running on.[br]
+*/
+
+static bool file_kvs_fnc_size(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szName);
+ QFileInfo f(szName);
+ c->returnValue()->setInteger(f.size());
+ return true;
+}
+/*
+ @doc: file.allSizese
+ @type:
+ function
+ @title:
+ $file.allSizes
+ @short:
+ Returns all sizes of a specified directory.
+ @syntax:
+ <array> $file.allSize(<dirname:string>)
+ @description:
+ Returns the size of every files of the specified directory as an array.[br]
+*/
+
+static bool file_kvs_fnc_allSizes(KviKvsModuleFunctionCall * c)
+{
+ QString szDir;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("directory",KVS_PT_NONEMPTYSTRING,0,szDir)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szDir);
+
+ QDir d(szDir);
+ if(!d.exists())
+ {
+ c->warning(__tr2qs("The specified directory does not exist '%Q'"),&szDir);
+ return true;
+ }
+
+ QStringList sl;
+ sl = d.entryList(QDir::Files);
+
+ KviKvsArray * a = new KviKvsArray();
+ QString szFile;
+ if(!sl.isEmpty())
+ {
+ int idx = 0;
+ for(QStringList::Iterator it = sl.begin();it != sl.end();++it)
+ {
+ szFile=szDir+(*it);
+ QFileInfo f(szFile);
+ a->set(idx,new KviKvsVariant((kvs_int_t)f.size()));
+ idx++;
+ }
+ }
+ c->returnValue()->setArray(a);
+
+
+
+
+ return true;
+}
+
+/*
+ @doc: file.fixpath
+ @type:
+ function
+ @title:
+ $file.fixpath
+ @short:
+ Converts file paths
+ @syntax:
+ <string> $file.fixpath(<filename:string>)
+ @description:
+ Returns the <filename> adjusted to match the current operating
+ system file path conventions.[br] This means that on UNIX , a path like "C:\folder\file.mp3"
+ will be returned as "/folder/file.mp3" and vice-versa.[br]
+ There is a minor problem with unix paths converted to the windows system: unix
+ has no "drive" concept thus the unix paths do not contain a drive. KVIrc will
+ always map the paths to the "default" C: drive.[br]
+ This is a good reason to avoid using absolute hard-coded paths :).[br]
+ Please note that you DON'T NEED to call this function on paths that you
+ pass to the other file.* functions: they are adjusted automatically.[br]
+ @seealso:
+ [fnc]$file.ps[/fnc]
+*/
+
+
+static bool file_kvs_fnc_fixpath(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szName);
+ c->returnValue()->setString(szName);
+ return true;
+}
+
+
+/*
+ @doc: file.ps
+ @type:
+ function
+ @title:
+ $file.ps
+ @short:
+ Returns the file path separator
+ @syntax:
+ <string> $file.ps()
+ @description:
+ Returns the file path separator for the current operating system.[br]
+ On windows , '\' is returned , on UNIX , '/'.[br]
+ @seealso:
+ [fnc]$file.fixpath[/fnc]
+*/
+
+static bool file_kvs_fnc_ps(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setString(QString(QChar(KVI_PATH_SEPARATOR_CHAR)));
+ return true;
+}
+
+
+/*
+ @doc: file.ls
+ @type:
+ function
+ @title:
+ $file.ls
+ @short:
+ Returns a directory listing
+ @syntax:
+ <array> $file.ls(<directory:string>,[<flags:string>[,<namefilter:string>]])
+ @description:
+ Returns the listing of the specified directory as an array.[br]
+ The <directory> should be an unix-style file path and is adjusted according to the system that KVIrc is running on.[br]
+ <flags> may be a combination of the following characters:[br]
+ d: list directories[br]
+ f: list files[br]
+ l: list symbolic links[br]
+ r: list readable files[br]
+ w: list writeable files[br]
+ x: list executable files[br]
+ h: list hidden files[br]
+ s: list system files[br]
+ n: sort files by name[br]
+ t: sort files by file time[br]
+ b: sort files by file size[br]
+ z: put the directories first, then the files[br]
+ k: invert sort order[br]
+ i: case insensitive sort[br]
+ If <flags> is empty then a default of 'dfrwxhs'.[br]
+ If none of r,w,x is set then KVIrc sets all of them by default.[br]
+ If <namefilter> is passed then it is interpreted as a wildcard string
+ that must match the entries to be returned.[br]
+ @example:
+ [example]
+ %dir[]=$file.ls(/,"d")
+ [cmd]foreach[/cmd](%f,%dir[])echo %f
+ %dir[]=$file.ls(/usr/include,"f","t*.h");
+ [cmd]foreach[/cmd](%f,%dir[])echo %f
+ %dir[]=$file.ls($file.homedir,"dfr");
+ [cmd]foreach[/cmd](%f,%dir[])echo %f
+ [/example]
+*/
+
+static bool file_kvs_fnc_ls(KviKvsModuleFunctionCall * c)
+{
+ QString szDir,szFlags,szFilter;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("directory",KVS_PT_NONEMPTYSTRING,0,szDir)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETER("filter",KVS_PT_STRING,KVS_PF_OPTIONAL,szFilter)
+ KVSM_PARAMETERS_END(c)
+
+ KviFileUtils::adjustFilePath(szDir);
+
+ QDir d(szDir);
+ if(!d.exists())
+ {
+ c->warning(__tr2qs("The specified directory does not exist '%Q'"),&szDir);
+ return true;
+ }
+
+#ifdef COMPILE_USE_QT4
+ QFlags<QDir::Filter> iFlags = 0;
+#else
+ int iFlags = 0;
+#endif
+ if(szFlags.isEmpty())iFlags = QDir::Dirs | QDir::Files | QDir::NoSymLinks | QDir::Readable | QDir::Writable | QDir::Executable | QDir::Hidden | QDir::System;
+ else {
+ if(szFlags.find('d',false) != -1)iFlags |= QDir::Dirs;
+ if(szFlags.find('f',false) != -1)iFlags |= QDir::Files;
+ if(szFlags.find('l',false) == -1)iFlags |= QDir::NoSymLinks;
+ if(szFlags.find('r',false) != -1)iFlags |= QDir::Readable;
+ if(szFlags.find('w',false) != -1)iFlags |= QDir::Writable;
+ if(szFlags.find('x',false) != -1)iFlags |= QDir::Executable;
+ if(szFlags.find('h',false) != -1)iFlags |= QDir::Hidden;
+ if(szFlags.find('s',false) != -1)iFlags |= QDir::System;
+ }
+#ifdef COMPILE_USE_QT4
+ QFlags<QDir::SortFlag> iSort = 0;
+#else
+ int iSort = 0;
+#endif
+ if(szFlags.isEmpty())iSort = QDir::Unsorted;
+ else {
+ if(szFlags.find('n',false) != -1)iSort |= QDir::Name;
+ if(szFlags.find('t',false) != -1)iSort |= QDir::Time;
+ if(szFlags.find('b',false) != -1)iSort |= QDir::Size;
+ if(szFlags.find('z',false) != -1)iSort |= QDir::DirsFirst;
+ if(szFlags.find('k',false) != -1)iSort |= QDir::Reversed;
+ if(szFlags.find('i',false) != -1)iSort |= QDir::IgnoreCase;
+ }
+
+ QStringList sl;
+ if(!szFilter.isEmpty())sl = d.entryList(szFilter,iFlags,iSort);
+ else sl = d.entryList(iFlags,iSort);
+
+ KviKvsArray * a = new KviKvsArray();
+ if(!sl.isEmpty())
+ {
+ int idx = 0;
+ for(QStringList::Iterator it = sl.begin();it != sl.end();++it)
+ {
+ a->set(idx,new KviKvsVariant(*it));
+ idx++;
+ }
+ }
+ c->returnValue()->setArray(a);
+
+ return true;
+}
+
+/*
+ @doc: file.read
+ @type:
+ function
+ @title:
+ $file.read
+ @short:
+ Reads a text file
+ @syntax:
+ <string> $file.read(<filename:string>[,<size:integer>[,<flags:string>]])
+ @description:
+ Reads at most <size> bytes of the file pointed by <filename>.[br]
+ <size> is an upper limit but may be not reached if the real file is smaller.[br]
+ The data read is returned as a string , so if the file contains binary data,
+ expect strange results.[br] If <size> is not specified, then KVIrc tries to read
+ the whole file up to the 1 MB limit (so if you want to read a file that is
+ bigger thatn 1 MB then you MUST specify the <size>).[br]
+ WARNING: always check the file size before attemting to read a whole file...
+ reading a CDROM iso image may sit down your system :) (and will prolly crash while
+ allocating memory , before attempting to read anything)[br]
+ An empty string is returned if a serious error occures.[br]
+ The <filename> is adjusted according to the system that KVIrc is running on.[br]
+ Flags are actually limited to the single letter 'l'. By default the file
+ is decoded from the ut8 characters set. If 'l' is present the the file
+ is decoded by using the local 8 bit character set instead.
+ @examples:
+ [example]
+ echo $file.read(/proc/cpuinfo)
+ [/example]
+ @seealso:
+ [fnc]$file.readbinary[/fnc]
+*/
+
+static bool file_kvs_fnc_read(KviKvsModuleFunctionCall * c)
+{
+ QString szNameZ;
+ kvs_uint_t uSize;
+ QString szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szNameZ)
+ KVSM_PARAMETER("size",KVS_PT_UINT,KVS_PF_OPTIONAL,uSize)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szNameZ);
+
+ QFile f(szNameZ);
+ if(!f.open(IO_ReadOnly))
+ {
+ c->warning(__tr2qs("Can't open the file \"%Q\" for reading"),&szNameZ);
+ return true;
+ }
+
+ if(c->params()->count() < 2)uSize = 1024 * 1024; // 1 meg file default
+
+ char * buf = (char *)kvi_malloc(sizeof(char) * (uSize + 1));
+ unsigned int uReaded = 0;
+ unsigned int uRetries = 0;
+
+ while((uReaded < uSize) && (!f.atEnd()))
+ {
+ int readedNow = f.readBlock(buf + uReaded,uSize - uReaded);
+ if(readedNow < 0)
+ {
+ kvi_free(buf);
+ c->warning(__tr2qs("Read error for file %Q"),&szNameZ);
+ return true;
+ } else readedNow += uReaded;
+ uRetries ++;
+ if(uRetries > 1000)
+ {
+ // ops
+ kvi_free(buf);
+ c->warning(__tr2qs("Read error for file %Q (have been unable to read the requested size in 1000 retries)"),&szNameZ);
+ return true;
+ }
+ uReaded += readedNow;
+ }
+
+ buf[uReaded] = '\0';
+
+ if(szFlags.find('l',false) == -1)
+ c->returnValue()->setString(QString::fromUtf8(buf));
+ else
+ c->returnValue()->setString(QString::fromLocal8Bit(buf));
+
+ kvi_free(buf);
+
+ return true;
+}
+
+
+/*
+ @doc: file.readLines
+ @type:
+ function
+ @title:
+ $file.readLines
+ @short:
+ Reads lines of a text file
+ @syntax:
+ <array> $file.readLines(<filename:string>[,<startline:integer>,[<count:integer>[,<flags:string>]]])
+ @description:
+ Reads lines from the specified file and returns them as an array of strings.
+ The lines are assumed to be separated by linefeed characters (which are NOT returned).
+ Eventual terminating carriage return characters at the end of the line are stripped.
+ If <startline> is specified, then all the lines with indexes lower that <startline> are
+ discarded. If <count> is specified then a maximum of <count> lines is returned.
+ If <count> is not specified then all the lines until the end are read.
+ The <filename> is adjusted according to the system that KVIrc is running on.[br]
+ Flags are actually limited to the single letter 'l'. By default the file
+ is decoded from the ut8 characters set. If 'l' is present the the file
+ is decoded by using the local 8 bit character set instead.
+ WARNING: Always check the size of the file you're going to read: it is not
+ a good idea attempting to read a 700 MB binary file with this function since
+ it will probably sit down your system and exhaust your virtual memory.
+ @examples:
+ [example]
+ echo $file.readLines(/proc/cpuinfo)
+ [/example]
+ @seealso:
+ [fnc]$file.read[/fnc], [cmd]file.writeLines[/cmd], [fnc]$lf[/fnc]
+*/
+
+
+
+static bool file_kvs_fnc_readLines(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ QString szFlags;
+ kvs_int_t iStartLine;
+ kvs_int_t iCount;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETER("startline",KVS_PT_INT,KVS_PF_OPTIONAL,iStartLine)
+ KVSM_PARAMETER("count",KVS_PT_INT,KVS_PF_OPTIONAL,iCount)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::adjustFilePath(szName);
+
+ QFile f(szName);
+ if(!f.open(IO_ReadOnly))
+ {
+ c->warning(__tr2qs("Can't open the file \"%Q\" for reading"),&szName);
+ return true;
+ }
+
+ if(c->params()->count() < 2)iStartLine = 0;
+ if(c->params()->count() < 3)iCount = -1;
+
+ bool bLocal8Bit = szFlags.find('l',0,false) != -1;
+
+ KviKvsArray * a = new KviKvsArray();
+
+ int iIndex=0;
+
+ QTextStream stream( &f );
+
+ stream.setEncoding(bLocal8Bit ? QTextStream::Locale : QTextStream::UnicodeUTF8);
+ for(int i=0;i<iStartLine;i++)
+ stream.readLine();
+
+ if(iCount>0)
+ {
+ for(; (iCount>0 && !stream.atEnd()) ; iCount-- )
+ a->set(iIndex,new KviKvsVariant(stream.readLine()));
+ iIndex++;
+ } else {
+ while(!stream.atEnd()) {
+ a->set(iIndex,new KviKvsVariant(stream.readLine()));
+ iIndex++;
+ }
+ }
+
+ f.close();
+
+ c->returnValue()->setArray(a);
+
+ return true;
+}
+
+
+/*
+ @doc: file.writelines
+ @type:
+ command
+ @title:
+ file.writeLines
+ @short:
+ Writes an array of lines to a file
+ @syntax:
+ file.writeLines [-l] [-a] [-c] <filename:string> <lines:array>
+ @switches:
+ !sw: -l | --local-8-bit
+ Causes the lines to be saved in local 8 bit character set instead
+ of the default unicode encoding.
+ !sw: -a | --append
+ If the file already exists, then the lines are appended to the end
+ instead of overwriting the file.
+ !sw: -c | --crlf
+ The lines are separated by a carriage-return+line-feed character
+ combination, compatible with windows text mode files.
+ This is the only way to make the file readable in windows notepad, for example.
+ Please note that this is broken design: do NOT use it :)
+ !sw: -n | --no-separator
+ Do not separate the lines at all (either the separators are already
+ inside the lines array or no line separation is desired at all).
+ -n takes precedence over -c.
+ !sw: -q | --quiet
+ Don't complain if the file can't be opened: just fail silently
+ @description:
+ Writes the array of <lines> to the specified file.
+ The lines are separated by a single linefeed character (see also [fnc]$lf[/fnc])
+ unless the -c or -n switches are used. If the file already exists then it is
+ overwritten with the new data unless the -a switch is used.
+ The lines array is encoded in the ut8 character set unless the -l switch is used.
+ @seealso:
+ [fnc]$file.readLines[/fnc]
+*/
+
+
+
+static bool file_kvs_cmd_writeLines(KviKvsModuleCommandCall * c)
+{
+ QString szFile,szFlags;
+ KviKvsArrayCast a;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szFile)
+ KVSM_PARAMETER("lines",KVS_PT_ARRAYCAST,0,a)
+ KVSM_PARAMETERS_END(c)
+
+ KviFileUtils::adjustFilePath(szFile);
+
+ KviFile f(szFile);
+ int iFlags = IO_WriteOnly;
+
+ if(!f.openForWriting(c->switches()->find('a',"append")))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("Can't open the file \"%Q\" for writing"),&szFile);
+ return true;
+ }
+
+ bool bLocal8Bit = c->switches()->find('l',"local-8-bit");
+ bool bNoSeparator = c->switches()->find('n',"no-separator");
+ bool bAddCR = c->switches()->find('c',"crlf");
+
+ unsigned int u = 0;
+ while(u < a.array()->size())
+ {
+ KviKvsVariant * v = a.array()->at(u);
+ KviQCString dat;
+ if(v)
+ {
+ QString szDat;
+ v->asString(szDat);
+ KviQCString dat = bLocal8Bit ? szDat.local8Bit() : szDat.utf8();
+ }
+ if(!bNoSeparator)
+ {
+ if(bAddCR)dat += "\r\n";
+ else dat += '\n';
+ }
+ f.writeBlock(dat.data(),dat.length());
+ u++;
+ }
+
+ f.close();
+
+ return true;
+}
+
+
+/*
+ @doc: file.localdir
+ @type:
+ function
+ @title:
+ $file.localdir
+ @short:
+ Get the KVIrc local directory
+ @syntax:
+ <string> $file.localdir([relative_path:string])
+ @description:
+ Returns the path to the KVIrc local data directory.[br]
+ The KVIrc local data directory is always writeable and contains
+ the various subdirectories that KVIrc uses internally: audio , avatars ,
+ config , help , incoming , log , modules , msgcolors and pics.[br]
+ If <relative_path> is passed , then it is appended at the end of the directory
+ to form a complete filepath.[br]
+ The path is adjusted to contain single separators suitable for the platform
+ that KVIrc is atually running on (thus you not need to care about path
+ separators in the <relative_path> , KVIrc will adjust them).[br]
+ @examples:
+ [example]
+ echo KVIrc looks for pictures in $file.localdir(pics)
+ echo panic.png would be translated to $file.localdir(pics/panic.png)
+ [/example]
+*/
+
+static bool file_kvs_fnc_localdir(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("relative_path",KVS_PT_STRING,KVS_PF_OPTIONAL,szName)
+ KVSM_PARAMETERS_END(c)
+ if(szName.isEmpty())szName.append(KVI_PATH_SEPARATOR_CHAR);
+ QString szPath;
+ g_pApp->getLocalKvircDirectory(szPath,KviApp::None,szName);
+ KviFileUtils::adjustFilePath(szPath);
+ c->returnValue()->setString(szPath);
+ return true;
+}
+
+
+
+/*
+ @doc: file.homedir
+ @type:
+ function
+ @title:
+ $file.homedir
+ @short:
+ Get the user's HOME directory
+ @syntax:
+ <string> $file.homedir([relative_path:string])
+ @description:
+ Returns the user's HOME directory path.[br]
+ If <relative_path> is passed , then it is appended at the end of the directory
+ to form a complete filepath.[br]
+ The path is adjusted to contain single separators suitable for the platform
+ that KVIrc is atually running on (thus you not need to care about path
+ separators in the <relative_path> , KVIrc will adjust them).[br]
+*/
+
+static bool file_kvs_fnc_homedir(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("relative_path",KVS_PT_STRING,KVS_PF_OPTIONAL,szName)
+ KVSM_PARAMETERS_END(c)
+ if(szName.isEmpty())szName.append(KVI_PATH_SEPARATOR_CHAR);
+ QString szPath = QDir::homeDirPath();
+ KviQString::ensureLastCharIs(szPath,KVI_PATH_SEPARATOR_CHAR);
+ szPath.append(szName);
+ KviFileUtils::adjustFilePath(szPath);
+ c->returnValue()->setString(szPath);
+ return true;
+}
+
+
+
+/*
+ @doc: file.rootdir
+ @type:
+ function
+ @title:
+ $file.rootdir
+ @short:
+ Get the system root directory
+ @syntax:
+ $file.rootdir(<relative_path>)
+ $file.rootdir
+ @description:
+ Returns the system's root directory (/ on UNIX and C:/ on Windows).[br]
+ If <relative_path> is passed , then it is appended at the end of the directory
+ to form a complete filepath.[br]
+ The path is adjusted to contain single separators suitable for the platform
+ that KVIrc is atually running on (thus you not need to care about path
+ separators in the <relative_path> , KVIrc will adjust them).[br]
+*/
+
+static bool file_kvs_fnc_rootdir(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("relative_path",KVS_PT_STRING,KVS_PF_OPTIONAL,szName)
+ KVSM_PARAMETERS_END(c)
+ if(szName.isEmpty())szName.append(KVI_PATH_SEPARATOR_CHAR);
+ QString szPath = QDir::rootDirPath();
+ KviQString::ensureLastCharIs(szPath,KVI_PATH_SEPARATOR_CHAR);
+ szPath.append(szName);
+ KviFileUtils::adjustFilePath(szPath);
+ c->returnValue()->setString(szPath);
+ return true;
+}
+
+
+/*
+ @doc: file.cwd
+ @type:
+ function
+ @title:
+ $file.currentdir
+ @short:
+ Get the current directory
+ @syntax:
+ <string> $file.cwd([relative_path:string])
+ @description:
+ Returns the current working directory.[br]
+ If <relative_path> is passed , then it is appended at the end of the directory
+ to form a complete filepath.[br]
+ The path is adjusted to contain single separators suitable for the platform
+ that KVIrc is atually running on (thus you not need to care about path
+ separators in the <relative_path> , KVIrc will adjust them).[br]
+*/
+
+static bool file_kvs_fnc_cwd(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("relative_path",KVS_PT_STRING,KVS_PF_OPTIONAL,szName)
+ KVSM_PARAMETERS_END(c)
+ if(szName.isEmpty())szName.append(KVI_PATH_SEPARATOR_CHAR);
+ QString szPath = QDir::currentDirPath();
+ KviQString::ensureLastCharIs(szPath,KVI_PATH_SEPARATOR_CHAR);
+ szPath.append(szName);
+ KviFileUtils::adjustFilePath(szPath);
+ c->returnValue()->setString(szPath);
+ return true;
+}
+
+
+/*
+ @doc: file.globaldir
+ @type:
+ function
+ @title:
+ $file.globaldir
+ @short:
+ Get the KVIrc global directory
+ @syntax:
+ $file.globaldir(<relative_path>)
+ $file.globaldir
+ @description:
+ Returns the path to the KVIrc global data directory.[br]
+ The KVIrc local data directory is always readable but usually not writeable and contains
+ the various subdirectories that KVIrc uses internally: audio , avatars ,
+ config , help , incoming , log , modules , msgcolors and pics.[br]
+ If <relative_path> is passed , then it is appended at the end of the directory
+ to form a complete filepath.[br]
+ The path is adjusted to contain single separators suitable for the platform
+ that KVIrc is atually running on (thus you not need to care about path
+ separators in the <relative_path> , KVIrc will adjust them).[br]
+ @examples:
+ [example]
+ echo KVIrc looks for pictures in $file.globaldir(pics)
+ echo panic.png would be translated to $file.globaldir(pics/panic.png)
+ [/example]
+*/
+
+static bool file_kvs_fnc_globaldir(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("relative_path",KVS_PT_STRING,KVS_PF_OPTIONAL,szName)
+ KVSM_PARAMETERS_END(c)
+ if(szName.isEmpty())szName.append(KVI_PATH_SEPARATOR_CHAR);
+ QString szPath;
+ g_pApp->getGlobalKvircDirectory(szPath,KviApp::None,szName);
+ KviFileUtils::adjustFilePath(szPath);
+ c->returnValue()->setString(szPath);
+ return true;
+}
+
+/*
+ @doc: file.extractpath
+ @type:
+ function
+ @title:
+ $file.extractpath
+ @short:
+ Extract the path from a filename
+ @syntax:
+ <string> $file.extractpath(<filepath:string>)
+ @description:
+ Returns the path part of the <filepath> translated to match the current
+ platform filesystem conventions.[br]
+ The path will NOT contain a trailing path separator.[br]
+ For example, if <filepath> is /usr/arch/mp3/Carisma_SuonoDelSilenzio.mp3 then
+ this function will return /usr/arch/mp3 on UNIX and C:\usr\arch\mp3 on Windows.
+ @seealso:
+ [fnc]$file.extractFileName[/fnc]
+*/
+
+static bool file_kvs_fnc_extractpath(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filepath",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(QFileInfo(szName).dirPath(TRUE));
+ return true;
+}
+
+
+/*
+ @doc: file.extractfilename
+ @type:
+ function
+ @title:
+ $file.extractfilename
+ @short:
+ Extract the filename from a file path
+ @syntax:
+ <string> $file.extractpath(<filepath:string>)
+ @description:
+ Returns the filename part of the filepath translated to match the current
+ platform filesystem conventions.[br]
+ For example, if <filepath> is /usr/arch/mp3/Carisma_SuonoDelSilenzio.mp3 then
+ this function will return Carisma_SuonoDelSilenzio.mp3
+ @seealso:
+ [fnc]$file.extractPath[/fnc]
+*/
+
+static bool file_kvs_fnc_extractfilename(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filepath",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+ KviFileUtils::extractFileName(szName);
+ KviQString::cutToLast(szName,KVI_PATH_SEPARATOR_CHAR);
+ c->returnValue()->setString(szName);
+ return true;
+}
+
+
+
+static bool file_module_init(KviModule * m)
+{
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"copy",file_kvs_cmd_copy);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"rename",file_kvs_cmd_rename);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"mkdir",file_kvs_cmd_mkdir);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"write",file_kvs_cmd_write);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"remove",file_kvs_cmd_remove);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"rmdir",file_kvs_cmd_rmdir);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"addimagepath",file_kvs_cmd_addimagepath);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"delimagepath",file_kvs_cmd_delimagepath);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"writeLines",file_kvs_cmd_writeLines);
+
+ KVSM_REGISTER_FUNCTION(m,"exists",file_kvs_fnc_exists);
+ KVSM_REGISTER_FUNCTION(m,"type",file_kvs_fnc_type);
+ KVSM_REGISTER_FUNCTION(m,"size",file_kvs_fnc_size);
+
+ KVSM_REGISTER_FUNCTION(m,"allsizes",file_kvs_fnc_allSizes);
+
+ KVSM_REGISTER_FUNCTION(m,"fixpath",file_kvs_fnc_fixpath);
+ KVSM_REGISTER_FUNCTION(m,"ps",file_kvs_fnc_ps);
+ KVSM_REGISTER_FUNCTION(m,"read",file_kvs_fnc_read);
+ KVSM_REGISTER_FUNCTION(m,"localdir",file_kvs_fnc_localdir);
+ KVSM_REGISTER_FUNCTION(m,"homedir",file_kvs_fnc_homedir);
+ KVSM_REGISTER_FUNCTION(m,"rootdir",file_kvs_fnc_rootdir);
+ KVSM_REGISTER_FUNCTION(m,"cwd",file_kvs_fnc_cwd);
+ KVSM_REGISTER_FUNCTION(m,"globaldir",file_kvs_fnc_globaldir);
+ KVSM_REGISTER_FUNCTION(m,"extractpath",file_kvs_fnc_extractpath);
+ KVSM_REGISTER_FUNCTION(m,"extractfilename",file_kvs_fnc_extractfilename);
+ KVSM_REGISTER_FUNCTION(m,"ls",file_kvs_fnc_ls);
+ KVSM_REGISTER_FUNCTION(m,"readLines",file_kvs_fnc_readLines);
+
+
+ return true;
+}
+
+static bool file_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "File", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Interface to the file system",
+ file_module_init,
+ 0,
+ 0,
+ file_module_cleanup
+)
diff --git a/src/modules/filetransferwindow/Makefile.am b/src/modules/filetransferwindow/Makefile.am
new file mode 100644
index 00000000..910d86b4
--- /dev/null
+++ b/src/modules/filetransferwindow/Makefile.am
@@ -0,0 +1,22 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+SUBDIRS = caps
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvifiletransferwindow.la
+
+libkvifiletransferwindow_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvifiletransferwindow_la_SOURCES = libkvifiletransferwindow.cpp filetransferwindow.cpp
+libkvifiletransferwindow_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= filetransferwindow.h
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+filetransferwindow.cpp: m_filetransferwindow.moc
diff --git a/src/modules/filetransferwindow/caps/Makefile.am b/src/modules/filetransferwindow/caps/Makefile.am
new file mode 100644
index 00000000..c3e694b7
--- /dev/null
+++ b/src/modules/filetransferwindow/caps/Makefile.am
@@ -0,0 +1,9 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir = $(pluglibdir)/caps/tool/
+
+tmp_DATA= filetransferwindow
+
+EXTRA_DIST = $(tmp_DATA)
diff --git a/src/modules/filetransferwindow/caps/filetransferwindow b/src/modules/filetransferwindow/caps/filetransferwindow
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/modules/filetransferwindow/caps/filetransferwindow
diff --git a/src/modules/filetransferwindow/filetransferwindow.cpp b/src/modules/filetransferwindow/filetransferwindow.cpp
new file mode 100644
index 00000000..a3951a7c
--- /dev/null
+++ b/src/modules/filetransferwindow/filetransferwindow.cpp
@@ -0,0 +1,768 @@
+//==================================================================================
+//
+// 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) 1999-2001 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 "kvi_iconmanager.h"
+#include "kvi_ircview.h"
+#include "kvi_out.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_out.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_themedlabel.h"
+#include "kvi_input.h"
+#include "kvi_qstring.h"
+
+#include <qsplitter.h>
+#include <qtooltip.h>
+#include "kvi_tal_hbox.h"
+#ifdef COMPILE_USE_QT4
+ #include <q3header.h>
+#else
+ #include <qheader.h>
+#endif
+#include <qpainter.h>
+#include <qmessagebox.h>
+#include <qclipboard.h>
+#include <qfileinfo.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qfontmetrics.h>
+#include <qevent.h>
+
+#ifdef COMPILE_KDE_SUPPORT
+ #include <kurl.h>
+ #include <krun.h>
+ #include <kuserprofile.h>
+ #include <kmimetype.h>
+#endif //COMPILE_KDE_SUPPORT
+
+extern KviFileTransferWindow * g_pFileTransferWindow;
+
+
+KviFileTransferItem::KviFileTransferItem(KviTalListView * v,KviFileTransfer * t)
+: KviTalListViewItem(v)
+{
+ m_pTransfer = t;
+ m_pTransfer->setDisplayItem(this);
+}
+
+KviFileTransferItem::~KviFileTransferItem()
+{
+ m_pTransfer->setDisplayItem(0);
+}
+
+QString KviFileTransferItem::key(int column,bool bAcending) 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;
+}
+
+void KviFileTransferItem::paintCell(QPainter * p,const QColorGroup &cg,int column,int width,int align)
+{
+ QPainter * newP;
+ QPixmap * pix = 0;
+ if(p->device() == listView()->viewport())
+ {
+ // ops.. there is no double buffering active ?
+ // we'll do it then
+ pix = g_pFileTransferWindow->memPixmap();
+ if((pix->width() < width) || (pix->height() < height()))
+ {
+ pix->resize(width,height());
+ } else {
+ if((pix->width() > 500) || (pix->height() > 110))
+ {
+ if((pix->width() * pix->height()) > (width * height() * 4))
+ {
+ // this is getting too big
+ pix->resize(width,height());
+ }
+ }
+ }
+ newP = new QPainter(pix);
+ } else {
+ newP = p;
+ }
+
+ p->setFont(listView()->font());
+
+ newP->setPen(isSelected() ? cg.highlight() : cg.base());
+ newP->drawRect(0,0,width,height());
+ newP->setPen(m_pTransfer->active() ? QColor(180,180,180) : QColor(200,200,200));
+ newP->drawRect(1,1,width - 2,height() - 2);
+ newP->fillRect(2,2,width - 4,height() - 4,m_pTransfer->active() ? QColor(240,240,240) : QColor(225,225,225));
+
+ m_pTransfer->displayPaint(newP,column,width,height());
+
+ if(newP != p)
+ {
+ p->drawPixmap(0,0,*pix,0,0,width,height());
+ delete newP;
+ }
+}
+
+void KviFileTransferItem::setHeight(int h)
+{
+ KviTalListViewItem::setHeight(m_pTransfer->displayHeight(g_pFileTransferWindow->lineSpacing()));
+}
+
+
+KviFileTransferWindow::KviFileTransferWindow(KviModuleExtensionDescriptor * d,KviFrame * lpFrm)
+: KviWindow(KVI_WINDOW_TYPE_TOOL,lpFrm,"file transfer window",0) , KviModuleExtension(d)
+{
+ g_pFileTransferWindow = this;
+
+ m_pContextPopup = 0;
+ m_pLocalFilePopup = 0;
+ m_pOpenFilePopup = 0;
+
+ m_pMemPixmap = new QPixmap(1,1);
+
+ m_pTimer = new QTimer(this);
+ connect(m_pTimer,SIGNAL(timeout()),this,SLOT(heartbeat()));
+
+ m_pInput = new KviInput(this,0);
+
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"splitter");
+ m_pVertSplitter = new QSplitter(Qt::Vertical,m_pSplitter,"vsplitter");
+
+ m_pListView = new KviTalListView(m_pVertSplitter);
+ //m_pListView->header()->hide();
+ m_pListView->setAllColumnsShowFocus(true);
+ m_pListView->addColumn(__tr2qs_ctx("Type","filetransferwindow"),56);
+ m_pListView->addColumn(__tr2qs_ctx("Information","filetransferwindow"),350);
+ m_pListView->addColumn(__tr2qs_ctx("Progress","filetransferwindow"),350);
+
+ KviDynamicToolTip * tp = new KviDynamicToolTip(m_pListView->viewport());
+ connect(tp,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &)));
+
+ //m_pListView->setFocusPolicy(NoFocus);
+ //m_pListView->viewport()->setFocusPolicy(NoFocus);
+
+ //connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),
+ // this,SLOT(showHostPopup(KviTalListViewItem *,const QPoint &,int)));
+
+ QFontMetrics fm(font());
+ m_iLineSpacing = fm.lineSpacing();
+
+ m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this);
+
+ m_pListView->installEventFilter(this);
+ connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),this,SLOT(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)));
+ connect(m_pListView,SIGNAL(doubleClicked(KviTalListViewItem *,const QPoint &,int)),this,SLOT(doubleClicked(KviTalListViewItem *,const QPoint &,int)));
+ 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);
+
+ //setFocusHandler(m_pInput,this);
+
+ m_pTimer->start(2000);
+}
+
+KviFileTransferWindow::~KviFileTransferWindow()
+{
+ KviFileTransferManager::instance()->setTransferWindow(0);
+ g_pFileTransferWindow = 0;
+ delete m_pMemPixmap;
+}
+
+bool KviFileTransferWindow::eventFilter( QObject *obj, QEvent *ev )
+{
+ if( (obj==m_pListView) && ( ev->type() == QEvent::KeyPress ) )
+ {
+ QKeyEvent *keyEvent = (QKeyEvent*)ev;
+ switch(keyEvent->key())
+ {
+ case Qt::Key_Delete:
+ if(m_pListView->currentItem())
+ {
+ delete m_pListView->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_pListView->itemAt(pnt);
+ if(!it)return;
+ QString txt = it->transfer()->tipText();
+ tip->tip(m_pListView->itemRect(it),txt);
+}
+
+void KviFileTransferWindow::fillTransferView()
+{
+ KviPointerList<KviFileTransfer> * l = KviFileTransferManager::instance()->transferList();
+ if(!l)return;
+ KviFileTransferItem * it;
+ for(KviFileTransfer * t = l->first();t;t = l->next())
+ {
+ it = new KviFileTransferItem(m_pListView,t);
+ t->setDisplayItem(it);
+ }
+}
+
+KviFileTransferItem * KviFileTransferWindow::findItem(KviFileTransfer * t)
+{
+ KviFileTransferItem * it = (KviFileTransferItem *)m_pListView->firstChild();
+ while(it)
+ {
+ if(it->transfer() == t)return it;
+ it = (KviFileTransferItem *)(it->nextSibling());
+ }
+ return 0;
+}
+
+void KviFileTransferWindow::transferRegistered(KviFileTransfer * t)
+{
+ KviFileTransferItem * it = new KviFileTransferItem(m_pListView,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(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ if(it)
+ openLocalFile();
+}
+
+void KviFileTransferWindow::rightButtonPressed(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ 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 = "<b>file:/";
+ tmp += szFile;
+ tmp += "</b><br>";
+
+ QFileInfo fi(szFile);
+ if(fi.exists())
+ {
+ tmp += "<nobr>";
+ tmp += __tr2qs_ctx("Size: %1","filetransferwindow").arg(KviQString::makeSizeReadable(fi.size()));
+ tmp += "</nobr><br>";
+ }
+
+#ifdef COMPILE_KDE_SUPPORT
+ tmp += "<nobr>Mime: ";
+ tmp += KMimeType::findByPath(szFile)->name();
+ tmp += "</nobr>";
+#endif //COMPILE_KDE_SUPPORT
+
+ QLabel * l = new QLabel(tmp,m_pLocalFilePopup);
+ l->setFrameStyle(QFrame::Raised | QFrame::Panel);
+ m_pLocalFilePopup->insertItem(l);
+
+#ifdef COMPILE_KDE_SUPPORT
+ QString mimetype = KMimeType::findByPath(szFile)->name();
+ KServiceTypeProfile::OfferList offers = KServiceTypeProfile::offers(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(KServiceTypeProfile::OfferList::Iterator itOffers = offers.begin();
+ itOffers != offers.end(); ++itOffers)
+ {
+ id = m_pOpenFilePopup->insertItem((*itOffers).service()->pixmap(KIcon::Small),(*itOffers).service()->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 |-
+#ifdef COMPILE_ON_WINDOWS
+ 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 //COMPILE_ON_WINDOWS
+// 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,col);
+ m_pContextPopup->insertSeparator();
+ }
+ }
+
+
+ bool bHaveTerminated = false;
+ KviFileTransferItem * item = (KviFileTransferItem *)m_pListView->firstChild();
+ while(item)
+ {
+ if(item->transfer()->terminated())
+ {
+ bHaveTerminated = true;
+ break;
+ }
+ item = (KviFileTransferItem *)item->nextSibling();
+ }
+
+ id = m_pContextPopup->insertItem(__tr2qs_ctx("&Clear Terminated","filetransferwindow"),this,SLOT(clearTerminated()));
+ m_pContextPopup->setItemEnabled(id,bHaveTerminated);
+
+ bool bAreTransfersActive = false;
+ if(m_pListView->childCount() >= 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()
+{
+ KviTalListViewItem * it = m_pListView->selectedItem();
+ 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;
+ QString txt = m_pOpenFilePopup->text(id);
+
+ KviFileTransfer * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+
+ QString mimetype = KMimeType::findByPath(tmp)->name();
+ KServiceTypeProfile::OfferList offers = KServiceTypeProfile::offers(mimetype,"Application");
+
+ for(KServiceTypeProfile::OfferList::Iterator itOffers = offers.begin();
+ itOffers != offers.end(); ++itOffers)
+ {
+ if(txt == (*itOffers).service()->name())
+ {
+ KURL::List lst;
+ KURL url;
+ url.setPath(tmp);
+ lst.append(url);
+ KRun::run(*((*itOffers).service()), lst);
+ break;
+ }
+ }
+#endif //COMPILE_KDE_SUPPORT
+}
+
+void KviFileTransferWindow::openLocalFileTerminal()
+{
+//-| Grifisx & Noldor |-
+#ifdef COMPILE_ON_WINDOWS
+ KviFileTransfer * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+ int idx = tmp.findRev("/");
+ if(idx == -1)return;
+ tmp = tmp.left(idx);
+ tmp.append("\"");
+/*FIX ME " 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.local8Bit().data());
+#else //COMPILE_ON_WINDOWS
+// G&N end
+ #ifdef COMPILE_KDE_SUPPORT
+ KviFileTransfer * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+
+ int idx = tmp.findRev("/");
+ if(idx == -1)return;
+ tmp = tmp.left(idx);
+
+ tmp.prepend("konsole --workdir=\"");
+ tmp.append("\"");
+
+ KRun::runCommand(tmp);
+ #endif //COMPILE_KDE_SUPPORT
+#endif //!COMPILE_ON_WINDOWS
+}
+
+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 |-
+#ifdef COMPILE_ON_WINDOWS
+
+ KviFileTransfer * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+ tmp.replace("/","\\");
+ ShellExecute(0,"open",tmp.local8Bit().data(),NULL,NULL,SW_SHOWNORMAL); //You have to link the shell32.lib
+#else //!COMPILE_ON_WINDOWS
+// 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 = KServiceTypeProfile::preferredService(mimetype,"Application");
+ if(!offer)
+ {
+ openLocalFileWith();
+ return;
+ }
+
+ KURL::List lst;
+ KURL url;
+ url.setPath(tmp);
+ lst.append(url);
+ KRun::run(*offer, lst);
+ #endif //COMPILE_KDE_SUPPORT
+#endif //!COMPILE_ON_WINDOWS
+}
+
+void KviFileTransferWindow::openLocalFileWith()
+{
+//-| Grifisx & Noldor |-
+#ifdef COMPILE_ON_WINDOWS
+ 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.local8Bit().data(),SW_SHOWNORMAL);
+#else //!COMPILE_ON_WINDOWS
+// 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);
+ #endif //COMPILE_KDE_SUPPORT
+#endif //!COMPILE_ON_WINDOWS
+}
+
+void KviFileTransferWindow::copyLocalFileToClipboard()
+{
+ KviFileTransfer * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+#ifdef COMPILE_USE_QT4
+ QApplication::clipboard()->setText(tmp);
+#else
+ QApplication::clipboard()->setSelectionMode(false);
+ QApplication::clipboard()->setText(tmp);
+ QApplication::clipboard()->setSelectionMode(true);
+ QApplication::clipboard()->setText(tmp);
+#endif
+}
+
+void KviFileTransferWindow::openLocalFileFolder()
+{
+//-| Grifisx & Noldor|-
+#ifdef COMPILE_ON_WINDOWS
+ KviFileTransfer * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+ tmp=QFileInfo(tmp).dirPath(TRUE);
+ tmp.replace('/','\\');
+ tmp.prepend("explorer.exe ");
+ WinExec(tmp.local8Bit().data(), SW_MAXIMIZE);
+#else //!COMPILE_ON_WINDOWS
+// G&N end
+ #ifdef COMPILE_KDE_SUPPORT
+ KviFileTransfer * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+
+ int idx = tmp.findRev("/");
+ if(idx == -1)return;
+ tmp = tmp.left(idx);
+
+ QString mimetype = KMimeType::findByPath(tmp)->name(); // inode/directory
+ KService::Ptr offer = KServiceTypeProfile::preferredService(mimetype,"Application");
+ if(!offer)return;
+
+ KURL::List lst;
+ KURL url;
+ url.setPath(tmp);
+ lst.append(url);
+ KRun::run(*offer, lst);
+ #endif //COMPILE_KDE_SUPPORT
+#endif //!COMPILE_ON_WINDOWS
+}
+
+
+void KviFileTransferWindow::heartbeat()
+{
+ if(m_pListView->childCount() < 1)return;
+
+ KviTalListViewItem * i1;
+ KviTalListViewItem * i2;
+
+ i1 = m_pListView->itemAt(QPoint(1,1));
+ if(!i1)
+ {
+ m_pListView->viewport()->update();
+ return;
+ }
+ i2 = m_pListView->itemAt(QPoint(1,m_pListView->viewport()->height() - 2));
+ if(i2)i2 = i2->nextSibling();
+
+ while(i1 && (i1 != i2))
+ {
+ if(((KviFileTransferItem *)i1)->transfer()->active())
+ {
+ m_pListView->repaintItem(i1);
+ }
+ i1 = i1->nextSibling();
+ }
+}
+
+void KviFileTransferWindow::clearAll()
+{
+ QString tmp;
+
+ bool bHaveAllTerminated = true;
+ KviFileTransferItem * item = (KviFileTransferItem *)m_pListView->firstChild();
+ while(item)
+ {
+ if(!item->transfer()->terminated())
+ {
+ bHaveAllTerminated = false;
+ break;
+ }
+ item = (KviFileTransferItem *)item->nextSibling();
+ }
+
+ 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(KviStr &buffer)
+{
+ buffer.sprintf("FILETRANSFER");
+}
+
+QPixmap * KviFileTransferWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_FILETRANSFER);
+}
+
+void KviFileTransferWindow::resizeEvent(QResizeEvent *e)
+{
+ int h = m_pInput->heightHint();
+ m_pSplitter->setGeometry(0,0,width(),height() - h);
+ m_pInput->setGeometry(0,height() - h,width(),h);
+}
+
+QSize KviFileTransferWindow::sizeHint() const
+{
+ return m_pSplitter->sizeHint();
+}
+
+void KviFileTransferWindow::fillCaptionBuffers()
+{
+ m_szPlainTextCaption = __tr2qs_ctx("File Transfers","filetransferwindow");
+
+ m_szHtmlActiveCaption = "<nobr><font color=\"";
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += "\"><b>";
+ m_szHtmlActiveCaption += m_szPlainTextCaption;
+ m_szHtmlActiveCaption += "</b></font></nobr>";
+
+ m_szHtmlInactiveCaption = "<nobr><font color=\"";
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += "\"><b>";
+ m_szHtmlInactiveCaption += m_szPlainTextCaption;
+ m_szHtmlInactiveCaption += "</b></font></nobr>";
+}
+
+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<int> 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<int> 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();
+}
+
+#include "m_filetransferwindow.moc"
diff --git a/src/modules/filetransferwindow/filetransferwindow.h b/src/modules/filetransferwindow/filetransferwindow.h
new file mode 100644
index 00000000..423dc3a1
--- /dev/null
+++ b/src/modules/filetransferwindow/filetransferwindow.h
@@ -0,0 +1,111 @@
+#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) 1999-2001 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 "kvi_window.h"
+#include "kvi_string.h"
+#include "kvi_ircsocket.h"
+#include "kvi_sparser.h"
+#include "kvi_console.h"
+#include "kvi_moduleextension.h"
+#include "kvi_filetransfer.h"
+#include "kvi_dynamictooltip.h"
+
+#include "kvi_tal_listview.h"
+#include "kvi_tal_popupmenu.h"
+#include <qtoolbutton.h>
+#include <qtimer.h>
+#include <qpixmap.h>
+
+
+
+class KviFileTransferItem : public KviTalListViewItem
+{
+public:
+ KviFileTransferItem(KviTalListView * v,KviFileTransfer * t);
+ ~KviFileTransferItem();
+protected:
+ KviFileTransfer * m_pTransfer;
+public:
+ KviFileTransfer * transfer(){ return m_pTransfer; };
+ virtual void paintCell(QPainter * p,const QColorGroup &cg,int column,int width,int align);
+ virtual void setHeight(int h);
+ virtual QString key(int column,bool bAcending) const;
+};
+
+
+class KviFileTransferWindow : public KviWindow , public KviModuleExtension
+{
+ friend class KviFileTransferItem;
+ Q_OBJECT
+public:
+ KviFileTransferWindow(KviModuleExtensionDescriptor * d,KviFrame * lpFrm);
+ ~KviFileTransferWindow();
+protected:
+ QSplitter * m_pVertSplitter;
+ KviTalListView * m_pListView;
+ KviTalPopupMenu * m_pContextPopup;
+ KviTalPopupMenu * m_pLocalFilePopup;
+ KviTalPopupMenu * m_pOpenFilePopup;
+ QTimer * m_pTimer;
+ QPixmap * m_pMemPixmap;
+ int m_iLineSpacing; // cached fm value
+public: // Methods
+ virtual void die();
+protected:
+ QPixmap * memPixmap(){ return m_pMemPixmap; };
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void applyOptions();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void getBaseLogFileName(KviStr &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(KviTalListViewItem *it,const QPoint &pnt,int col);
+ void doubleClicked(KviTalListViewItem *it,const QPoint &pnt,int col);
+ 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
new file mode 100644
index 00000000..6427e5eb
--- /dev/null
+++ b/src/modules/filetransferwindow/libkvifiletransferwindow.cpp
@@ -0,0 +1,161 @@
+//==================================================================================
+//
+// File : libkvifiletransferwindow.cpp
+// Creation date : Mon Apr 21 2003 23:14:12 CEST by Szymon Stefanek
+//
+// Copyright (C) 2003 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_module.h"
+
+
+#include "filetransferwindow.h"
+
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_window.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+#include <qsplitter.h>
+
+KviFileTransferWindow * g_pFileTransferWindow = 0;
+
+static KviModuleExtension * filetransferwindow_extension_alloc(KviModuleExtensionAllocStruct * s)
+{
+ bool bCreateMinimized = false;
+ bool bNoRaise = false;
+
+ if(!g_pFileTransferWindow)
+ {
+ if(s->pParams)
+ {
+ if(QVariant * v = s->pParams->find("bCreateMinimized"))
+ {
+ if(v->isValid())
+ {
+ if(v->type() == QVariant::Bool)
+ {
+ bCreateMinimized = v->toBool();
+ }
+ }
+ }
+ }
+
+ g_pFileTransferWindow = new KviFileTransferWindow(s->pDescriptor,g_pFrame);
+ g_pFrame->addWindow(g_pFileTransferWindow,!bCreateMinimized);
+ if(bCreateMinimized)g_pFileTransferWindow->minimize();
+ return g_pFileTransferWindow;
+ }
+
+ if(s->pParams)
+ {
+ if(QVariant * v = s->pParams->find("bNoRaise"))
+ {
+ if(v)
+ {
+ if(v->isValid() && v->type() == QVariant::Bool)
+ bNoRaise = v->toBool();
+ }
+ }
+ }
+
+ if(!bNoRaise)g_pFileTransferWindow->delayedAutoRaise();
+ return g_pFileTransferWindow;
+}
+
+
+/*
+ @doc: filetransferwindow.open
+ @type:
+ command
+ @title:
+ filetransferwindow.open
+ @short:
+ Opens the file transfer window
+ @syntax:
+ filetransferwindow.open [-m] [-n]
+ @switches:
+ !sw: -m
+ Causes the window to be created as minimized
+ !sw: -n
+ Causes the window to be not raised if already open
+ @description:
+ Opens the file transfer window
+*/
+
+static bool filetransferwindow_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ KviModuleExtensionDescriptor * d = c->module()->findExtensionDescriptor("tool",KVI_FILE_TRANSFER_WINDOW_EXTENSION_NAME);
+
+ if(d)
+ {
+ KviPointerHashTable<QString,QVariant> dict(17,true);
+ dict.setAutoDelete(true);
+ QString dummy;
+ dict.replace("bCreateMinimized",new QVariant(c->hasSwitch('m',dummy)));
+ dict.replace("bNoRaise",new QVariant(c->hasSwitch('n',dummy)));
+
+ d->allocate(c->window(),&dict,0);
+ } else {
+ c->warning(__tr("Ops.. internal error"));
+ }
+ return true;
+}
+
+static bool filetransferwindow_module_init(KviModule * m)
+{
+ KviModuleExtensionDescriptor * d = m->registerExtension("tool",
+ KVI_FILE_TRANSFER_WINDOW_EXTENSION_NAME,
+ __tr2qs("Manage File &Transfers"),
+ filetransferwindow_extension_alloc);
+
+ if(d)d->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_FILETRANSFER)));
+
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",filetransferwindow_kvs_cmd_open);
+
+
+ return true;
+}
+
+static bool filetransferwindow_module_cleanup(KviModule *m)
+{
+ if(g_pFileTransferWindow)
+ {
+ delete g_pFileTransferWindow;
+ g_pFileTransferWindow = 0;
+ }
+ return true;
+}
+
+static bool filetransferwindow_module_can_unload(KviModule *m)
+{
+ return (!g_pFileTransferWindow);
+}
+
+KVIRC_MODULE(
+ "FileTransferWindow",
+ "1.0.0",
+ "Copyright (C) 2003 Szymon Stefanek (pragma at kvirc dot net)",
+ "Links window extension",
+ filetransferwindow_module_init,
+ filetransferwindow_module_can_unload,
+ 0,
+ filetransferwindow_module_cleanup
+)
diff --git a/src/modules/help/Makefile.am b/src/modules/help/Makefile.am
new file mode 100644
index 00000000..fe6f03f6
--- /dev/null
+++ b/src/modules/help/Makefile.am
@@ -0,0 +1,22 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvihelp.la
+
+libkvihelp_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvihelp_la_SOURCES = libkvihelp.cpp helpwidget.cpp helpwindow.cpp index.cpp index.moc
+libkvihelp_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= helpwidget.h helpwindow.h index.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+helpwidget.cpp: helpwidget.moc
+helpwindow.cpp: helpwindow.moc
+index.cpp: index.moc
diff --git a/src/modules/help/helpwidget.cpp b/src/modules/help/helpwidget.cpp
new file mode 100644
index 00000000..4036a0dd
--- /dev/null
+++ b/src/modules/help/helpwidget.cpp
@@ -0,0 +1,154 @@
+//
+// 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) 1999-2000 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 "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_msgbox.h"
+#include "kvi_module.h"
+#include "kvi_styled_controls.h"
+#include "helpwindow.h"
+#include "kvi_fileutils.h"
+
+#include <qtoolbutton.h>
+#include <qlineedit.h>
+#include <qtooltip.h>
+#include <qtimer.h>
+#include <qclipboard.h>
+
+extern Index * g_pDocIndex;
+extern KviPointerList<KviHelpWindow> * g_pHelpWindowList;
+extern KviPointerList<KviHelpWidget> * g_pHelpWidgetList;
+
+KviHelpWidget::KviHelpWidget(QWidget * par,KviFrame * lpFrm,bool bIsStandalone)
+: QWidget(par,"help_widget")
+{
+
+ if(bIsStandalone)g_pHelpWidgetList->append(this);
+ m_bIsStandalone = bIsStandalone;
+
+//#warning "Re enable this when using Qt 3.0 : QProcess "
+ m_pTextBrowser = new QTextBrowser(this,"text_browser");
+ m_pTextBrowser->setFrameStyle(QFrame::StyledPanel|QFrame::Sunken);
+#ifndef COMPILE_USE_QT4
+ m_pTextBrowser->setFocusPolicy(QWidget::NoFocus);
+#endif
+ m_pToolBar = new KviTalHBox(this);
+
+ m_pBtnIndex = new KviStyledToolButton(m_pToolBar);
+ m_pBtnIndex->setIconSet(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPINDEX));
+ connect(m_pBtnIndex,SIGNAL(clicked()),this,SLOT(showIndex()));
+ //m_pBtnIndex->setUsesBigPixmap(true);
+
+ m_pBtnBackward = new KviStyledToolButton(m_pToolBar);
+ m_pBtnBackward->setIconSet(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPBACK));
+ connect(m_pBtnBackward,SIGNAL(clicked()),m_pTextBrowser,SLOT(backward()));
+ m_pBtnBackward->setEnabled(false);
+ //m_pBtnBackward->setUsesBigPixmap(true);
+
+ m_pBtnForward = new KviStyledToolButton(m_pToolBar);
+ m_pBtnForward->setIconSet(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPFORWARD));
+ connect(m_pBtnForward,SIGNAL(clicked()),m_pTextBrowser,SLOT(forward()));
+ m_pBtnForward->setEnabled(false);
+ //m_pBtnForward->setUsesBigPixmap(true);
+
+ QWidget* pSpacer=new QWidget(m_pToolBar);
+
+ if(bIsStandalone)
+ {
+ QToolButton * b = new KviStyledToolButton(m_pToolBar);
+ b->setIconSet(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPCLOSE));
+ connect(b,SIGNAL(clicked()),this,SLOT(doClose()));
+ //b->setUsesBigPixmap(true);
+ }
+
+ 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)));
+
+ m_pTextBrowser->viewport()->installEventFilter(this);
+
+}
+
+KviHelpWidget::~KviHelpWidget()
+{
+ if(m_bIsStandalone)g_pHelpWidgetList->removeRef(this);
+}
+
+void KviHelpWidget::showIndex()
+{
+#ifdef COMPILE_USE_QT4
+ m_pTextBrowser->setSource(QUrl("index.html"));
+#else
+ m_pTextBrowser->setSource("index.html");
+#endif
+}
+
+void KviHelpWidget::resizeEvent(QResizeEvent *e)
+{
+ 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;
+}
+
+bool KviHelpWidget::eventFilter(QObject * o, QEvent *e)
+{
+ QClipboard *cb = QApplication::clipboard();
+
+ if(e->type() == QEvent::MouseButtonRelease) {
+ if(m_pTextBrowser->hasSelectedText()) {
+ cb->setText(m_pTextBrowser->selectedText());
+ }
+ }
+
+ return QWidget::eventFilter(o,e);
+}
+
+
+
+#include "helpwidget.moc"
diff --git a/src/modules/help/helpwidget.h b/src/modules/help/helpwidget.h
new file mode 100644
index 00000000..e00f8bcf
--- /dev/null
+++ b/src/modules/help/helpwidget.h
@@ -0,0 +1,61 @@
+#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) 1999-2000 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_tal_hbox.h"
+#include <qtextbrowser.h>
+#include "index.h"
+#include <qprogressbar.h>
+
+class KviFrame;
+class QToolButton;
+class QLineEdit;
+//class KviProcess;
+
+class KviHelpWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ KviHelpWidget(QWidget *par,KviFrame * 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);
+ bool eventFilter(QObject *, QEvent *);
+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 00000000..9fc11427
--- /dev/null
+++ b/src/modules/help/helpwindow.cpp
@@ -0,0 +1,329 @@
+//
+// 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) 1999-2000 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 "kvi_app.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_module.h"
+#include "kvi_config.h"
+#include "kvi_styled_controls.h"
+
+#include <qfileinfo.h>
+#include <qsplitter.h>
+#include <qlineedit.h>
+#include <qmessagebox.h>
+#include <qregexp.h>
+#include <qtooltip.h>
+#include "kvi_valuelist.h"
+
+#include "kvi_sourcesdate.h"
+
+extern Index * g_pDocIndex;
+extern KviPointerList<KviHelpWindow> * g_pHelpWindowList;
+extern KviPointerList<KviHelpWidget> * g_pHelpWidgetList;
+
+bool g_bIndexingDone = FALSE;
+KviHelpWindow::KviHelpWindow(KviFrame * lpFrm,const char * name)
+: KviWindow(KVI_WINDOW_TYPE_HELP,lpFrm,name)
+{
+
+ if(!g_bIndexingDone)
+ {
+ QString szDoclist,szDict;
+
+ g_pApp->getLocalKvircDirectory(szDoclist,KviApp::Help,"help.doclist." KVI_SOURCES_DATE);
+ g_pApp->getLocalKvircDirectory(szDict,KviApp::Help,"help.dict." KVI_SOURCES_DATE);
+
+ if ( QFileInfo( szDoclist ).exists() && QFileInfo( szDict ).exists() ) {
+ g_pDocIndex->readDict();
+ } else {
+#ifdef COMPILE_USE_QT4
+ QProgressDialog* pProgressDialog = new QProgressDialog( __tr2qs("Indexing help files"), __tr2qs("Cancel"), 0,100 );
+#else
+ QProgressDialog* pProgressDialog = new QProgressDialog( __tr2qs("Indexing help files"), __tr2qs("Cancel"), 100 );
+#endif
+ connect(g_pDocIndex,SIGNAL(indexingProgress(int)), pProgressDialog, SLOT(setProgress(int)) );
+ g_pDocIndex->makeIndex();
+ g_pDocIndex->writeDict();
+ g_pDocIndex->writeDocumentList();
+ delete pProgressDialog;
+ }
+ g_bIndexingDone=TRUE;
+ }
+
+ g_pHelpWindowList->append(this);
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"main_splitter");
+ m_pHelpWidget = new KviHelpWidget(m_pSplitter,lpFrm);
+
+ m_pToolBar=new KviTalVBox(m_pSplitter);
+
+ m_pTabWidget = new QTabWidget(m_pToolBar);
+
+ m_pIndexTab = new KviTalVBox(m_pTabWidget);
+ m_pTabWidget->insertTab(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() ) );
+
+ KviStyledToolButton* pBtnRefreshIndex = new KviStyledToolButton(pSearchBox);
+ pBtnRefreshIndex->setIconSet(*g_pIconManager->getBigIcon(KVI_REFRESH_IMAGE_NAME));
+ connect(pBtnRefreshIndex,SIGNAL(clicked()),this,SLOT(refreshIndex()));
+ QToolTip::add( pBtnRefreshIndex, __tr2qs("Refresh index") );
+
+ m_pIndexListBox = new KviTalListBox(m_pIndexTab);
+ QStringList docList=g_pDocIndex->titlesList();
+ m_pIndexListBox->insertStringList(docList);
+ connect(m_pIndexListBox,SIGNAL(selected(int)),this,SLOT(indexSelected ( int )));
+ m_pIndexListBox->sort();
+
+ m_pSearchTab = new KviTalVBox(m_pTabWidget);
+ m_pTabWidget->insertTab(m_pSearchTab,__tr2qs("Search"));
+
+ m_pTermsEdit = new QLineEdit(m_pSearchTab);
+/* connect( m_pTermsEdit, SIGNAL( textChanged(const QString&) ),
+ this, SLOT( searchInIndex(const QString&) ) );*/
+ connect( m_pTermsEdit, SIGNAL( returnPressed() ),
+ this, SLOT( startSearch() ) );
+
+ m_pResultBox = new KviTalListBox(m_pSearchTab);
+ connect(m_pResultBox,SIGNAL(selected(int)),this,SLOT(searchSelected ( int )));
+
+ KviValueList<int> li;
+ li.append(width()-80);
+ li.append(80);
+ m_pSplitter->setSizes(li);
+
+}
+
+KviHelpWindow::~KviHelpWindow()
+{
+ g_pHelpWindowList->removeRef(this);
+}
+
+void KviHelpWindow::saveProperties(KviConfig *cfg)
+{
+ KviWindow::saveProperties(cfg);
+ cfg->writeEntry("Splitter",m_pSplitter->sizes());
+}
+
+void KviHelpWindow::loadProperties(KviConfig *cfg)
+{
+ KviValueList<int> 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()
+{
+ m_pIndexListBox->clear();
+#ifdef COMPILE_USE_QT4
+ QProgressDialog* pProgressDialog = new QProgressDialog( __tr2qs("Indexing help files"), __tr2qs("Cancel"), 0,100 );
+#else
+ QProgressDialog* pProgressDialog = new QProgressDialog( __tr2qs("Indexing help files"), __tr2qs("Cancel"), 100 );
+#endif
+ connect(g_pDocIndex,SIGNAL(indexingProgress(int)), pProgressDialog, SLOT(setProgress(int)) );
+ g_pDocIndex->makeIndex();
+ g_pDocIndex->writeDict();
+ g_pDocIndex->writeDocumentList();
+ delete pProgressDialog;
+ g_bIndexingDone=TRUE;
+ QStringList docList=g_pDocIndex->titlesList();
+ m_pIndexListBox->insertStringList(docList);
+ m_pIndexListBox->sort();
+}
+
+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 = QStringList::split( " ", str );
+ QStringList termSeq;
+ QStringList seqWords;
+ QStringList::iterator it = m_terms.begin();
+ for ( ; it != m_terms.end(); ++it ) {
+ (*it) = (*it).simplifyWhiteSpace();
+ (*it) = (*it).lower();
+ (*it) = (*it).replace( "\"", "" );
+ }
+ if ( str.contains( '\"' ) ) {
+#ifdef COMPILE_USE_QT4
+ if ( (str.count( '\"' ))%2 == 0 ) {
+#else
+ if ( (str.contains( '\"' ))%2 == 0 ) {
+#endif
+ int beg = 0;
+ int end = 0;
+ QString s;
+ beg = str.find( '\"', beg );
+ while ( beg != -1 ) {
+ beg++;
+ end = str.find( '\"', beg );
+ s = str.mid( beg, end - beg );
+ s = s.lower();
+ s = s.simplifyWhiteSpace();
+ if ( s.contains( '*' ) ) {
+ QMessageBox::warning( this, tr( "Full Text Search" ),
+ tr( "Using a wildcard within phrases is not allowed." ) );
+ return;
+ }
+ seqWords += QStringList::split( ' ', s );
+ termSeq << s;
+ beg = str.find( '\"', end + 1);
+ }
+ } else {
+ QMessageBox::warning( this, tr( "Full Text Search" ),
+ tr( "The closing quotation mark is missing." ) );
+ return;
+ }
+ }
+#ifdef COMPILE_USE_QT4
+ setCursor( Qt::WaitCursor );
+#else
+ setCursor( waitCursor );
+#endif
+ 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->insertItem( 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.simplifyWhiteSpace();
+ if ( !s.isEmpty() )
+ m_terms << s;
+ s = "";
+ } else if ( buf[i] == ' ' && !isPhrase ) {
+ s = s.simplifyWhiteSpace();
+ if ( !s.isEmpty() )
+ m_terms << s;
+ s = "";
+ } else
+ s += buf[i];
+ }
+ if ( !s.isEmpty() )
+ m_terms << s;
+
+#ifdef COMPILE_USE_QT4
+ setCursor( Qt::ArrowCursor );
+#else
+ setCursor( arrowCursor );
+#endif
+}
+
+QTextBrowser * KviHelpWindow::textBrowser()
+{
+ return m_pHelpWidget->textBrowser();
+}
+
+void KviHelpWindow::showIndexTopic()
+{
+ if (m_pIndexSearch->text().isEmpty()|| !m_pIndexListBox->selectedItem()) return;
+ int i=g_pDocIndex->titlesList().findIndex(m_pIndexListBox->selectedItem()->text());
+ textBrowser()->setSource(g_pDocIndex->documentList()[ i ]);
+}
+
+void KviHelpWindow::searchInIndex( const QString &s )
+{
+ KviTalListBoxItem *i = m_pIndexListBox->firstItem();
+ QString sl = s.lower();
+ while ( i ) {
+ QString t = i->text();
+ if ( t.length() >= sl.length() &&
+ i->text().left(s.length()).lower() == sl ) {
+ m_pIndexListBox->setCurrentItem( i );
+ m_pIndexListBox->setTopItem(m_pIndexListBox->index(i));
+ break;
+ }
+ i = i->next();
+ }
+}
+
+void KviHelpWindow::indexSelected ( int index )
+{
+ int i=g_pDocIndex->titlesList().findIndex(m_pIndexListBox->text(index));
+ textBrowser()->setSource(g_pDocIndex->documentList()[ i ]);
+}
+
+void KviHelpWindow::searchSelected ( int index )
+{
+ int i=g_pDocIndex->titlesList().findIndex(m_pResultBox->text(index));
+ textBrowser()->setSource(g_pDocIndex->documentList()[ i ]);
+}
+
+QPixmap * KviHelpWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_MDIHELP);
+}
+
+void KviHelpWindow::resizeEvent(QResizeEvent *e)
+{
+ m_pSplitter->setGeometry(0,0,width(),height());
+}
+
+QSize KviHelpWindow::sizeHint() const
+{
+ return m_pHelpWidget->sizeHint();
+}
+void KviHelpWindow::fillCaptionBuffers()
+{
+ m_szPlainTextCaption = __tr2qs("Help Browser");
+
+ m_szHtmlActiveCaption = "<nobr><font color=\"";
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += "\"><b>";
+ m_szHtmlActiveCaption += m_szPlainTextCaption;
+ m_szHtmlActiveCaption += "</b></font></nobr>";
+
+
+ m_szHtmlInactiveCaption = "<nobr><font color=\"";
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += "\"><b>";
+ m_szHtmlInactiveCaption += m_szPlainTextCaption;
+ m_szHtmlInactiveCaption += "</b></font></nobr>";
+}
+
+
+#include "helpwindow.moc"
diff --git a/src/modules/help/helpwindow.h b/src/modules/help/helpwindow.h
new file mode 100644
index 00000000..70f27af6
--- /dev/null
+++ b/src/modules/help/helpwindow.h
@@ -0,0 +1,75 @@
+#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) 1999-2000 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_window.h"
+#include "kvi_string.h"
+#include "kvi_tal_vbox.h"
+#include <qtabwidget.h>
+#include "kvi_tal_listbox.h"
+#include <qlineedit.h>
+#include <qprogressdialog.h>
+
+class KviHelpWidget;
+class QTextBrowser;
+
+class KviHelpWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviHelpWindow(KviFrame * lpFrm,const char * name);
+ ~KviHelpWindow();
+protected:
+ KviHelpWidget * m_pHelpWidget;
+ KviTalVBox * m_pToolBar;
+ QTabWidget * m_pTabWidget;
+ KviTalVBox * m_pIndexTab;
+ KviTalVBox * m_pSearchTab;
+
+ KviTalListBox * m_pIndexListBox;
+ QLineEdit * m_pIndexSearch;
+ QStringList m_foundDocs;
+ QStringList m_terms;
+ KviTalListBox * m_pResultBox;
+ QLineEdit * m_pTermsEdit;
+public:
+ KviHelpWidget * helpWidget(){ return m_pHelpWidget; };
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void saveProperties(KviConfig * cfg);
+ virtual void loadProperties(KviConfig * cfg);
+public:
+ virtual QSize sizeHint() const;
+ QTextBrowser * textBrowser();
+public slots:
+ void indexSelected ( int );
+ void searchInIndex( const QString &s );
+ void showIndexTopic();
+ void startSearch();
+ void searchSelected ( int index );
+ void refreshIndex();
+};
+
+#endif //_KVI_HELPWINDOW_H_
diff --git a/src/modules/help/index.cpp b/src/modules/help/index.cpp
new file mode 100755
index 00000000..659ff44c
--- /dev/null
+++ b/src/modules/help/index.cpp
@@ -0,0 +1,854 @@
+#include "index.h"
+
+#include "kvi_file.h"
+#include <qdir.h>
+#include <qstringlist.h>
+#include "kvi_pointerhashtable.h"
+#include <qapplication.h>
+#include <qtextstream.h>
+#include <ctype.h>
+
+
+int kvi_compare(const Term * p1,const Term * p2)
+{
+ if(p1->frequency == p2->frequency)
+ return 0;
+ if(p1->frequency < p2->frequency)
+ return -1;
+ return 1;
+}
+
+QDataStream &operator>>( QDataStream &s, Document &l )
+{
+ s >> l.docNumber;
+ s >> l.frequency;
+ return s;
+}
+
+QDataStream &operator<<( QDataStream &s, const Document &l )
+{
+ s << (Q_INT16)l.docNumber;
+ s << (Q_INT16)l.frequency;
+ return s;
+}
+
+Index::Index( const QString &dp, const QString &hp )
+
+ : QObject( 0, 0 ), dict( 8999 ), docPath( dp )
+
+{
+ alreadyHaveDocList = FALSE;
+ lastWindowClosed = FALSE;
+ connect( qApp, SIGNAL( lastWindowClosed() ),
+ this, SLOT( setLastWinClosed() ) );
+}
+
+
+
+Index::Index( const QStringList &dl, const QString &hp )
+
+ : QObject( 0, 0 ), dict( 8999 )
+
+{
+ 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;
+}
+
+
+
+int Index::makeIndex()
+{
+ if ( !alreadyHaveDocList )
+ setupDocumentList();
+ if ( docList.isEmpty() )
+ return 1;
+ dict.clear();
+ QStringList::Iterator it = docList.begin();
+ int steps = docList.count() / 100;
+ if ( !steps )
+ steps++;
+ int prog = 0;
+ for ( int i = 0; it != docList.end(); ++it, ++i ) {
+ if ( lastWindowClosed ) {
+ return -1;
+ }
+ parseDocument( *it, i );
+ if ( i%steps == 0 ) {
+ prog++;
+ emit indexingProgress( prog );
+ }
+ }
+ return 0;
+}
+
+
+
+void Index::setupDocumentList()
+
+{
+ docList.clear();
+ titleList.clear();
+ QDir d( docPath );
+ QString szCur;
+ QStringList lst = d.entryList( "*.html" );
+ QStringList::ConstIterator it = lst.begin();
+ for ( ; it != lst.end(); ++it )
+ {
+ szCur=docPath + "/" + *it;
+ docList.append( szCur );
+ titleList.append(getDocumentTitle( szCur ));
+ }
+}
+
+
+
+void Index::insertInDict( const QString &str, int docNum )
+{
+ if ( strcmp( str, "amp" ) == 0 || strcmp( str, "nbsp" ) == 0 )
+ return;
+ Entry *e = 0;
+ if ( dict.count() )
+ e = dict[ str ];
+
+ if ( e ) {
+ if ( e->documents.first().docNumber != docNum )
+ e->documents.prepend( Document( docNum, 1 ) );
+ else
+ e->documents.first().frequency++;
+ } else {
+ dict.insert( str, new Entry( docNum ) );
+ }
+}
+
+
+
+void Index::parseDocument( const QString &filename, int docNum )
+{
+ KviFile file( filename );
+ if ( !file.openForReading() ) {
+ qWarning( "can not open file " + filename );
+ return;
+ }
+ QTextStream s( &file );
+ QString text = s.read();
+ 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 ( (uint)j < text.length() ) {
+ if ( c == '<' || c == '&' ) {
+ valid = FALSE;
+ if ( i > 1 )
+ insertInDict( QString(str,i), docNum );
+ i = 0;
+ c = buf[++j];
+ continue;
+ }
+ if ( ( c == '>' || c == ';' ) && !valid ) {
+ valid = TRUE;
+ c = buf[++j];
+ continue;
+ }
+
+ if ( !valid ) {
+
+ c = buf[++j];
+
+ continue;
+
+ }
+
+ if ( ( c.isLetterOrNumber() || c == '_' ) && i < 63 ) {
+
+ str[i] = c.lower();
+
+ ++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()
+
+{
+
+ KviPointerHashTableIterator<QString,Entry> it( dict );
+
+ KviFile f( dictFile );
+
+ if ( !f.openForWriting() )
+
+ return;
+
+ QDataStream s( &f );
+
+ for( ; it.current(); ++it ) {
+
+ Entry *e = it.current();
+
+ s << it.currentKey();
+
+ s << e->documents;
+
+ }
+
+ f.close();
+
+ writeDocumentList();
+
+}
+
+
+
+void Index::writeDocumentList()
+
+{
+ KviFile f( docListFile );
+ if ( !f.openForWriting() )
+ return;
+ QTextStream s( &f );
+ QString docs = docList.join("[#item#]");
+ s << docs;
+
+ KviFile f1( docListFile+".titles" );
+ if ( !f1.openForWriting() )
+ return;
+ QTextStream s1( &f1 );
+ docs = titleList.join("[#item#]");
+ s1 << docs;
+}
+
+
+
+void Index::readDict()
+
+{
+ KviFile f( dictFile );
+ if ( !f.openForReading() )
+ return;
+ dict.clear();
+ QDataStream s( &f );
+ QString key;
+ KviValueList<Document> docs;
+ while ( !s.atEnd() ) {
+ s >> key;
+ s >> docs;
+ dict.insert( key, new Entry( docs ) );
+ }
+ f.close();
+ readDocumentList();
+}
+
+
+
+void Index::readDocumentList()
+{
+ //reading docs
+ KviFile f( docListFile );
+ if ( !f.openForReading() )
+ return;
+ QTextStream s( &f );
+ docList = QStringList::split("[#item#]",s.read());
+
+ //reading titles
+ KviFile f1( docListFile+".titles" );
+ if ( !f1.openForReading() )
+ return;
+ QTextStream s1( &f1 );
+ titleList = QStringList::split("[#item#]",s1.read());
+// debug(titleList);
+}
+
+
+
+QStringList Index::query( const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords )
+
+{
+
+ TermList termList;
+
+
+
+ QStringList::ConstIterator it = terms.begin();
+
+ for ( it = terms.begin(); it != terms.end(); ++it ) {
+
+ Entry *e = 0;
+
+ if ( (*it).contains( '*' ) ) {
+
+ KviValueList<Document> wcts = setupDummyTerm( getWildcardTerms( *it ) );
+
+ termList.append( new Term( "dummy", wcts.count(), wcts ) );
+
+ } else if ( dict[ *it ] ) {
+
+ e = dict[ *it ];
+
+ termList.append( new Term( *it, e->documents.count(), e->documents ) );
+
+ } else {
+
+ return QStringList();
+
+ }
+
+ }
+
+ termList.sort();
+
+
+
+ Term *minTerm = termList.first();
+
+ if ( !termList.count() )
+
+ return QStringList();
+
+ termList.removeFirst();
+
+
+
+ KviValueList<Document> minDocs = minTerm->documents;
+
+ KviValueList<Document>::iterator C;
+
+ KviValueList<Document>::ConstIterator It;
+
+ Term *t = termList.first();
+
+ for ( ; t; t = termList.next() ) {
+
+ KviValueList<Document> docs = t->documents;
+
+ C = minDocs.begin();
+
+ while ( C != minDocs.end() ) {
+
+ bool found = FALSE;
+
+ for ( It = docs.begin(); It != docs.end(); ++It ) {
+
+ if ( (*C).docNumber == (*It).docNumber ) {
+
+ (*C).frequency += (*It).frequency;
+
+ found = TRUE;
+
+ break;
+
+ }
+
+ }
+
+ if ( !found )
+
+ C = minDocs.remove( C );
+
+ else
+
+ ++C;
+
+ }
+
+ }
+
+
+
+ QStringList results;
+
+#ifndef COMPILE_USE_QT4
+ qHeapSort( minDocs );
+#endif
+ if ( termSeq.isEmpty() ) {
+
+ for ( C = minDocs.begin(); C != minDocs.end(); ++C )
+
+ results << docList[ (int)(*C).docNumber ];
+
+ return results;
+
+ }
+
+
+
+ QString fileName;
+
+ for ( C = minDocs.begin(); C != minDocs.end(); ++C ) {
+
+ fileName = docList[ (int)(*C).docNumber ];
+
+ if ( searchForPattern( termSeq, seqWords, fileName ) )
+
+ results << fileName;
+
+ }
+
+ return results;
+
+}
+
+
+
+QString Index::getDocumentTitle( const QString &fileName )
+
+{
+
+ KviFile file( fileName );
+
+ if ( !file.openForReading() ) {
+
+ qWarning( "cannot open file " + fileName );
+
+ return fileName;
+
+ }
+
+ QTextStream s( &file );
+
+ QString text = s.read();
+
+
+
+ int start = text.find( "<title>", 0, FALSE ) + 7;
+
+ int end = text.find( "</title>", 0, FALSE );
+
+
+
+ QString title = ( end - start <= 0 ? tr("Untitled") : text.mid( start, end - start ) );
+
+ return title;
+
+}
+
+
+
+QStringList Index::getWildcardTerms( const QString &term )
+
+{
+
+ QStringList lst;
+
+ QStringList terms = split( term );
+
+#ifdef COMPILE_USE_QT4
+ QStringList::Iterator iter;
+#else
+ KviValueList<QString>::iterator iter;
+#endif
+
+
+ KviPointerHashTableIterator<QString,Entry> it( dict );
+
+ for( ; it.current(); ++it ) {
+
+ int index = 0;
+
+ bool found = FALSE;
+
+ QString text( it.currentKey() );
+
+ for ( iter = terms.begin(); iter != terms.end(); ++iter ) {
+
+ if ( *iter == "*" ) {
+
+ found = TRUE;
+
+ continue;
+
+ }
+
+ if ( iter == terms.begin() && (*iter)[0] != text[0] ) {
+
+ found = FALSE;
+
+ break;
+
+ }
+
+ index = text.find( *iter, index );
+
+ if ( *iter == terms.last() && index != (int)text.length()-1 ) {
+
+ index = text.findRev( *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.find( '*', j );
+
+
+
+ while ( i != -1 ) {
+
+ if ( i > j && i <= (int)str.length() ) {
+
+ lst << str.mid( j, i - j );
+
+ lst << "*";
+
+ }
+
+ j = i + 1;
+
+ i = str.find( '*', j );
+
+ }
+
+
+
+ int l = str.length() - 1;
+
+ if ( str.mid( j, l - j + 1 ).length() > 0 )
+
+ lst << str.mid( j, l - j + 1 );
+
+
+
+ return lst;
+
+}
+
+
+
+KviValueList<Document> Index::setupDummyTerm( const QStringList &terms )
+
+{
+
+ TermList termList;
+
+ QStringList::ConstIterator it = terms.begin();
+
+ for ( ; it != terms.end(); ++it ) {
+
+ Entry *e = 0;
+
+ if ( dict[ *it ] ) {
+
+ e = dict[ *it ];
+
+ termList.append( new Term( *it, e->documents.count(), e->documents ) );
+
+ }
+
+ }
+
+ termList.sort();
+
+
+
+ KviValueList<Document> maxList;
+
+
+
+ if ( !termList.count() )
+
+ return maxList;
+
+ maxList = termList.last()->documents;
+
+ termList.removeLast();
+
+
+
+ KviValueList<Document>::iterator docIt;
+
+ Term *t = termList.first();
+
+ while ( t ) {
+
+ KviValueList<Document> docs = t->documents;
+
+ for ( docIt = docs.begin(); docIt != docs.end(); ++docIt ) {
+
+ if ( maxList.findIndex( *docIt ) == -1 )
+
+ maxList.append( *docIt );
+
+ }
+
+ t = termList.next();
+
+ }
+
+ 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 )
+
+{
+
+ KviFile file( fileName );
+
+ if ( !file.openForReading() ) {
+
+ qWarning( "cannot open file " + fileName );
+
+ 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.read();
+
+ bool valid = TRUE;
+
+ const QChar *buf = text.unicode();
+
+ QChar str[64];
+
+ QChar c = buf[0];
+
+ int j = 0;
+
+ int i = 0;
+
+ while ( (uint)j < text.length() ) {
+
+ if ( c == '<' || c == '&' ) {
+
+ valid = FALSE;
+
+ if ( i > 1 )
+
+ buildMiniDict( QString(str,i) );
+
+ i = 0;
+
+ c = buf[++j];
+
+ continue;
+
+ }
+
+ if ( ( c == '>' || c == ';' ) && !valid ) {
+
+ valid = TRUE;
+
+ c = buf[++j];
+
+ continue;
+
+ }
+
+ if ( !valid ) {
+
+ c = buf[++j];
+
+ continue;
+
+ }
+
+ if ( ( c.isLetterOrNumber() || c == '_' ) && i < 63 ) {
+
+ str[i] = c.lower();
+
+ ++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;
+
+ KviValueList<uint> a, b;
+
+ KviValueList<uint>::iterator aIt;
+
+ for ( ; patIt != patterns.end(); ++patIt ) {
+
+ wordLst = QStringList::split( ' ', *patIt );
+
+ 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.find( *aIt + 1 ) != b.end() ) {
+
+ (*aIt)++;
+
+ ++aIt;
+
+ } else {
+
+ aIt = a.remove( aIt );
+
+ }
+
+ }
+
+ }
+
+ }
+
+ if ( a.count() )
+
+ return TRUE;
+
+ return FALSE;
+
+}
+
+
+
+#include "index.moc" \ No newline at end of file
diff --git a/src/modules/help/index.h b/src/modules/help/index.h
new file mode 100755
index 00000000..9debcb3e
--- /dev/null
+++ b/src/modules/help/index.h
@@ -0,0 +1,124 @@
+/**********************************************************************
+** Copyright (C) 2000-2003 Trolltech AS. All rights reserved.
+**
+** This file is part of the Qt Assistant.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+
+#ifndef INDEX_H
+#define INDEX_H
+
+#include <qstringlist.h>
+#include "kvi_pointerhashtable.h"
+#include "kvi_pointerlist.h"
+#include "kvi_valuelist.h"
+#include <qdatastream.h>
+#include <qobject.h>
+
+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;
+ }
+ Q_INT16 docNumber;
+ Q_INT16 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( KviValueList<Document> l ) : documents( l ) {}
+ KviValueList<Document> documents;
+ };
+ struct PosEntry {
+ PosEntry( int p ) { positions.append( p ); }
+ KviValueList<uint> positions;
+ };
+ Index( const QString &dp, const QString &hp );
+ Index( const QStringList &dl, const QString &hp );
+ void writeDict();
+ void readDict();
+ int makeIndex();
+ QStringList query( const QStringList&, const QStringList&, const QStringList& );
+ QString getDocumentTitle( const QString& );
+ void setDictionaryFile( const QString& );
+ void setDocListFile( const QString& );
+ void writeDocumentList();
+ void readDocumentList();
+ void setupDocumentList();
+ const QStringList& documentList() { return docList; };
+ const QStringList& titlesList() { return titleList; };
+signals:
+ void indexingProgress( int );
+private slots:
+ void setLastWinClosed();
+private:
+ void parseDocument( const QString&, int );
+ void insertInDict( const QString&, int );
+ QStringList getWildcardTerms( const QString& );
+ QStringList split( const QString& );
+ KviValueList<Document> setupDummyTerm( const QStringList& );
+ bool searchForPattern( const QStringList&, const QStringList&, const QString& );
+ void buildMiniDict( const QString& );
+ QStringList docList;
+ QStringList titleList;
+ KviPointerHashTable<QString,Entry> dict;
+ KviPointerHashTable<QString,PosEntry> miniDict;
+ uint wordNum;
+ QString docPath;
+ QString dictFile, docListFile;
+ bool alreadyHaveDocList;
+ bool lastWindowClosed;
+};
+
+struct Term {
+ Term( const QString &t, int f, KviValueList<Document> l )
+ : term( t ), frequency( f ), documents( l ) {}
+ QString term;
+ int frequency;
+ KviValueList<Document>documents;
+};
+
+
+
+#define TermList KviPointerList<Term>
+
+#endif
+
diff --git a/src/modules/help/libkvihelp.cpp b/src/modules/help/libkvihelp.cpp
new file mode 100644
index 00000000..c8da3c33
--- /dev/null
+++ b/src/modules/help/libkvihelp.cpp
@@ -0,0 +1,236 @@
+//
+// File : libkvihelp.cpp
+// Creation date : Sun Aug 13 2000 03:00:00 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 "libkvihelp.h"
+
+#include "kvi_module.h"
+
+#include "kvi_sourcesdate.h"
+
+#include "helpwidget.h"
+#include "helpwindow.h"
+#include "index.h"
+#include "kvi_app.h"
+
+#include "kvi_frame.h"
+
+#ifdef COMPILE_USE_QT4
+ #include <q3mimefactory.h>
+#endif
+
+
+#include <qsplitter.h>
+Index * g_pDocIndex = 0;
+KviPointerList<KviHelpWidget> * g_pHelpWidgetList = 0;
+KviPointerList<KviHelpWindow> * g_pHelpWindowList = 0;
+
+/*
+ @doc: help.search
+ @type:
+ command
+ @title:
+ help.search
+ @short:
+ Searches the documentation
+ @syntax:
+ help.search [-n] [-m] <key terms>
+ @description:
+ Finds the first available help browser in the current frame
+ then searches the documentation for the specified <key terms>.
+ If no help browser is available it creates one first:
+ if the -m switch is present, the created browser is a MDI window,
+ otherwise it is a static window.
+ If the -n switch is present, the window creation is forced even
+ if there are other help browsers already open.[br]
+ The <key terms> are [b]space separated words[/b]
+ to be matched inside the document body (logical AND).[br]
+ This command is exported by the "help" module.
+*/
+
+/*tatic bool help_module_cmd_search(KviModule *m,KviCommand *c)
+{
+ ENTER_STACK_FRAME(c,"help_module_cmd_search");
+
+ KviStr keys;
+ if(!g_pZZZZZZUserParser->parseCmdFinalPart(c,keys))return false;
+
+ if(keys.isEmpty())keys = "kvirc";
+
+ if(!c->hasSwitch('n'))
+ {
+ // look for an already open help widget in this frame
+ KviHelpWidget * w = (KviHelpWidget *)c->window()->frame()->child(
+ "help_widget","KviHelpWidget");
+
+ if(w)
+ {
+ w->doExactSearchFor(keys.ptr());
+ return c->leaveStackFrame();
+ }
+ }
+
+ if(c->hasSwitch('m'))
+ {
+ KviHelpWindow *w = new KviHelpWindow(c->window()->frame(),"Help browser");
+ w->helpWidget()->doExactSearchFor(keys.ptr());
+ c->window()->frame()->addWindow(w);
+ } else {
+ KviHelpWidget *w = new KviHelpWidget(c->window()->frame()->splitter(),
+ c->window()->frame(),true);
+ w->doExactSearchFor(keys.ptr());
+ w->show();
+ }
+
+ return c->leaveStackFrame();
+}*/
+/*
+#ifdef COMPILE_NEW_KVS
+static bool help_kvs_cmd_search(KviKvsModuleCommandCall * c)
+{
+}
+#endif
+*/
+/*
+ @doc: help.open
+ @type:
+ command
+ @title:
+ help.open
+ @short:
+ Shows a help document
+ @syntax:
+ help.open [-n] [-m] [document: string]
+ @description:
+ Finds the first available help browser in the current frame
+ then opens the specified [document].
+ If no [document] is specified it the documentation index is shown.
+ If no help browser is available , a new one is created.
+ [document] can be an absolute path or a relative one: in this case
+ the document is searched in the KVIrc documentation directory.[br]
+ The help browser has limited html browsing capabilities: you can
+ use it to view simple html files on your filesystem.[br]
+ This command is exported by the "help" module.
+ @switches:
+ !sw: -m | --mdi
+ The created browser is a MDI window,
+ otherwise it is a static window.
+ !sw: -n | --new
+ The window creation is forced even
+ if there are other help browsers already open.[br]
+*/
+
+
+static bool help_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ QString doc;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("document",KVS_PT_STRING,KVS_PF_OPTIONAL,doc)
+ KVSM_PARAMETERS_END(c)
+ if(doc.isEmpty())doc = "index.html";
+#ifdef COMPILE_USE_QT4
+ Q3MimeSourceFactory * f = Q3MimeSourceFactory::defaultFactory();
+#else
+ QMimeSourceFactory * f = QMimeSourceFactory::defaultFactory();
+#endif
+ if(f)
+ {
+ if(!f->data(doc))
+ doc = "nohelpavailable.html";
+ }
+
+ if(!c->switches()->find('n',"new"))
+ {
+ KviHelpWidget * w = (KviHelpWidget *)c->window()->frame()->child("help_widget","KviHelpWidget");
+ if(w)
+ {
+ w->textBrowser()->setSource(doc);
+ return true;
+ }
+ }
+ if(c->switches()->find('m',"mdi"))
+ {
+ KviHelpWindow *w = new KviHelpWindow(c->window()->frame(),"Help browser");
+ w->textBrowser()->setSource(doc);
+ c->window()->frame()->addWindow(w);
+ } else {
+ KviHelpWidget *w = new KviHelpWidget(c->window()->frame()->splitter(),
+ c->window()->frame(),true);
+ w->textBrowser()->setSource(doc);
+ w->show();
+ //debug ("mostro");
+ }
+ return true;
+}
+
+
+
+static bool help_module_init(KviModule * m)
+{
+ QString szHelpDir,szDocList;
+
+ g_pApp->getLocalKvircDirectory(szDocList,KviApp::Help,"help.doclist." KVI_SOURCES_DATE);
+ g_pApp->getGlobalKvircDirectory(szHelpDir,KviApp::Help);
+
+ g_pDocIndex = new Index(szHelpDir,szDocList);
+ g_pDocIndex->setDocListFile(szDocList);
+
+ g_pApp->getLocalKvircDirectory(szHelpDir,KviApp::Help,"help.dict." KVI_SOURCES_DATE);
+ g_pDocIndex->setDictionaryFile(szHelpDir);
+
+ g_pHelpWidgetList = new KviPointerList<KviHelpWidget>;
+ g_pHelpWidgetList->setAutoDelete(false);
+ g_pHelpWindowList = new KviPointerList<KviHelpWindow>;
+ g_pHelpWindowList->setAutoDelete(false);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",help_kvs_cmd_open);
+
+
+ return true;
+}
+
+static bool help_module_cleanup(KviModule *m)
+{
+ if(g_pDocIndex) delete g_pDocIndex;
+ while(g_pHelpWidgetList->first())delete g_pHelpWidgetList->first();
+ delete g_pHelpWidgetList;
+ g_pHelpWidgetList = 0;
+ while(g_pHelpWindowList->first())g_pHelpWindowList->first()->close();
+ delete g_pHelpWindowList;
+ g_pHelpWindowList = 0;
+ return true;
+}
+
+static bool help_module_can_unload(KviModule *m)
+{
+ return (g_pHelpWidgetList->isEmpty() && g_pHelpWindowList->isEmpty());
+}
+
+KVIRC_MODULE(
+ "Help", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Help browser extension",
+ help_module_init,
+ help_module_can_unload,
+ 0,
+ help_module_cleanup
+)
diff --git a/src/modules/http/Makefile.am b/src/modules/http/Makefile.am
new file mode 100644
index 00000000..ab7fe3b2
--- /dev/null
+++ b/src/modules/http/Makefile.am
@@ -0,0 +1,26 @@
+###############################################################################
+# KVirc IRC client Makefile - 31.01.2002 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir=$(picsdir)
+
+tmp_DATA=kvi_httpicons.png
+
+EXTRA_DIST=kvi_httpicons.png
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvihttp.la
+
+libkvihttp_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvihttp_la_SOURCES = libkvihttp.cpp httpfiletransfer.cpp
+libkvihttp_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= httpfiletransfer.h
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+httpfiletransfer.cpp: m_httpfiletransfer.moc
diff --git a/src/modules/http/httpfiletransfer.cpp b/src/modules/http/httpfiletransfer.cpp
new file mode 100644
index 00000000..09c3b1f9
--- /dev/null
+++ b/src/modules/http/httpfiletransfer.cpp
@@ -0,0 +1,489 @@
+//==================================================================================
+//
+// 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 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 "kvi_app.h"
+#include "kvi_out.h"
+#include "kvi_locale.h"
+#include "kvi_window.h"
+#include "kvi_iconmanager.h"
+#include "kvi_netutils.h"
+#include "kvi_kvs_eventtriggers.h"
+#include "kvi_console.h"
+
+#include "kvi_kvs_script.h"
+
+#include "kvi_tal_popupmenu.h"
+#include <qpainter.h>
+
+static KviPointerList<KviHttpFileTransfer> * 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<const char *,KviStr> *)),this,SLOT(headersReceived(KviPointerHashTable<const char *,KviStr> *)));
+ 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()
+{
+ die();
+}
+
+void KviHttpFileTransfer::die()
+{
+ delete this;
+}
+
+QString KviHttpFileTransfer::localFileName()
+{
+ return m_pHttpRequest->fileName();
+}
+
+void KviHttpFileTransfer::abort()
+{
+ m_pHttpRequest->abort();
+}
+
+void KviHttpFileTransfer::fillContextPopup(KviTalPopupMenu * m,int column)
+{
+ 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,int width,int height)
+{
+ QString txt;
+ bool bIsTerminated = ((m_eGeneralStatus == Success) || (m_eGeneralStatus == Failure));
+
+ switch(column)
+ {
+ case COLUMN_TRANSFERTYPE:
+ {
+ int offset = 0;
+ switch(m_eGeneralStatus)
+ {
+ case Initializing: offset = 0; break;
+ case Connecting: offset = 0; break;
+ case Downloading: offset = 48; break;
+ case Success: offset = 96; break;
+ case Failure: offset = 144; break;
+ }
+ p->drawPixmap(3,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 = 4;
+
+ p->drawText(4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,m_pHttpRequest->url().url().ptr());
+ iY += iLineSpacing;
+ if(!(m_pHttpRequest->fileName().isEmpty()))
+ {
+ p->drawText(4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,m_pHttpRequest->fileName());
+ }
+ iY += iLineSpacing;
+
+
+ p->setPen(Qt::darkGray);
+
+ p->drawText(4,4,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szFrom);
+ p->drawText(4,4 + iLineSpacing,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szTo);
+
+ p->setPen(QColor(180,180,200));
+
+ iLineSpacing += 2;
+
+ p->drawRect(4,height - (iLineSpacing + 4),width - 8,iLineSpacing);
+ p->fillRect(5,height - (iLineSpacing + 3),width - 10,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240));
+ p->setPen(Qt::black);
+ p->drawText(7,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(4,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)
+ {
+ //debug("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(5,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))
+ .arg(KviQString::makeSizeReadable(uTotal)).arg(dPerc,0,'f',2);
+ } else {
+ txt = KviQString::makeSizeReadable(m_pHttpRequest->receivedSize());
+ }
+
+ p->setPen(Qt::black);
+
+ p->drawText(4,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(4,iDaH,iLeftHalf,iLineSpacing);
+ p->fillRect(5,iDaH + 1,iLeftHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240));
+ p->setPen(bIsTerminated ? Qt::darkGray : Qt::black);
+ p->drawText(6,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 += QString(__tr2qs_ctx("%1d %2h %3m %4s","http")).arg(uD).arg(uH).arg(uM).arg(uS);
+ else if(uH > 0)txt += QString(__tr2qs_ctx("%2h %3m %4s","http")).arg(uH).arg(uM).arg(uS);
+ else txt += QString(__tr2qs_ctx("%3m %4s","http")).arg(uM).arg(uS);
+ } else {
+ if(iEta >= 0)
+ {
+ KviTimeUtils::secondsToDaysHoursMinsSecs(iEta,&uD,&uH,&uM,&uS);
+ txt = "ETA: ";
+ if(uD > 0)txt += QString(__tr2qs_ctx("%1d %2h %3m %4s","http")).arg(uD).arg(uH).arg(uM).arg(uS);
+ else if(uH > 0)txt += QString(__tr2qs_ctx("%2h %3m %4s","http")).arg(uH).arg(uM).arg(uS);
+ else txt += QString(__tr2qs_ctx("%3m %4s","http")).arg(uM).arg(uS);
+ } else {
+ txt = "ETA: Unknown";
+ }
+ }
+
+ p->setPen(QColor(180,180,200));
+ p->drawRect(width - (4 + iRightHalf),iDaH,iRightHalf,iLineSpacing);
+ p->fillRect(width - (3 + iRightHalf),iDaH + 1,iRightHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240));
+ p->setPen(bIsTerminated ? Qt::darkGray : Qt::black);
+ p->drawText(width - (2 + iRightHalf),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("<table><tr><td bgcolor=\"#000000\"><font color=\"#FFFFFF\"><b>HTTP Transfer (ID %1)</b></font></td></tr>").arg(id());
+
+ if(m_lRequest.count() > 0)
+ {
+ s += "<tr><td bgcolor=\"#404040\"><font color=\"#FFFFFF\">Request Headers</font></td></tr>";
+ s += "<tr><td bgcolor=\"#C0C0C0\">";
+ for(QStringList::ConstIterator it = m_lRequest.begin();it != m_lRequest.end();++it)
+ {
+ s += "&nbsp; &nbsp;";
+ s += *it;
+ s += "<br>";
+ }
+ s += "</td></tr>";
+ }
+
+ if(m_lHeaders.count() > 0)
+ {
+ s += "<tr><td bgcolor=\"#404040\"><font color=\"#FFFFFF\">Response Headers</font></td></tr>";
+ s += "<tr><td bgcolor=\"#C0C0C0\">";
+ for(QStringList::ConstIterator it = m_lHeaders.begin();it != m_lHeaders.end();++it)
+ {
+ s += "&nbsp; &nbsp;";
+ s += *it;
+ s += "<br>";
+ }
+ s += "</td></tr>";
+ }
+
+ s += "<table>";
+
+ return s;
+}
+
+void KviHttpFileTransfer::init()
+{
+ if(g_pHttpFileTransfers)return;
+ g_pHttpFileTransfers = new KviPointerList<KviHttpFileTransfer>;
+ g_pHttpFileTransfers->setAutoDelete(false);
+
+ QPixmap * pix = g_pIconManager->getImage("kvi_httpicons.png");
+ if(pix)g_pHttpIcon = new QPixmap(*pix);
+ else g_pHttpIcon = new QPixmap(192,48);
+}
+
+void KviHttpFileTransfer::done()
+{
+ if(!g_pHttpFileTransfers)return;
+ while(KviHttpFileTransfer * t = g_pHttpFileTransfers->first())
+ delete t;
+ delete g_pHttpFileTransfers;
+ g_pHttpFileTransfers = 0;
+ 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).utf8().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(new KviKvsVariant(bSuccess));
+ vParams.append(new KviKvsVariant(m_pHttpRequest->url().url()));
+ vParams.append(new KviKvsVariant(m_pHttpRequest->fileName()));
+ 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().ptr(),m_pHttpRequest->fileName(),QString::null,QString::null,!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().ptr(),m_pHttpRequest->fileName(),QString::null,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,true);
+ }
+}
+
+void KviHttpFileTransfer::headersReceived(KviPointerHashTable<const char *,KviStr> *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<const char *,KviStr> it(*h);
+ while(KviStr * 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();
+}
+
+#include "m_httpfiletransfer.moc"
diff --git a/src/modules/http/httpfiletransfer.h b/src/modules/http/httpfiletransfer.h
new file mode 100644
index 00000000..e6c5006e
--- /dev/null
+++ b/src/modules/http/httpfiletransfer.h
@@ -0,0 +1,104 @@
+#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 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_filetransfer.h"
+#include "kvi_http.h"
+#include "kvi_time.h"
+
+#include "kvi_kvs_variant.h"
+
+#include <qstringlist.h>
+#include <qtimer.h>
+
+class QPainter;
+class KviTalPopupMenu;
+
+class KviHttpFileTransfer : public KviFileTransfer
+{
+ enum GeneralStatus { Initializing, Connecting, Downloading, Success, Failure };
+ Q_OBJECT
+public:
+ KviHttpFileTransfer();
+ ~KviHttpFileTransfer();
+private:
+ 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,int width,int height);
+ virtual int displayHeight(int iLineSpacing);
+ virtual void fillContextPopup(KviTalPopupMenu * m,int column);
+ virtual bool active();
+ virtual void die();
+ virtual QString tipText();
+ virtual QString localFileName();
+protected slots:
+ void statusMessage(const QString &txt);
+ void transferTerminated(bool bSuccess);
+ void headersReceived(KviPointerHashTable<const char *,KviStr> *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/kvi_httpicons.png b/src/modules/http/kvi_httpicons.png
new file mode 100644
index 00000000..30776c0f
--- /dev/null
+++ b/src/modules/http/kvi_httpicons.png
Binary files differ
diff --git a/src/modules/http/libkvihttp.cpp b/src/modules/http/libkvihttp.cpp
new file mode 100644
index 00000000..eb6f28fb
--- /dev/null
+++ b/src/modules/http/libkvihttp.cpp
@@ -0,0 +1,324 @@
+//==================================================================================
+//
+// File : libkvihttp.cpp
+// 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 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_module.h"
+#include "kvi_string.h"
+
+
+#include "kvi_app.h"
+#include "kvi_locale.h"
+#include "kvi_filedialog.h"
+#include "kvi_window.h"
+#include "kvi_error.h"
+#include "kvi_cmdformatter.h"
+
+#include "httpfiletransfer.h"
+
+
+static bool http_kvs_complete_get(KviKvsModuleCommandCall * c,QString &szUrl,QString &szFileName,const QString &szCallback)
+{
+ if(szUrl.isEmpty())
+ {
+ c->warning(__tr2qs_ctx("No url specified","http"));
+ return true;
+ }
+
+ KviUrl url(szUrl);
+
+ QString tmp;
+
+ if(szFileName.isEmpty())
+ {
+ if(c->switches()->find('a',"auto-file-name"))
+ {
+ tmp = szUrl;
+ tmp.replace('/',"_");
+ tmp.replace(':',"_");
+ tmp.replace('@',"_");
+ tmp.replace('?',"_");
+ // http____path_path2_path3_filename.ext
+ g_pApp->getLocalKvircDirectory(szFileName,KviApp::Incoming,tmp);
+ } else {
+ if(!KviFileDialog::askForSaveFileName(szFileName,__tr2qs_ctx("Choose a save file name","http")))
+ return true;
+ if(szFileName.isEmpty())return true;
+ }
+ }
+
+ KviHttpFileTransfer * hft = new KviHttpFileTransfer();
+
+ bool bHead = c->switches()->find('h',"head");
+
+ if(c->switches()->getAsStringIfExisting('p',"post-data",tmp))
+ {
+ if(bHead)
+ {
+ c->warning(__tr2qs_ctx("The switch -p is incompatible with -h: -p takes precedence","http"));
+ bHead = false;
+ }
+ hft->request()->setPostData(tmp);
+ }
+
+ hft->request()->setUrl(url);
+ hft->request()->setProcessingType(bHead ? KviHttpRequest::HeadersOnly : KviHttpRequest::StoreToFile);
+ hft->request()->setFileName(szFileName);
+
+ if(c->switches()->getAsStringIfExisting('e',"existing-file-action",tmp))
+ {
+ if(KviQString::equalCI(tmp,"e"))
+ hft->request()->setExistingFileAction(KviHttpRequest::RenameExisting);
+ else if(KviQString::equalCI(tmp,"i"))
+ hft->request()->setExistingFileAction(KviHttpRequest::RenameIncoming);
+ else if(KviQString::equalCI(tmp,"o"))
+ hft->request()->setExistingFileAction(KviHttpRequest::Overwrite);
+ else if(KviQString::equalCI(tmp,"r"))
+ hft->request()->setExistingFileAction(KviHttpRequest::Resume);
+ }
+
+ // FIXME: this should be numeric
+ if(c->switches()->getAsStringIfExisting('m',"max-len",tmp))
+ {
+ bool bOk;
+ unsigned int uContentLength = tmp.toUInt(&bOk);
+ if(bOk)hft->request()->setMaxContentLength(uContentLength);
+ }
+
+ // FIXME: this should be numeric
+ if(c->switches()->getAsStringIfExisting('o',"offset",tmp))
+ {
+ bool bOk;
+ unsigned int uContentOffset = tmp.toUInt(&bOk);
+ if(bOk)hft->request()->setContentOffset(uContentOffset);
+ }
+
+ if(c->switches()->getAsStringIfExisting('w',"winctrl",tmp))
+ {
+ if(!tmp.contains('h'))hft->invokeTransferWindow(c->window(),tmp.contains('m'),tmp.contains('n'));
+ } else {
+ hft->invokeTransferWindow(c->window(),false,false);
+ }
+
+ KviKvsVariant * v = c->switches()->find('i',"identifier");
+ if(v)
+ hft->setMagicIdentifier(*v);
+
+ if(c->switches()->find('q',"quiet"))
+ hft->setNotifyCompletion(false);
+
+ if(c->switches()->find('y',"no-output"))
+ hft->setNoOutput(true);
+
+ if(!szCallback.isEmpty())
+ hft->setCompletionCallback(szCallback);
+
+ if(c->switches()->find('c',"clear"))
+ hft->setAutoClean(true);
+
+ if(!hft->startDownload())
+ {
+ tmp = hft->request()->lastError();
+ c->warning(__tr2qs_ctx("Failed to start the get request: %Q","http"),&tmp);
+ delete hft;
+ }
+
+ return true;
+}
+
+
+/*
+ @doc: http.get
+ @type:
+ command
+ @title:
+ http.get
+ @keyterms:
+ HTTP extension
+ @short:
+ Retrieves a file via HTTP GET
+ @syntax:
+ http.get [switches] <http_url> [save_file_name]
+ @description:
+ Attempts to download the file at <http_url> by using the HTTP GET or POST protocol.[br]
+ If [save_file_name] is specified, then is is used as save file name, otherwise
+ a save file dialog is displayed (unless -a is used).[br]
+ The event OnHTTPGetTerminated is triggered upon the download completion (both
+ in case of success or failure). If you want a callback command to be triggered
+ instead please use [cmd]http.asyncGet[/cmd].
+ If the url contains a https:// prefix then a SSL connection will be used.
+ @switches:
+ !sw: -a=<auto_file_name> | --auto-file-name=<auto_file_name>
+ Don't show the savefile dialog but determine automatically a file name.
+ The file is put in the KVIrc incoming directory and the file name
+ is the processed url.[br]
+
+ !sw: -e=<existing_file_action> | --existing-file-action=<existing_file_action>
+ Specifies the action to be taken when the local file already exists.[br]
+ The action can be one of "i","e","o" or "r".[br]
+ "i" causes the incoming file to be automatically renamed by appending a
+ non colliding suffix. "e" causes the existing file to be renamed
+ by appending a non colliding suffix (the incoming file will then have its name preserved).
+ "o" causes the existing file to be overwritten and "r" will attempt to resume
+ a interrupted transfer.[br]
+ The default is to rename the incoming file.[br]
+
+ !sw: -m=<max_content_length> | --max-len=<max_content_length>
+ Causes content longer than <max_content_length> to be discarded.[br]
+ This is mainly to prevent you from automatically downloading 300 MB files
+ and to prevent DOS attacks from malicious servers that do not report the Content-length header.[br]
+ If the Content-length header is reported by the server then the transfer is aborted
+ if the length exceedes <max_content_length>.[br]
+ If the Content-length header is missing then the transfer is interrupted when
+ the received data length exceeds <max_content_length>.[br]
+ -m=0 means "accept any content length" (which is the default).[br]
+
+ !sw: -o=<content_offset> | --offset=<content_offset>
+ Causes the download to start from position <content offset>.[br]
+ This can be used to download only a part of the file starting at byte <content_offset>.[br]
+ <content_offset> is used regardless if the file is resumed or not.
+ Please note that you don't need to specify the content offset when using
+ -e=r : the offset is automatically calculated. If you specify both -o=<content_offset>
+ and -e=r then the file will be resumed, the transfer will start at the specified offset
+ and the received stream will be appended to the existing file.(avoid it unless you know what you're doing:
+ it's easy to download broken files).[br]
+
+ !sw: -h | --head
+ Causes the connection to use the HTTP HEAD method that effectively
+ does not transfer real data. The server sends only the response headers.
+ This might be used in conjunction with the -v option to print the headers to the
+ active window.[br]
+
+ !sw: -w=<flags> | --winctrl
+ This switch controls the creation and visualization of the transfer window.
+ <flags> can be any combination of 'm','n' and 'h'.
+ The flag 'h' causes the window to not be created. The transfer will simply run in background.
+ Note that with 'h' the user has no possibility to interact with the transfer.
+ The flag 'm' causes the transfer window to be created as "minimized". 'm' does nothing
+ if the window alread exists. The flag 'n' causes the window to be NOT activated (brought to top).
+
+ !sw: -i=<magic identifier> | --identifier=<magic identifier>
+ This identifier is passed as $3 parameter to the [event]OnHTTPGetTerminated[/event]
+ when this transfer terminates. If this switch is not present then an empty string is used.
+ With [cmd]http.asyngGet[/cmd] this parameter is passed to the callback command instead.
+
+ !sw: -p=<post data> | --post-data=<post data>
+ The request is sent in form of a POST request. <post data> is the urlencoded payload of
+ the request. -p is incompatible with -h.
+
+ !sw: -q | --quiet
+ Do not notify download completion in the notifier window nor in the console.
+
+ !sw: -y | --no-output
+ Supress any output in the file transfer window. This will effectively disable
+ the file transfer window highlighting (so the user will not be alerted by a failed
+ download unless he's really watching the window). This is useful when you're notifying
+ failures in some other way...
+
+ !sw: -c | --clear
+ Automatically remove the transfer from the transfer list when terminated
+ @seealso:
+ [cmd]http.asyncGet[/cmd]
+*/
+
+static bool http_kvs_cmd_get(KviKvsModuleCommandCall * c)
+{
+ QString szUrl,szFileName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("url",KVS_PT_NONEMPTYSTRING,0,szUrl)
+ KVSM_PARAMETER("filename",KVS_PT_STRING,KVS_PF_OPTIONAL,szFileName)
+ KVSM_PARAMETERS_END(c)
+
+ return http_kvs_complete_get(c,szUrl,szFileName,QString::null);
+}
+/*
+ @doc: http.asyncGet
+ @type:
+ command
+ @title:
+ http.asyncGet
+ @keyterms:
+ HTTP extension
+ @short:
+ Retrieves a file via HTTP GET and triggers a callback
+ @syntax:
+ http.asyncGet [switches] (<http_url> [,save_file_name])
+ {
+ <callback command>
+ }
+ @description:
+ Attempts to download the file at <http_url> by using the HTTP GET or POST protocol.[br]
+ If [save_file_name] is specified, then is is used as save file name, otherwise
+ a save file dialog is displayed (unless -a is used).[br]
+ This command is really similar to [cmd]http.get[/cmd]: it has exactly the same
+ parameters and switches (so also refer to its documentation).
+ The only difference is that asyncGet triggers the <callback command> upon completion
+ instead of the global OnHTTPGetTerminated event.
+ The parameters passed to the callback are exactly the same.
+ If the url contains a https:// prefix then a SSL connection will be used.
+ @seealso:
+ [cmd]http.get[/cmd]
+*/
+
+static bool http_kvs_cmd_asyncGet(KviKvsModuleCallbackCommandCall * c)
+{
+ QString szUrl,szFileName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("url",KVS_PT_NONEMPTYSTRING,0,szUrl)
+ KVSM_PARAMETER("filename",KVS_PT_STRING,KVS_PF_OPTIONAL,szFileName)
+ KVSM_PARAMETERS_END(c)
+
+ return http_kvs_complete_get(c,szUrl,szFileName,c->callback()->code());
+}
+
+
+static bool http_module_init(KviModule * m)
+{
+ KviHttpFileTransfer::init();
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"get",http_kvs_cmd_get);
+ KVSM_REGISTER_CALLBACK_COMMAND(m,"asyncGet",http_kvs_cmd_asyncGet);
+
+ return true;
+}
+
+static bool http_module_cleanup(KviModule *m)
+{
+ KviHttpFileTransfer::done();
+ return true;
+}
+
+static bool http_module_can_unload(KviModule *m)
+{
+ return (KviHttpFileTransfer::runningTransfers() == 0);
+}
+
+KVIRC_MODULE(
+ "Http", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2003 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "HTTP interface for KVIrc",
+ http_module_init,
+ http_module_can_unload,
+ 0,
+ http_module_cleanup
+)
diff --git a/src/modules/ident/Makefile.am b/src/modules/ident/Makefile.am
new file mode 100644
index 00000000..c02c0b47
--- /dev/null
+++ b/src/modules/ident/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviident.la
+
+libkviident_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviident_la_SOURCES = libkviident.cpp
+libkviident_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= libkviident.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkviident.cpp: libkviident.moc
diff --git a/src/modules/ident/libkviident.cpp b/src/modules/ident/libkviident.cpp
new file mode 100644
index 00000000..c8f4f194
--- /dev/null
+++ b/src/modules/ident/libkviident.cpp
@@ -0,0 +1,615 @@
+//
+// File : libkviident.cpp
+// Creation date : Tue Oct 2 18:22:04 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_module.h"
+
+#include "libkviident.h"
+
+#include "kvi_socket.h"
+#include "kvi_app.h"
+#include "kvi_out.h"
+#include "kvi_netutils.h"
+#include "kvi_locale.h"
+#include "kvi_window.h"
+
+#include "kvi_options.h"
+#include "kvi_defaults.h"
+
+#define KVI_IDENT_THREAD_EVENT_EXITING KVI_THREAD_USER_EVENT_BASE + 111
+#define KVI_IDENT_THREAD_EVENT_EXITING_ON_REQUEST KVI_THREAD_USER_EVENT_BASE + 112
+
+
+// FIXME: Should have a timeout on the requests!!!
+
+static KviIdentDaemon * g_pIdentDaemon = 0;
+static KviIdentSentinel * g_pIdentSentinel = 0;
+
+extern KVIRC_API int g_iIdentDaemonRunningUsers;
+
+void startIdentService()
+{
+// debug("Stargin");
+ if(!g_pIdentDaemon)g_pIdentDaemon = new KviIdentDaemon();
+ if(!g_pIdentDaemon->isRunning())g_pIdentDaemon->start();
+ while(g_pIdentDaemon->isStartingUp())
+ {
+#ifdef COMPILE_ON_WINDOWS
+ Sleep(10);
+#else
+ usleep(100);
+#endif
+ }
+// debug("Service started");
+}
+
+void stopIdentService()
+{
+// debug("Stopping");
+ if(g_pIdentDaemon)delete g_pIdentDaemon;
+ g_pIdentDaemon = 0;
+// debug("Stopped");
+}
+
+KviIdentSentinel::KviIdentSentinel()
+: QObject(0)
+{
+}
+
+KviIdentSentinel::~KviIdentSentinel()
+{
+ KviThreadManager::killPendingEvents(this);
+}
+
+bool KviIdentSentinel::event(QEvent *e)
+{
+ if(KVI_OPTION_UINT(KviOption_uintIdentdOutputMode)==KviIdentdOutputMode::Quiet || !g_pActiveWindow)
+ return QObject::event(e);
+
+ KviWindow * pTarget = KVI_OPTION_UINT(KviOption_uintIdentdOutputMode)==KviIdentdOutputMode::ToActiveWindow ?
+ (KviWindow *)g_pActiveWindow : (KviWindow *)g_pApp->activeConsole();
+
+ if(e->type() == KVI_THREAD_EVENT)
+ {
+ if(((KviThreadEvent *)e)->id() == KVI_THREAD_EVENT_DATA)
+ {
+ KviIdentMessageData * d = ((KviThreadDataEvent<KviIdentMessageData> *)e)->getData();
+ if(pTarget)
+ {
+ if(d->szHost.hasData())
+ {
+ if(d->szAux.hasData())
+ {
+ if(_OUTPUT_PARANOIC)
+ pTarget->output(KVI_OUT_IDENT,__tr("%s (%s) (%s:%u)"),d->szMessage.ptr(),d->szAux.ptr(),d->szHost.ptr(),d->uPort);
+ else
+ pTarget->output(KVI_OUT_IDENT,__tr("%s (%s)"),d->szMessage.ptr(),d->szAux.ptr());
+ } else {
+ if(_OUTPUT_PARANOIC)
+ pTarget->output(KVI_OUT_IDENT,__tr("%s (%s:%u)"),d->szMessage.ptr(),d->szHost.ptr(),d->uPort);
+ else
+ pTarget->output(KVI_OUT_IDENT,__tr("%s"),d->szMessage.ptr());
+ }
+ } else {
+ pTarget->output(KVI_OUT_IDENT,__tr("[IDENT]: %s"),d->szMessage.ptr());
+ }
+ }
+ delete d;
+ } else if(((KviThreadEvent *)e)->id() == KVI_IDENT_THREAD_EVENT_EXITING)
+ {
+ if(_OUTPUT_VERBOSE)
+ if(pTarget)pTarget->outputNoFmt(KVI_OUT_IDENT,__tr("Shutting down identd service (spontaneous action)"));
+ stopIdentService();
+ } else if(((KviThreadEvent *)e)->id() == KVI_IDENT_THREAD_EVENT_EXITING_ON_REQUEST)
+ {
+ if(_OUTPUT_VERBOSE)
+ if(pTarget)pTarget->outputNoFmt(KVI_OUT_IDENT,__tr("Shutting down identd service (requested action)"));
+ }
+
+ return true;
+ }
+
+ return QObject::event(e);
+}
+
+
+KviIdentRequest::KviIdentRequest(kvi_socket_t sock,const char * host,kvi_u32_t uPort)
+{
+ m_sock = sock;
+ m_szHost = host;
+ m_uPort = uPort;
+ m_tStart = time(0);
+}
+
+KviIdentRequest::~KviIdentRequest()
+{
+ kvi_socket_close(m_sock);
+}
+
+
+
+KviIdentDaemon::KviIdentDaemon()
+: KviSensitiveThread()
+{
+// debug("Thread constructor");
+ m_szUser = KVI_OPTION_STRING(KviOption_stringIdentdUser);
+ if(m_szUser.isEmpty())m_szUser = "kvirc";
+ m_uPort = KVI_OPTION_UINT(KviOption_uintIdentdPort);
+#ifdef COMPILE_IPV6_SUPPORT
+ m_bEnableIpV6 = KVI_OPTION_BOOL(KviOption_boolIdentdEnableIpV6);
+#else
+ m_bEnableIpV6 = false;
+#endif
+ m_bIpV6ContainsIpV4 = KVI_OPTION_BOOL(KviOption_boolIdentdIpV6ContainsIpV4);
+// debug("Thread constructor done");
+}
+
+KviIdentDaemon::~KviIdentDaemon()
+{
+// debug("Thread destructor");
+ terminate();
+ g_iIdentDaemonRunningUsers = 0;
+
+ g_pIdentDaemon = 0;
+// debug("Destructor gone");
+}
+
+void KviIdentDaemon::postMessage(const char * message,KviIdentRequest * r,const char * szAux)
+{
+ KviThreadDataEvent<KviIdentMessageData> * e = new KviThreadDataEvent<KviIdentMessageData>(KVI_THREAD_EVENT_DATA);
+
+ KviIdentMessageData * d = new KviIdentMessageData;
+
+ d->szMessage = message;
+ if(szAux)d->szAux = szAux;
+
+ if(r)
+ {
+ d->szHost = r->m_szHost;
+ d->uPort = r->m_uPort;
+ }
+
+ e->setData(d);
+ postEvent(g_pIdentSentinel,e);
+}
+
+void KviIdentDaemon::run()
+{
+// debug("RUN STARTED");
+ m_sock = KVI_INVALID_SOCKET;
+ m_sock6 = KVI_INVALID_SOCKET;
+ bool bEventPosted = false;
+
+ m_pRequestList = new KviPointerList<KviIdentRequest>;
+ m_pRequestList->setAutoDelete(true);
+
+ KviPointerList<KviIdentRequest> dying;
+ dying.setAutoDelete(false);
+
+#ifdef COMPILE_IPV6_SUPPORT
+ // If we have enabled ipv6 and we have to use a single socket: this one is IPV6
+ // otherwise this one is IPV4
+ KviSockaddr sa(m_uPort,m_bEnableIpV6 && m_bIpV6ContainsIpV4);
+#else
+ KviSockaddr sa(m_uPort,false);
+#endif
+
+ KviIdentRequest * r;
+
+#ifdef COMPILE_IPV6_SUPPORT
+ m_sock = kvi_socket_create((m_bEnableIpV6 && m_bIpV6ContainsIpV4) ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP);
+#else
+ m_sock = kvi_socket_create(KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP);
+#endif
+
+ if(m_sock == KVI_INVALID_SOCKET)
+ {
+ postMessage(__tr("Can't start the ident service : socket() failed"),0);
+ goto exit_thread;
+ }
+
+ if(!kvi_socket_setNonBlocking(m_sock))
+ {
+ postMessage(__tr("Can't start the ident service : async setting failed"),0);
+ goto exit_thread;
+ }
+
+ if(!sa.socketAddress())
+ {
+ postMessage(__tr("Can't enable the ident service : can't setup the listen address"),0);
+ goto exit_thread;
+ }
+
+ if(!kvi_socket_bind(m_sock,sa.socketAddress(),((int)(sa.addressLength()))))
+ {
+ postMessage(__tr("Can't start the ident service : bind() failed"),0);
+ goto exit_thread;
+ }
+
+ if(!kvi_socket_listen(m_sock,128))
+ {
+ postMessage(__tr("Can't start the ident service : listen() failed"),0);
+ goto exit_thread;
+ }
+
+
+#ifdef COMPILE_IPV6_SUPPORT
+ if(m_bEnableIpV6 && (!m_bIpV6ContainsIpV4))
+ {
+ // Need to start the IPV6 socket too
+ KviSockaddr sa6(m_uPort,true);
+ m_sock6 = kvi_socket_create(KVI_SOCKET_PF_INET6,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP);
+
+ if(m_sock6 == KVI_INVALID_SOCKET)
+ {
+ postMessage(__tr("Can't start the ident service on IpV6 : socket() failed"),0);
+ goto ipv6_failure;
+ }
+
+ if(!kvi_socket_setNonBlocking(m_sock6))
+ {
+ postMessage(__tr("Can't start the ident service on IpV6 : async setting failed"),0);
+ kvi_socket_close(m_sock6);
+ m_sock6 = KVI_INVALID_SOCKET;
+ goto ipv6_failure;
+ }
+
+ if(!sa6.socketAddress())
+ {
+ postMessage(__tr("Can't enable the ident service on IpV6 : can't setup the listen address"),0);
+ kvi_socket_close(m_sock6);
+ m_sock6 = KVI_INVALID_SOCKET;
+ goto ipv6_failure;
+ }
+
+ if(!kvi_socket_bind(m_sock6,sa6.socketAddress(),((int)(sa6.addressLength()))))
+ {
+ postMessage(__tr("Can't start the ident service on IpV6 : bind() failed"),0);
+ kvi_socket_close(m_sock6);
+ m_sock6 = KVI_INVALID_SOCKET;
+ goto ipv6_failure;
+
+ }
+
+ if(!kvi_socket_listen(m_sock6,128))
+ {
+ postMessage(__tr("Can't start the ident service on IpV6 : listen() failed"),0);
+ kvi_socket_close(m_sock6);
+ m_sock6 = KVI_INVALID_SOCKET;
+ goto ipv6_failure;
+ }
+
+ }
+#endif
+
+ipv6_failure:
+
+#ifdef COMPILE_IPV6_SUPPORT
+ if(m_bEnableIpV6)
+ {
+ if(m_sock6 != KVI_INVALID_SOCKET) {
+ if(_OUTPUT_PARANOIC)
+ postMessage(__tr("Starting identd service (IpV4/V6 on separate namespaces)"),0);
+ } else {
+ if(_OUTPUT_PARANOIC)
+ postMessage(__tr("Starting identd service (IpV4/V6 in IpV6 namespace)"),0);
+ }
+
+ } else {
+ if(_OUTPUT_PARANOIC)
+ postMessage(__tr("Starting identd service (IpV4)"),0);
+ }
+#else //!COMPILE_IPV6_SUPPORT
+ if(_OUTPUT_PARANOIC)
+ postMessage(__tr("Service startup (IpV4)"),0);
+#endif //!COMPILE_IPV6_SUPPORT
+
+
+ for(;;)
+ {
+
+ if(KviThreadEvent * e = dequeueEvent())
+ {
+ // This can be ONLY a terminate event
+ delete e;
+ goto exit_on_request;
+ }
+
+ struct timeval t;
+ t.tv_sec = 0;
+ t.tv_usec = 10000;
+
+ int nmax = 0;
+
+ fd_set rs;
+ FD_ZERO(&rs);
+
+ if(m_sock != KVI_INVALID_SOCKET)
+ {
+ FD_SET(m_sock,&rs);
+ if(((unsigned int)m_sock) > ((unsigned int)nmax))nmax = m_sock;
+ }
+#ifdef COMPILE_IPV6_SUPPORT
+ if(m_sock6 != KVI_INVALID_SOCKET)
+ {
+ FD_SET(m_sock6,&rs);
+ if(((unsigned int)m_sock6) > ((unsigned int)nmax))nmax = m_sock6;
+ }
+#endif
+
+ for(r = m_pRequestList->first();r;r = m_pRequestList->next())
+ {
+ FD_SET(r->m_sock,&rs);
+ if(((unsigned int)r->m_sock) > ((unsigned int)nmax))nmax = r->m_sock;
+ }
+
+ // FIXME: SO_REUSEADDR ?
+
+
+ int ret = kvi_socket_select(nmax + 1,&rs,0,0,&t);
+
+
+ if(ret == 0)msleep(100);
+ else {
+
+
+ if(m_sock != KVI_INVALID_SOCKET)
+ {
+ if(FD_ISSET(m_sock,&rs))
+ {
+#ifdef COMPILE_IPV6_SUPPORT
+ KviSockaddr satmp(0,m_bEnableIpV6 && m_bIpV6ContainsIpV4);
+#else
+ KviSockaddr satmp(0,false);
+#endif
+ int salen = (int)satmp.addressLength();
+
+ kvi_socket_t t = kvi_socket_accept(m_sock,satmp.socketAddress(),&salen);
+ if(t != KVI_INVALID_SOCKET)
+ {
+ QString szHost;
+ if(!satmp.getStringAddress(szHost))szHost = "unknown";
+ KviIdentRequest * r = new KviIdentRequest(t,szHost.utf8().data(),satmp.port());
+ m_pRequestList->append(r);
+ postMessage(__tr("Identd accepting connection"),r);
+ }
+ }
+ }
+
+#ifdef COMPILE_IPV6_SUPPORT
+ if(m_sock6 != KVI_INVALID_SOCKET)
+ {
+ if(FD_ISSET(m_sock6,&rs))
+ {
+ KviSockaddr satmp(0,true);
+ int salen = (int)satmp.addressLength();
+
+ kvi_socket_t t = kvi_socket_accept(m_sock6,satmp.socketAddress(),&salen);
+ if(t != KVI_INVALID_SOCKET)
+ {
+ QString szHost;
+ if(!satmp.getStringAddress(szHost))szHost = "unknown";
+ KviIdentRequest * r = new KviIdentRequest(t,szHost.utf8().data(),satmp.port());
+ m_pRequestList->append(r);
+ postMessage(__tr("Identd accepting connection"),r);
+ }
+ }
+ }
+#endif
+
+ for(r = m_pRequestList->first();r;r = m_pRequestList->next())
+ {
+ if(FD_ISSET(r->m_sock,&rs))
+ {
+ char buffer[1025];
+ int readed = kvi_socket_recv(r->m_sock,buffer,1024);
+ if(readed > 0)
+ {
+ buffer[readed] = '\0';
+ r->m_szData.append(buffer);
+ } else {
+ // error ?
+ if(readed < 0)
+ {
+ int err = kvi_socket_error();
+ if(!kvi_socket_recoverableConnectError(err))
+ {
+ postMessage(__tr("Identd socket error : dropping connection"),r);
+ dying.append(r);
+ }
+ } else {
+ // connection closed
+ postMessage(__tr("Identd connection closed by remote host"),r);
+ dying.append(r);
+ }
+ }
+ }
+ }
+
+ for(r = m_pRequestList->first();r;r = m_pRequestList->next())
+ {
+
+ int idx = r->m_szData.findFirstIdx('\n');
+
+ if(idx != -1)
+ {
+ // Ok...parse the request
+ KviStr szReq = r->m_szData.left(idx);
+ r->m_szData.cutLeft(idx + 1);
+ szReq.stripWhiteSpace();
+
+ if(szReq.hasData())
+ {
+ postMessage(__tr("Identd processing request"),r,szReq.ptr());
+
+ if(kvi_strEqualCI("VERSION",szReq.ptr()))
+ {
+ KviStr reply("Quad-Echelon 7.12-r-244");
+ kvi_socket_write(r->m_sock,reply.ptr(),reply.len());
+ } else {
+ KviStr reply(KviStr::Format,"%s : USERID : UNIX : %s\r\n",szReq.ptr(),m_szUser.ptr());
+ kvi_socket_write(r->m_sock,reply.ptr(),reply.len());
+ }
+
+ dying.append(r);
+
+ } else {
+
+ postMessage(__tr("Empty request (EOT ?)"),r,szReq.ptr());
+
+ dying.append(r);
+ }
+
+ } else {
+ // debug("Data is : (%s)",r->m_szData.ptr());
+ if(r->m_szData.len() > 1024)
+ {
+ // request too long...kill it
+ dying.append(r);
+ postMessage(__tr("Dropping connection (request too long)"),r);
+ }
+ }
+
+ }
+ }
+
+ time_t curTime = time(0);
+
+ for(r = m_pRequestList->first();r;r = m_pRequestList->next())
+ {
+ if((unsigned int)(curTime - r->m_tStart) > 30)
+ {
+ postMessage(__tr("Timed out while waiting for the request : dropping connection"),r);
+ dying.append(r);
+ }
+ }
+
+ for(KviIdentRequest * ir = dying.first();ir;ir = dying.next())
+ m_pRequestList->removeRef(ir);
+
+ dying.clear();
+
+ }
+
+
+
+exit_on_request:
+
+ postEvent(g_pIdentSentinel,new KviThreadEvent(KVI_IDENT_THREAD_EVENT_EXITING_ON_REQUEST));
+ bEventPosted = true;
+
+exit_thread:
+
+ if(!bEventPosted)
+ postEvent(g_pIdentSentinel,new KviThreadEvent(KVI_IDENT_THREAD_EVENT_EXITING));
+
+
+ if(m_sock != KVI_INVALID_SOCKET)kvi_socket_close(m_sock);
+ if(m_sock6 != KVI_INVALID_SOCKET)kvi_socket_close(m_sock6);
+ delete m_pRequestList;
+ m_pRequestList = 0;
+
+// debug("RUN EXITING");
+}
+
+
+/*
+ @doc: ident.start
+ @type:
+ command
+ @title:
+ ident.start
+ @short:
+ Starts the builtin ident service
+ @syntax:
+ ident.start
+ @description:
+ Starts the builtin ident service.[br]
+ WARNING: the kvirc ident service is just a partial implementation
+ of the RFC specifications. You should use is ONLY if you can't get
+ any other ident daemon running on your machine.[br]
+*/
+
+static bool ident_kvs_cmd_start(KviKvsModuleCommandCall * c)
+{
+ if(!g_iIdentDaemonRunningUsers)
+ startIdentService();
+ g_iIdentDaemonRunningUsers++;
+ return true;
+}
+
+/*
+ @doc: ident.stop
+ @type:
+ command
+ @title:
+ ident.stop
+ @short:
+ Stops the ident service
+ @syntax:
+ ident.stop
+ @description:
+ Stops the ident service
+ @seealso:
+ [cmd]ident.start[/cmd]
+*/
+
+static bool ident_kvs_cmd_stop(KviKvsModuleCommandCall * c)
+{
+ if(g_iIdentDaemonRunningUsers) g_iIdentDaemonRunningUsers--;
+ if(!g_iIdentDaemonRunningUsers) stopIdentService();
+ return true;
+}
+
+static bool ident_module_init(KviModule *m)
+{
+ g_pIdentSentinel = new KviIdentSentinel();
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"start",ident_kvs_cmd_start);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"stop",ident_kvs_cmd_stop);
+ return true;
+}
+
+static bool ident_module_cleanup(KviModule *m)
+{
+ stopIdentService();
+ delete g_pIdentSentinel;
+ g_pIdentSentinel = 0;
+
+ return true;
+}
+
+static bool ident_module_can_unload(KviModule *m)
+{
+ return !g_pIdentDaemon;
+}
+
+KVIRC_MODULE(
+ "Ident", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Ident service",
+ ident_module_init,
+ ident_module_can_unload,
+ 0,
+ ident_module_cleanup
+)
+
+#include "libkviident.moc"
diff --git a/src/modules/ident/libkviident.h b/src/modules/ident/libkviident.h
new file mode 100644
index 00000000..c6d3d390
--- /dev/null
+++ b/src/modules/ident/libkviident.h
@@ -0,0 +1,86 @@
+#ifndef _LIBKVIIDENT_H_
+#define _LIBKVIIDENT_H_
+//
+// File : libkviident.h
+// Creation date : Tue Oct 2 18:22:05 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_thread.h"
+#include "kvi_sockettype.h"
+#include "kvi_string.h"
+#include "kvi_time.h"
+#include "kvi_settings.h"
+
+#include "kvi_pointerlist.h"
+#include <qobject.h>
+
+class KviIdentRequest
+{
+public:
+ KviIdentRequest(kvi_socket_t sock,const char * host,kvi_u32_t uPort);
+ ~KviIdentRequest();
+public:
+ kvi_socket_t m_sock;
+ KviStr m_szData;
+ KviStr m_szHost;
+ kvi_u32_t m_uPort;
+ time_t m_tStart;
+};
+
+typedef struct _KviIdentMessageData
+{
+ KviStr szMessage;
+ KviStr szHost;
+ KviStr szAux;
+ unsigned int uPort;
+} KviIdentMessageData;
+
+class KviIdentSentinel : public QObject
+{
+ Q_OBJECT
+public:
+ KviIdentSentinel();
+ ~KviIdentSentinel();
+protected:
+ virtual bool event(QEvent * e);
+};
+
+
+class KviIdentDaemon : public KviSensitiveThread
+{
+public:
+ KviIdentDaemon();
+ ~KviIdentDaemon();
+private:
+ KviStr m_szUser;
+ kvi_u32_t m_uPort;
+ bool m_bEnableIpV6;
+ bool m_bIpV6ContainsIpV4;
+ kvi_socket_t m_sock;
+ kvi_socket_t m_sock6;
+ KviPointerList<KviIdentRequest> * m_pRequestList;
+public:
+ virtual void run();
+protected:
+ void postMessage(const char * message,KviIdentRequest * r,const char * szAux = 0);
+};
+
+
+#endif //_LIBKVIIDENT_H_
diff --git a/src/modules/iograph/Makefile.am b/src/modules/iograph/Makefile.am
new file mode 100644
index 00000000..a9ea3928
--- /dev/null
+++ b/src/modules/iograph/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviiograph.la
+
+libkviiograph_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviiograph_la_SOURCES = libkviiograph.cpp
+libkviiograph_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= libkviiograph.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkviiograph.cpp: libkviiograph.moc
diff --git a/src/modules/iograph/libkviiograph.cpp b/src/modules/iograph/libkviiograph.cpp
new file mode 100644
index 00000000..ab9aa4f1
--- /dev/null
+++ b/src/modules/iograph/libkviiograph.cpp
@@ -0,0 +1,297 @@
+//
+// File : kvi_iograph.cpp
+// Creation date : Tue Oct 31 2000 00:14:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 "libkviiograph.h"
+#include "kvi_module.h"
+
+#if 0
+
+
+#include "kvi_console.h"
+#include "kvi_options.h"
+#include "kvi_ircsocket.h"
+#include "kvi_frame.h"
+#include "kvi_locale.h"
+
+#include "kvi_pointerlist.h"
+#include <qtooltip.h>
+#include <qpointarray.h>
+#include <qpainter.h>
+
+
+extern QPixmap * g_pIccMemBuffer;
+
+
+static KviPointerList<KviIOGraphDisplay> * g_pIOGraphWidgetList;
+
+KviIOGraphDisplay::KviIOGraphDisplay(KviIrcContextController * pController,bool sentGraph,bool recvGraph)
+: KviIrcContextGraphicalApplet(pController,"iograph_display")
+{
+ g_pIOGraphWidgetList->append(this);
+ for(int i=0;i < KVI_IOGRAPH_NUMBER_POINTS;i++)
+ {
+ m_sendRates[i] = 0;
+ m_recvRates[i] = 0;
+ }
+ m_iNextPoint = 1;
+ m_uLastSentBytes = pController->console()->socket()->sentBytes();
+ m_uLastRecvBytes = pController->console()->socket()->readBytes();
+ m_bShowSentGraph = sentGraph;
+ m_bShowRecvGraph = recvGraph;
+
+ KviStr tip;
+ if(sentGraph)tip = __tr("Outgoing traffic");
+ if(recvGraph)
+ {
+ if(tip.hasData())tip.append("\n");
+ tip.append(__tr("Incoming traffic"));
+ }
+
+ QToolTip::add(this,tip.ptr());
+
+ startTimer(1000);
+}
+
+KviIOGraphDisplay::~KviIOGraphDisplay()
+{
+ g_pIOGraphWidgetList->removeRef(this);
+}
+
+void KviIOGraphDisplay::timerEvent(QTimerEvent *e)
+{
+ unsigned int sB = console()->socket()->sentBytes();
+ unsigned int rB = console()->socket()->readBytes();
+ int sDiff = (sB - m_uLastSentBytes) / 8;
+ int rDiff = (rB - m_uLastRecvBytes) / 32;
+// debug("s:%d,r:%d",sDiff,rDiff);
+ if(sDiff < 0)sDiff = 0;
+ else if(sDiff > 30)sDiff = 30;
+ if(rDiff < 0)rDiff = 0;
+ else if(rDiff > 30)rDiff = 30;
+ m_uLastSentBytes = sB;
+ m_uLastRecvBytes = rB;
+ m_sendRates[m_iNextPoint] = sDiff;
+ m_recvRates[m_iNextPoint] = rDiff;
+ m_iNextPoint++;
+ if(m_iNextPoint >= KVI_IOGRAPH_NUMBER_POINTS)m_iNextPoint = 0;
+ update();
+}
+
+static QCOORD horizSegments[6 * 4]=
+{
+ 5 , 3 , KVI_IRCTOOLBARAPPLET_MAXIMUM_WIDTH - 4 , 3 ,
+ 5 , 8 , KVI_IRCTOOLBARAPPLET_MAXIMUM_WIDTH - 4 , 8 ,
+ 5 , 13 , KVI_IRCTOOLBARAPPLET_MAXIMUM_WIDTH - 4 , 13 ,
+ 5 , 18 , KVI_IRCTOOLBARAPPLET_MAXIMUM_WIDTH - 4 , 18 ,
+ 5 , 23 , KVI_IRCTOOLBARAPPLET_MAXIMUM_WIDTH - 4 , 23 ,
+ 5 , 28 , KVI_IRCTOOLBARAPPLET_MAXIMUM_WIDTH - 4 , 28
+};
+
+static QCOORD vertSegments[29 * 4]=
+{
+ 9 , 4 , 9 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 14 , 4 , 14 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 19 , 4 , 19 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 24 , 4 , 24 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 29 , 4 , 29 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 34 , 4 , 34 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 39 , 4 , 39 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 44 , 4 , 44 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 49 , 4 , 49 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 54 , 4 , 54 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 59 , 4 , 59 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 64 , 4 , 64 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 69 , 4 , 69 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 74 , 4 , 74 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 79 , 4 , 79 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 84 , 4 , 84 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 89 , 4 , 89 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 94 , 4 , 94 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 99 , 4 , 99 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 104 , 4 , 104 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 109 , 4 , 109 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 114 , 4 , 114 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 119 , 4 , 119 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 124 , 4 , 124 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 129 , 4 , 129 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 134 , 4 , 134 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 139 , 4 , 139 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 144 , 4 , 144 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5 ,
+ 149 , 4 , 149 , KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5
+};
+
+void KviIOGraphDisplay::drawContents(QPainter * p)
+{
+ static QPointArray hp(6 * 4,horizSegments);
+ static QPointArray vp(29 * 4,vertSegments);
+
+ p->setPen(KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundLowContrast));
+ p->drawLineSegments(hp,0,6);
+ p->drawLineSegments(vp,0,29);
+ p->setPen(KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundMidContrast));
+
+ p->drawLine(4,33,KVI_IRCTOOLBARAPPLET_MAXIMUM_WIDTH - 4,33);
+ p->drawLine(4,3,4,KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT - 5);
+
+ p->setPen(isActiveContext() ?
+ KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundHighContrastActive1) :
+ KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundHighContrastInactive1));
+
+ // the first point to draw is "m_iNextPoint"
+ // it will be drawn at X = 4
+
+ int leftPart = KVI_IOGRAPH_NUMBER_POINTS - m_iNextPoint;
+
+ int i;
+
+ if(m_bShowSentGraph)
+ {
+ for(i = 1;i < leftPart;i++)
+ {
+ p->drawLine(3 + i,33 - m_sendRates[m_iNextPoint + i - 1],4 + i,33 - m_sendRates[m_iNextPoint + i]);
+ }
+
+ p->drawLine(3 + i,33 - m_sendRates[m_iNextPoint + i - 1],4 + i,33 - m_sendRates[0]);
+
+ for(i = 1;i < m_iNextPoint;i++)
+ {
+ p->drawLine(leftPart + 3 + i,33 - m_sendRates[i - 1],leftPart + 4 + i,33 - m_sendRates[i]);
+ }
+ }
+
+ if(m_bShowRecvGraph)
+ {
+ p->setPen(isActiveContext() ?
+ KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundHighContrastActive2) :
+ KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundHighContrastInactive2));
+
+ for(i = 1;i < leftPart;i++)
+ {
+ p->drawLine(3 + i,33 - m_recvRates[m_iNextPoint + i - 1],4 + i,33 - m_recvRates[m_iNextPoint + i]);
+ }
+
+ p->drawLine(3 + i,33 - m_recvRates[m_iNextPoint + i - 1],4 + i,33 - m_recvRates[0]);
+
+ for(i = 1;i < m_iNextPoint;i++)
+ {
+ p->drawLine(leftPart + 3 + i,33 - m_recvRates[i - 1],leftPart + 4 + i,33 - m_recvRates[i]);
+ }
+ }
+}
+
+QSize KviIOGraphDisplay::sizeHint() const
+{
+ return QSize(KVI_IRCTOOLBARAPPLET_MAXIMUM_WIDTH,KVI_IRCTOOLBARAPPLET_MAXIMUM_HEIGHT);
+}
+
+
+/*
+ @doc: iograph.add
+ @type:
+ command
+ @title:
+ iograph.add
+ @short:
+ Adds an IOGraph applet
+ @syntax:
+ iograph.add [-i] [-o]
+ @description:
+ Adds an IOGraph applet to the current irc-context toolbar. It will
+ monitor the Incoming and Outgoing socket traffic.[br]
+ Since both graphs often are somewhat unreadable,
+ the -i switch will cause the IOGraph applet to show only
+ the incoming traffic, and the -o switch will cause it to show
+ only the outgoing traffic.[br]
+ Well...I agree...this is an amazing misuse of resources :)
+*/
+
+
+
+static bool iograph_module_cmd_add(KviModule *m,KviCommand *c)
+{
+ ENTER_STACK_FRAME(c,"iograph_module_cmd_add");
+
+ KviStr dummy;
+ if(!g_pUserParser->parseCmdFinalPart(c,dummy))return false;
+
+ if(!c->window()->console())return c->noIrcContext();
+
+ bool bSentGraph = !(c->hasSwitch('i'));
+ bool bRecvGraph = !(c->hasSwitch('o'));
+
+ if(!(bSentGraph || bRecvGraph))bRecvGraph = true;
+
+ KviIOGraphDisplay * dpy = new KviIOGraphDisplay(c->window()->console()->icController(),bSentGraph,bRecvGraph);
+ c->window()->console()->icController()->addApplet(dpy);
+ dpy->show();
+
+ return c->leaveStackFrame();
+}
+#endif
+
+static bool iograph_module_init(KviModule *m)
+{
+#if 0
+ g_pIOGraphWidgetList = new KviPointerList<KviIOGraphDisplay>;
+ g_pIOGraphWidgetList->setAutoDelete(false);
+ m->registerCommand("add",iograph_module_cmd_add);
+#endif
+ return true;
+}
+
+static bool iograph_module_cleanup(KviModule *m)
+{
+#if 0
+ while(g_pIOGraphWidgetList->first())
+ {
+ KviIOGraphDisplay * dpy = g_pIOGraphWidgetList->first();
+ dpy->controller()->removeApplet(dpy); // deleted path
+ }
+ delete g_pIOGraphWidgetList;
+#endif
+ return true;
+}
+
+static bool iograph_module_can_unload(KviModule *m)
+{
+#if 0
+ return g_pIOGraphWidgetList->isEmpty();
+#else
+ return true;
+#endif
+}
+
+KVIRC_MODULE(
+ "IOGraph", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "IRC socket traffic monitor",
+ iograph_module_init,
+ iograph_module_can_unload,
+ 0,
+ iograph_module_cleanup
+)
+
+#if 0
+#include "libkviiograph.moc"
+#endif
diff --git a/src/modules/iograph/libkviiograph.h b/src/modules/iograph/libkviiograph.h
new file mode 100644
index 00000000..9b134615
--- /dev/null
+++ b/src/modules/iograph/libkviiograph.h
@@ -0,0 +1,55 @@
+#ifndef _LIBKVIIOGRAPH_H_
+#define _LIBKVIIOGRAPH_H_
+
+//
+// File : kvi_iograph.cpp
+// Creation date : Tue Oct 31 2000 00:14:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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.
+//
+
+#if 0
+
+#include "kvi_irctoolbar.h"
+
+
+#define KVI_IOGRAPH_NUMBER_POINTS 148
+
+class KviIOGraphDisplay : public KviIrcContextGraphicalApplet
+{
+ Q_OBJECT
+public:
+ KviIOGraphDisplay(KviIrcContextController * pController,bool sentGraph,bool recvGraph);
+ ~KviIOGraphDisplay();
+protected:
+ unsigned int m_sendRates[KVI_IOGRAPH_NUMBER_POINTS];
+ unsigned int m_recvRates[KVI_IOGRAPH_NUMBER_POINTS];
+ int m_iNextPoint;
+ unsigned int m_uLastSentBytes;
+ unsigned int m_uLastRecvBytes;
+ bool m_bShowSentGraph;
+ bool m_bShowRecvGraph;
+protected:
+ virtual void drawContents(QPainter *p);
+ virtual QSize sizeHint() const;
+ virtual void timerEvent(QTimerEvent *e);
+};
+
+#endif
+
+#endif
diff --git a/src/modules/lamerizer/Makefile.am b/src/modules/lamerizer/Makefile.am
new file mode 100644
index 00000000..ce798e5c
--- /dev/null
+++ b/src/modules/lamerizer/Makefile.am
@@ -0,0 +1,27 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvilamerizer.la
+
+libkvilamerizer_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvilamerizer_la_SOURCES = libkvilamerizer.cpp
+libkvilamerizer_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= libkvilamerizer.h
+
+tmpdir = $(pluglibdir)/caps/crypt/
+
+tmp_DATA= lamerizer
+
+EXTRA_DIST = $(tmp_DATA)
+
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkvilamerizer.cpp: libkvilamerizer.moc
diff --git a/src/modules/lamerizer/lamerizer b/src/modules/lamerizer/lamerizer
new file mode 100644
index 00000000..9788f702
--- /dev/null
+++ b/src/modules/lamerizer/lamerizer
@@ -0,0 +1 @@
+timestamp
diff --git a/src/modules/lamerizer/libkvilamerizer.cpp b/src/modules/lamerizer/libkvilamerizer.cpp
new file mode 100644
index 00000000..adb7a194
--- /dev/null
+++ b/src/modules/lamerizer/libkvilamerizer.cpp
@@ -0,0 +1,279 @@
+//=============================================================================
+//
+// File : libkvilamerizer.cpp
+// Creation date : Sat Jan 20 2002 17:06:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2005 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 "libkvilamerizer.h"
+
+#include "kvi_module.h"
+#include "kvi_debug.h"
+#include "kvi_locale.h"
+
+
+
+/*
+ @doc: lamerizer
+ @type:
+ module
+ @short:
+ The Lamerizer text transformation engine
+ @title:
+ The lamerizer module
+ @body:
+ This is an example of what you should NOT do with a text transformation
+ engine. Do NOT use it! :D
+*/
+
+
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+ #include "kvi_memmove.h"
+ #include "kvi_malloc.h"
+
+ #include "kvi_pointerlist.h"
+
+ static KviPointerList<KviCryptEngine> * g_pEngineList = 0;
+
+ KviLamerizerEngine::KviLamerizerEngine(bool bLight)
+ : KviCryptEngine()
+ {
+ m_bLight = bLight;
+ g_pEngineList->append(this);
+ }
+
+ KviLamerizerEngine::~KviLamerizerEngine()
+ {
+ g_pEngineList->removeRef(this);
+ }
+
+ bool KviLamerizerEngine::init(const char *,int,const char *,int)
+ {
+ return true;
+ }
+
+ static char subst_table[256] =
+ {
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 007
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 015
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 023
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 031
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 039 : '
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 047 : /
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 055 : 7
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 063 : ?
+ 0 , '4' , '8' , 'C' , 'D' , '3' , 'F' , 'G' , // 071 : G
+ 'H' , '|' , 'J' , 'K' , 'L' , 'm' , 'N' , 'O' , // 079 : O
+ 'P' , 'q' , 'R' , '5' , '7' , 'U' , 'V' , 'W' , // 087 : W
+ 'x' , 'Y' , '2' , 0 , 0 , 0 , 0 , 0 , // 095 : _
+ 0 , '4' , 'b' , 'c' , 'd' , '3' , 'f' , '9' , // 103 : g
+ 'h' , '|' , 'j' , 'k' , '1' , 'm' , 'n' , '0' ,
+ 'p' , 'q' , 'r' , '5' , '7' , 'u' , 'v' , 'w' , // 119 : w
+ 'x' , 'y' , '2' , 0 , 0 , 0 , 0 , 0 , // 127 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 135 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 143 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 151 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 159 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 167 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 175 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 183 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 191 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 199 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 215 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 223 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 231 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 239 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 247 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+ };
+
+ static char subst_table_light[256] =
+ {
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 007
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 015
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 023
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 031
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 039 : '
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 047 : /
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 055 : 7
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 063 : ?
+ 0 , '4' , 'B' , 'C' , 'D' , '3' , 'F' , 'G' , // 071 : G
+ 'H' , '|' , 'J' , 'K' , 'L' , 'm' , 'N' , 'O' , // 079 : O
+ 'P' , 'q' , 'R' , '5' , '7' , 'U' , 'V' , 'W' , // 087 : W
+ 'x' , 'Y' , 'Z' , 0 , 0 , 0 , 0 , 0 , // 095 : _
+ 0 , '4' , 'b' , 'c' , 'd' , '3' , 'f' , 'G' , // 103 : g
+ 'h' , '|' , 'j' , 'k' , '1' , 'm' , 'n' , '0' ,
+ 'p' , 'q' , 'r' , '5' , '7' , 'u' , 'v' , 'w' , // 119 : w
+ 'x' , 'y' , 'z' , 0 , 0 , 0 , 0 , 0 , // 127 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 135 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 143 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 151 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 159 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 167 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 175 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 183 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 191 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 199 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 215 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 223 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 231 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 239 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 247 :
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+ };
+
+
+ KviCryptEngine::EncryptResult KviLamerizerEngine::encrypt(const char * plainText,KviStr &outBuffer)
+ {
+ outBuffer = plainText;
+ unsigned char * aux = (unsigned char *)outBuffer.ptr();
+ if(m_bLight)
+ {
+ while(*aux)
+ {
+ if(subst_table_light[*aux])
+ {
+ *aux = subst_table_light[*aux];
+ }
+ aux++;
+ }
+ } else {
+ while(*aux)
+ {
+ if(subst_table[*aux])
+ {
+ *aux = subst_table[*aux];
+ }
+ aux++;
+ }
+ }
+
+ if(!m_bLight)
+ {
+ outBuffer.replaceAll("F","Ph");
+ outBuffer.replaceAll("V","\\/");
+ }
+
+ return KviCryptEngine::Encoded;
+ }
+
+ KviCryptEngine::DecryptResult KviLamerizerEngine::decrypt(const char * inBuffer,KviStr &plainText)
+ {
+ plainText = inBuffer;
+ return KviCryptEngine::DecryptOkWasPlainText;
+ }
+
+ static KviCryptEngine * allocLamerizerEngine()
+ {
+ return new KviLamerizerEngine(false);
+ }
+
+ static KviCryptEngine * allocLightLamerizerEngine()
+ {
+ return new KviLamerizerEngine(true);
+ }
+
+ static void deallocLamerizerEngine(KviCryptEngine * e)
+ {
+ delete e;
+ }
+
+#endif
+
+
+// =======================================
+// module routines
+// =======================================
+static bool lamerizer_module_init(KviModule * m)
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ g_pEngineList = new KviPointerList<KviCryptEngine>;
+ g_pEngineList->setAutoDelete(false);
+
+ // FIXME: Maybe convert this repeated code to a function eh ?
+
+ KviCryptEngineDescription * d = new KviCryptEngineDescription;
+ d->szName = "Lamerizer";
+ d->szAuthor = "Szymon Stefanek and Jan Wagner";
+ d->szDescription = __tr2qs("A really lame text transformation engine :D");
+ d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT;
+ d->allocFunc = allocLamerizerEngine;
+ d->deallocFunc = deallocLamerizerEngine;
+ m->registerCryptEngine(d);
+
+
+ d = new KviCryptEngineDescription;
+ d->szName = "LamerizerLight";
+ d->szAuthor = "Szymon Stefanek and Jan Wagner";
+ d->szDescription = __tr2qs("A really lame text transformation engine: Light Version.");
+ d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT;
+ d->allocFunc = allocLightLamerizerEngine;
+ d->deallocFunc = deallocLamerizerEngine;
+ m->registerCryptEngine(d);
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+static bool lamerizer_module_cleanup(KviModule *m)
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ while(g_pEngineList->first())delete g_pEngineList->first();
+ delete g_pEngineList;
+ g_pEngineList = 0;
+ m->unregisterCryptEngines();
+ return true;
+#else
+ return false;
+#endif
+}
+
+static bool lamerizer_module_can_unload(KviModule *)
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ return g_pEngineList->isEmpty();
+#else
+ return true;
+#endif
+}
+
+// =======================================
+// plugin definition structure
+// =======================================
+KVIRC_MODULE(
+ "Lamerizer crypt engine",
+ "1.0.1",
+ "Szymon Stefanek <pragma at kvirc dot net> \n Jan Wagner <istari@kvirc.net>" ,
+ "Exports the lamerizer text transformation engine",
+ lamerizer_module_init ,
+ lamerizer_module_can_unload,
+ 0,
+ lamerizer_module_cleanup
+)
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ #include "libkvilamerizer.moc"
+#endif
diff --git a/src/modules/lamerizer/libkvilamerizer.h b/src/modules/lamerizer/libkvilamerizer.h
new file mode 100644
index 00000000..e0b78bd7
--- /dev/null
+++ b/src/modules/lamerizer/libkvilamerizer.h
@@ -0,0 +1,47 @@
+#ifndef _LIBKVILAMERIZER_H_
+#define _LIBKVILAMERIZER_H_
+//
+// File : libkvilamerizer.h
+// Creation date : Sat Now 4 2000 15:41:41 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Till Bush (buti@geocities.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_settings.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+ #include "kvi_crypt.h"
+
+ class KviLamerizerEngine : public KviCryptEngine
+ {
+ Q_OBJECT
+ public:
+ KviLamerizerEngine(bool bLight);
+ ~KviLamerizerEngine();
+ protected:
+ bool m_bLight;
+ public:
+ virtual bool init(const char *encKey,int encKeyLen,const char *decKey,int decKeyLen);
+ virtual KviCryptEngine::EncryptResult encrypt(const char * plainText,KviStr &outBuffer);
+ virtual KviCryptEngine::DecryptResult decrypt(const char * inBuffer,KviStr &plainText);
+ };
+
+#endif // COMPILE_CRYPT_SUPPORT
+
+#endif // _LIBKVILAMERIZER_H_
diff --git a/src/modules/links/Makefile.am b/src/modules/links/Makefile.am
new file mode 100644
index 00000000..51eea094
--- /dev/null
+++ b/src/modules/links/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvilinks.la
+
+libkvilinks_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvilinks_la_SOURCES = libkvilinks.cpp linkswindow.cpp
+libkvilinks_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= linkswindow.h
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+linkswindow.cpp: m_linkswindow.moc
diff --git a/src/modules/links/libkvilinks.cpp b/src/modules/links/libkvilinks.cpp
new file mode 100644
index 00000000..6486b985
--- /dev/null
+++ b/src/modules/links/libkvilinks.cpp
@@ -0,0 +1,116 @@
+//
+// File : libkvilinks.cpp
+// Creation date : Thu Dec 21 2000 12:39:12 CEST by Szymon Stefanek
+//
+// Copyright (C) 1999-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_module.h"
+
+
+#include "linkswindow.h"
+
+#include "kvi_frame.h"
+#include "kvi_window.h"
+#include "kvi_locale.h"
+
+#include <qsplitter.h>
+
+KviPointerList<KviLinksWindow> * g_pLinksWindowList = 0;
+
+
+/*
+ @doc: links.open
+ @type:
+ command
+ @title:
+ links.open
+ @short:
+ Opens a Links window
+ @syntax:
+ links.open
+ @description:
+ Opens a "links" window attacched to the current irc context.[br]
+ The links window handles the RPL_LINKS server replies and shows
+ them in a Tree-View form: this is useful in vizualizing the
+ current network connections.[br]
+ Please note that the total number of links received (and the
+ total count of servers displayed when all the links have been received)
+ may actually be less than the real number of irc servers in the network.
+ Servers that contain a wildcard in their name often act as gateways (hubs)
+ for a "local irc network"; if you're requesting links from a server that is
+ external to the gateway, the servers internal to the network "behind the gateway"
+ will not be shown; in the extreme case you will see the gateway as leaf node (and it isn't).
+ To see the internal network server tree you might request LINKS from the gateway server.[br]
+*/
+
+
+static bool links_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+
+ // FIND ME
+ if(!c->window()->console())return c->context()->errorNoIrcContext();
+
+ if(!(c->window()->console()->ircContext()->linksWindow()))
+ {
+ KviLinksWindow *w = new KviLinksWindow(c->window()->frame(),c->window()->console());
+ c->window()->frame()->addWindow(w);
+ } else {
+ c->warning(__tr2qs("Links window alread open for this IRC context"));
+ }
+
+ return true;
+}
+
+
+
+
+static bool links_module_init(KviModule * m)
+{
+ g_pLinksWindowList = new KviPointerList<KviLinksWindow>;
+ g_pLinksWindowList->setAutoDelete(false);
+
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",links_kvs_cmd_open);
+
+ return true;
+}
+
+static bool links_module_cleanup(KviModule *m)
+{
+ while(g_pLinksWindowList->first())g_pLinksWindowList->first()->die();
+ delete g_pLinksWindowList;
+ g_pLinksWindowList = 0;
+ return true;
+}
+
+static bool links_module_can_unload(KviModule *m)
+{
+ return (g_pLinksWindowList->isEmpty());
+}
+
+KVIRC_MODULE(
+ "Links", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000-2001 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Links window extension",
+ links_module_init,
+ links_module_can_unload,
+ 0,
+ links_module_cleanup
+)
diff --git a/src/modules/links/linkswindow.cpp b/src/modules/links/linkswindow.cpp
new file mode 100644
index 00000000..1dd567f5
--- /dev/null
+++ b/src/modules/links/linkswindow.cpp
@@ -0,0 +1,472 @@
+//
+// 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) 1999-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 "linkswindow.h"
+
+#include "kvi_debug.h"
+#include "kvi_iconmanager.h"
+#include "kvi_ircview.h"
+#include "kvi_out.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_out.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_themedlabel.h"
+#include "kvi_irccontext.h"
+#include "kvi_ircconnection.h"
+
+#include <qsplitter.h>
+#include <qtooltip.h>
+#include "kvi_tal_hbox.h"
+#include <qlabel.h>
+
+extern KviPointerList<KviLinksWindow> * g_pLinksWindowList;
+
+KviLinksWindow::KviLinksWindow(KviFrame * lpFrm,KviConsole * lpConsole)
+: KviWindow(KVI_WINDOW_TYPE_LINKS,lpFrm,"links",lpConsole) , KviExternalServerDataParser()
+{
+ g_pLinksWindowList->append(this);
+
+ m_pTopSplitter = new QSplitter(Qt::Horizontal,this,"top_splitter");
+
+ // The button box on the left
+ KviTalHBox * box = new KviTalHBox(m_pTopSplitter);
+
+ m_pRequestButton = new QToolButton(box,"request_button");
+ m_pRequestButton->setUsesBigPixmap(false);
+ m_pRequestButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LINKS)));
+ connect(m_pRequestButton,SIGNAL(clicked()),this,SLOT(requestLinks()));
+ QToolTip::add(m_pRequestButton,__tr2qs("Request Links"));
+
+ QLabel * l = new QLabel(box,"");
+ box->setStretchFactor(l,1);
+ m_pInfoLabel = new KviThemedLabel(m_pTopSplitter,"info_label");
+
+ connect(lpConsole->context(),SIGNAL(stateChanged()),
+ this,SLOT(connectionStateChange()));
+
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"splitter");
+ m_pVertSplitter = new QSplitter(Qt::Vertical,m_pSplitter,"vsplitter");
+
+ m_pListView = new KviTalListView(m_pVertSplitter);
+ m_pListView->addColumn(__tr2qs("Link"));
+ m_pListView->addColumn(__tr2qs("Hops"));
+ m_pListView->addColumn(__tr2qs("Description"));
+ m_pListView->setRootIsDecorated(true);
+ m_pListView->setAllColumnsShowFocus(true);
+ connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),
+ this,SLOT(showHostPopup(KviTalListViewItem *,const QPoint &,int)));
+
+ m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this);
+
+ m_pLinkList = new KviPointerList<KviLink>;
+ m_pLinkList->setAutoDelete(true);
+
+ m_pHostPopup = new KviTalPopupMenu();
+ connect(m_pHostPopup,SIGNAL(activated(int)),this,SLOT(hostPopupClicked(int)));
+
+ connectionStateChange();
+
+ m_pConsole->ircContext()->setLinksWindowPointer(this);
+
+ m_szRootServer = __tr2qs("(None)");
+}
+
+KviLinksWindow::~KviLinksWindow()
+{
+ g_pLinksWindowList->removeRef(this);
+ m_pConsole->ircContext()->setLinksWindowPointer(0);
+ delete m_pLinkList;
+ delete m_pHostPopup;
+}
+
+void KviLinksWindow::getBaseLogFileName(KviStr &buffer)
+{
+ buffer.sprintf("LINKS_%d",console()->ircContextId());
+}
+
+
+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)
+ {
+ KviStr tmp(KviStr::Format,__tr2qs("Connected to %s (%s)"),m_pConsole->connection()->currentServerName().utf8().data(),m_pConsole->currentNetworkName().utf8().data());
+ m_pInfoLabel->setText(tmp.ptr());
+ } 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 *e)
+{
+ 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->ircContextId());
+
+ KviQString::sprintf(m_szHtmlActiveCaption,
+ __tr2qs("<nobr><font color=\"%s\"><b>Links for %Q</b></font> " \
+ "<font color=\"%s\">[IRC Context %u]</font></nobr>"),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(),
+ &m_szRootServer,
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name().ascii(),
+ m_pConsole->ircContextId());
+
+ KviQString::sprintf(m_szHtmlInactiveCaption,
+ __tr2qs("<nobr><font color=\"%s\"><b>Links for %Q</b></font> " \
+ "<font color=\"%s\">[IRC Context %u]</font></nobr>"),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(),
+ &m_szRootServer,
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name().ascii(),
+ m_pConsole->ircContextId());
+}
+
+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,"======================");
+
+ KviTalListViewItem * it = 0;
+ KviTalListViewItem * 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;
+
+ KviStr szMaxHop,szMaxLinks;
+
+ m_pListView->setUpdatesEnabled(false);
+ for(KviLink *l=m_pLinkList->first();l;l=m_pLinkList->next()){
+ totalHosts++;
+ if(l->hops == 0)root = new KviTalListViewItem(m_pListView,QString(l->host.ptr()),"0",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 <mask> ?)"),
+ l->parent.ptr(),l->host.ptr(),l->hops,l->description.ptr());
+ brokenLinks++;
+ KviStr tmp(KviStr::Format,__tr2qs("%s: Parent link %s"),l->description.ptr(),l->parent.ptr());
+ KviStr tmp2(KviStr::Format,"%d",l->hops);
+ if(root)it = new KviTalListViewItem(m_pListView,root,QString(l->host.ptr()),QString(tmp2.ptr()),QString(tmp.ptr()));
+ else {
+ outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Warning: No root link was sent by the server, the stats may be invalid."));
+ it = new KviTalListViewItem(m_pListView,QString(l->host.ptr()),QString(tmp2.ptr()),QString(tmp.ptr()));
+ }
+ } else {
+ it = 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"),KVI_TEXT_BOLD,KVI_TEXT_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->setUpdatesEnabled(true);
+ m_pListView->repaint();
+}
+
+KviTalListViewItem * KviLinksWindow::insertLink(KviLink *l)
+{
+ __range_valid(l->hops > 0);
+ KviTalListViewItem * i = getItemByHost(l->parent.ptr(),0);
+ KviTalListViewItem * it = 0;
+ if(!i)return 0;
+ else {
+ KviStr hops(KviStr::Format,"%d",l->hops);
+ it = new KviTalListViewItem(i,QString(l->host.ptr()),QString(hops.ptr()),QString(l->description.ptr()));
+ i->setOpen(true);
+ }
+ return it;
+}
+
+KviTalListViewItem * KviLinksWindow::getItemByHost(const char *host,KviTalListViewItem * par)
+{
+ KviTalListViewItem * i = (par ? par->firstChild() : m_pListView->firstChild());
+ if(!i)return 0;
+ while(i){
+ KviStr tmp = i->text(0);
+ if(kvi_strEqualCI(tmp.ptr(),host))return i;
+ KviTalListViewItem * ch = getItemByHost(host,i);
+ if(ch)return ch;
+ i = i->nextSibling();
+ }
+ return 0;
+}
+
+void KviLinksWindow::showHostPopup(KviTalListViewItem *i,const QPoint &p,int)
+{
+ if(!i)return;
+ KviStr host=i->text(0);
+ if(host.isEmpty())return;
+ m_pHostPopup->clear();
+ KviStr tmp(KviStr::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)
+{
+ KviStr 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++;
+ KviStr 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);
+}
+
+//#warning "Load & save properties of this kind of window"
+
+//void KviLinksWindow::saveProperties()
+//{
+// KviWindowProperty p;
+// p.rect = externalGeometry();
+// p.isDocked = isAttacched();
+// QValueList<int> 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 KviLinksWindow::setProperties(KviWindowProperty *p)
+//{
+// QValueList<int> l;
+// l.append(p->splitWidth1);
+// l.append(p->splitWidth2);
+// m_pVertSplitter->setSizes(l);
+// m_pIrcView->setTimestamp(p->timestamp);
+// m_pIrcView->setShowImages(p->imagesVisible);
+//}
+
+void KviLinksWindow::applyOptions()
+{
+ m_pIrcView->applyOptions();
+ KviWindow::applyOptions();
+}
+
+#include "m_linkswindow.moc"
diff --git a/src/modules/links/linkswindow.h b/src/modules/links/linkswindow.h
new file mode 100644
index 00000000..b9cba76e
--- /dev/null
+++ b/src/modules/links/linkswindow.h
@@ -0,0 +1,89 @@
+#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) 1999-2001 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 "kvi_window.h"
+#include "kvi_string.h"
+#include "kvi_ircsocket.h"
+#include "kvi_sparser.h"
+#include "kvi_console.h"
+#include "kvi_irccontext.h"
+
+#include "kvi_tal_listview.h"
+#include "kvi_tal_popupmenu.h"
+#include <qtoolbutton.h>
+
+class KviThemedLabel;
+
+
+typedef struct _KviLink
+{
+ KviStr host;
+ KviStr parent;
+ int hops;
+ KviStr description;
+} KviLink;
+
+
+class KviLinksWindow : public KviWindow, public KviExternalServerDataParser
+{
+ Q_OBJECT
+public:
+ KviLinksWindow(KviFrame * lpFrm,KviConsole * lpConsole);
+ ~KviLinksWindow();
+protected:
+ QSplitter * m_pVertSplitter;
+ QSplitter * m_pTopSplitter;
+ KviTalListView * m_pListView;
+ KviPointerList<KviLink> * 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(KviStr &buffer);
+// virtual void setProperties(KviWindowProperty *p);
+// virtual void saveProperties();
+protected slots:
+ void showHostPopup(KviTalListViewItem *i,const QPoint &p,int c);
+ void hostPopupClicked(int id);
+ void requestLinks();
+ void connectionStateChange();
+public:
+ virtual QSize sizeHint() const;
+private:
+ void reset();
+ void endOfLinks();
+ KviTalListViewItem * insertLink(KviLink * l);
+ KviTalListViewItem * getItemByHost(const char *host,KviTalListViewItem * par);
+};
+
+#endif //_KVI_LINKSWINDOW_H_
diff --git a/src/modules/list/Makefile.am b/src/modules/list/Makefile.am
new file mode 100644
index 00000000..52290210
--- /dev/null
+++ b/src/modules/list/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvilist.la
+
+libkvilist_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvilist_la_SOURCES = libkvilist.cpp listwindow.cpp
+libkvilist_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= listwindow.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+listwindow.cpp: listwindow.moc
diff --git a/src/modules/list/libkvilist.cpp b/src/modules/list/libkvilist.cpp
new file mode 100644
index 00000000..7920934d
--- /dev/null
+++ b/src/modules/list/libkvilist.cpp
@@ -0,0 +1,101 @@
+//
+// File : libkvilist.cpp
+// Creation date : Sun Oct 21 2001 13:29:12 CEST by Szymon Stefanek
+//
+// 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_module.h"
+
+
+#include "listwindow.h"
+
+#include "kvi_frame.h"
+#include "kvi_window.h"
+#include "kvi_locale.h"
+
+#include <qsplitter.h>
+
+KviPointerList<KviListWindow> * g_pListWindowList = 0;
+
+
+/*
+ @doc: list.open
+ @type:
+ command
+ @title:
+ list.open
+ @short:
+ Opens a List window
+ @syntax:
+ list.open
+ @description:
+ Opens the channel list window attacched to the current irc context.[br]
+ The channel list window is opened automatically when a channel list
+ is requested from the server.
+*/
+
+static bool list_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+
+ if(!c->window()->console())return c->context()->errorNoIrcContext();
+
+ if(!(c->window()->console()->ircContext()->listWindow()))
+ {
+ KviListWindow *w = new KviListWindow(c->window()->frame(),c->window()->console());
+ c->window()->frame()->addWindow(w);
+ } else {
+ c->warning(__tr2qs("List window alread open for this IRC context"));
+ }
+ return true;
+}
+
+
+
+static bool list_module_init(KviModule * m)
+{
+ g_pListWindowList = new KviPointerList<KviListWindow>;
+ g_pListWindowList->setAutoDelete(false);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",list_kvs_cmd_open);
+ return true;
+}
+
+static bool list_module_cleanup(KviModule *m)
+{
+ while(g_pListWindowList->first())g_pListWindowList->first()->die();
+ delete g_pListWindowList;
+ g_pListWindowList = 0;
+ return true;
+}
+
+static bool list_module_can_unload(KviModule *m)
+{
+ return (g_pListWindowList->isEmpty());
+}
+
+KVIRC_MODULE(
+ "List", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000-2001 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "List window extension",
+ list_module_init,
+ list_module_can_unload,
+ 0,
+ list_module_cleanup
+)
diff --git a/src/modules/list/listwindow.cpp b/src/modules/list/listwindow.cpp
new file mode 100644
index 00000000..2e1c5401
--- /dev/null
+++ b/src/modules/list/listwindow.cpp
@@ -0,0 +1,535 @@
+//=============================================================================
+//
+// 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-2004 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 "kvi_iconmanager.h"
+#include "kvi_ircview.h"
+#include "kvi_out.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_out.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_themedlabel.h"
+#include "kvi_options.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnection.h"
+#include "kvi_qstring.h"
+#include "kvi_qcstring.h"
+#include "kvi_topicw.h"
+#include "kvi_config.h"
+#include "kvi_filedialog.h"
+
+#include "kvi_styled_controls.h"
+#include <qtimer.h>
+#include <qpainter.h>
+#include <qfontmetrics.h>
+#include <qsplitter.h>
+#include <qtooltip.h>
+#include <qdatetime.h>
+#include "kvi_tal_hbox.h"
+#include "kvi_msgbox.h"
+
+extern KviPointerList<KviListWindow> * g_pListWindowList;
+
+// kvi_ircview.cpp
+//extern KVIRC_API const char * getColorBytes(const char *data_ptr,unsigned char *byte_1,unsigned char *byte_2);
+
+
+KviChannelListViewItemData::KviChannelListViewItemData(const QString &szChan,const QString &szUsers,const QString &szTopic)
+{
+ m_szChan = szChan;
+ m_szUsers = szUsers;
+ m_szTopic = szTopic;
+ m_szUsersKey = szUsers;
+ //setText(0,szChan.upper());
+ while(m_szUsersKey.length() < 6)m_szUsersKey.prepend("0");
+}
+
+KviChannelListViewItemData::~KviChannelListViewItemData()
+{
+}
+
+
+
+KviChannelListViewItem::KviChannelListViewItem(KviTalListView * v,KviChannelListViewItemData * pData)
+: KviTalListViewItem(v)
+{
+ m_pData = pData;
+}
+
+
+KviChannelListViewItem::~KviChannelListViewItem()
+{
+ delete m_pData;
+}
+#ifdef COMPILE_USE_QT4
+int KviChannelListViewItem::width ( const QFontMetrics & fm, const KviTalListView * lv, int column ) const
+#else
+int KviChannelListViewItem::width ( const QFontMetrics & fm, const QListView * lv, int column ) const
+#endif
+{
+ debug("width request");
+ QString szText;
+
+ switch(column)
+ {
+ case 0: szText = m_pData->m_szChan; break;
+ case 1: szText = m_pData->m_szUsers; break;
+ default: szText = m_pData->m_szTopic; break;
+ }
+ if(column==2) return fm.width(KviMircCntrl::stripControlBytes(szText));
+ else return fm.width(szText);
+}
+
+#define KVI_LABEL_DEF_BACK 100
+#define KVI_LABEL_DEF_FORE 101
+
+void KviChannelListViewItem::paintCell(QPainter * p,const QColorGroup &cg,int column,int width,int align)
+{
+ QString szText;
+
+ switch(column)
+ {
+ case 0: szText = m_pData->m_szChan; break;
+ case 1: szText = m_pData->m_szUsers; break;
+ default: szText = m_pData->m_szTopic; break;
+ }
+
+ KviTalListView* lv = (KviTalListView *)listView();
+ int marg = lv->itemMargin();
+ int r = marg;
+
+#ifdef COMPILE_USE_QT4
+
+ p->fillRect( 0, 0, width, height(), cg.brush(lv->viewport()->backgroundRole()) );
+#else
+ const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode(lv->viewport()->backgroundMode());
+
+ p->fillRect( 0, 0, width, height(), cg.brush( crole ) );
+#endif
+
+ if ( isSelected() &&
+ (column == 0 || lv->allColumnsShowFocus()) ) {
+ p->fillRect( r - marg, 0, width - r + marg, height(),
+ cg.brush( QColorGroup::Highlight ) );
+
+ if ( isEnabled() || !lv )
+ p->setPen( cg.highlightedText() );
+ else if ( !isEnabled() && lv)
+ p->setPen( lv->palette().disabled().highlightedText() );
+ } else {
+ if ( isEnabled() || !lv )
+ p->setPen( cg.text() );
+ else if ( !isEnabled() && lv)
+ p->setPen( lv->palette().disabled().text() );
+ }
+
+ KviTopicWidget::paintColoredText(p,szText,cg,height(),width);
+}
+
+QString KviChannelListViewItem::key(int col,bool) const
+{
+ switch(col)
+ {
+ case 0:
+ return m_pData->m_szChan;
+ break;
+ case 1:
+ return m_pData->m_szUsersKey;
+ break;
+ case 2:
+ return m_pData->m_szTopic;
+ break;
+ }
+ QString ret;
+ return ret;
+}
+
+
+
+KviListWindow::KviListWindow(KviFrame * lpFrm,KviConsole * lpConsole)
+: KviWindow(KVI_WINDOW_TYPE_LIST,lpFrm,"list",lpConsole) , KviExternalServerDataParser()
+{
+ g_pListWindowList->append(this);
+
+ m_pFlushTimer = 0;
+
+ m_pItemList = new KviPointerList<KviChannelListViewItemData>;
+ m_pItemList->setAutoDelete(false);
+
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"splitter");
+ m_pTopSplitter = new QSplitter(Qt::Horizontal,this,"top_splitter");
+ m_pVertSplitter = new QSplitter(Qt::Vertical,m_pSplitter,"vsplitter");
+
+ KviTalHBox * box = new KviTalHBox(m_pTopSplitter);
+ m_pOpenButton = new KviStyledToolButton(box);
+ m_pOpenButton->setPixmap(*(g_pIconManager->getBigIcon(KVI_BIGICON_OPEN)));
+ connect(m_pOpenButton,SIGNAL(clicked()),this,SLOT(importList()));
+
+ m_pSaveButton = new KviStyledToolButton(box);
+ m_pSaveButton->setPixmap(*(g_pIconManager->getBigIcon(KVI_BIGICON_SAVE)));
+ connect(m_pSaveButton,SIGNAL(clicked()),this,SLOT(exportList()));
+
+ m_pRequestButton = new KviStyledToolButton(box,"request_button");
+ m_pRequestButton->setUsesBigPixmap(false);
+ m_pRequestButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LIST)));
+ connect(m_pRequestButton,SIGNAL(clicked()),this,SLOT(requestList()));
+ QToolTip::add(m_pRequestButton,__tr2qs("Request List"));
+
+ m_pStopListDownloadButton = new KviStyledToolButton(box,"stoplistdownload_button");
+ m_pStopListDownloadButton->setUsesBigPixmap(false);
+ m_pStopListDownloadButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NICKNAMEPROBLEM)));
+ connect(m_pStopListDownloadButton,SIGNAL(clicked()),this,SLOT(stoplistdownload()));
+ QToolTip::add(m_pStopListDownloadButton,__tr2qs("Stop list download"));
+
+ m_pParamsEdit = new QLineEdit(box);
+ box->setStretchFactor(m_pParamsEdit,1);
+ QToolTip::add(m_pParamsEdit,__tr2qs("<center><b>/LIST command parameters:</b><br>Many servers accept special parameters that " \
+ "allow you to filter the returned entries.<br>" \
+ "Commonly, masked channel names (*kvirc*) are accepted as parameters, as well as strings " \
+ "like <b>c&lt;n</b> or <b>c&gt;n</b> where <b>n</b> is the minimum or maximum of users on the channel.</center>"));
+
+ m_pInfoLabel = new KviThemedLabel(m_pTopSplitter,"info_label");
+
+ m_pListView = new KviTalListView(m_pVertSplitter);
+ m_pListView->addColumn(__tr2qs("Channel"));
+ m_pListView->addColumn(__tr2qs("Users"));
+ m_pListView->addColumn(__tr2qs("Topic"));
+ m_pListView->setAllColumnsShowFocus(TRUE);
+ m_pListView->setColumnWidthMode(2,KviTalListView::Maximum);
+ m_pListView->setColumnWidthMode(3,KviTalListView::Maximum);
+ m_pListView->setSorting(100);
+
+ connect(m_pListView,SIGNAL(doubleClicked(KviTalListViewItem *)),this,SLOT(itemDoubleClicked(KviTalListViewItem *)));
+
+ m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this);
+
+ m_pConsole->ircContext()->setListWindowPointer(this);
+
+ connect(m_pConsole->context(),SIGNAL(stateChanged()),
+ this,SLOT(connectionStateChange()));
+
+ connectionStateChange();
+
+}
+
+KviListWindow::~KviListWindow()
+{
+ g_pListWindowList->removeRef(this);
+ m_pConsole->ircContext()->setListWindowPointer(0);
+ if(m_pFlushTimer)delete m_pFlushTimer;
+ m_pItemList->setAutoDelete(true);
+ delete m_pItemList;
+}
+
+void KviListWindow::getBaseLogFileName(KviStr &buffer)
+{
+ buffer.sprintf("LIST_%d",console()->ircContextId());
+}
+
+
+void KviListWindow::requestList()
+{
+ if(m_pConsole->isConnected())
+ {
+ KviStr 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 tmp;
+ KviQString::sprintf(tmp,
+ __tr2qs("Connected to %s (%s)"),
+ m_pConsole->connection()->currentServerName().utf8().data(),
+ m_pConsole->currentNetworkName().utf8().data());
+ m_pInfoLabel->setText(tmp);
+ } 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 *e)
+{
+ int hght = m_pTopSplitter->sizeHint().height();
+ m_pTopSplitter->setGeometry(0,0,width(),hght);
+ m_pSplitter->setGeometry(0,hght,width(),height() - hght);
+}
+
+QSize KviListWindow::sizeHint() const
+{
+ return m_pSplitter->sizeHint();
+}
+
+void KviListWindow::fillCaptionBuffers()
+{
+ KviQString::sprintf(m_szPlainTextCaption,__tr2qs("Channel List [IRC Context %u]"),m_pConsole->ircContextId());
+
+ KviQString::sprintf(m_szHtmlActiveCaption,
+ __tr2qs("<nobr><font color=\"%s\"><b>Channel List</b></font> " \
+ "<font color=\"%s\">[IRC Context %u]</font></nobr>"),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name().ascii(),
+ m_pConsole->ircContextId());
+
+ KviQString::sprintf(m_szHtmlInactiveCaption,
+ __tr2qs("<nobr><font color=\"%s\"><b>Channel list</b></font> " \
+ "<font color=\"%s\">[IRC Context %u]</font></nobr>"),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name().ascii(),
+ m_pConsole->ircContextId());
+}
+
+void KviListWindow::die()
+{
+ close();
+}
+
+void KviListWindow::exportList()
+{
+ if(!m_pListView->firstChild())
+ {
+ KviMessageBox::warning(__tr2qs("You cannot export an empty list"));
+ return;
+ }
+
+ QString szFile;
+ if(connection())
+ {
+ QString szDate = QDateTime::currentDateTime().toString("d MMM yyyy hh-mm");
+ KviQString::sprintf(szFile,__tr2qs("Channel list for %Q - %Q"),
+ &(connection()->networkName()),&(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).extension()!="kvc")
+ szFile.append(".kvc");
+ KviConfig cfg(szFile,KviConfig::Write);
+ cfg.clear();
+ KviTalListViewItemIterator it(m_pListView);
+
+ while(it.current())
+ {
+ KviChannelListViewItemData* pData= ((KviChannelListViewItem*) ( it.current() ))->m_pData;
+ cfg.setGroup(pData->m_szChan);
+ // Write properties
+ cfg.writeEntry("topic",pData->m_szTopic);
+ cfg.writeEntry("users",pData->m_szUsers);
+// cfg.writeEntry("usersKey",pData->m_szUsersKey);
+ ++it;
+ }
+ }
+}
+
+void KviListWindow::importList()
+{
+
+ QString szFile;
+ if(KviFileDialog::askForOpenFileName(szFile,__tr2qs("Choose filename"),QString::null,
+ __tr2qs("Configuration files (*.kvc)"),false,
+ false,this))
+ {
+ if(m_pConsole->isConnected())
+ {
+ m_pConsole->connection()->sendFmtData("list stoplistdownloadnow");
+ outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Stopping the list download...")); //G&N mar 2005
+ }
+
+ m_pItemList->clear();
+
+ KviConfig cfg(szFile,KviConfig::Read);
+ KviConfigIterator it(*cfg.dict());
+ while(it.current())
+ {
+ cfg.setGroup(it.currentKey());
+ m_pItemList->append(
+ new KviChannelListViewItemData(
+ it.currentKey(),
+ cfg.readQStringEntry("users","0"),
+ cfg.readQStringEntry("topic","")
+ )
+ );
+ ++it;
+ }
+ flush();
+ }
+}
+
+void KviListWindow::control(int message)
+{
+ switch(message)
+ {
+ 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_pListView->clear();
+
+ m_pRequestButton->setEnabled(false);
+}
+
+void KviListWindow::processData(KviIrcMessage *msg)
+{
+ if(!m_pFlushTimer)
+ {
+ m_pFlushTimer = new QTimer(this);
+ connect(m_pFlushTimer,SIGNAL(timeout()),this,SLOT(flush()));
+ m_pFlushTimer->start(1000);
+ m_pRequestButton->setEnabled(false);
+ }
+
+ QString sz2 = msg->connection()->decodeText(msg->safeParam(2));
+
+ m_pItemList->append(
+ new KviChannelListViewItemData(
+ msg->connection()->decodeText(msg->safeParam(1)),
+ msg->connection()->decodeText(msg->safeParam(2)),
+ msg->connection()->decodeText(msg->safeTrailing()))
+ );
+
+ if(_OUTPUT_VERBOSE)
+ {
+ QString zzz = msg->connection()->decodeText(msg->allParams());
+ output(KVI_OUT_LIST,__tr2qs("Processing list: %Q"),&zzz);
+ }
+}
+
+void KviListWindow::flush()
+{
+ m_pListView->setUpdatesEnabled(true); /* for v_scroolbar */
+ while(KviChannelListViewItemData * d = m_pItemList->first())
+ {
+ (void)new KviChannelListViewItem(m_pListView,d);
+ m_pItemList->removeFirst();
+ }
+ m_pListView->setUpdatesEnabled(true);
+ m_pListView->viewport()->update();
+}
+
+void KviListWindow::itemDoubleClicked(KviTalListViewItem *it)
+{
+ QString sz = ((KviChannelListViewItem *)it)->channel();
+ if(sz.isEmpty())return;
+ if(!connection())return;
+ KviQCString dat = connection()->encodeText(sz);
+ 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<int> 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<int> 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_pIrcView->applyOptions();
+ KviWindow::applyOptions();
+}
+
+#include "listwindow.moc"
diff --git a/src/modules/list/listwindow.h b/src/modules/list/listwindow.h
new file mode 100644
index 00000000..8e7d510e
--- /dev/null
+++ b/src/modules/list/listwindow.h
@@ -0,0 +1,122 @@
+#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-2004 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 "kvi_window.h"
+#include "kvi_string.h"
+#include "kvi_ircsocket.h"
+#include "kvi_pointerlist.h"
+#include "kvi_sparser.h"
+#include "kvi_console.h"
+#include "kvi_irccontext.h"
+
+#include "kvi_tal_listview.h"
+#include "kvi_tal_popupmenu.h"
+#include <qtoolbutton.h>
+#include <qlineedit.h>
+
+class KviThemedLabel;
+
+class KviChannelListViewItemData
+{
+ friend class KviChannelListViewItem;
+ friend class KviListWindow;
+public:
+ KviChannelListViewItemData(const QString &szChan,const QString &szUsers,const QString &szTopic);
+ ~KviChannelListViewItemData();
+protected:
+ QString m_szChan;
+ QString m_szUsers;
+ QString m_szTopic;
+ QString m_szUsersKey;
+};
+
+class KviChannelListViewItem : public KviTalListViewItem
+{
+ friend class KviListWindow;
+public:
+ KviChannelListViewItem(KviTalListView * v,KviChannelListViewItemData * pData);
+ ~KviChannelListViewItem();
+protected:
+ KviChannelListViewItemData * m_pData;
+public:
+ const QString & channel(){ return m_pData->m_szChan; };
+#ifdef COMPILE_USE_QT4
+ int width ( const QFontMetrics & fm, const KviTalListView * lv, int column ) const;
+#else
+ int width ( const QFontMetrics & fm, const QListView * lv, int column ) const;
+#endif
+protected:
+ virtual void paintCell(QPainter * p,const QColorGroup &cg,int col,int wdth,int align);
+ virtual QString key(int col,bool) const;
+};
+
+
+
+class KviListWindow : public KviWindow, public KviExternalServerDataParser
+{
+ Q_OBJECT
+public:
+ KviListWindow(KviFrame * lpFrm,KviConsole * lpConsole);
+ ~KviListWindow();
+protected:
+ QSplitter * m_pVertSplitter;
+ QSplitter * m_pTopSplitter;
+ KviTalListView * m_pListView;
+ QLineEdit * m_pParamsEdit;
+ QToolButton * m_pRequestButton;
+ QToolButton * m_pStopListDownloadButton;
+ QToolButton * m_pOpenButton;
+ QToolButton * m_pSaveButton;
+ KviThemedLabel * m_pInfoLabel;
+ QTimer * m_pFlushTimer;
+ KviPointerList<KviChannelListViewItemData> * m_pItemList;
+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(KviStr &buffer);
+protected slots:
+ void flush();
+ void itemDoubleClicked(KviTalListViewItem *it);
+ void requestList();
+ void stoplistdownload();
+ void connectionStateChange();
+ void exportList();
+ void importList();
+public:
+ virtual QSize sizeHint() const;
+private:
+ void reset();
+ void endOfList();
+ void startOfList();
+};
+
+#endif //_KVI_LISTWINDOW_H_
diff --git a/src/modules/log/Makefile.am b/src/modules/log/Makefile.am
new file mode 100644
index 00000000..e2bfe1e9
--- /dev/null
+++ b/src/modules/log/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvilog.la
+
+libkvilog_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvilog_la_SOURCES = libkvilog.cpp
+libkvilog_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/log/libkvilog.cpp b/src/modules/log/libkvilog.cpp
new file mode 100644
index 00000000..5e29e30d
--- /dev/null
+++ b/src/modules/log/libkvilog.cpp
@@ -0,0 +1,309 @@
+//==============================================================================
+//
+// File : libkvilog.cpp
+// Creation date : Sat Jan 06 2001 13:28:02 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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_module.h"
+#include "kvi_window.h"
+#include "kvi_app.h"
+#include "kvi_locale.h"
+#include "kvi_ircview.h"
+
+
+//#warning "log.stats"
+//#warning "log.compress (gzip -r the log directory)"
+
+/*
+ @doc: log
+ @title:
+ The log interface module
+ @short:
+ Interface to the KVirc log subsystem
+ @type:
+ module
+ @keyterms:
+ logging
+ @body:
+ The log module is an interface to the KVIrc logging subsystem.[br]
+ It provides commands and functions that allow the management of
+ logging in the KVIrc windows:[br]
+ [cmd]log.start[/cmd], [cmd]log.stop[/cmd], [cmd]log.flush[/cmd],
+ [fnc]$log.file[/fnc]().[br]
+ NOTE:[br]
+ If you want to AUTOENABLE logging in certain types of windows
+ you have to use the [cmd]option[/cmd] command.[br]
+ For example, [b]option boolAutoLogQueries 1[/b] enables logging in all the newly created
+ query windows.
+*/
+
+/*
+ @doc: log.start
+ @type:
+ command
+ @title:
+ log.start
+ @keyterms:
+ logging
+ @short:
+ Starts logging in a specified window
+ @syntax:
+ log.start [-w = <window_id>] [-p] [filename]
+ @description:
+ Starts logging in the current window or in the window specified by the -w switch.[br]
+ If a logging session is already running in the specified window, it is stopped first.[br]
+ If [filename] is specified, this filename is used as log file, otherwise a default
+ filename is used.[br]
+ If the -p switch is used, all the already existing contents of the window are
+ stored to the log file before starting the log action.[br]
+ Please note that some windows do not have logging capabilities...this command
+ will print a warning in that case.[br]
+ @seealso:
+ [fnc]$window[/fnc],
+ [cmd]log.stop[/cmd],
+ [fnc]$log.file[/fnc],
+ [doc:window_naming_conventions]window naming conventions documentation[/doc]
+*/
+
+
+static bool log_kvs_cmd_start(KviKvsModuleCommandCall * c)
+{
+ QString szFile;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_STRING,KVS_PF_OPTIONAL,szFile)
+ KVSM_PARAMETERS_END(c)
+
+ KviWindow * pWnd = c->window();
+ if(c->hasSwitch('w',"window"))
+ {
+ QString szWindow;
+ if(c->switches()->getAsStringIfExisting('w',"window",szWindow))
+ {
+ pWnd = g_pApp->findWindow(szWindow);
+ if(!pWnd)
+ {
+ c->warning(__tr2qs("Window %Q not found"),&szWindow);
+ return true;
+ }
+
+ } else {
+ c->warning(__tr2qs("Missing window id after the 'w' switch"));
+ return true;
+ }
+ }
+
+ if(pWnd->view())
+ {
+
+ if(szFile.isEmpty())
+ {
+ pWnd->getDefaultLogFileName(szFile);
+ }
+ if(!pWnd->view()->startLogging(szFile,c->hasSwitch('p',"log-buffer")))
+ c->warning(__tr2qs("Can't log to file %Q"),&szFile);
+ } else {
+ c->warning(__tr2qs("This window has no logging capabilities"));
+ return true;
+ }
+ return true;
+}
+
+/*
+ @doc: log.stop
+ @type:
+ command
+ @title:
+ log.stop
+ @keyterms:
+ logging
+ @short:
+ Stops logging in a specified window
+ @syntax:
+ log.stop [-w = <window_id>]
+ @description:
+ Stops logging in the current window or in the window specified by the -w switch.[br]
+ If logging is not enabled in the specified window, this command does nothing.[br]
+ @seealso:
+ [fnc]$window[/fnc],
+ [cmd]log.start[/cmd],
+ [doc:window_naming_conventions]window naming conventions documentation[/doc]
+*/
+
+static bool log_kvs_cmd_stop(KviKvsModuleCommandCall * c)
+{
+
+ KviWindow * pWnd = c->window();
+ if(c->hasSwitch('w',"window"))
+ {
+ QString szWindow;
+ if(c->switches()->getAsStringIfExisting('w',"window",szWindow))
+ {
+ pWnd = g_pApp->findWindow(szWindow);
+ if(!pWnd)
+ {
+ c->warning(__tr2qs("Window %Q not found"),&szWindow);
+ return true;
+ }
+
+ } else {
+ c->warning(__tr2qs("Missing window id after the 'w' switch"));
+ return true;
+ }
+ }
+
+ if(pWnd->view())
+ pWnd->view()->stopLogging();
+ return true;
+}
+
+/*
+ @doc: log.flush
+ @type:
+ command
+ @title:
+ log.flush
+ @keyterms:
+ logging
+ @short:
+ Flushes the log file for a specified window
+ @syntax:
+ log.flush [-w = <window_id>]
+ @description:
+ Flushes the log file the current window or in the window specified by the -w switch.[br]
+ If logging is not enabled in the specified window, this command does nothing.[br]
+ If this command is never used, the log file is flushed at regulear file-size intervals,
+ depending on the underlying IO subsystem. This is usually 4KB.[br]
+ The "block flushing" is used to achieve a fast I/O on files, but may cause
+ the last data block to be lost in case of a program crash.[br]
+ @seealso:
+ [fnc]$window[/fnc],
+ [cmd]log.start[/cmd],
+ [cmd]log.stop[/cmd],
+ [doc:window_naming_conventions]window naming conventions documentation[/doc]
+*/
+
+static bool log_kvs_cmd_flush(KviKvsModuleCommandCall * c)
+{
+
+ KviWindow * pWnd = c->window();
+ if(c->hasSwitch('w',"window"))
+ {
+ QString szWindow;
+ if(c->switches()->getAsStringIfExisting('w',"window",szWindow))
+ {
+ pWnd = g_pApp->findWindow(szWindow);
+ if(!pWnd)
+ {
+ c->warning(__tr2qs("Window %Q not found"),&szWindow);
+ return true;
+ }
+
+ } else {
+ c->warning(__tr2qs("Missing window id after the 'w' switch"));
+ return true;
+ }
+ }
+
+ if(pWnd->view())
+ pWnd->view()->flushLog();
+ return true;
+}
+
+/*
+ @doc: log.file
+ @type:
+ function
+ @title:
+ $log.file
+ @short:
+ Returns the current log filename
+ @syntax:
+ $log.file
+ $log.file(<window id>)
+ @description:
+ The form with the <window id> parameter returns the log file name
+ of the window that has the specified id. If logging is not enabled
+ in the specified window, this function returns an empty string.[br]
+ The form without parameters returns the log file name of the current window,
+ thus it is equivalent to calling $log.file([fnc]$window[/fnc])
+ @examples:
+ [example]
+ [cmd]log[/cmd] mylogfilename.log
+ [cmd]echo[/cmd] $log
+ [cmd]echo[/cmd] $log([fnc]$console[/fnc])
+ [/example]
+ @seealso:
+ [fnc]$window[/fnc],
+ [cmd]log.start[/cmd],
+ [cmd]log.stop[/cmd],
+ [doc:window_naming_conventions]window naming conventions documentation[/doc]
+*/
+
+static bool log_kvs_fnc_file(KviKvsModuleFunctionCall * c)
+{
+ QString szWindow;
+ QString buffer;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWindow)
+ KVSM_PARAMETERS_END(c)
+
+ KviWindow * wnd = c->window();
+
+ if(!szWindow.isEmpty())
+ {
+ wnd = g_pApp->findWindow(szWindow);
+ if(!wnd)
+ {
+ c->warning(__tr2qs("Window with id '%Q' not found, returning empty string"),&szWindow);
+ return true;
+ }
+ }
+
+ if(wnd->view())wnd->view()->getLogFileName(buffer);
+ c->returnValue()->setString(buffer);
+ return true;
+}
+
+static bool log_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"start",log_kvs_cmd_start);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"stop",log_kvs_cmd_stop);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"flush",log_kvs_cmd_flush);
+
+ KVSM_REGISTER_FUNCTION(m,"file",log_kvs_fnc_file);
+ return true;
+}
+
+static bool log_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "Log", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "User interface to the logging system for KVIrc",
+ log_module_init,
+ 0,
+ 0,
+ log_module_cleanup
+)
diff --git a/src/modules/logview/Makefile.am b/src/modules/logview/Makefile.am
new file mode 100644
index 00000000..03a1b07e
--- /dev/null
+++ b/src/modules/logview/Makefile.am
@@ -0,0 +1,23 @@
+###############################################################################
+# KVirc IRC client Makefile - 3.23.2002 Juanjo lvarez <juanjux@yahoo.es>
+###############################################################################
+
+SUBDIRS = caps
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvilogview.la
+
+libkvilogview_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvilogview_la_SOURCES = libkvilogview.cpp logviewwidget.cpp logviewmdiwindow.cpp
+libkvilogview_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= logviewwidget.h logviewmdiwindow.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+logviewwidget.cpp: logviewwidget.moc
+logviewmdiwindow.cpp: logviewmdiwindow.moc
diff --git a/src/modules/logview/caps/Makefile.am b/src/modules/logview/caps/Makefile.am
new file mode 100644
index 00000000..13c80350
--- /dev/null
+++ b/src/modules/logview/caps/Makefile.am
@@ -0,0 +1,9 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir = $(pluglibdir)/caps/tool/
+
+tmp_DATA= logview
+
+EXTRA_DIST = $(tmp_DATA)
diff --git a/src/modules/logview/caps/logview b/src/modules/logview/caps/logview
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/modules/logview/caps/logview
diff --git a/src/modules/logview/libkvilogview.cpp b/src/modules/logview/libkvilogview.cpp
new file mode 100644
index 00000000..2aa56a66
--- /dev/null
+++ b/src/modules/logview/libkvilogview.cpp
@@ -0,0 +1,170 @@
+//
+// File : libkvilogview.cpp
+// Creation date : Sun Feb 10 2000 23:25:10 CEST by Juanjo �varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 "logviewmdiwindow.h"
+
+#include "kvi_config.h"
+
+#include "kvi_module.h"
+
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+
+static QRect g_rectLogViewGeometry;
+KviLogViewMDIWindow * g_pLogViewWindow = 0;
+
+#define LOGVIEW_MODULE_EXTENSION_NAME "Log viewer extension"
+
+/*
+ @doc: logview.open
+ @type:
+ command
+ @title:
+ logview.open
+ @short:
+ Opens the log viewer window
+ @syntax:
+ logview.open [-m] [-n]
+ @switches:
+ !sw: -m
+ Causes the window to be created as minimized
+ !sw: -n
+ Causes the window to be not raised if already open
+ @description:
+ Opens a window that allows visual browsing of the logs
+ stored on disk.
+*/
+
+// ============================================
+// Module stuff
+// ============================================
+
+static bool logview_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ KviModuleExtensionDescriptor * d = c->module()->findExtensionDescriptor("tool",LOGVIEW_MODULE_EXTENSION_NAME);
+ if(d)
+ {
+ KviPointerHashTable<QString,QVariant> dict(17,true);
+ dict.setAutoDelete(true);
+ QString dummy;
+ dict.replace("bCreateMinimized",new QVariant(c->hasSwitch('m',dummy)));
+ dict.replace("bNoRaise",new QVariant(c->hasSwitch('n',dummy)));
+
+ d->allocate(c->window(),&dict,0);
+ } else {
+ c->warning("Ops.. internal error");
+ }
+ return true;
+}
+
+static KviModuleExtension * logview_extension_alloc(KviModuleExtensionAllocStruct * s)
+{
+ bool bCreateMinimized = false;
+ bool bNoRaise = false;
+
+ if(!g_pLogViewWindow)
+ {
+ if(s->pParams)
+ {
+ if(QVariant * v = s->pParams->find("bCreateMinimized"))
+ {
+ if(v->isValid())
+ {
+ if(v->type() == QVariant::Bool)
+ {
+ bCreateMinimized = v->toBool();
+ }
+ }
+ }
+ }
+
+ g_pLogViewWindow = new KviLogViewMDIWindow(s->pDescriptor,g_pFrame);
+ g_pFrame->addWindow(g_pLogViewWindow,!bCreateMinimized);
+ if(bCreateMinimized)g_pLogViewWindow->minimize();
+ return g_pLogViewWindow;
+ }
+
+ if(s->pParams)
+ {
+ if(QVariant * v = s->pParams->find("bNoRaise"))
+ {
+ if(v)
+ {
+ if(v->isValid() && v->type() == QVariant::Bool)
+ bNoRaise = v->toBool();
+ }
+ }
+ }
+
+ if(!bNoRaise)g_pLogViewWindow->delayedAutoRaise();
+ return g_pLogViewWindow;
+}
+
+
+static bool logview_module_init(KviModule * m)
+{
+ g_pLogViewWindow = 0;
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",logview_kvs_cmd_open);
+
+
+
+ KviModuleExtensionDescriptor * d = m->registerExtension("tool",
+ LOGVIEW_MODULE_EXTENSION_NAME,
+ __tr2qs_ctx("Browse &Log Files","logview"),
+ logview_extension_alloc);
+
+ if(d)d->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LOG)));
+
+ return true;
+}
+
+static bool logview_module_cleanup(KviModule * m)
+{
+ if(g_pLogViewWindow)delete g_pLogViewWindow;
+ g_pLogViewWindow = 0;
+ return true;
+}
+
+static bool logview_module_can_unload(KviModule *m)
+{
+ return (!g_pLogViewWindow);
+}
+
+
+// ============================================
+// module definition structure
+// ============================================
+
+KVIRC_MODULE(
+ "KVIrc Log Viewer Widget",
+ "1.0.0",
+ "Juanjo Alvarez <juanjux@yahoo.es>",
+ "An structured log file viewer",
+ logview_module_init,
+ logview_module_can_unload,
+ 0,
+ logview_module_cleanup
+)
diff --git a/src/modules/logview/logviewmdiwindow.cpp b/src/modules/logview/logviewmdiwindow.cpp
new file mode 100644
index 00000000..20a2a232
--- /dev/null
+++ b/src/modules/logview/logviewmdiwindow.cpp
@@ -0,0 +1,477 @@
+//
+// File : logviewmdiwindow.cpp
+// Creation date : Tue Apr 23 2002 18:08:22 by Juanjo �varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 "kvi_iconmanager.h"
+#include "kvi_locale.h"
+#include "kvi_module.h"
+#include "kvi_options.h"
+#include "kvi_frame.h"
+#include "kvi_ircview.h"
+#include "kvi_qstring.h"
+#include "kvi_qcstring.h"
+#include "kvi_app.h"
+#include "kvi_fileutils.h"
+#ifdef COMPILE_USE_QT4
+ #include <q3progressdialog.h>
+#else
+ #include <qprogressdialog.h>
+#endif
+#include "kvi_valuelist.h"
+#include "kvi_accel.h"
+#include <qpixmap.h>
+#include <qsplitter.h>
+#include <qtoolbutton.h>
+#include "kvi_tal_listview.h"
+#include <qfileinfo.h>
+#include <qdir.h>
+#include "kvi_tal_popupmenu.h"
+#include <qcursor.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+
+
+
+#ifdef COMPILE_ZLIB_SUPPORT
+ #include <zlib.h>
+#endif
+#include <qtextcodec.h>
+#include "kvi_styled_controls.h"
+#include <qdatetimeedit.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+
+extern KviLogViewMDIWindow * g_pLogViewWindow;
+
+KviLogViewMDIWindow::KviLogViewMDIWindow(KviModuleExtensionDescriptor * d,KviFrame * lpFrm)
+: KviWindow(KVI_WINDOW_TYPE_LOGVIEW,lpFrm,"logview"), KviModuleExtension(d)
+{
+ g_pLogViewWindow = this;
+// m_pLogViewWidget = new KviLogViewWidget(this);
+ #ifdef COMPILE_USE_QT4
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"main_splitter");
+#else
+ m_pSplitter = new QSplitter(QSplitter::Horizontal,this,"main_splitter");
+#endif
+ m_pTabWidget = new QTabWidget(m_pSplitter);
+
+ m_pIndexTab = new KviTalVBox(m_pTabWidget);
+ m_pTabWidget->insertTab(m_pIndexTab,__tr2qs_ctx("Index","logview"));
+ m_pListView = new KviTalListView(m_pIndexTab);
+ m_pListView->addColumn(__tr2qs_ctx("Log File","logview"),135);
+ m_pListView->setColumnWidthMode(0,KviTalListView::Maximum);
+ m_pListView->setAllColumnsShowFocus(true);
+ m_pListView->setMultiSelection(false);
+ m_pListView->setShowSortIndicator(true);
+ m_pListView->setRootIsDecorated(true);
+ connect(m_pListView,SIGNAL(selectionChanged(KviTalListViewItem *)),this,SLOT(itemSelected(KviTalListViewItem *)));
+ connect(m_pListView,SIGNAL(rightButtonClicked ( KviTalListViewItem * , const QPoint &, int )),this,SLOT(rightButtonClicked ( KviTalListViewItem * , const QPoint &, int )));
+
+ m_pSearchTab = new QWidget(m_pTabWidget);
+ m_pTabWidget->insertTab(m_pSearchTab,__tr2qs_ctx("Filter","logview"));
+
+ QGridLayout *layout = new QGridLayout(m_pSearchTab,10,2,3,5);
+
+ m_pShowChannelsCheck = new KviStyledCheckBox(__tr2qs_ctx("Show channel logs","logview"),m_pSearchTab);
+ m_pShowChannelsCheck->setChecked(true);
+ layout->addMultiCellWidget(m_pShowChannelsCheck,0,0,0,1);
+
+ m_pShowQueryesCheck = new KviStyledCheckBox(__tr2qs_ctx("Show query logs","logview"),m_pSearchTab);
+ m_pShowQueryesCheck->setChecked(true);
+ layout->addMultiCellWidget(m_pShowQueryesCheck,1,1,0,1);
+
+ m_pShowConsolesCheck = new KviStyledCheckBox(__tr2qs_ctx("Show console logs","logview"),m_pSearchTab);
+ m_pShowConsolesCheck->setChecked(true);
+ layout->addMultiCellWidget(m_pShowConsolesCheck,2,2,0,1);
+
+ m_pShowDccChatCheck = new KviStyledCheckBox(__tr2qs_ctx("Show DCC chat logs","logview"),m_pSearchTab);
+ m_pShowDccChatCheck->setChecked(true);
+ layout->addMultiCellWidget(m_pShowDccChatCheck,3,3,0,1);
+
+ m_pShowOtherCheck = new KviStyledCheckBox(__tr2qs_ctx("Show other logs","logview"),m_pSearchTab);
+ m_pShowOtherCheck->setChecked(true);
+ layout->addMultiCellWidget(m_pShowOtherCheck,4,4,0,1);
+
+ QLabel *l;
+ l = new QLabel(__tr2qs_ctx("Contents filter","logview"),m_pSearchTab);
+ layout->addMultiCellWidget(l,5,5,0,1);
+
+ 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 KviStyledCheckBox(__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 KviStyledCheckBox(__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);
+
+ QPushButton *pb = new QPushButton(__tr2qs_ctx("Apply filter","logview"),m_pSearchTab);
+ connect(pb,SIGNAL(clicked()),this,SLOT(applyFilter()));
+ layout->addWidget(pb,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);
+#ifdef COMPILE_USE_QT4
+ m_pIrcView->setFocusPolicy(Qt::ClickFocus);
+#else
+ m_pIrcView->setFocusPolicy(QWidget::ClickFocus);
+#endif
+ KviValueList<int> li;
+ li.append(110);
+ li.append(width()-110);
+ m_pSplitter->setSizes(li);
+
+ g_pApp->getLocalKvircDirectory(m_szLogDirectory,KviApp::Log);
+ KviQString::ensureLastCharIs(m_szLogDirectory,'/'); // Does this work on Windows?
+
+ cacheFileList();
+ setupItemList();
+ KviAccel *a = new KviAccel( this );
+ a->connectItem( a->insertItem(Qt::Key_F+Qt::CTRL),
+ m_pIrcView,
+ SLOT(toggleToolWidget()) );
+}
+
+
+
+KviLogViewMDIWindow::~KviLogViewMDIWindow()
+{
+ g_pLogViewWindow = 0;
+}
+
+void KviLogViewMDIWindow::applyFilter()
+{
+ setupItemList();
+}
+
+
+QPixmap * KviLogViewMDIWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_LOG);
+}
+
+
+void KviLogViewMDIWindow::resizeEvent(QResizeEvent *e)
+{
+ m_pSplitter->setGeometry(0,0,width(),height());
+}
+
+void KviLogViewMDIWindow::fillCaptionBuffers()
+{
+ m_szPlainTextCaption = __tr2qs_ctx("Log Viewer","logview");
+
+ m_szHtmlActiveCaption = QString("<nobr><font color=\"%1\"><b>").arg(KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii());
+ m_szHtmlActiveCaption.append(m_szPlainTextCaption);
+ m_szHtmlActiveCaption.append("</b></font></nobr>");
+
+ m_szHtmlInactiveCaption = QString("<nobr><font color=\"%1\"><b>").arg(KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii());
+ m_szHtmlInactiveCaption.append(m_szPlainTextCaption);
+ m_szHtmlInactiveCaption.append("</b></font></nobr>");
+}
+
+void KviLogViewMDIWindow::die()
+{
+ close();
+}
+
+QSize KviLogViewMDIWindow::sizeHint() const
+{
+ QSize ret(m_pSplitter->sizeHint().width(),m_pIrcView->sizeHint().height());
+ return ret;
+}
+
+void KviLogViewMDIWindow::setupItemList()
+{
+ m_pListView->clear();
+ KviLogFile *pFile;
+ //m_logList.begin();
+ KviLogListViewItem *pLastCategory=0;
+ KviLogListViewItemFolder *pLastGroupItem;
+ QString szLastGroup;
+ QString szCurGroup;
+ const bool bShowChannel=m_pShowChannelsCheck->isChecked();
+ const bool bShowQuery=m_pShowQueryesCheck->isChecked();
+ const bool bShowConsole=m_pShowConsolesCheck->isChecked();
+ const bool bShowOther=m_pShowOtherCheck->isChecked();
+ const bool bShowDccChat=m_pShowDccChatCheck->isChecked();
+
+ const bool filterFromDate=m_pEnableFromFilter->isChecked();
+ const bool filterToDate=m_pEnableToFilter->isChecked();
+
+ const QString nameFilterText = m_pFileNameMask->text();
+ const bool enableNameFilter = !nameFilterText.isEmpty();
+
+ const QString contentFilterText = m_pContentsMask->text();
+ const bool enableContentFilter = !contentFilterText.isEmpty();
+
+ QDate fromDate = m_pFromDateEdit->date();
+ QDate toDate = m_pToDateEdit->date();
+
+ QString textBuffer;
+#ifdef COMPILE_USE_QT4
+ Q3ProgressDialog progress( __tr2qs_ctx("Filtering files...","logview"),
+ __tr2qs_ctx("Abort filtering","logview"), m_logList.count(),
+ this, "progress", TRUE );
+#else
+ QProgressDialog progress( __tr2qs_ctx("Filtering files...","logview"),
+ __tr2qs_ctx("Abort filtering","logview"), m_logList.count(),
+ this, "progress", TRUE );
+#endif
+
+
+ int i=0;
+ for(pFile=m_logList.first();pFile;pFile=m_logList.next())
+ {
+ progress.setProgress( i );
+ i++;
+ g_pApp->processEvents();
+
+ if ( progress.wasCanceled() )
+ break;
+
+ if(pFile->type()==KviLogFile::Channel && !bShowChannel)
+ continue;
+ if(pFile->type()==KviLogFile::Console && !bShowConsole)
+ continue;
+ if(pFile->type()==KviLogFile::DccChat && !bShowDccChat)
+ continue;
+ if(pFile->type()==KviLogFile::Other && !bShowOther)
+ continue;
+ if(pFile->type()==KviLogFile::Query && !bShowQuery)
+ continue;
+
+ if(filterFromDate)
+ if(pFile->date()<fromDate)
+ continue;
+
+ if(filterToDate)
+ if(pFile->date()>toDate)
+ continue;
+
+ if(enableNameFilter)
+ if(!KviQString::matchStringCI(nameFilterText,pFile->name()))
+ continue;
+
+ if(enableContentFilter)
+ {
+ pFile->getText(textBuffer,m_szLogDirectory);
+ if(!KviQString::matchStringCI(contentFilterText,textBuffer))
+ continue;
+ }
+
+ if(pLastCategory)
+ {
+ if(pLastCategory->m_type!=pFile->type())
+ pLastCategory = new KviLogListViewItemType(m_pListView,pFile->type());
+ } else {
+ pLastCategory = new KviLogListViewItemType(m_pListView,pFile->type());
+ }
+
+ KviQString::sprintf(szCurGroup,__tr2qs_ctx("%Q on %Q","logview"),&(pFile->name()),
+ &(pFile->network())
+ );
+
+ if(szLastGroup!=szCurGroup) {
+ szLastGroup=szCurGroup;
+ pLastGroupItem=new KviLogListViewItemFolder(pLastCategory,szLastGroup);
+ }
+ new KviLogListViewLog(pLastGroupItem,pFile->type(),pFile);
+ }
+ progress.setProgress( m_logList.count() );
+}
+
+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.extension(false)=="gz" || fi.extension(false)=="log")
+ m_logList.append(new KviLogFile(szFname));
+ }
+}
+
+void KviLogViewMDIWindow::itemSelected(KviTalListViewItem * it)
+{
+ bool bCompressed=0;
+ //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=QStringList::split('\n',text);
+ 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(false);
+}
+
+QStringList KviLogViewMDIWindow::getFileNames()
+{
+ QString logPath;
+ g_pApp->getLocalKvircDirectory(logPath,KviApp::Log);
+ QString qPath(logPath);
+ QDir logDir(qPath);
+ return logDir.entryList();
+}
+
+void KviLogViewMDIWindow::rightButtonClicked ( KviTalListViewItem * it, const QPoint &, int )
+{
+ if(!it) return;
+ if(((KviLogListViewItem *)it)->fileName(0).isEmpty()) return;
+ KviTalPopupMenu* popup = new KviTalPopupMenu(this);
+ 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->fileName(0).isNull())
+ {
+ QString szFname;
+ g_pApp->getLocalKvircDirectory(szFname,KviApp::Log,pItem->m_pFileData->fileName());
+ KviFileUtils::removeFile(szFname);
+ delete pItem;
+ m_pIrcView->clearBuffer();
+ }
+ }
+}
+
+KviLogFile::KviLogFile(const QString& name)
+{
+ m_szFilename=name;
+ QFileInfo fi(m_szFilename);
+ m_bCompressed=(fi.extension(false)=="gz");
+ QString typeToken = m_szFilename.section('_',0,0);
+ // Ignore non-logs files, this includes '.' and '..'
+ if( KviQString::equalCI(typeToken,"channel") )
+ m_type = Channel;
+ else if( KviQString::equalCI(typeToken,"console") )
+ m_type = Console;
+ else if( KviQString::equalCI(typeToken,"dccchat") )
+ m_type = DccChat;
+ else if( KviQString::equalCI(typeToken,"query") )
+ m_type = Query;
+ else
+ m_type = Other;
+
+ KviStr undecoded = m_szFilename.section('.',0,0);
+ undecoded.cutToFirst('_');
+ m_szName = undecoded.hexDecode(undecoded.ptr()).ptr();
+
+ undecoded = m_szFilename.section('.',1,1).section('_',0,0);
+ m_szNetwork = undecoded.hexDecode(undecoded.ptr()).ptr();
+
+ QString szDate = m_szFilename.section('.',1,3).section('_',1,1);
+ 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);
+
+ //debug("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.local8Bit().data(),"rb");
+ if(file)
+ {
+ char buff[1025];
+ int len;
+ KviQCString 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 {
+ debug("Cannot open compressed file %s",logName.local8Bit().data());
+ }
+ } else {
+#endif
+ logFile.setName(logName);
+
+ if(!logFile.open(IO_ReadOnly))
+ return;
+
+ QByteArray bytes;
+ bytes=logFile.readAll();
+ text = QString::fromUtf8(bytes.data(), bytes.size());
+ logFile.close();
+#ifdef COMPILE_ZLIB_SUPPORT
+ }
+#endif
+}
+
+#include "logviewmdiwindow.moc"
diff --git a/src/modules/logview/logviewmdiwindow.h b/src/modules/logview/logviewmdiwindow.h
new file mode 100644
index 00000000..df4bb245
--- /dev/null
+++ b/src/modules/logview/logviewmdiwindow.h
@@ -0,0 +1,125 @@
+#ifndef _LOGVIEWMDIWINDOW_H_
+#define _LOGVIEWMDIWINDOW_H_
+//
+// File : logviewmdiwindow.h
+// Creation date : Tue Apr 23 2002 18:05:59 by Juanjo �varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2007 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 "kvi_window.h"
+#include "kvi_moduleextension.h"
+
+#include "kvi_tal_vbox.h"
+#include "kvi_tal_listview.h"
+#include "kvi_pointerlist.h"
+#include <qtabwidget.h>
+#include <qdatetime.h>
+
+class KviTalListView;
+class QStringList;
+class KviLogViewWidget;
+class QCheckBox;
+class QLineEdit;
+class QDateEdit;
+
+class KviLogFile {
+
+public:
+
+ enum KviLogTypes {
+ Channel,
+ Console,
+ Query,
+ DccChat,
+ Other
+ };
+
+ KviLogFile(const QString& name);
+
+ const QString & fileName() { return m_szFilename; };
+ const QString & name() { return m_szName; };
+ const QString & network() { return m_szNetwork; };
+ const QDate & date() { return m_date; };
+
+ void getText(QString & text,const QString& logDir);
+
+ KviLogTypes type() { return m_type; };
+private:
+ KviLogTypes m_type;
+ QString m_szFilename;
+ bool m_bCompressed;
+ QString m_szName;
+ QString m_szNetwork;
+ QDate m_date;
+};
+
+class KviLogViewMDIWindow : public KviWindow , public KviModuleExtension
+{
+ Q_OBJECT
+public:
+ KviLogViewMDIWindow(KviModuleExtensionDescriptor * d,KviFrame * lpFrm);
+ ~KviLogViewMDIWindow();
+protected:
+ KviPointerList<KviLogFile> m_logList;
+
+ KviTalListView * 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;
+ QWidget * m_pSearchTab;
+protected:
+ QStringList getFileNames();
+
+ void setupItemList();
+ void cacheFileList();
+
+ virtual QPixmap * myIconPtr();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void fillCaptionBuffers();
+ virtual void die();
+ virtual QSize sizeHint() const;
+protected slots:
+ void rightButtonClicked ( KviTalListViewItem *, const QPoint &, int );
+ void itemSelected(KviTalListViewItem * it);
+ void deleteCurrent();
+ void applyFilter();
+};
+
+#endif //_LOGVIEWMDIWINDOW_H_
+
diff --git a/src/modules/logview/logviewwidget.cpp b/src/modules/logview/logviewwidget.cpp
new file mode 100644
index 00000000..fc5c8abc
--- /dev/null
+++ b/src/modules/logview/logviewwidget.cpp
@@ -0,0 +1,76 @@
+//
+// File : logviewwidget.cpp
+// Creation date : Thu Apr 23 2002 17:42:12 by Juanjo �varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 <qsplitter.h>
+#include <qlayout.h>
+#include <qdir.h>
+
+//#include "kvi_debug.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_app.h"
+
+#include "kvi_qstring.h"
+#ifdef COMPILE_ZLIB_SUPPORT
+ #include <zlib.h>
+#endif
+#include <qtextcodec.h>
+
+const QPixmap * KviLogListViewItemType::pixmap(int col) const
+{
+
+ switch(m_type)
+ {
+ case KviLogFile::Channel:
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL);
+ case KviLogFile::Query:
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_QUERY);
+ case KviLogFile::DccChat:
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG);
+ case KviLogFile::Console:
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE);
+ default:
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_HELP);
+ }
+}
+
+QString KviLogListViewItemType::text(int col) const
+{
+ switch(m_type)
+ {
+ case KviLogFile::Channel:
+ return __tr2qs_ctx("Channel","logview");
+ case KviLogFile::Query:
+ return __tr2qs_ctx("Query","logview");
+ case KviLogFile::DccChat:
+ return __tr2qs_ctx("DCC Chat","logview");
+ case KviLogFile::Console:
+ return __tr2qs_ctx("Console","logview");
+ default:
+ return __tr2qs_ctx("Other","logview");
+ }
+};
+
+
+#include "logviewwidget.moc"
diff --git a/src/modules/logview/logviewwidget.h b/src/modules/logview/logviewwidget.h
new file mode 100644
index 00000000..1b5eff97
--- /dev/null
+++ b/src/modules/logview/logviewwidget.h
@@ -0,0 +1,86 @@
+#ifndef _LOGVIEWWIDGET_H_
+#define _LOGVIEWWIDGET_H_
+
+//
+// File : logviewwidget.h
+// Creation date : Thue Apr 23 2002 03:01:53 CET by Juanjo �varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2003 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_window.h"
+#include "kvi_scripteditor.h"
+#include "logviewmdiwindow.h"
+
+#include "kvi_tal_listview.h"
+
+
+class KviScriptEditor;
+
+class KviLogListViewItem : public KviTalListViewItem
+{
+public:
+ KviLogListViewItem(KviTalListViewItem * par, KviLogFile::KviLogTypes type, KviLogFile * fileData)
+ : KviTalListViewItem(par), m_type(type), m_pFileData(fileData) {};
+ KviLogListViewItem(KviTalListView * par, KviLogFile::KviLogTypes type, KviLogFile * fileData)
+ : KviTalListViewItem(par), m_type(type), m_pFileData(fileData) {};
+ ~KviLogListViewItem() {};
+public:
+ KviLogFile::KviLogTypes m_type;
+ KviLogFile* m_pFileData;
+
+ virtual QString fileName(int col) const { return m_pFileData ? m_pFileData->name() : QString::null; };
+ virtual QString text(int col) const { return m_pFileData ? m_pFileData->name() : QString::null; };
+};
+
+class KviLogListViewItemFolder : public KviLogListViewItem
+{
+public:
+ KviLogListViewItemFolder(KviTalListViewItem * par, const QString& label)
+ : KviLogListViewItem(par,KviLogFile::Other,0),m_szLabel(label) {};
+ ~KviLogListViewItemFolder() {};
+public:
+ QString m_szLabel;
+ virtual QString text(int col) const { return m_szLabel; };
+};
+
+class KviLogListViewItemType : public KviLogListViewItem
+{
+public:
+ KviLogListViewItemType(KviTalListView * par, KviLogFile::KviLogTypes type)
+ : KviLogListViewItem(par,type,0) {};
+ ~KviLogListViewItemType() {};
+public:
+ virtual const QPixmap * pixmap(int col) const;
+ virtual QString text(int col) const;
+};
+
+
+class KviLogListViewLog : public KviLogListViewItem
+{
+public:
+ KviLogListViewLog(KviTalListViewItem * par, KviLogFile::KviLogTypes type, KviLogFile * fileData)
+ : KviLogListViewItem(par,type,fileData){};
+ ~KviLogListViewLog() {};
+ virtual QString key ( int column, bool ascending ) const { return m_pFileData->date().toString("yyyy.MM.dd"); };
+ virtual QString text(int col) const { return m_pFileData->date().toString("dd.MM.yyyy"); };
+};
+
+
+#endif
+
diff --git a/src/modules/mask/Makefile.am b/src/modules/mask/Makefile.am
new file mode 100644
index 00000000..0ca529fe
--- /dev/null
+++ b/src/modules/mask/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvimask.la
+
+libkvimask_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvimask_la_SOURCES = libkvimask.cpp
+libkvimask_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/mask/libkvimask.cpp b/src/modules/mask/libkvimask.cpp
new file mode 100644
index 00000000..3f8be4b2
--- /dev/null
+++ b/src/modules/mask/libkvimask.cpp
@@ -0,0 +1,201 @@
+//
+// File : libkvistr.cpp
+// Creation date : Thu Dec 27 2001 17:13:12 GMT by Szymon Stefanek
+//
+// This str 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_module.h"
+
+#include "kvi_locale.h"
+#include "kvi_string.h"
+#include "kvi_ircmask.h"
+
+ /*
+ @doc: mask.match
+ @type:
+ function
+ @title:
+ $mask.match
+ @short:
+ Matches a mask agains a wildcarded one
+ @syntax:
+ <boolean> $mask.match(<wildcard_mask:string>,<fixed_mask:string>)
+ @description:
+ Returns 1 if the <wildcard_mask> matches <fixed_mask> and 0 otherwise.
+ <wildcard_mask> can obviously contain wildcards ('*' and '?').
+ @example:
+ [example]
+ [cmd]if[/cmd]($mask.match(*!*@*.linux.it,$0))
+ [cmd]op[/cmd] [fnc]$mask.nick[/fnc]($0)
+ [/example]
+ */
+
+static bool mask_kvs_fnc_match(KviKvsModuleFunctionCall * c)
+{
+
+ QString wildmask,fixedmask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("wildcard mask",KVS_PT_STRING,0,wildmask)
+ KVSM_PARAMETER("fixed mask",KVS_PT_STRING,0,fixedmask)
+ KVSM_PARAMETERS_END(c)
+ KviIrcMask mk1(wildmask);
+ KviIrcMask mk2(fixedmask);
+ c->returnValue()->setBoolean(mk1.matchesFixed(mk2.nick(),mk2.user(),mk2.host()));
+ return true;
+}
+
+ /*
+ @doc: mask.nick
+ @type:
+ function
+ @title:
+ $mask.nick
+ @short:
+ Returns the nick part of an IRC mask
+ @syntax:
+ <string> $mask.nick(<mask:string>)
+ @description:
+ Returns the nickname part of an IRC mask.
+ */
+
+static bool mask_kvs_fnc_nick(KviKvsModuleFunctionCall * c)
+{
+
+ QString mask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,mask)
+ KVSM_PARAMETERS_END(c)
+ KviIrcMask mk(mask);
+ c->returnValue()->setString(mk.nick());
+ return true;
+}
+
+ /*
+ @doc: mask.user
+ @type:
+ function
+ @title:
+ $mask.user
+ @short:
+ Returns the username part of an IRC mask
+ @syntax:
+ <string> $mask.user(<mask:string>)
+ @description:
+ Returns the username part of an IRC mask.
+ */
+
+static bool mask_kvs_fnc_user(KviKvsModuleFunctionCall * c)
+{
+
+ QString mask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,mask)
+ KVSM_PARAMETERS_END(c)
+ KviIrcMask mk(mask);
+ c->returnValue()->setString(mk.user());
+ return true;
+}
+
+
+ /*
+ @doc: mask.host
+ @type:
+ function
+ @title:
+ $mask.host
+ @short:
+ Returns the hostname part of an IRC mask
+ @syntax:
+ <string> $mask.host(<mask:string>)
+ @description:
+ Returns the hostname part of an IRC mask.
+ */
+
+static bool mask_kvs_fnc_host(KviKvsModuleFunctionCall * c)
+{
+ QString mask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,mask)
+ KVSM_PARAMETERS_END(c)
+ KviIrcMask mk(mask);
+ c->returnValue()->setString(mk.host());
+ return true;
+}
+
+
+ /*
+ @doc: mask.hasnumerichost
+ @type:
+ function
+ @title:
+ $mask.hasNumericHost
+ @short:
+ Checks if a host part of a mask is numeric
+ @syntax:
+ <boolean> $mask.hasNumericHost(<mask: string>)
+ @description:
+ Returns 1 if the hostname part of the mask is numeric (e.g : unresolved IPV4 or IPV6 address)
+ */
+
+
+static bool mask_kvs_fnc_hasnumerichost(KviKvsModuleFunctionCall * c)
+{
+ QString mask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,mask)
+ KVSM_PARAMETERS_END(c)
+ KviIrcMask mk(mask);
+ c->returnValue()->setBoolean(mk.hasNumericHost());
+ return true;
+}
+
+
+/*********************************************************************/
+// Module stuff
+/********************************************************************/
+
+
+
+static bool mask_module_init(KviModule * m)
+{
+ KVSM_REGISTER_FUNCTION(m,"match",mask_kvs_fnc_match);
+ KVSM_REGISTER_FUNCTION(m,"nick",mask_kvs_fnc_nick);
+ KVSM_REGISTER_FUNCTION(m,"user",mask_kvs_fnc_user);
+ KVSM_REGISTER_FUNCTION(m,"host",mask_kvs_fnc_host);
+ KVSM_REGISTER_FUNCTION(m,"hasnumerichost",mask_kvs_fnc_hasnumerichost);
+
+ return true;
+}
+
+static bool mask_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "File", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)",
+ "Mask manipulation functions",
+ mask_module_init,
+ 0,
+ 0,
+ mask_module_cleanup
+)
diff --git a/src/modules/math/Makefile.am b/src/modules/math/Makefile.am
new file mode 100644
index 00000000..001bef24
--- /dev/null
+++ b/src/modules/math/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makemath - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvimath.la
+
+libkvimath_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvimath_la_SOURCES = libkvimath.cpp
+libkvimath_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/math/libkvimath.cpp b/src/modules/math/libkvimath.cpp
new file mode 100644
index 00000000..63a29787
--- /dev/null
+++ b/src/modules/math/libkvimath.cpp
@@ -0,0 +1,475 @@
+//=============================================================================
+//
+// File : libkvimath.cpp
+// Creation date : Sat Jan 13 14:00:12 2006 GMT by Szymon Stefanek
+//
+// This math is part of the KVirc irc client distribution
+// Copyright (C) 2006 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 "kvi_module.h"
+#include "kvi_string.h"
+
+#include <math.h>
+
+// Workaround for lost isnan and isinf definitions after
+// inclusion of iostream.h on some MacOS X systems
+#ifdef Q_OS_MACX
+ #ifndef isnan
+ extern "C" int isnan (double);
+ #endif
+ #ifndef isinf
+ extern "C" int isinf (double);
+ #endif
+#endif
+
+#define MATH_KVS_1PARAM_FUNCTION(__fncname,__paramname,__mathcallname) \
+static bool __fncname(KviKvsModuleFunctionCall * c) \
+{ \
+ kvs_real_t dReal; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER(__paramname,KVS_PT_REAL,0,dReal) \
+ KVSM_PARAMETERS_END(c) \
+ c->returnValue()->setReal(__mathcallname(dReal)); \
+ return true; \
+}
+
+#ifdef COMPILE_ON_WINDOWS
+// dobbiamo testare meglio, i risultati.
+static double cbrt(double x)
+{
+ if (x > 0.0) return pow(x, 1.0/3.0);
+ else return -pow(-x, 1.0/3.0);
+}
+
+static int isinf (double d) {
+ int expon = 0;
+ double val = frexp (d, &expon);
+ if (expon == 1025) {
+ if (val == 0.5) return 1;
+ else if (val == -0.5) return -1;
+ else return 0;
+ } else {
+ return 0;
+ }
+}
+static int isnan (double d) {
+ int expon = 0;
+ double val = frexp (d, &expon);
+ if (expon == 1025) {
+ if (val == 0.5) return 0;
+ else if (val == -0.5) return 0;
+ else return 1;
+ } else {
+ return 0;
+ }
+}
+#endif
+/*
+ @doc: math.sin
+ @type:
+ function
+ @title:
+ $math.sin
+ @short:
+ Returns the sinus of the specified angle in radiants
+ @syntax:
+ <real> $math.sin(<angle:real>)
+ @description:
+ Returns the sinus of the specified angle in radiants
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_sin,"angle",sin)
+
+/*
+ @doc: math.cos
+ @type:
+ function
+ @title:
+ $math.cos
+ @short:
+ Returns the cosinus of the specified angle in radiants
+ @syntax:
+ <real> $math.cos(<angle:real>)
+ @description:
+ Returns the cosinus of the specified angle in radiants
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_cos,"angle",cos)
+
+/*
+ @doc: math.tan
+ @type:
+ function
+ @title:
+ $math.tan
+ @short:
+ Returns the tangent of the specified angle in radiants
+ @syntax:
+ <real> $math.tan(<angle:real>)
+ @description:
+ Returns the tangent of the specified angle in radiants
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_tan,"angle",tan)
+
+/*
+ @doc: math.asin
+ @type:
+ function
+ @title:
+ $math.asin
+ @short:
+ Returns the angle in radiants that has the specified sinus value.
+ @syntax:
+ <real> $math.asin(<sinus:real>)
+ @description:
+ Returns the angle in radiants that has the specified sinus value.
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_asin,"sinus",asin)
+
+/*
+ @doc: math.acos
+ @type:
+ function
+ @title:
+ $math.acos
+ @short:
+ Returns the angle in radiants that has the specified cosinus value.
+ @syntax:
+ <real> $math.acos(<cosinus:real>)
+ @description:
+ Returns the angle in radiants that has the specified cosinus value.
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_acos,"cosinus",acos)
+
+
+/*
+ @doc: math.atan
+ @type:
+ function
+ @title:
+ $math.atan
+ @short:
+ Returns the angle in radiants that has the specified tangent value.
+ @syntax:
+ <real> $math.atan(<tangent:real>)
+ @description:
+ Returns the angle in radiants that has the specified tangent value.
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_atan,"tangent",atan)
+
+/*
+ @doc: math.sqrt
+ @type:
+ function
+ @title:
+ $math.sqrt
+ @short:
+ Returns the square root of a number
+ @syntax:
+ <real> $math.sqrt(<number:real>)
+ @description:
+ Returns the square root of the specified number
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_sqrt,"number",sqrt)
+
+/*
+ @doc: math.cbrt
+ @type:
+ function
+ @title:
+ $math.cbrt
+ @short:
+ Returns the cube root of a number
+ @syntax:
+ <real> $math.cbrt(<number:real>)
+ @description:
+ Returns the cube root of the specified number
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_cbrt,"number",cbrt)
+
+/*
+ @doc: math.abs
+ @type:
+ function
+ @title:
+ $math.abs
+ @short:
+ Returns the absolute value of a number
+ @syntax:
+ <real> $math.abs(<number:real>)
+ @description:
+ Returns the absolute value of the specified number
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_abs,"number",fabs)
+
+/*
+ @doc: math.floor
+ @type:
+ function
+ @title:
+ $math.floor
+ @short:
+ Rounds down to the nearest integer
+ @syntax:
+ <real> $math.floor(<number:real>)
+ @description:
+ Rounds down number to the nearest integer
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_floor,"number",floor)
+
+/*
+ @doc: math.ceil
+ @type:
+ function
+ @title:
+ $math.ceil
+ @short:
+ Rounds up to the nearest integer
+ @syntax:
+ <real> $math.ceil(<number:real>)
+ @description:
+ Rounds up number to the nearest integer
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_ceil,"number",ceil)
+
+/*
+ @doc: math.exp
+ @type:
+ function
+ @title:
+ $math.exp
+ @short:
+ Returns the exponential of the specified number
+ @syntax:
+ <real> $math.exp(<number:real>)
+ @description:
+ Returns the exponential of the specified number
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_exp,"number",exp)
+
+/*
+ @doc: math.log
+ @type:
+ function
+ @title:
+ $math.log
+ @short:
+ Returns the natural logarithm of the specified number
+ @syntax:
+ <real> $math.log(<number:real>)
+ @description:
+ Returns the natural (base e) logarithm of the specified number
+*/
+
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_log,"number",log)
+
+
+/*
+ @doc: math.log10
+ @type:
+ function
+ @title:
+ $math.log10
+ @short:
+ Returns the base 10 logarithm of the specified number
+ @syntax:
+ <real> $math.log10(<number:real>)
+ @description:
+ Returns the base 10 logarithm of the specified number
+*/
+MATH_KVS_1PARAM_FUNCTION(math_kvs_fnc_log10,"number",log10)
+
+/*
+ @doc: math.isnan
+ @type:
+ function
+ @title:
+ $math.isnan
+ @short:
+ Checks if the value is not a number
+ @syntax:
+ <boolean> $math.isnan(<value:real>)
+ @description:
+ Checks if the specified value is a valid number
+ or NaN (Not a Number). NaN is returned by several
+ math functions when the result would be undefined.
+*/
+static bool math_kvs_fnc_isnan(KviKvsModuleFunctionCall * c)
+{
+ kvs_real_t dReal;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("value",KVS_PT_REAL,0,dReal)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setBoolean(isnan(dReal));
+ return true;
+}
+
+/*
+ @doc: math.isinf
+ @type:
+ function
+ @title:
+ $math.isinf
+ @short:
+ Checks if the value is the infinity
+ @syntax:
+ <boolean> $math.isinf(<value:real>)
+ @description:
+ Checks if the specified value is the infinity.
+*/
+#ifdef COMPILE_ON_WINDOWS
+static bool math_kvs_fnc_isinf(KviKvsModuleFunctionCall * c)
+{
+ kvs_real_t dReal;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("value",KVS_PT_REAL,0,dReal)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setBoolean(sinf(dReal));
+ return true;
+}
+#else
+static bool math_kvs_fnc_isinf(KviKvsModuleFunctionCall * c)
+{
+ kvs_real_t dReal;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("value",KVS_PT_REAL,0,dReal)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setBoolean(isinf(dReal));
+ return true;
+}
+#endif //COMPILE_ON_WINDOWS
+/*
+ @doc: math.pow
+ @type:
+ function
+ @title:
+ $math.pow
+ @short:
+ Returns a to the power of b
+ @syntax:
+ <real> $math.pow(<a:real>,<b:real>)
+ @description:
+ Returns a to the power of b
+*/
+static bool math_kvs_fnc_pow(KviKvsModuleFunctionCall * c)
+{
+ kvs_real_t dA,dB;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("a",KVS_PT_REAL,0,dA)
+ KVSM_PARAMETER("b",KVS_PT_REAL,0,dB)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setReal(pow(dA,dB));
+ return true;
+}
+
+/*
+ @doc: math.pi
+ @type:
+ function
+ @title:
+ $math.pi
+ @short:
+ Returns the value of pi
+ @syntax:
+ <real> $math.pi()
+ @description:
+ Returns the value of pi
+*/
+#ifdef COMPILE_ON_WINDOWS
+static bool math_kvs_fnc_pi(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setReal(3.141592653589793238462643383279502884197169399375);
+ return true;
+}
+#else
+static bool math_kvs_fnc_pi(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setReal(M_PI);
+ return true;
+}
+#endif
+/*
+ @doc: math.e
+ @type:
+ function
+ @title:
+ $math.e
+ @short:
+ Returns the value of e
+ @syntax:
+ <real> $math.e()
+ @description:
+ Returns the value of the euler constant e
+*/
+
+
+#ifdef COMPILE_ON_WINDOWS
+static bool math_kvs_fnc_e(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setReal(1.56903485);
+ return true;
+}
+#else
+static bool math_kvs_fnc_e(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setReal(M_E);
+ return true;
+}
+#endif
+static bool math_module_init(KviModule * m)
+{
+ KVSM_REGISTER_FUNCTION(m,"sin",math_kvs_fnc_sin);
+ KVSM_REGISTER_FUNCTION(m,"cos",math_kvs_fnc_cos);
+ KVSM_REGISTER_FUNCTION(m,"tan",math_kvs_fnc_tan);
+ KVSM_REGISTER_FUNCTION(m,"asin",math_kvs_fnc_asin);
+ KVSM_REGISTER_FUNCTION(m,"acos",math_kvs_fnc_acos);
+ KVSM_REGISTER_FUNCTION(m,"atan",math_kvs_fnc_atan);
+ KVSM_REGISTER_FUNCTION(m,"sqrt",math_kvs_fnc_sqrt);
+ KVSM_REGISTER_FUNCTION(m,"cbrt",math_kvs_fnc_cbrt);
+ KVSM_REGISTER_FUNCTION(m,"abs",math_kvs_fnc_abs);
+ KVSM_REGISTER_FUNCTION(m,"floor",math_kvs_fnc_floor);
+ KVSM_REGISTER_FUNCTION(m,"ceil",math_kvs_fnc_ceil);
+ KVSM_REGISTER_FUNCTION(m,"pow",math_kvs_fnc_pow);
+ KVSM_REGISTER_FUNCTION(m,"exp",math_kvs_fnc_exp);
+ KVSM_REGISTER_FUNCTION(m,"log",math_kvs_fnc_log);
+ KVSM_REGISTER_FUNCTION(m,"log10",math_kvs_fnc_log10);
+ KVSM_REGISTER_FUNCTION(m,"pi",math_kvs_fnc_pi);
+ KVSM_REGISTER_FUNCTION(m,"e",math_kvs_fnc_e);
+ KVSM_REGISTER_FUNCTION(m,"isnan",math_kvs_fnc_isnan);
+ KVSM_REGISTER_FUNCTION(m,"isinf",math_kvs_fnc_isinf);
+ return true;
+}
+
+
+static bool math_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "Math", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2006 Szymon Stefanek (pragma at kvirc dot net),"\
+ "Tonino Imbesi (grifisx at barmes dot org)," \
+ "Alessandro Carbone (noldor at barmes dot org)",
+ "Mathematical function module",
+ math_module_init,
+ 0,
+ 0,
+ math_module_cleanup
+)
diff --git a/src/modules/mediaplayer/Makefile.am b/src/modules/mediaplayer/Makefile.am
new file mode 100644
index 00000000..af5caa60
--- /dev/null
+++ b/src/modules/mediaplayer/Makefile.am
@@ -0,0 +1,36 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvimediaplayer.la
+
+#%.moc: %.h
+# $(SS_QT_MOC) $< -o $@
+
+libkvimediaplayer_la_LDFLAGS = -avoid-version -module
+
+libkvimediaplayer_la_SOURCES = libkvimediaplayer.cpp \
+ mp_amarokinterface.cpp \
+ mp_amipinterface.cpp \
+ mp_dcopinterface.cpp \
+ mp_interface.cpp \
+ mp_jukinterface.cpp \
+ mp_mp3.cpp \
+ mp_winampinterface.cpp \
+ mp_xmmsinterface.cpp
+
+libkvimediaplayer_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS = mp_amarokinterface.h \
+ mp_amipinterface.h \
+ mp_dcopinterface.h \
+ mp_interface.h \
+ mp_jukinterface.h \
+ mp_mp3.h \
+ mp_winampinterface.h \
+ mp_xmmsinterface.h
+
+
diff --git a/src/modules/mediaplayer/libkvimediaplayer.cpp b/src/modules/mediaplayer/libkvimediaplayer.cpp
new file mode 100644
index 00000000..bd8a144f
--- /dev/null
+++ b/src/modules/mediaplayer/libkvimediaplayer.cpp
@@ -0,0 +1,1751 @@
+//=============================================================================
+//
+// File : libkvimediaplayer.cpp
+// Creation date : Sat Nov 3 19:28:25 2001 GMT by Szymon Stefanek
+// Renamed to file : libkvimediaplayer.cpp on Fri Mar 25 2005
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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_xmmsinterface.h"
+#include "mp_amarokinterface.h"
+#include "mp_winampinterface.h"
+#include "mp_amipinterface.h"
+#include "mp_jukinterface.h"
+
+#include "kvi_module.h"
+#include "kvi_options.h"
+
+
+#include "kvi_locale.h"
+#include "kvi_out.h"
+
+static KviPointerList<KviMediaPlayerInterfaceDescriptor> * g_pDescriptorList = 0;
+
+static KviMediaPlayerInterface * g_pMPInterface = 0;
+
+static KviMediaPlayerInterface * auto_detect_player(KviWindow * pOut = 0)
+{
+ int iBest = 0;
+ KviMediaPlayerInterface * pBest = 0;
+ KviMediaPlayerInterfaceDescriptor * d;
+ KviMediaPlayerInterfaceDescriptor * pDBest = 0;
+ for(d = g_pDescriptorList->first();d;d = g_pDescriptorList->next())
+ {
+ KviMediaPlayerInterface * i = d->instance();
+ if(i)
+ {
+ int iScore = i->detect(false);
+ if(iScore > iBest)
+ {
+ iBest = iScore;
+ pBest = i;
+ pDBest = d;
+ }
+ if(pOut)
+ {
+ QString szOut;
+ QString szNam = d->name();
+ KviQString::sprintf(szOut,__tr2qs_ctx("Trying media player interface \"%Q\": score %d","mediaplayer"),&(szNam),iScore);
+ pOut->output(KVI_OUT_MULTIMEDIA,szOut);
+ }
+ }
+ }
+ if(iBest < 90)
+ {
+ if(pOut)
+ pOut->outputNoFmt(KVI_OUT_MULTIMEDIA,__tr2qs_ctx("Not sure about the results, trying a second, more agressive detection pass","mediaplayer"));
+ // no sure player found... try again with a destructive test
+ for(d = g_pDescriptorList->first();d;d = g_pDescriptorList->next())
+ {
+ KviMediaPlayerInterface * i = d->instance();
+ if(i)
+ {
+ int iScore = i->detect(true);
+ if(iScore > iBest)
+ {
+ iBest = iScore;
+ pBest = i;
+ pDBest = d;
+ }
+ if(pOut)
+ {
+ QString szOut;
+ QString szNam = d->name();
+ KviQString::sprintf(szOut,__tr2qs_ctx("Trying media player interface \"%Q\": score %d","mediaplayer"),&(szNam),iScore);
+ pOut->output(KVI_OUT_MULTIMEDIA,szOut);
+ }
+ }
+ }
+ }
+ if(pDBest)
+ {
+ KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer) = pDBest->name();
+ if(pOut)
+ pOut->output(KVI_OUT_MULTIMEDIA,__tr2qs_ctx("Choosing media player interface \"%Q\"","mediaplayer"),&(KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer)));
+ } else {
+ if(pOut)
+ pOut->outputNoFmt(KVI_OUT_MULTIMEDIA,__tr2qs_ctx("Seems that there is no usable media player on this machine","mediaplayer"));
+ }
+ return pBest;
+}
+
+
+
+ #define MP_KVS_FAIL_ON_NO_INTERFACE \
+ if(!g_pMPInterface) \
+ { \
+ c->warning(__tr2qs_ctx("No mediaplayer interface selected. Try /mediaplayer.detect","mediaplayer")); \
+ return true; \
+ } \
+
+ #define MP_KVS_COMMAND(__name) static bool mediaplayer_kvs_cmd_ ## __name (KviKvsModuleCommandCall * c)
+ #define MP_KVS_FUNCTION(__name) static bool mediaplayer_kvs_fnc_ ## __name (KviKvsModuleFunctionCall * c)
+
+ #define MP_KVS_SIMPLE_COMMAND(__name,__ifacecommand) \
+ MP_KVS_COMMAND(__name) \
+ { \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETERS_END(c) \
+ \
+ MP_KVS_FAIL_ON_NO_INTERFACE \
+ \
+ if(!g_pMPInterface->__ifacecommand()) \
+ { \
+ if(!c->hasSwitch('q',"quiet")) \
+ { \
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer")); \
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer"); \
+ tmp += g_pMPInterface->lastError(); \
+ c->warning(tmp); \
+ } \
+ }\
+ return true; \
+ }
+
+ #define MP_KVS_SIMPLE_STRING_FUNCTION(__name,__ifacecommand) \
+ MP_KVS_FUNCTION(__name) \
+ { \
+ MP_KVS_FAIL_ON_NO_INTERFACE \
+ QString szRet = g_pMPInterface->__ifacecommand(); \
+ c->returnValue()->setString(szRet); \
+ return true; \
+ }
+
+ #define MP_KVS_SIMPLE_INT_FUNCTION(__name,__ifacecommand) \
+ MP_KVS_FUNCTION(__name) \
+ { \
+ MP_KVS_FAIL_ON_NO_INTERFACE \
+ int iRet = g_pMPInterface->__ifacecommand(); \
+ c->returnValue()->setInteger(iRet); \
+ return true; \
+ }
+ // FINDME!
+ #define MP_KVS_SIMPLE_BOOL_FUNCTION(__name,__ifacecommand) \
+ MP_KVS_FUNCTION(__name) \
+ { \
+ MP_KVS_FAIL_ON_NO_INTERFACE \
+ bool bRet = g_pMPInterface->__ifacecommand(); \
+ c->returnValue()->setBoolean(bRet); \
+ return true; \
+ }
+
+
+/*
+ @doc: mediaplayer.play
+ @type:
+ command
+ @title:
+ mediaplayer.play
+ @short:
+ Starts media playback in the selected media player
+ @syntax:
+ mediaplayer.play [-q]
+ @description:
+ Starts playback in the remote instance of the currently selected media player.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.stop[/cmd],
+ [cmd]mediaplayer.pause[/cmd],
+ [cmd]mediaplayer.prev[/cmd],
+ [cmd]mediaplayer.next[/cmd],
+ [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.status[/fnc]
+*/
+
+MP_KVS_SIMPLE_COMMAND(play,play)
+
+/*
+ @doc: mediaplayer.hide
+ @type:
+ command
+ @title:
+ mediaplayer.hide
+ @short:
+ Hide the mediaplayer [-q]
+ @syntax:
+ mediaplayer.hide
+ @description:
+ Hide the player interface.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.quit[/cmd],
+ [cmd]mediaplayer.show[/cmd],
+ [cmd]mediaplayer.minimize[/cmd]
+*/
+
+MP_KVS_SIMPLE_COMMAND(hide,hide)
+
+/*
+ @doc: mediaplayer.show
+ @type:
+ command
+ @title:
+ mediaplayer.show
+ @short:
+ Show the mediaplayer.
+ @syntax:
+ mediaplayer.show [-q]
+ @description:
+ Show the player interface.[br]
+ When you use this function in your script, remember to reshow mediaplayer's window [br]
+ or quit the mediplayerwindow to the exit.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.quit[/cmd],
+ [cmd]mediaplayer.hide[/cmd],
+ [cmd]mediaplayer.minimize[/cmd]
+*/
+
+MP_KVS_SIMPLE_COMMAND(show,show)
+
+/*
+ @doc: mediaplayer.minimize
+ @type:
+ command
+ @title:
+ mediaplayer.minimize
+ @short:
+ Minimize the mediaplayer.
+ @syntax:
+ mediaplayer.minimize [-q]
+ @description:
+ Minimize the player interface.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.quit[/cmd],
+ [cmd]mediaplayer.hide[/cmd],
+ [cmd]mediaplayer.show[/cmd]
+*/
+
+MP_KVS_SIMPLE_COMMAND(minimize,minimize)
+
+/*
+ @doc: mediaplayer.stop
+ @type:
+ command
+ @title:
+ mediaplayer.stop
+ @short:
+ Stops media playback in the selected media player
+ @syntax:
+ mediaplayer.stop [-q]
+ @description:
+ Stops playback in the remote instance of the currently selected media player.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.play[/cmd],
+ [cmd]mediaplayer.pause[/cmd],
+ [cmd]mediaplayer.prev[/cmd],
+ [cmd]mediaplayer.next[/cmd],
+ [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.status[/fnc]
+*/
+
+MP_KVS_SIMPLE_COMMAND(stop,stop)
+
+/*
+ @doc: mediaplayer.next
+ @type:
+ command
+ @title:
+ mediaplayer.next
+ @short:
+ Starts playback of the next song (mediaplayer interface module)
+ @syntax:
+ mediaplayer.next [-q]
+ @description:
+ Starts playback of the next song in the remote instance of the slave media player.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [cmd]mediaplayer.stop[/cmd],
+ [cmd]mediaplayer.pause[/cmd],
+ [cmd]mediaplayer.prev[/cmd],
+ [cmd]mediaplayer.play[/cmd],
+ [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.status[/fnc]
+*/
+
+MP_KVS_SIMPLE_COMMAND(next,next)
+
+/*
+ @doc: mediaplayer.prev
+ @type:
+ command
+ @title:
+ mediaplayer.prev
+ @short:
+ Starts playback of the previous song (mediaplayer interface module)
+ @syntax:
+ mediaplayer.prev [-q]
+ @description:
+ Starts playback of the previous song in the remote instance of the slave media player.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [cmd]mediaplayer.stop[/cmd],
+ [cmd]mediaplayer.pause[/cmd],
+ [cmd]mediaplayer.play[/cmd],
+ [cmd]mediaplayer.next[/cmd],
+ [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.status[/fnc]
+*/
+
+MP_KVS_SIMPLE_COMMAND(prev,prev)
+
+/*
+ @doc: mediaplayer.quit
+ @type:
+ command
+ @title:
+ mediaplayer.quit
+ @short:
+ Quits the remote media player (mediaplayer interface module)
+ @syntax:
+ mediaplayer.quit [-q]
+ @description:
+ Quits the remote instance of the slave media player.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [cmd]mediaplayer.stop[/cmd],
+ [cmd]mediaplayer.pause[/cmd],
+ [cmd]mediaplayer.prev[/cmd],
+ [cmd]mediaplayer.next[/cmd],
+ [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.status[/fnc]
+*/
+
+MP_KVS_SIMPLE_COMMAND(quit,quit)
+
+/*
+ @doc: mediaplayer.pause
+ @type:
+ command
+ @title:
+ mediaplayer.pause
+ @short:
+ Pauses playback (mediaplayer interface module)
+ @syntax:
+ mediaplayer.pause [-q]
+ @description:
+ Pauses playback in the remote instance of the slave media player.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [cmd]mediaplayer.stop[/cmd],
+ [cmd]mediaplayer.pause[/cmd],
+ [cmd]mediaplayer.prev[/cmd],
+ [cmd]mediaplayer.next[/cmd],
+ [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.status[/fnc]
+*/
+
+MP_KVS_SIMPLE_COMMAND(pause,pause)
+
+/*
+ @doc: mediaplayer.detect
+ @type:
+ command
+ @title:
+ mediaplayer.detect
+ @short:
+ Detects the media player interface to use
+ @syntax:
+ mediaplayer.detect [-q]
+ @description:
+ Attempts to detect the best media player interface
+ for the current system. The -q switch causes the detection
+ algorithm to run quietly. This function may attempt to start
+ the media players in order to verify their presence on the system.
+ You can guide the function by starting the media player you
+ prefer before running it: if a running media player is found, it takes
+ precedence over the others.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [cmd]mediaplayer.stop[/cmd], [cmd]mediaplayer.pause[/cmd],
+ [cmd]mediaplayer.prev[/cmd],
+ [cmd]mediaplayer.next[/cmd],
+ [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.status[/fnc],
+ [cmd]mediaplayer.setPlayer[/cmd],
+ [fnc]$mediaplayer.player[/fnc]
+*/
+
+MP_KVS_COMMAND(detect)
+{
+ g_pMPInterface = auto_detect_player(c->hasSwitch('q',"quiet") ? 0 : c->window());
+ return true;
+}
+
+/*
+ @doc: mediaplayer.setPlayer
+ @type:
+ command
+ @title:
+ mediaplayer.setPlayer
+ @short:
+ Sets the media player interface
+ @syntax:
+ mediaplayer.setPlayer <player_name>
+ @description:
+ Sets the media player interface to be used by the
+ mediaplayer module. <interface_name> must be one
+ of the player names returned by [fnc]$mediaplayer.playerList()[/fnc]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.detect[/cmd], [fnc]$mediaplayer.player[/fnc]
+*/
+
+MP_KVS_COMMAND(setPlayer)
+{
+ QString szPlayer;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("player",KVS_PT_STRING,0,szPlayer)
+ KVSM_PARAMETERS_END(c)
+
+ for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next())
+ {
+ if(d->name() == szPlayer)
+ {
+ g_pMPInterface = d->instance();
+ KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer) = szPlayer;
+ return true;
+ }
+ }
+
+ return true;
+}
+
+/*
+ @doc: mediaplayer.player
+ @type:
+ function
+ @title:
+ $mediaplayer.player
+ @short:
+ Returns the currently set media player interface
+ @syntax:
+ $mediaplayer.player()
+ @description:
+ Returns the currently set media player interface.
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.detect[/cmd], [cmd]mediaplayer.setPlayer[/cmd]
+*/
+
+MP_KVS_FUNCTION(player)
+{
+ c->returnValue()->setString(KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer));
+ return true;
+}
+
+/*
+ @doc: mediaplayer.playerList
+ @type:
+ function
+ @title:
+ $mediaplayer.playerList
+ @short:
+ Returns a the list of the supported media player interfaces
+ @syntax:
+ $mediaplayer.playerList()
+ @description:
+ Returns an array containing the supported media player interfaces.
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [cmd]mediaplayer.detect[/cmd], [cmd]mediaplayer.setPlayer[/cmd],
+ [fnc]$mediaplayer.player[/fnc]
+*/
+
+MP_KVS_FUNCTION(playerList)
+{
+ KviKvsArray* pArray = new KviKvsArray();
+ int id=0;
+
+ for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next())
+ {
+ pArray->set(id++,new KviKvsVariant(d->name()));
+ }
+ c->returnValue()->setArray(pArray);
+ return true;
+}
+/*
+ @doc: mediaplayer.playmrl
+ @type:
+ command
+ @title:
+ mediaplayer.playMrl
+ @short:
+ Plays the specified media on the selected media player
+ @syntax:
+ mediaplayer.playMrl <mrl>
+ @description:
+ Plays the media specified by the <mrl> on the currently
+ selected media player interface. <mrl> is a standard Media Resource
+ Locator. Examples of such locators are: 'file:///home/myfile.mp3' ,
+ 'http://streaming.server.top:123', 'dvd:// or dvb://channelname'.
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc],
+ [fnc]$mediaplayer.localFile[/fnc],
+ [cmd]mediaplayer.play[/cmd]
+*/
+
+MP_KVS_COMMAND(playMrl)
+{
+ QString szMrl;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("player",KVS_PT_STRING,0,szMrl)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ if(!g_pMPInterface->playMrl(szMrl))
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ {
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer"));
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer");
+ tmp += g_pMPInterface->lastError();
+ c->warning(tmp);
+ }
+ }
+
+ return true;
+}
+
+MP_KVS_COMMAND(amipExec)
+{
+ QString szMrl;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("player",KVS_PT_STRING,0,szMrl)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ if(!g_pMPInterface->amipExec(szMrl))
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ {
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer"));
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer");
+ tmp += g_pMPInterface->lastError();
+ c->warning(tmp);
+ }
+ }
+
+ return true;
+}
+
+
+/*
+ @doc: mediaplayer.jumpTo
+ @type:
+ command
+ @title:
+ mediaplayer.jumpTo
+ @short:
+ Sets the position in seconds of the current song.
+ @syntax:
+ mediaplayer.jumpTo [-q] <pos>
+ @description:
+ Sets the position in seconds of the current song .
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.position[/fnc],
+ [fnc]$mediaplayer.lenght[/fnc],
+*/
+
+MP_KVS_COMMAND(jumpTo)
+{
+ int iPos;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("position",KVS_PT_INT,0,iPos)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ if(!g_pMPInterface->jumpTo(iPos))
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ {
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer"));
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer");
+ tmp += g_pMPInterface->lastError();
+ c->warning(tmp);
+ }
+ }
+ return true;
+}
+
+/*
+ @doc: mediaplayer.setVol
+ @type:
+ command
+ @title:
+ mediaplayer.setVol
+ @short:
+ Set the media player volume to <vol> (from 0-255)
+ @syntax:
+ mediaplayer.setVol [-q] <vol>
+ @description:
+ Set the media player volume to <vol> (the valid range is from 0 to ....)
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.getVol[/fnc]
+*/
+
+MP_KVS_COMMAND(setVol)
+{
+ kvs_int_t iVol;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("volume",KVS_PT_INT,0,iVol)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ if(!g_pMPInterface->setVol(iVol))
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ {
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer"));
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer");
+ tmp += g_pMPInterface->lastError();
+ c->warning(tmp);
+ }
+ }
+ return true;
+}
+
+/*
+ @doc: mediaplayer.getVol
+ @type:
+ function
+ @title:
+ $mediaplayer.getVol
+ @short:
+ Returns the current volume of the media player
+ @syntax:
+ $mediaplayer.getVol()
+ @description:
+ Returns the current volume of the media player within 0 to 255.
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.setVol[/cmd]
+*/
+
+MP_KVS_SIMPLE_INT_FUNCTION(getVol,getVol)
+
+/*
+ @doc: mediaplayer.mute
+ @type:
+ command
+ @title:
+ mediaplayer.mute
+ @short:
+ Mute the volume selected media player
+ @syntax:
+ mediaplayer.mute
+ @description:
+ Mutes the volume selected media player.[br]
+ If already muted, it restores the volume.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.play[/cmd], [cmd]mediaplayer.pause[/cmd],
+ [cmd]mediaplayer.prev[/cmd],
+ [cmd]mediaplayer.next[/cmd],
+ [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.status[/fnc]
+*/
+
+MP_KVS_SIMPLE_COMMAND(mute,mute)
+
+
+/*
+ @doc: mediaplayer.mrl
+ @type:
+ function
+ @title:
+ $mediaplayer.mrl
+ @short:
+ Returns the mrl of the currently played media
+ @syntax:
+ $mediaplayer.mrl()
+ @description:
+ Returns the mrl of the media currently played by the selected media player interface.
+ The mrl is a standard Media Resource Locator.
+ Examples of such locators are: 'file:///home/myfile.mp3' ,
+ 'http://streaming.server.top:123', 'dvd:// or dvb://channelname'.
+ This means that the returned string may NOT refer to a local file:
+ it refers to the local file only if the 'file://' prefix is found ([fnc]$mediaplayer.localFile()[/fnc]
+ checks that for you).
+ The returned string is empty if the player isn't currently playing.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.playMrl[/cmd],
+ [fnc]$mediaplayer.localFile[/fnc]
+*/
+
+MP_KVS_SIMPLE_STRING_FUNCTION(mrl,mrl)
+
+/*
+ @doc: mediaplayer.nowPlaying
+ @type:
+ function
+ @title:
+ $mediaplayer.nowPlaying
+ @short:
+ Returns a descripting of the currently played media
+ @syntax:
+ $mediaplayer.nowPlaying()
+ @description:
+ Returns a description fo the media currently played
+ by the selected media player interface. The description
+ will usually contain the title of the media and eventually
+ some additional information like the artist name or album.
+ This function is granted to be implemented by all the media
+ player interfaces and return an empty string only
+ if the player is not currently playing or there is a communication
+ error.
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.title[/fnc],
+ [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.genre[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.mediaType[/fnc],
+ [fnc]$mediaplayer.bitRate[/fnc],
+ [fnc]$mediaplayer.sampleRate[/fnc],
+ [fnc]$mediaplayer.length[/fnc],
+ [fnc]$mediaplayer.position[/fnc]
+*/
+
+MP_KVS_SIMPLE_STRING_FUNCTION(nowPlaying,nowPlaying)
+
+/*
+ @doc: mediaplayer.title
+ @type:
+ function
+ @title:
+ $mediaplayer.title
+ @short:
+ Returns the title of the current media
+ @syntax:
+ $mediaplayer.title()
+ @description:
+ Returns the title of the multimedia file being played by the
+ remote instance of the media player. This function is not granted
+ to work with all the player interfaces and all the media types:
+ if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc]
+ instead.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.genre[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.mediaType[/fnc]
+*/
+
+MP_KVS_SIMPLE_STRING_FUNCTION(title,title)
+
+/*
+ @doc: mediaplayer.artist
+ @type:
+ function
+ @title:
+ $mediaplayer.artist
+ @short:
+ Returns the artist of the media player
+ @syntax:
+ $mediaplayer.artist()
+ @description:
+ Returns the artist property of the media currently played by
+ the selected media player interface. This function is not granted
+ to work with all the player interfaces and all the media types:
+ if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc]
+ instead.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.title[/fnc], [fnc]$mediaplayer.genre[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.mediaType[/fnc],
+ [fnc]$mediaplayer.album[/fnc],
+ [fnc]$mediaplayer.length[/fnc],
+ [fnc]$mediaplayer.position[/fnc]
+*/
+
+MP_KVS_SIMPLE_STRING_FUNCTION(artist,artist)
+
+/*
+ @doc: mediaplayer.genre
+ @type:
+ function
+ @title:
+ $mediaplayer.genre
+ @short:
+ Returns the genre of the media player
+ @syntax:
+ $mediaplayer.genre()
+ @description:
+ Returns the genre property of the media currently played by
+ the selected media player interface. This function is not granted
+ to work with all the player interfaces and all the media types:
+ if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc]
+ instead.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.mediaType[/fnc], [fnc]$mediaplayer.album[/fnc],
+ [fnc]$mediaplayer.length[/fnc], [fnc]$mediaplayer.position[/fnc]
+*/
+
+MP_KVS_SIMPLE_STRING_FUNCTION(genre,genre)
+
+/*
+ @doc: mediaplayer.year
+ @type:
+ function
+ @title:
+ $mediaplayer.year
+ @short:
+ Returns the year of the media player
+ @syntax:
+ $mediaplayer.year()
+ @description:
+ Returns the year property of the media currently played by
+ the selected media player interface. This function is not granted
+ to work with all the player interfaces and all the media types:
+ if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc]
+ instead.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.genre[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.mediaType[/fnc], [fnc]$mediaplayer.album[/fnc],
+ [fnc]$mediaplayer.length[/fnc], [fnc]$mediaplayer.position[/fnc]
+*/
+
+MP_KVS_SIMPLE_STRING_FUNCTION(year,year)
+
+/*
+ @doc: mediaplayer.comment
+ @type:
+ function
+ @title:
+ $mediaplayer.comment
+ @short:
+ Returns the comment of the media player
+ @syntax:
+ $mediaplayer.comment()
+ @description:
+ Returns the comment property of the media currently played by
+ the selected media player interface. This function is not granted
+ to work with all the player interfaces and all the media types:
+ if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc]
+ instead.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.year[/fnc],
+ [fnc]$mediaplayer.mediaType[/fnc], [fnc]$mediaplayer.album[/fnc],
+ [fnc]$mediaplayer.length[/fnc], [fnc]$mediaplayer.position[/fnc]
+*/
+
+MP_KVS_SIMPLE_STRING_FUNCTION(comment,comment)
+
+/*
+ @doc: mediaplayer.album
+ @type:
+ function
+ @title:
+ $mediaplayer.album
+ @short:
+ Returns the album of the media player
+ @syntax:
+ $mediaplayer.album()
+ @description:
+ Returns the album property of the media currently played by
+ the selected media player interface. This function is not granted
+ to work with all the player interfaces and all the media types:
+ if you want to write portable code you should use [fnc]$mediaplayer.nowPlaying[/fnc]
+ instead.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.mediaType[/fnc],
+ [fnc]$mediaplayer.bitRate[/fnc],
+ [fnc]$mediaplayer.sampleRate[/fnc],
+ [fnc]$mediaplayer.length[/fnc],
+ [fnc]$mediaplayer.position[/fnc]
+*/
+
+MP_KVS_SIMPLE_STRING_FUNCTION(album,album)
+
+/*
+ @doc: mediaplayer.mediaType
+ @type:
+ function
+ @title:
+ $mediaplayer.mediaType
+ @short:
+ Returns the currently played media type
+ @syntax:
+ $mediaplayer.medyaType()
+ @description:
+ Returns a string describing the media type currently played
+ by the selected media player interface. This function is not granted
+ to work with all the player interfaces and all the media types.
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc]
+*/
+
+MP_KVS_SIMPLE_STRING_FUNCTION(mediaType,mediaType)
+
+/*
+ @doc: mediaplayer.bitRate
+ @type:
+ function
+ @title:
+ $mediaplayer.bitRate
+ @short:
+ Returns the bit rate of the current song
+ @syntax:
+ $mediaplayer.bitRate
+ @description:
+ Returns the bit rate (in bits/sec) of the multimedia file being played by the
+ remote instance of the media player.This function is not granted
+ to work with all the player interfaces and all the media types so
+ you may get -1 or 0 in return sometimes.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.sampleRate[/fnc],
+ [fnc]$mediaplayer.length[/fnc],
+ [fnc]$mediaplayer.position[/fnc]
+*/
+
+MP_KVS_SIMPLE_INT_FUNCTION(bitRate,bitRate)
+
+
+/*
+ @doc: mediaplayer.sampleRate
+ @type:
+ function
+ @title:
+ $mediaplayer.sampleRate
+ @short:
+ Returns the sample rate of the current song
+ @syntax:
+ $mediaplayer.sampleRate
+ @description:
+ Returns the sample rate (in Hz) of the multimedia file being played by the
+ remote instance of the media player.This function is not granted
+ to work with all the player interfaces and all the media types so
+ you may get -1 or 0 in return sometimes.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.bitRate[/fnc], [fnc]$mediaplayer.length[/fnc],
+ [fnc]$mediaplayer.position[/fnc], [fnc]$mediaplayer.channels[/fnc]
+*/
+
+MP_KVS_SIMPLE_INT_FUNCTION(sampleRate,sampleRate)
+
+
+/*
+ @doc: mediaplayer.length
+ @type:
+ function
+ @title:
+ $mediaplayer.length
+ @short:
+ Returns the length of the current media
+ @syntax:
+ $mediaplayer.length()
+ @description:
+ Returns the length in milliseconds of the multimedia file being played by the
+ remote instance of the media player.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.sampleRate[/fnc],
+ [fnc]$mediaplayer.bitRate[/fnc],
+ [fnc]$mediaplayer.position[/fnc]
+*/
+
+MP_KVS_SIMPLE_INT_FUNCTION(length,length)
+
+/*
+ @doc: mediaplayer.position
+ @type:
+ function
+ @title:
+ $mediaplayer.position
+ @short:
+ Returns the position of the current media
+ @syntax:
+ $mediaplayer.position()
+ @description:
+ Returns the currently elapsed time of the multimedia file being played by the
+ remote instance of the media player.
+ The time is expressed in milliseconds.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.playMrl[/cmd],
+ [cmd]mediaplayer.play[/cmd], [fnc]$mediaplayer.nowPlaying[/fnc],
+ [fnc]$mediaplayer.artist[/fnc], [fnc]$mediaplayer.artist[/fnc],
+ [fnc]$mediaplayer.year[/fnc], [fnc]$mediaplayer.comment[/fnc],
+ [fnc]$mediaplayer.sampleRate[/fnc],
+ [fnc]$mediaplayer.length[/fnc],
+ [fnc]$mediaplayer.bitRate[/fnc], [fnc]$mediaplayer.channels[/fnc]
+*/
+
+MP_KVS_SIMPLE_INT_FUNCTION(position,position)
+
+/*
+ @doc: mediaplayer.channels
+ @type:
+ function
+ @title:
+ $mediaplayer.channels
+ @short:
+ Returns the number of channels of the current song
+ @syntax:
+ $mediaplayer.channels()
+ @description:
+ Returns the number of channels of the multimedia file being played by the
+ remote instance of the media player.This function is not granted
+ to work with all the player interfaces and all the media types so
+ you may get -1 or 0 in return sometimes.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module]
+*/
+
+MP_KVS_SIMPLE_INT_FUNCTION(channels,channels)
+
+
+/*
+ @doc: mediaplayer.setPlayListPos
+ @type:
+ command
+ @title:
+ mediaplayer.setPlayListPos
+ @short:
+ Set the position for the current song.
+ @syntax:
+ mediaplayer.setPlayListPos [-q] <pos:integer>
+ @description:
+ Set the position in the player list for the current song to <pos>.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.getPlayListPos[/fnc]
+*/
+
+MP_KVS_COMMAND(setPlayListPos)
+{
+ int iPos;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("position",KVS_PT_INT,0,iPos)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ if(!g_pMPInterface->setPlayListPos(iPos))
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ {
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer"));
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer");
+ tmp += g_pMPInterface->lastError();
+ c->warning(tmp);
+ }
+ }
+ return true;
+}
+
+/*
+ @doc: mediaplayer.getPlayListPos
+ @type:
+ function
+ @title:
+ $mediaplayer.getPlayListPos
+ @short:
+ Get the position for the current song.
+ @syntax:
+ $mediaplayer.getPlayListPos()
+ @description:
+ Get the song's position in the player list.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.getPlayListPos[/cmd]
+*/
+
+MP_KVS_SIMPLE_INT_FUNCTION(getPlayListPos,getPlayListPos)
+
+/*
+ @doc: mediaplayer.getListLength
+ @type:
+ function
+ @title:
+ $mediaplayer.getListLength
+ @short:
+ Return the play list length.
+ @syntax:
+ $mediaplayer.getListLength()
+ @description:
+ Return the player list length.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+*/
+
+MP_KVS_SIMPLE_INT_FUNCTION(getListLength,getListLength)
+
+
+/*
+ @doc: mediaplayer.getRepeat
+ @type:
+ function
+ @title:
+ $mediaplayer.getRepeat
+ @short:
+ Return if "Repeat" is on.
+ @syntax:
+ $mediaplayer.getRepeat()
+ @description:
+ Return the value of the Repeat flag for the current track (1 for ON, 0 for OFF.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.setRepeat[/cmd], [cmd]mediaplayer.setShuffle[/cmd],
+ [fnc]$mediaplayer.getShuffle[/fnc]
+*/
+
+MP_KVS_SIMPLE_INT_FUNCTION(getRepeat,getRepeat)
+
+
+/*
+ @doc: mediaplayer.getShuffle
+ @type:
+ function
+ @title:
+ $mediaplayer.getShuffle
+ @short:
+ Return if "Shuffle" is on.
+ @syntax:
+ $mediaplayer.getShuffle()
+ @description:
+ Return the value of the Shuffle flag (1 for ON, 0 for OFF.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.setShuffle[/cmd], [cmd]mediaplayer.setRepeat[/cmd],
+ [fnc]$mediaplayer.getRepeat[/fnc]
+*/
+
+MP_KVS_SIMPLE_BOOL_FUNCTION(getShuffle,getShuffle)
+
+/*
+ @doc: mediaplayer.getEqData
+ @type:
+ function
+ @title:
+ $mediaplayer.getEqData
+ @short:
+ Return the Equalizer Value.
+ @syntax:
+ $mediaplayer.getEqData(<item:integer>,<options:string>)
+ @description:
+ Return the value of the Eq <item>.[br]
+ if 'q' is given as an option, it runs in quiet mode.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.setShuffle[/cmd], [cmd]mediaplayer.setRepeat[/cmd],
+ [fnc]$mediaplayer.getRepeat[/fnc]
+
+*/
+
+MP_KVS_FUNCTION(getEqData)
+{
+ int iValue;
+ QString szOptions;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("item",KVS_PT_INT,0,iValue)
+ KVSM_PARAMETER("options",KVS_PT_STRING,KVS_PF_OPTIONAL,szOptions)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+
+ bool bQuiet = szOptions.find('q',false) != -1;
+
+ int ret = g_pMPInterface->getEqData(iValue);
+
+ if(!ret && !bQuiet)
+ {
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer"));
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer");
+ tmp += g_pMPInterface->lastError();
+ c->warning(tmp);
+ }
+
+ c->returnValue()->setInteger(ret);
+ return true;
+}
+
+/*
+ @doc: mediaplayer.setEqData
+ @type:
+ command
+ @title:
+ mediaplayer.setEqData
+ @short:
+ Return the Equalizer Value.
+ @syntax:
+ mediaplayer.setEqData [-q] <item:integer> <value:integer>
+ @description:
+ Set the value of the Eq <item> to <value>.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.getEqData[/fnc]
+*/
+
+MP_KVS_COMMAND(setEqData)
+{
+ int iPos;
+ int iValue;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("item",KVS_PT_INT,0,iPos)
+ KVSM_PARAMETER("value",KVS_PT_INT,0,iValue)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ if(!g_pMPInterface->setEqData(iPos,iValue))
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ {
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer"));
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer");
+ tmp += g_pMPInterface->lastError();
+ c->warning(tmp);
+ }
+ }
+ return true;
+}
+
+/*
+ @doc: mediaplayer.localFile
+ @type:
+ function
+ @title:
+ $mediaplayer.localFile
+ @short:
+ Returns the name of the local file played by the media player
+ @syntax:
+ $mediaplayer.localFile()
+ @description:
+ Returns the name of the local file played by the currently
+ selected media player interface. This function returns
+ an empty string if the player is not playing, there is a communication
+ error or the media played is not a local file (e.g. a stream or another
+ kind of media).[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.mrl[/fnc], [cmd]mediaplayer.play[/cmd]
+*/
+
+MP_KVS_FUNCTION(localFile)
+{
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ QString szRet = g_pMPInterface->mrl();
+ if(szRet.isEmpty())return true;
+ if(szRet.startsWith("file://",false))
+ {
+ szRet.remove(0,7);
+ c->returnValue()->setString(szRet);
+ }
+ return true;
+}
+
+MP_KVS_FUNCTION(amipEval)
+{
+ QString szMrl;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("player",KVS_PT_STRING,0,szMrl)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ QString szRet = g_pMPInterface->amipEval(szMrl);
+ if(szRet.isEmpty())return true;
+
+ c->returnValue()->setString(szRet);
+
+ return true;
+}
+
+/*
+ @doc: mediaplayer.status
+ @type:
+ function
+ @title:
+ $mediaplayer.status
+ @short:
+ Returns the status of the media player
+ @syntax:
+ $mediaplayer.status()
+ @description:
+ Returns the status if the currently selected media player: "playing",
+ "stopped", "paused" or "unknown".
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [cmd]mediaplayer.play[/cmd]
+*/
+
+MP_KVS_FUNCTION(status)
+{
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ KviMediaPlayerInterface::PlayerStatus eStat = g_pMPInterface->status();
+ switch(eStat)
+ {
+ case KviMediaPlayerInterface::Stopped:
+ c->returnValue()->setString("stopped");
+ break;
+ case KviMediaPlayerInterface::Playing:
+ c->returnValue()->setString("playing");
+ break;
+ case KviMediaPlayerInterface::Paused:
+ c->returnValue()->setString("paused");
+ break;
+ default:
+ c->returnValue()->setString("unknown");
+ break;
+ }
+ return true;
+}
+
+
+/*
+ @doc: mediaplayer
+ @type:
+ module
+ @short:
+ Interface to various media players
+ @title:
+ The mediaplayer interface module
+ @body:
+ The mediaplayer module is an interface to various popular media players.
+ It allows controlling them remotely to a certain degree and retrieving
+ the informations about the currently played media (in order to implement the nice /playing
+ scripts). The module has replaced the old mediaplayer module which after
+ years of development had developed some design flaws and needed a complete rewrite.
+ At the moment of writing the supported players are: xmms (unix), audacious (unix), winamp (windows),
+ amarok (kde) and juk (kde). You choose the player interface by either setting
+ the option in the settings dialog, by manually setting [cmd]option[/cmd] stringPreferredMediaPlayer
+ or by running [cmd]mediaplayer.detect[/cmd] that will guess the media player interface for you.[br]
+ If you're going to use the Winamp media player then you must install the "gen_kvirc.dll" plugin
+ (included in the kvirc distribution) as a "general" winamp plugin.
+ This is achieved by simpy copying the file gen_kvirc.dll
+ to the winamp plugins directory and restarting winamp.[br]
+ [br]
+ The commands and functions exported by this module serve mainly for two
+ purposes: control the playback and get informations about the currently played media.
+ Playback control is achieved by the means of [cmd]mediaplayer.play[/cmd],
+ [cmd]mediaplayer.stop[/cmd], [cmd]mediaplayer.pause[/cmd], [cmd]mediaplayer.next[/cmd],
+ [cmd]mediaplayer.prev[/cmd] and [fnc]$mediaplayer.status()[/fnc]. The
+ informations about the currently played media can be retrieved with
+ [fnc]$mediaplayer.nowplaying()[/fnc] and [fnc]$mediaplayer.mrl()[/fnc].
+ Several other informative function are available as well but they are not
+ granted to work with all the supported media players or media types (e.g.
+ with winamp you can play video files that probably have no album, genre
+ or sampleRate information...).[br]
+ If you intend to write portable code, you should check the return value
+ of the functions like [fnc]$mediaplayer.artist()[/fnc], [fnc]$mediaplayer.title()[/fnc]
+ or [fnc]$mediaplayer.channels()[/fnc] and be ready to discard it when it
+ does not appear to be meaningful. The functions that are granted
+ to work are [fnc]$mediaplayer.nowplaying()[/fnc], [fnc]$mediaplayer.mrl()[/fnc]
+ and [fnc]$mediaplayer.localFile()[/fnc].
+*/
+
+/*
+ @doc: mediaplayer.setRepeat
+ @type:
+ command
+ @title:
+ $mediaplayer.setRepeat
+ @short:
+ Set the repeat flag.
+ @syntax:
+ mediaplayer.getRepeat [-q] <repeat:bool>
+ @description:
+ Set the Repeat flag to "repeat" (1 for ON, 0 for OFF.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.getRepeat[/fnc], [cmd]mediaplayer.setShuffle[/cmd],
+ [fnc]$mediaplayer.getShuffle[/fnc]
+*/
+
+MP_KVS_COMMAND(setRepeat)
+{
+ bool bVal;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("repeat",KVS_PT_BOOL,0,bVal)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ if(!g_pMPInterface->setRepeat(bVal))
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ {
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer"));
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer");
+ tmp += g_pMPInterface->lastError();
+ c->warning(tmp);
+ }
+ }
+ return true;
+}
+
+
+/*
+ @doc: mediaplayer.setShuffle
+ @type:
+ command
+ @title:
+ $mediaplayer.setShuffle
+ @short:
+ Set the repeat flag.
+ @syntax:
+ mediaplayer.getShuffle [-q] <shuffle:bool>
+ @description:
+ Set the Shuffle flag to "shuffle" (1 for ON, 0 for OFF.[br]
+ Take a look at the [module:mediaplayer]mediaplayer module documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:mediaplayer]media player module documentation[/module],
+ [fnc]$mediaplayer.getShuffle[/fnc], [cmd]mediaplayer.setRepeat[/cmd],
+ [fnc]$mediaplayer.getRepeat[/fnc]
+*/
+
+MP_KVS_COMMAND(setShuffle)
+{
+ bool bVal;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("shuffle",KVS_PT_BOOL,0,bVal)
+ KVSM_PARAMETERS_END(c)
+
+ MP_KVS_FAIL_ON_NO_INTERFACE
+ if(!g_pMPInterface->setShuffle(bVal))
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ {
+ c->warning(__tr2qs_ctx("The selected media player interface failed to execute the requested function","mediaplayer"));
+ QString tmp = __tr2qs_ctx("Last interface error: ","mediaplayer");
+ tmp += g_pMPInterface->lastError();
+ c->warning(tmp);
+ }
+ }
+ return true;
+}
+
+static bool mediaplayer_module_init( KviModule * m )
+{
+ g_pDescriptorList = new KviPointerList<KviMediaPlayerInterfaceDescriptor>;
+ g_pDescriptorList->setAutoDelete(true);
+
+#ifndef COMPILE_ON_WINDOWS
+ g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviXmmsInterface));
+ g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAudaciousInterface));
+#endif
+
+#ifdef COMPILE_ON_WINDOWS
+ g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAmipInterface));
+ g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviWinampInterface));
+#endif
+
+#ifdef COMPILE_KDE_SUPPORT
+ g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAmarokInterface));
+ g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviJukInterface));
+#endif
+
+ g_pMPInterface = 0;
+
+ if(KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer) == "auto")
+ {
+ g_pMPInterface = auto_detect_player();
+ } else {
+ for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next())
+ {
+ if(d->name() == KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer))
+ {
+ g_pMPInterface = d->instance();
+ }
+ }
+ }
+
+ // check for "auto" interface too!
+
+
+ #define MP_KVS_REGCMD(__name,__stringname) KVSM_REGISTER_SIMPLE_COMMAND(m,__stringname,mediaplayer_kvs_cmd_ ## __name)
+ #define MP_KVS_REGFNC(__name,__stringname) KVSM_REGISTER_FUNCTION(m,__stringname,mediaplayer_kvs_fnc_ ## __name)
+
+ MP_KVS_REGCMD(play,"play");
+ MP_KVS_REGCMD(stop,"stop");
+ MP_KVS_REGCMD(next,"next");
+ MP_KVS_REGCMD(prev,"prev");
+ MP_KVS_REGCMD(quit,"quit");
+ MP_KVS_REGCMD(pause,"pause");
+ MP_KVS_REGCMD(detect,"detect");
+ MP_KVS_REGCMD(playMrl,"playMrl");
+ MP_KVS_REGCMD(amipExec,"amipExec");
+ MP_KVS_REGCMD(hide,"hide");
+ MP_KVS_REGCMD(show,"show");
+ MP_KVS_REGCMD(minimize,"minimize");
+ MP_KVS_REGCMD(jumpTo,"jumpTo");
+ MP_KVS_REGCMD(setPlayer,"setPlayer");
+ MP_KVS_REGCMD(setVol,"setVol");
+ MP_KVS_REGCMD(mute,"mute");
+ MP_KVS_REGCMD(setRepeat,"setRepeat");
+ MP_KVS_REGCMD(setShuffle,"setShuffle");
+ MP_KVS_REGCMD(setPlayListPos,"setPlayListPos");
+ MP_KVS_REGCMD(setEqData,"setEqData");
+
+ MP_KVS_REGFNC(nowPlaying,"nowPlaying");
+ MP_KVS_REGFNC(mrl,"mrl");
+ MP_KVS_REGFNC(title,"title");
+ MP_KVS_REGFNC(artist,"artist");
+ MP_KVS_REGFNC(genre,"genre");
+ MP_KVS_REGFNC(year,"year");
+ MP_KVS_REGFNC(comment,"comment");
+ MP_KVS_REGFNC(album,"album");
+ MP_KVS_REGFNC(mediaType,"mediaType");
+ MP_KVS_REGFNC(bitRate,"bitRate");
+ MP_KVS_REGFNC(sampleRate,"sampleRate");
+ MP_KVS_REGFNC(length,"length");
+ MP_KVS_REGFNC(position,"position");
+ MP_KVS_REGFNC(status,"status");
+ MP_KVS_REGFNC(player,"player");
+ MP_KVS_REGFNC(playerList,"playerList");
+ MP_KVS_REGFNC(localFile,"localFile");
+ MP_KVS_REGFNC(amipEval,"amipEval");
+ MP_KVS_REGFNC(channels,"channels");
+ MP_KVS_REGFNC(getListLength,"getListLength");
+ MP_KVS_REGFNC(getPlayListPos,"getPlayListPos");
+ MP_KVS_REGFNC(getEqData,"getEqData");
+ MP_KVS_REGFNC(getRepeat,"getRepeat");
+ MP_KVS_REGFNC(getShuffle,"getShuffle");
+ MP_KVS_REGFNC(getVol,"getVol");
+/*
+ // Crissi
+ m->registerFunction( "getmp3tag_date", mediaplayer_fnc_getmp3tag_date );
+ m->registerFunction( "getmp3tag_version", mediaplayer_fnc_getmp3tag_version );
+ m->registerFunction( "getmp3tag_layer", mediaplayer_fnc_getmp3tag_layer );
+ m->registerFunction( "getmp3tag_crc", mediaplayer_fnc_getmp3tag_crc );
+ m->registerFunction( "getmp3tag_copyright", mediaplayer_fnc_getmp3tag_copyright );
+ m->registerFunction( "getmp3tag_original", mediaplayer_fnc_getmp3tag_original );
+ m->registerFunction( "getmp3tag_emphasis", mediaplayer_fnc_getmp3tag_emphasis );
+ m->registerFunction( "getmp3tag_tracknumber", mediaplayer_fnc_getmp3tag_tracknumber );
+*/
+ return true;
+}
+
+static bool mediaplayer_module_cleanup( KviModule * m )
+{
+ delete g_pDescriptorList;
+ return true;
+}
+
+static bool mediaplayer_module_can_unload( KviModule * m )
+{
+ return true;
+}
+
+static bool mediaplayer_module_ctrl(KviModule * m,const char * operation,void * param)
+{
+ if(kvi_strEqualCI(operation,"getAvailableMediaPlayers"))
+ {
+ // we expect param to be a pointer to QStringList
+ QStringList * l = (QStringList *)param;
+ for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next())
+ {
+ l->append(d->name());
+ }
+ return true;
+ }
+ if(kvi_strEqualCI(operation,"detectMediaPlayer"))
+ {
+ auto_detect_player(0);
+ return true;
+ }
+ return false;
+}
+
+
+
+KVIRC_MODULE(
+ "mediaplayer",
+ "1.1.0",
+ "Copyright (C) 2001-2007 Szymon Stefanek (pragma at kvirc dot net), " \
+ "Christoph Thielecke (crissi99 at gmx dot de)," \
+ "Tonino Imbesi (grifisx at barmes dot org)," \
+ "Alessandro Carbone (noldor at barmes dot org)," \
+ "Alexey Uzhva (wizard at opendoor dot ru), " \
+ "Serge Baranov (sbaranov at gmail dot com)",
+ "Interface to various media players",
+ mediaplayer_module_init,
+ mediaplayer_module_can_unload,
+ mediaplayer_module_ctrl,
+ mediaplayer_module_cleanup
+)
diff --git a/src/modules/mediaplayer/mp_amarokinterface.cpp b/src/modules/mediaplayer/mp_amarokinterface.cpp
new file mode 100644
index 00000000..5c941d4f
--- /dev/null
+++ b/src/modules/mediaplayer/mp_amarokinterface.cpp
@@ -0,0 +1,189 @@
+//=============================================================================
+//
+// File : mp_amarokinterface.cpp
+// Created on Sun 27 Mar 2005 16:55:09 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005 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_amarokinterface.h"
+
+#ifdef COMPILE_KDE_SUPPORT
+
+#include "kvi_app.h"
+
+#include "dcopclient.h"
+#include "kurl.h"
+
+#include <qdatastream.h>
+#include <qvaluelist.h>
+
+#include "kvi_locale.h"
+
+MP_IMPLEMENT_DESCRIPTOR(
+ KviAmarokInterface,
+ "amarok",
+ __tr2qs_ctx(
+ "An interface to the AmaroK KDE media player."
+ ,
+ "mediaplayer"
+ )
+)
+
+
+KviAmarokInterface::KviAmarokInterface()
+ : KviDCOPHelper(true, "amarok")
+{
+}
+
+KviAmarokInterface::~KviAmarokInterface()
+{
+}
+
+int KviAmarokInterface::detect(bool bStart){ return detectApp("amarok",bStart,95,99); }
+
+bool KviAmarokInterface::prev(){ return voidRetVoidDCOPCall("player","prev()"); }
+bool KviAmarokInterface::next(){ return voidRetVoidDCOPCall("player","next()"); }
+bool KviAmarokInterface::play(){ return voidRetVoidDCOPCall("player","play()"); }
+bool KviAmarokInterface::stop(){ return voidRetVoidDCOPCall("player","stop()"); }
+bool KviAmarokInterface::pause(){ return voidRetVoidDCOPCall("player","pause()"); }
+bool KviAmarokInterface::mute(){ return voidRetVoidDCOPCall("player","mute()"); }
+bool KviAmarokInterface::quit(){ return voidRetVoidDCOPCall("MainApplication-Interface","quit()"); }
+
+bool KviAmarokInterface::jumpTo(kvs_int_t &iPos)
+{
+ return voidRetIntDCOPCall("player","seek(int)",iPos/1000);
+}
+bool KviAmarokInterface::setVol(kvs_int_t &iVol)
+{
+ return voidRetIntDCOPCall("player","setVolume(int)",100*iVol/255);
+}
+
+#define MP_DCOP_STRING_CALL(_fncname,_iface,_fnc) \
+QString KviAmarokInterface::_fncname() \
+{ \
+ QString ret; \
+ if(!stringRetVoidDCOPCall(_iface,_fnc,ret))return false; \
+ return ret; \
+}
+
+MP_DCOP_STRING_CALL(nowPlaying,"player","nowPlaying()")
+MP_DCOP_STRING_CALL(artist,"player","artist()")
+MP_DCOP_STRING_CALL(title,"player","title()")
+MP_DCOP_STRING_CALL(genre,"player","genre()")
+MP_DCOP_STRING_CALL(year,"player","year()")
+MP_DCOP_STRING_CALL(comment,"player","comment()")
+MP_DCOP_STRING_CALL(album,"player","album()")
+
+int KviAmarokInterface::getVol()
+{
+ int ret;
+ if(!intRetVoidDCOPCall("player","getVolume()",ret))return false;
+ return ret * 255 / 100;
+}
+
+int KviAmarokInterface::sampleRate()
+{
+ int ret;
+ if(!intRetVoidDCOPCall("player","sampleRate()",ret))return false;
+ return ret;
+}
+
+int KviAmarokInterface::length()
+{
+ int ret;
+ if(!intRetVoidDCOPCall("player","trackTotalTime()",ret))return false;
+ return ret * 1000;
+}
+
+int KviAmarokInterface::position()
+{
+ int ret;
+ if(!intRetVoidDCOPCall("player","trackCurrentTime()",ret))return false;
+ return ret * 1000;
+}
+
+bool KviAmarokInterface::getRepeat()
+{
+ bool ret;
+ if(!boolRetVoidDCOPCall("player","repeatTrackStatus()",ret))return false;
+ return ret;
+}
+
+bool KviAmarokInterface::getShuffle()
+{
+ bool ret;
+ if(!boolRetVoidDCOPCall("player","randomModeStatus()",ret))return false;
+ return ret;
+}
+
+bool KviAmarokInterface::setRepeat(bool &bVal)
+{
+ return voidRetBoolDCOPCall("player","enableRepeatTrack(bool)",bVal);
+}
+
+bool KviAmarokInterface::setShuffle(bool &bVal)
+{
+ return voidRetBoolDCOPCall("player","enableRandomMode(bool)",bVal);
+}
+
+KviMediaPlayerInterface::PlayerStatus KviAmarokInterface::status()
+{
+ int ret;
+ if(!intRetVoidDCOPCall("player","status()",ret))return KviMediaPlayerInterface::Unknown;
+ switch(ret)
+ {
+ case 0:
+ return KviMediaPlayerInterface::Stopped;
+ break;
+ case 1:
+ return KviMediaPlayerInterface::Paused;
+ break;
+ case 2:
+ return KviMediaPlayerInterface::Playing;
+ break;
+ default:
+ return KviMediaPlayerInterface::Unknown;
+ break;
+ }
+ return KviMediaPlayerInterface::Unknown;
+}
+
+QString KviAmarokInterface::mrl()
+{
+ QString ret;
+ if(!stringRetVoidDCOPCall("player","encodedURL()",ret))return false;
+ KURL url(ret);
+ return url.prettyURL();
+}
+
+bool KviAmarokInterface::playMrl(const QString &mrl)
+{
+ QString title;
+ QByteArray data, replyData;
+ KviQCString replyType;
+ QDataStream arg(data,IO_WriteOnly);
+ arg << KURL(mrl);
+ if(!g_pApp->dcopClient()->call(m_szAppId,"playlist","playMedia(KURL)",data,replyType,replyData))
+ return false;
+ return true;
+}
+
+
+#endif //COMPILE_KDE_SUPPORT
diff --git a/src/modules/mediaplayer/mp_amarokinterface.h b/src/modules/mediaplayer/mp_amarokinterface.h
new file mode 100644
index 00000000..ac856219
--- /dev/null
+++ b/src/modules/mediaplayer/mp_amarokinterface.h
@@ -0,0 +1,76 @@
+#ifndef _MP_AMAROKINTERFACE_H_
+#define _MP_AMAROKINTERFACE_H_
+//=============================================================================
+//
+// File : mp_amarokinterface.h
+// Created on Sun 27 Mar 2005 16:55:09 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005 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_KDE_SUPPORT
+
+ #include "kvi_dcophelper.h"
+ #include "mp_interface.h"
+
+ class KviAmarokInterface : public KviMediaPlayerInterface, private KviDCOPHelper
+ {
+ public:
+ KviAmarokInterface();
+ ~KviAmarokInterface();
+ public:
+ virtual int detect(bool bStart);
+ virtual bool prev();
+ virtual bool next();
+ virtual bool play();
+ virtual bool stop();
+ virtual bool pause();
+ virtual bool jumpTo(kvs_int_t &iPos);
+ virtual bool setVol(kvs_int_t &iVol);
+ virtual bool mute();
+ virtual int getVol();
+ virtual bool quit();
+ 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 position();
+ virtual int length();
+ //virtual int bitRate(); unsupported
+ virtual int sampleRate();
+ virtual bool playMrl(const QString &mrl);
+ virtual KviMediaPlayerInterface::PlayerStatus status();
+ virtual bool getRepeat();
+ virtual bool getShuffle();
+ virtual bool setRepeat(bool &bVal);
+ virtual bool setShuffle(bool &bVal);
+ };
+
+ MP_DECLARE_DESCRIPTOR(KviAmarokInterface)
+
+#endif //COMPILE_KDE_SUPPORT
+
+#endif //!_MP_AMAROKINTERFACE_H_
diff --git a/src/modules/mediaplayer/mp_amipinterface.cpp b/src/modules/mediaplayer/mp_amipinterface.cpp
new file mode 100644
index 00000000..3a7094bc
--- /dev/null
+++ b/src/modules/mediaplayer/mp_amipinterface.cpp
@@ -0,0 +1,400 @@
+#include "mp_amipinterface.h"
+#include "kvi_options.h"
+
+#ifdef COMPILE_ON_WINDOWS
+
+#include <qtextcodec.h>
+
+#include "kvi_locale.h"
+#include "kvi_module.h"
+
+#include <windows.h>
+
+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));
+ 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);
+ else ret=fn;
+ if(!ret.startsWith("http://",false))
+ 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);
+ 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();
+ KviStr szCmd = c ? c->fromUnicode(cmd) : cmd.utf8();
+ 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();
+ KviStr szCmd = c ? c->fromUnicode(cmd) : cmd.utf8();
+ 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);
+ 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
new file mode 100644
index 00000000..22bbf9d5
--- /dev/null
+++ b/src/modules/mediaplayer/mp_amipinterface.h
@@ -0,0 +1,58 @@
+#ifndef _MP_AMIPINTERFACE_H_
+#define _MP_AMIPINTERFACE_H_
+
+#include "kvi_settings.h"
+
+#ifdef COMPILE_ON_WINDOWS
+
+ #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_dcopinterface.cpp b/src/modules/mediaplayer/mp_dcopinterface.cpp
new file mode 100644
index 00000000..7c86e420
--- /dev/null
+++ b/src/modules/mediaplayer/mp_dcopinterface.cpp
@@ -0,0 +1,224 @@
+//=============================================================================
+//
+// File : mp_dcopinterface.cpp
+// Created on Sun 27 Mar 2005 16:56:21 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005 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_dcopinterface.h"
+
+#ifdef COMPILE_KDE_SUPPORT
+
+#include "dcopclient.h"
+
+#include <qdatastream.h>
+#include <qvaluelist.h>
+
+#include "kvi_app.h"
+#include "kvi_thread.h"
+
+KviMediaPlayerDCOPInterface::KviMediaPlayerDCOPInterface(const KviQCString &szAppId)
+: KviMediaPlayerInterface()
+{
+ m_szAppId = szAppId;
+}
+
+KviMediaPlayerDCOPInterface::~KviMediaPlayerDCOPInterface()
+{
+}
+
+bool KviMediaPlayerDCOPInterface::ensureAppRunning(const QString &szApp)
+{
+ if(findRunningApp(m_szAppId))return true;
+ return startApp(m_szAppId,400);
+}
+
+
+bool KviMediaPlayerDCOPInterface::simpleDCOPCall(const KviQCString &szObj,const KviQCString &szFunc)
+{
+ if(!ensureAppRunning(m_szAppId))return false;
+ QByteArray data;
+ return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data);
+}
+
+bool KviMediaPlayerDCOPInterface::boolDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,bool bVal)
+{
+ if(!ensureAppRunning(m_szAppId))return false;
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << bVal;
+ return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data);
+}
+
+bool KviMediaPlayerDCOPInterface::intDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,int iVal)
+{
+ if(!ensureAppRunning(m_szAppId))return false;
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << iVal;
+ return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data);
+}
+
+bool KviMediaPlayerDCOPInterface::floatDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,float fVal)
+{
+ if(!ensureAppRunning(m_szAppId))return false;
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << fVal;
+ return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data);
+}
+
+bool KviMediaPlayerDCOPInterface::stringDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,QString szVal)
+{
+ if(!ensureAppRunning(m_szAppId))return false;
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << szVal;
+ return g_pApp->dcopClient()->send(m_szAppId,szObj,szFunc,data);
+}
+
+bool KviMediaPlayerDCOPInterface::stringRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,QString &ret)
+{
+ if(!ensureAppRunning(m_szAppId))return false;
+ QString title;
+ QByteArray data, replyData;
+ KviQCString replyType;
+ if(!g_pApp->dcopClient()->call(m_szAppId,szObj,szFunc,data,replyType,replyData))
+ return false;
+ QDataStream reply( replyData, IO_ReadOnly );
+ if(replyType == "QString")
+ {
+ reply >> ret;
+ return true;
+ }
+ return false;
+}
+
+bool KviMediaPlayerDCOPInterface::intRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,int &ret)
+{
+ if(!ensureAppRunning(m_szAppId))return false;
+ QString title;
+ QByteArray data, replyData;
+ KviQCString replyType;
+ if(!g_pApp->dcopClient()->call(m_szAppId,szObj,szFunc,data,replyType,replyData))
+ return false;
+ QDataStream reply( replyData, IO_ReadOnly );
+ if(replyType == "int")
+ {
+ reply >> ret;
+ return true;
+ }
+ return false;
+}
+
+bool KviMediaPlayerDCOPInterface::boolRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,bool &ret)
+{
+ if(!ensureAppRunning(m_szAppId))return false;
+ QString title;
+ QByteArray data, replyData;
+ KviQCString replyType;
+ if(!g_pApp->dcopClient()->call(m_szAppId,szObj,szFunc,data,replyType,replyData))
+ return false;
+ QDataStream reply( replyData, IO_ReadOnly );
+ if(replyType == "bool")
+ {
+ reply >> ret;
+ return true;
+ }
+ return false;
+}
+
+
+bool KviMediaPlayerDCOPInterface::findRunningApp(const QString &szApp)
+{
+ QValueList<KviQCString> allApps = g_pApp->dcopClient() ->registeredApplications();
+ QValueList<KviQCString>::iterator iterator;
+ KviQCString sz = szApp.local8Bit();
+ for(iterator = allApps.begin();iterator != allApps.end();iterator++)
+ {
+ if(*iterator == sz)return true;
+ }
+ return false;
+}
+
+int KviMediaPlayerDCOPInterface::detectApp(const QString &szApp,bool bStart,int iScoreWhenFound,int iScoreWhenStarted)
+{
+ // lookup the amarok interface
+ if(!g_pApp->dcopClient())return 0;
+ if(findRunningApp(szApp))return 95; // found a running amarok, no need to run further
+
+ // no amarok app found
+ if(bStart)
+ {
+ // try to start it
+ if(!startApp(szApp,5000))return 10; // very low possibility
+ return findRunningApp(szApp) ? 99 : 0; // try to find it again
+ }
+
+ return 30; // it still might be installed on the system but we're just unable to start it...
+}
+
+
+bool KviMediaPlayerDCOPInterface::startApp(const QString &szApp,int iWaitMSecs)
+{
+ // we could use KApplication::startServiceByDesktopName here
+ // but we want to be able to wait a defined amount of time
+ QStringList tmp;
+ QByteArray data, replyData;
+ KviQCString replyType;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << szApp << tmp;
+ if(!g_pApp->dcopClient()->call(
+ "klauncher",
+ "klauncher",
+ "start_service_by_desktop_name(QString,QStringList)",
+ data,
+ replyType,
+ replyData))
+ {
+ return false;
+ } else {
+ QDataStream reply(replyData, IO_ReadOnly);
+ if(replyType != "serviceResult")return false;
+ int result;
+ KviQCString dcopName;
+ QString error;
+ reply >> result >> dcopName >> error;
+ if(result != 0)return false;
+ }
+ // ok , we seem to have started it.. but it might take some seconds
+ // for the app to get registered
+ // we wait up to five seconds
+ if(iWaitMSecs > 0)
+ {
+ int i = 0;
+ while(i < iWaitMSecs)
+ {
+ if(findRunningApp(szApp))return true;
+ KviThread::msleep(100);
+ i += 100;
+ }
+ return findRunningApp(szApp);
+ }
+ return true;
+}
+
+
+#endif //COMPILE_KDE_SUPPORT
diff --git a/src/modules/mediaplayer/mp_dcopinterface.h b/src/modules/mediaplayer/mp_dcopinterface.h
new file mode 100644
index 00000000..6ce8594d
--- /dev/null
+++ b/src/modules/mediaplayer/mp_dcopinterface.h
@@ -0,0 +1,57 @@
+#ifndef _MP_DCOPINTERFACE_H_
+#define _MP_DCOPINTERFACE_H_
+//=============================================================================
+//
+// File : mp_dcopinterface.h
+// Created on Sun 27 Mar 2005 16:56:21 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005 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_KDE_SUPPORT
+
+#include "mp_interface.h"
+
+class KviMediaPlayerDCOPInterface : public KviMediaPlayerInterface
+{
+public:
+ KviMediaPlayerDCOPInterface(const KviQCString &szAppId);
+ ~KviMediaPlayerDCOPInterface();
+protected:
+ KviQCString m_szAppId;
+protected:
+ bool ensureAppRunning(const QString &szApp);
+ bool findRunningApp(const QString &szApp);
+ bool startApp(const QString &szApp,int iWaitMSecs = 0);
+ int detectApp(const QString &szApp,bool bStart,int iScoreWhenFound,int iScoreWhenStarted);
+ bool simpleDCOPCall(const KviQCString &szObj,const KviQCString &szFunc);
+ bool intDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,int iVal);
+ bool boolDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,bool bVal);
+ bool stringDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,QString szVal);
+ bool floatDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,float fVal);
+ bool stringRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,QString &ret);
+ bool intRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,int &ret);
+ bool boolRetDCOPCall(const KviQCString &szObj,const KviQCString &szFunc,bool &ret);
+};
+
+#endif //COMPILE_KDE_SUPPORT
+
+#endif //!_MP_DCOPINTERFACE_H_
diff --git a/src/modules/mediaplayer/mp_interface.cpp b/src/modules/mediaplayer/mp_interface.cpp
new file mode 100644
index 00000000..0894de05
--- /dev/null
+++ b/src/modules/mediaplayer/mp_interface.cpp
@@ -0,0 +1,277 @@
+//=============================================================================
+//
+// 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 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 "kvi_options.h"
+#include "kvi_locale.h"
+#include <qtextcodec.h>
+
+static QTextCodec * mediaplayer_get_codec()
+{
+ QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding));
+ 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://",false))
+ {
+ ret.remove(0,7);
+ return ret;
+ }
+ return QString::null;
+}
+
+QString KviMediaPlayerInterface::amipEval(const QString &cmd)
+{
+ return QString::null;
+}
+
+#define SCAN_MP3_FILE \
+ QString f = getLocalFile(); \
+ if(f.isEmpty())return QString::null; \
+ mp3info mp3; \
+ if(!scan_mp3_file(f,&mp3))return QString::null; \
+ 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(KviQCString(mp3.id3.artist));
+}
+
+QString KviMediaPlayerInterface::title()
+{
+ SCAN_MP3_FILE
+ return pCodec->toUnicode(KviQCString(mp3.id3.title));
+}
+
+
+QString KviMediaPlayerInterface::genre()
+{
+ SCAN_MP3_FILE
+ return pCodec->toUnicode(KviQCString(get_typegenre(mp3.id3.genre[0])));
+}
+
+QString KviMediaPlayerInterface::comment()
+{
+ SCAN_MP3_FILE
+ return pCodec->toUnicode(KviQCString(mp3.id3.comment));
+}
+
+QString KviMediaPlayerInterface::year()
+{
+ SCAN_MP3_FILE
+ return QString(mp3.id3.year);
+}
+
+QString KviMediaPlayerInterface::album()
+{
+ SCAN_MP3_FILE
+ return pCodec->toUnicode(KviQCString(mp3.id3.album));
+}
+
+bool KviMediaPlayerInterface::playMrl(const QString &mrl)
+{
+ notImplemented();
+ return false;
+}
+
+bool KviMediaPlayerInterface::amipExec(const QString &cmd)
+{
+ notImplemented();
+ return false;
+}
+
+bool KviMediaPlayerInterface::setVol(kvs_int_t &iVol)
+{
+ notImplemented();
+ return false;
+}
+
+int KviMediaPlayerInterface::getVol()
+{
+ notImplemented();
+ return -1;
+}
+
+bool KviMediaPlayerInterface::mute()
+{
+ notImplemented();
+ return false;
+}
+
+bool KviMediaPlayerInterface::jumpTo(int &iPos)
+{
+ 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(int &iPos)
+{
+ notImplemented();
+ return false;
+}
+
+int KviMediaPlayerInterface::getListLength()
+{
+ notImplemented();
+ return -1;
+}
+
+
+int KviMediaPlayerInterface::getEqData(int &ival)
+{
+ notImplemented();
+ return -1;
+}
+
+bool KviMediaPlayerInterface::setEqData(int &iPos, int &iVal)
+{
+ notImplemented();
+ return false;
+}
+
+bool KviMediaPlayerInterface::getRepeat()
+{
+ notImplemented();
+ return false;
+}
+
+bool KviMediaPlayerInterface::getShuffle()
+{
+ notImplemented();
+ return false;
+}
+
+bool KviMediaPlayerInterface::setRepeat(bool &bVal)
+{
+ notImplemented();
+ return false;
+}
+
+bool KviMediaPlayerInterface::setShuffle(bool &bVal)
+{
+ notImplemented();
+ return false;
+}
+
+QString KviMediaPlayerInterface::mediaType()
+{
+ QString ret = mrl();
+ if(ret.endsWith(".mp3",false))ret = "MPEG Layer 3";
+ else if(ret.endsWith(".ogg",false))ret = "OGG Vorbis";
+ else if(ret.endsWith(".avi",false))ret = "Audio Video Interleave";
+ else if(ret.endsWith(".mpeg",false))ret = "MPEG Video";
+ else if(ret.endsWith(".mpg",false))ret = "MPEG Video";
+ else if(ret.startsWith("http://",false))ret = "HTTP Audio Stream";
+ else ret = QString::null;
+ return ret;
+}
+
diff --git a/src/modules/mediaplayer/mp_interface.h b/src/modules/mediaplayer/mp_interface.h
new file mode 100644
index 00000000..44667309
--- /dev/null
+++ b/src/modules/mediaplayer/mp_interface.h
@@ -0,0 +1,238 @@
+#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 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 "kvi_qstring.h"
+#include "kvi_kvs_types.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(){ 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 informations.
+ // 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://<filepath> 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(int &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 informations
+ // 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(int &iPos);
+ // return the list's length
+ virtual int getListLength();
+ // return the Eq(number) value
+ virtual int getEqData(int &i_val);
+ // set the Eq(iPos) to Eq(iVal) value
+ virtual bool setEqData(int &iPos, int &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_jukinterface.cpp b/src/modules/mediaplayer/mp_jukinterface.cpp
new file mode 100644
index 00000000..d5a69a77
--- /dev/null
+++ b/src/modules/mediaplayer/mp_jukinterface.cpp
@@ -0,0 +1,185 @@
+//=============================================================================
+//
+// File : mp_jukinterface.cpp
+// Created on Tue 29 Mar 2005 01:38:34 by Szymon Stfeanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005 Szymon Stfeanek <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_jukinterface.h"
+
+#ifdef COMPILE_KDE_SUPPORT
+
+#include "kvi_app.h"
+
+#include "dcopclient.h"
+#include "kurl.h"
+
+#include <qdatastream.h>
+#include <qvaluelist.h>
+
+#include "kvi_locale.h"
+
+// the dcop interface of this player is incomplete :(
+
+MP_IMPLEMENT_DESCRIPTOR(
+ KviJukInterface,
+ "juk",
+ __tr2qs_ctx(
+ "An interface to the Juk KDE media player."
+ ,
+ "mediaplayer"
+ )
+)
+
+
+KviJukInterface::KviJukInterface()
+ : KviDCOPHelper(true, "amarok")
+{
+}
+
+KviJukInterface::~KviJukInterface()
+{
+}
+
+int KviJukInterface::detect(bool bStart){ return detectApp("juk",bStart,90,96); }
+
+bool KviJukInterface::prev(){ return voidRetVoidDCOPCall("Player","forward()"); }
+bool KviJukInterface::next(){ return voidRetVoidDCOPCall("Player","back()"); }
+bool KviJukInterface::play(){ return voidRetVoidDCOPCall("Player","play()"); }
+bool KviJukInterface::stop(){ return voidRetVoidDCOPCall("Player","stop()"); }
+bool KviJukInterface::pause(){ return voidRetVoidDCOPCall("Player","pause()"); }
+bool KviJukInterface::quit(){ return voidRetVoidDCOPCall("MainApplication-Interface","quit()"); }
+
+bool KviJukInterface::setVol(kvs_int_t &iVol)
+{
+ return voidRetFloatDCOPCall("player","setVolume(float)",(float)(iVol)/255.);
+}
+
+bool KviJukInterface::jumpTo(kvs_int_t &iPos)
+{
+ return voidRetIntDCOPCall("player","seek(int)",iPos/1000);
+}
+
+bool KviJukInterface::getShuffle()
+{
+ QString szMode;
+ if(!stringRetVoidDCOPCall("player","randomPlayMode()",szMode))return false;
+ return (szMode != "NoRandom");
+}
+
+bool KviJukInterface::setShuffle(bool &bVal)
+{
+ QString szMode;
+ if(bVal)
+ {
+ szMode = "Random";
+ } else {
+ szMode = "NoRandom";
+ }
+ if(!voidRetStringDCOPCall("player","setRandomPlayMode(QString)",szMode))return false;
+ return true;
+}
+
+
+#define MP_DCOP_STRING_CALL(_fncname,_iface,_fnc) \
+QString KviJukInterface::_fncname() \
+{ \
+ QString ret; \
+ if(!stringRetVoidDCOPCall(_iface,_fnc,ret))return false; \
+ return ret; \
+}
+
+MP_DCOP_STRING_CALL(nowPlaying,"Player","playingString()")
+
+/*
+ FIXME: there is trackProperty(propertyName) for these...
+MP_DCOP_STRING_CALL(artist,"player","artist()")
+MP_DCOP_STRING_CALL(title,"player","title()")
+MP_DCOP_STRING_CALL(genre,"player","genre()")
+MP_DCOP_STRING_CALL(year,"player","year()")
+MP_DCOP_STRING_CALL(comment,"player","comment()")
+MP_DCOP_STRING_CALL(album,"player","album()")
+
+
+int KviJukInterface::sampleRate()
+{
+ int ret;
+ if(!intRetVoidDCOPCall("player","sampleRate()",ret))return false;
+ return ret;
+}
+*/
+
+int KviJukInterface::length()
+{
+ int ret;
+ if(!intRetVoidDCOPCall("player","totalTime()",ret))return false;
+ return ret * 1000;
+}
+
+int KviJukInterface::position()
+{
+ int ret;
+ if(!intRetVoidDCOPCall("player","currentTime()",ret))return false;
+ return ret * 1000;
+}
+
+KviMediaPlayerInterface::PlayerStatus KviJukInterface::status()
+{
+ int ret;
+ if(!intRetVoidDCOPCall("player","status()",ret))return KviMediaPlayerInterface::Unknown;
+ switch(ret)
+ {
+ case 0:
+ return KviMediaPlayerInterface::Stopped;
+ break;
+ case 1:
+ return KviMediaPlayerInterface::Paused;
+ break;
+ case 2:
+ return KviMediaPlayerInterface::Playing;
+ break;
+ default:
+ return KviMediaPlayerInterface::Unknown;
+ break;
+ }
+ return KviMediaPlayerInterface::Unknown;
+}
+
+QString KviJukInterface::mrl()
+{
+ // ugh :/
+ QString ret;
+ return ret;
+}
+
+bool KviJukInterface::playMrl(const QString &mrl)
+{
+ QString title;
+ QByteArray data, replyData;
+ KviQCString replyType;
+ QDataStream arg(data,IO_WriteOnly);
+ arg << mrl;
+ if(!g_pApp->dcopClient()->call(m_szAppId,"playlist","play(QString)",data,replyType,replyData))
+ return false;
+ return true;
+}
+
+
+#endif //COMPILE_KDE_SUPPORT
diff --git a/src/modules/mediaplayer/mp_jukinterface.h b/src/modules/mediaplayer/mp_jukinterface.h
new file mode 100644
index 00000000..478a3c16
--- /dev/null
+++ b/src/modules/mediaplayer/mp_jukinterface.h
@@ -0,0 +1,77 @@
+#ifndef _MP_JUKINTERFACE_H_
+#define _MP_JUKINTERFACE_H_
+//=============================================================================
+//
+// File : mp_jukinterface.h
+// Created on Tue 29 Mar 2005 01:38:34 by Szymon Stfeanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005 Szymon Stfeanek <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_KDE_SUPPORT
+
+ #include "kvi_dcophelper.h"
+ #include "mp_interface.h"
+
+ class KviJukInterface : public KviMediaPlayerInterface, private KviDCOPHelper
+ {
+ public:
+ KviJukInterface();
+ ~KviJukInterface();
+ 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 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 position();
+ virtual int length();
+ /*
+ virtual int bitRate();
+ virtual int sampleRate();
+ */
+ virtual bool getShuffle();
+ virtual bool setShuffle(bool &bVal);
+
+ virtual bool playMrl(const QString &mrl);
+ virtual KviMediaPlayerInterface::PlayerStatus status();
+ };
+
+ MP_DECLARE_DESCRIPTOR(KviJukInterface)
+
+#endif //COMPILE_KDE_SUPPORT
+
+#endif //!_MP_JUKINTERFACE_H_
diff --git a/src/modules/mediaplayer/mp_mp3.cpp b/src/modules/mediaplayer/mp_mp3.cpp
new file mode 100644
index 00000000..6e27fa5f
--- /dev/null
+++ b/src/modules/mediaplayer/mp_mp3.cpp
@@ -0,0 +1,468 @@
+//=============================================================================
+//
+// 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 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 <cedric@earthling.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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// This file is based in part on:
+//
+// * MP3Info 0.5 by Ricardo Cerqueira <rmc@rccn.net>
+// * MP3Stat 0.9 by Ed Sweetman <safemode@voicenet.com> and
+// Johannes Overmann <overmann@iname.com>
+//
+// There has been also a remarkable work by Cristopher Tieckle (Crissi)
+//
+//=============================================================================
+
+#include "mp_mp3.h"
+#include "kvi_options.h"
+
+#include <qfileinfo.h>
+#include <qtextcodec.h>
+
+#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)
+{
+ int frame_type[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ float seconds=0,total_rate=0;
+ int frames=0,frame_types=0,frames_so_far=0;
+ int l,vbr_median=-1;
+ int bitrate,lastrate;
+ int counter=0;
+// mp3header header;
+
+ int sample_pos,data_start=0;
+
+ QFile fi(mp3->filename);
+ mp3->datasize=fi.size();//filestat.st_size;
+
+ get_id3(mp3);
+
+ if(get_first_header(mp3,0L))
+ {
+ data_start=ftell(mp3->file);
+ lastrate=15-mp3->header.bitrate;
+ while((counter < NUM_SAMPLES) && lastrate)
+ {
+ 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)/(l=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 {
+ 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);
+ fread(mp3->id3.title,1,30,mp3->file); mp3->id3.title[30] = '\0';
+ fread(mp3->id3.artist,1,30,mp3->file); mp3->id3.artist[30] = '\0';
+ fread(mp3->id3.album,1,30,mp3->file); mp3->id3.album[30] = '\0';
+ fread(mp3->id3.year,1,4,mp3->file); mp3->id3.year[4] = '\0';
+ 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];
+ }
+ 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(l<length)
+ {
+ string[l] = ' ';
+ l++;
+ }
+
+ string[l]='\0';
+ return string;
+}
+
+// Remove trailing whitespace from the end of a string
+
+char *unpad(char *string)
+{
+ char *pos=string+strlen(string)-1;
+ while(isspace(pos[0])) (pos--)[0]=0;
+ return string;
+}
+
+bool scan_mp3_file(QString& szFileName,mp3info * i)
+{
+ //memset(i,0,sizeof(mp3info));
+ resetmp3infoStruct(i);
+
+
+ i->filename = "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
new file mode 100644
index 00000000..d42c5ef7
--- /dev/null
+++ b/src/modules/mediaplayer/mp_mp3.h
@@ -0,0 +1,137 @@
+//=============================================================================
+//
+// 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 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.h
+//
+// Copyright (C) 2000 Cedric Tefft <cedric@earthling.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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// This file is based in part on:
+//
+// * MP3Info 0.5 by Ricardo Cerqueira <rmc@rccn.net>
+// * MP3Stat 0.9 by Ed Sweetman <safemode@voicenet.com> and
+// Johannes Overmann <overmann@iname.com>
+//
+// 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 <stdio.h>
+#include <stdlib.h>
+#include <qstring.h>
+
+#ifdef COMPILE_ON_WINDOWS
+ #include <windows.h>
+#else
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <ctype.h>
+ #include <string.h>
+#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_winampinterface.cpp b/src/modules/mediaplayer/mp_winampinterface.cpp
new file mode 100644
index 00000000..ae157782
--- /dev/null
+++ b/src/modules/mediaplayer/mp_winampinterface.cpp
@@ -0,0 +1,566 @@
+//=============================================================================
+//
+// File : mp_winampinterface.cpp
+// Created on Mon 28 Mar 2005 23:41:50 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005 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_winampinterface.h"
+#include "kvi_options.h"
+
+#ifdef COMPILE_ON_WINDOWS
+
+#include <qtextcodec.h>
+
+#include "kvi_locale.h"
+#include "kvi_module.h"
+
+#include <windows.h>
+
+#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));
+ 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://",false))
+ 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();
+ KviStr szMrl = c ? c->fromUnicode(mrl) : mrl.utf8();
+ 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(hWinamp)ret = SendMessage(hWinamp,WM_USER,-666,IPC_SETVOLUME);
+ 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(int &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(int &iPos, int &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(int &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
new file mode 100644
index 00000000..ed2068db
--- /dev/null
+++ b/src/modules/mediaplayer/mp_winampinterface.h
@@ -0,0 +1,76 @@
+#ifndef _MP_WINAMPINTERFACE_H_
+#define _MP_WINAMPINTERFACE_H_
+//=============================================================================
+//
+// File : mp_winampinterface.h
+// Created on Mon 28 Mar 2005 23:41:50 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005 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_ON_WINDOWS
+
+ #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(int &iPos);
+ virtual int getListLength();
+ virtual int getEqData(int &ival);
+ virtual bool setEqData(int &iPos, int &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
new file mode 100644
index 00000000..532327af
--- /dev/null
+++ b/src/modules/mediaplayer/mp_xmmsinterface.cpp
@@ -0,0 +1,355 @@
+//=============================================================================
+//
+// File : mp_xmmsinterface.cpp
+// Created on Fri 25 Mar 2005 20:04:54 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005-2007 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.
+//
+// Thnx to Alexander Stillich <torque at pltn dot org> for Audacious
+// media player interface hints :)
+//
+//=============================================================================
+
+#include "mp_xmmsinterface.h"
+
+#ifndef COMPILE_ON_WINDOWS
+
+#include "kvi_locale.h"
+
+MP_IMPLEMENT_DESCRIPTOR(
+ KviXmmsInterface,
+ "xmms",
+ __tr2qs_ctx(
+ "An interface to the popular UNIX xmms media player.\n" \
+ "Download it from http://www.xmms.org\n"
+ ,
+ "mediaplayer"
+ )
+)
+
+MP_IMPLEMENT_DESCRIPTOR(
+ KviAudaciousInterface,
+ "audacious",
+ __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_hPlayerLibrary = 0;
+ m_szPlayerLibraryName = "libxmms.so";
+ m_pLibraryPaths = xmms_lib_names;
+}
+
+KviXmmsInterface::~KviXmmsInterface()
+{
+ if(m_hPlayerLibrary)
+ {
+ kvi_library_close(m_hPlayerLibrary);
+ m_hPlayerLibrary = 0;
+ }
+}
+
+KviAudaciousInterface::KviAudaciousInterface()
+: KviXmmsInterface()
+{
+ m_szPlayerLibraryName = "libaudacious.so";
+ m_pLibraryPaths = audacious_lib_names;
+}
+
+KviAudaciousInterface::~KviAudaciousInterface()
+{
+}
+
+bool KviXmmsInterface::loadPlayerLibrary()
+{
+ if(m_hPlayerLibrary)return true;
+
+ const char **lib_name = m_pLibraryPaths;
+ while(*lib_name)
+ {
+ m_hPlayerLibrary = kvi_library_load(*lib_name);
+ if(m_hPlayerLibrary)
+ {
+ m_szPlayerLibraryName = *lib_name;
+ break;
+ }
+ lib_name++;
+ }
+ return true;
+}
+
+void * KviXmmsInterface::lookupSymbol(const char * szSymbolName)
+{
+ if(!m_hPlayerLibrary)
+ {
+ 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 = kvi_library_symbol(m_hPlayerLibrary,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 bStart)
+{
+ 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");
+ KviQCString tmp = mrl.local8Bit();
+ 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::null;
+ int pos = sym(0);
+ char * (*sym2)(int,int) = (char * (*)(int,int))lookupSymbol("xmms_remote_get_playlist_title");
+ if(!sym2)return QString::null;
+ return QString::fromLocal8Bit(sym2(0,pos));
+}
+
+QString KviXmmsInterface::mrl()
+{
+ int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos");
+ if(!sym)return QString::null;
+ int pos = sym(0);
+ char * (*sym2)(int,int) = (char * (*)(int,int))lookupSymbol("xmms_remote_get_playlist_file");
+ if(!sym2)return QString::null;
+ 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
new file mode 100644
index 00000000..15f81811
--- /dev/null
+++ b/src/modules/mediaplayer/mp_xmmsinterface.h
@@ -0,0 +1,84 @@
+#ifndef _MP_XMMSINTERFACE_H_
+#define _MP_XMMSINTERFACE_H_
+//=============================================================================
+//
+// File : mp_xmmsinterface.h
+// Created on Fri 25 Mar 2005 20:04:54 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2005-2007 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.
+//
+// Thnx to Alexander Stillich <torque at pltn dot org> for Audacious
+// media player interface hints :)
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "mp_interface.h"
+#include "kvi_library.h"
+
+#ifndef COMPILE_ON_WINDOWS
+ class KviXmmsInterface : public KviMediaPlayerInterface
+ {
+ public:
+ KviXmmsInterface();
+ virtual ~KviXmmsInterface();
+ protected:
+ kvi_library_t m_hPlayerLibrary;
+ 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 KviAudaciousInterface : public KviXmmsInterface
+ {
+ public:
+ KviAudaciousInterface();
+ virtual ~KviAudaciousInterface();
+ };
+
+ MP_DECLARE_DESCRIPTOR(KviAudaciousInterface)
+
+#endif //!COMPILE_ON_WINDOWS
+
+#endif //!_MP_XMMSINTERFACE_H_
diff --git a/src/modules/mircimport/Makefile.am b/src/modules/mircimport/Makefile.am
new file mode 100644
index 00000000..d47e88c7
--- /dev/null
+++ b/src/modules/mircimport/Makefile.am
@@ -0,0 +1,22 @@
+###############################################################################
+# KVirc IRC client Makefile- 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+SUBDIRS = caps pics
+
+pluglib_LTLIBRARIES = libkvimircimport.la
+
+libkvimircimport_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvimircimport_la_SOURCES = libkvimircimport.cpp
+libkvimircimport_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= libkvimircimport.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkvimircimport.cpp: libkvimircimport.moc
diff --git a/src/modules/mircimport/caps/Makefile.am b/src/modules/mircimport/caps/Makefile.am
new file mode 100644
index 00000000..151a1e0a
--- /dev/null
+++ b/src/modules/mircimport/caps/Makefile.am
@@ -0,0 +1,9 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir = $(pluglibdir)/caps/serverimport/
+
+tmp_DATA= mircimport
+
+EXTRA_DIST = $(tmp_DATA)
diff --git a/src/modules/mircimport/caps/mircimport b/src/modules/mircimport/caps/mircimport
new file mode 100644
index 00000000..9788f702
--- /dev/null
+++ b/src/modules/mircimport/caps/mircimport
@@ -0,0 +1 @@
+timestamp
diff --git a/src/modules/mircimport/libkvimircimport.cpp b/src/modules/mircimport/libkvimircimport.cpp
new file mode 100644
index 00000000..4f3ac568
--- /dev/null
+++ b/src/modules/mircimport/libkvimircimport.cpp
@@ -0,0 +1,385 @@
+//
+// File : libkvimircimport.cpp
+// Creation date : Tue Aug 27 01:20:35 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)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under 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 "libkvimircimport.h"
+#include "kvi_module.h"
+
+#include "kvi_filedialog.h"
+#include "kvi_fileutils.h"
+#include "kvi_locale.h"
+#include "kvi_config.h"
+#include "kvi_app.h"
+#include "kvi_qstring.h"
+
+
+#include <qmessagebox.h>
+#include <qdir.h>
+#include <qpushbutton.h>
+#include "kvi_tal_vbox.h"
+
+KviMircServersIniImport * g_pMircServersIniImport = 0;
+KviRemoteMircServersIniImport * g_pRemoteMircServersIniImport = 0;
+
+
+KviMircServersIniImport::KviMircServersIniImport(KviModuleExtensionDescriptor * d)
+: KviMexServerImport(d)
+{
+}
+
+KviMircServersIniImport::~KviMircServersIniImport()
+{
+ g_pMircServersIniImport = 0;
+}
+
+int KviMircServersIniImport::doImport(const QString& filename)
+{
+ KviConfig cfg(filename,KviConfig::Read,true);
+ int iCount = 0;
+ if(cfg.hasGroup("servers"))
+ {
+ cfg.setGroup("servers");
+ int i = 0;
+ QString key;
+ QString entry;
+ do {
+ KviQString::sprintf(key,"n%d",i);
+ entry = cfg.readEntry(key,"");
+ if(!entry.isEmpty())
+ {
+ QString description;
+ QString serv;
+ QString port;
+ kvi_u32_t uPort = 0;
+ // <description>SERVER:<server:port>GROUP:<network>
+ int idx = KviQString::find(entry,"SERVER:");
+ if(idx != -1)
+ {
+ description = entry.left(idx);
+ entry.remove(0,idx + 7);
+ idx = KviQString::find(entry,"GROUP:");
+ if(idx != -1)
+ {
+ port = entry.left(idx);
+ entry.remove(0,idx + 6);
+ }
+ idx = KviQString::find(port,':');
+ if(idx != -1)
+ {
+ serv = port.left(idx);
+ port.remove(0,idx + 1);
+ bool bOk;
+ uPort = port.toUInt(&bOk);
+ if(!bOk)uPort = 6667;
+ } else {
+ serv = port;
+ uPort = 6667;
+ }
+ }
+ if(entry.isEmpty())entry = __tr("Standalone Servers");
+ if(!serv.isEmpty())
+ {
+ KviIrcServer s;
+ s.m_szHostname = serv;
+ s.m_szDescription = description;
+ s.m_uPort = uPort;
+ iCount++;
+ emit server(s,entry);
+ }
+ ++i;
+ }
+ } while(!entry.isEmpty());
+ } else {
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("%Q doesn't look like a servers.ini file.\nImport failed."),&filename);
+ QMessageBox::warning(0,__tr2qs("Warning - KVIrc"),tmp);
+ }
+ return iCount;
+}
+
+void KviMircServersIniImport::start()
+{
+ //KviStr buffer;
+ QString buffer;
+ if(!KviFileDialog::askForOpenFileName(buffer,__tr("Choose a servers.ini file"),0,"*.ini",false,true))return;
+
+ doImport(buffer);
+ delete this;
+}
+
+void KviMircServersIniImport::die()
+{
+ delete this;
+}
+
+
+
+
+
+
+
+#define KVI_WWWMIRCCOUK_SERVERSINI "http://www.mirc.co.uk/servers.ini"
+
+
+
+KviRemoteMircServerImportWizard::KviRemoteMircServerImportWizard(KviRemoteMircServersIniImport * f)
+: KviTalWizard(0)
+{
+ QString capt = __tr2qs("Remote mIRC servers.ini Import Wizard");
+ setCaption(capt);
+
+
+ m_pRequest = 0;
+ m_pFilter = f;
+
+ QLabel * l = new QLabel(this);
+ l->setText(__tr2qs("<center><b>Welcome!</b><br><br>This wizard will guide you in the process of " \
+ "downloading a list of IRC servers. Please click \"<b>Next</b>\" to begin the operation.</center>"));
+ addPage(l,capt);
+
+
+ KviTalVBox * vb = new KviTalVBox(this);
+ l = new QLabel(vb);
+ l->setText(__tr2qs("<center>Here you can modify the URL that the list will be downloaded from. In most cases the default URL is acceptable.</center>"));
+
+ vb->setStretchFactor(l,1);
+
+ m_pUrlEdit = new QLineEdit(vb);
+
+ m_pUrlEdit->setText(KVI_WWWMIRCCOUK_SERVERSINI);
+
+ addPage(vb,__tr2qs("URL Selection"));
+
+ vb = new KviTalVBox(this);
+
+ l = new QLabel(__tr2qs("Please wait while the list is being downloaded"),vb);
+ vb->setStretchFactor(l,1);
+
+ m_pOutput = new QLabel(vb);
+ m_pOutput->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
+
+ addPage(vb,__tr2qs("List Download"));
+
+ setBackEnabled(vb,false);
+ setNextEnabled(vb,false);
+ setFinishEnabled(vb,true);
+
+ connect(this,SIGNAL(selected(const QString &)),this,SLOT(pageSelected(const QString &)));
+}
+
+KviRemoteMircServerImportWizard::~KviRemoteMircServerImportWizard()
+{
+ if(m_pRequest)delete m_pRequest;
+}
+
+void KviRemoteMircServerImportWizard::pageSelected(const QString &title)
+{
+ if(title == __tr2qs("List Download"))
+ {
+ start();
+ }
+}
+
+void KviRemoteMircServerImportWizard::closeEvent(QCloseEvent *)
+{
+ m_pFilter->die();
+}
+
+void KviRemoteMircServerImportWizard::done(int r)
+{
+ m_pFilter->die();
+}
+
+
+void KviRemoteMircServerImportWizard::start()
+{
+ QString url = m_pUrlEdit->text();
+ if(url.isEmpty())url = KVI_WWWMIRCCOUK_SERVERSINI;
+
+ finishButton()->setEnabled(false);
+ if(m_pRequest)delete m_pRequest;
+
+ m_pRequest = new KviHttpRequest();
+ connect(m_pRequest,SIGNAL(terminated(bool)),this,SLOT(getListTerminated(bool)));
+ connect(m_pRequest,SIGNAL(status(const QString &)),this,SLOT(getListMessage(const QString &)));
+
+ g_pApp->getTmpFileName(m_szTmpFileName,"servers.ini");
+ if(!m_pRequest->get(KviUrl(url),KviHttpRequest::StoreToFile,m_szTmpFileName))
+ {
+ delete m_pRequest;
+ m_pRequest = 0;
+ m_pOutput->setText(__tr2qs("Failed to start the server list transfer :("));
+ finishButton()->setEnabled(true);
+ }
+}
+
+void KviRemoteMircServerImportWizard::getListMessage(const QString &message)
+{
+ if(!message.isEmpty())m_pOutput->setText(message);
+}
+
+
+void KviRemoteMircServerImportWizard::getListTerminated(bool bSuccess)
+{
+ if(!m_pRequest)return;
+ if(bSuccess)
+ {
+ m_pOutput->setText(__tr2qs("File downloaded: processing ..."));
+ m_pOutput->repaint();
+#ifndef COMPILE_ON_WINDOWS
+ g_pApp->syncX();
+#endif //!COMPILE_ON_WINDOWS
+
+ int iCount = m_pFilter->doImport(m_szTmpFileName);
+
+ QString tmp;
+ if(iCount > 0)
+ tmp = __tr2qs("%1 servers imported succesfully").arg(iCount);
+ else
+ tmp = __tr2qs("No servers imported");
+ m_pOutput->setText(tmp);
+
+ QDir d;
+ d.remove(m_szTmpFileName);
+ } else m_pOutput->setText(m_pRequest->lastError());
+
+ delete m_pRequest;
+ m_pRequest = 0;
+ cancelButton()->setEnabled(false);
+ finishButton()->setEnabled(true);
+}
+
+
+KviRemoteMircServersIniImport::KviRemoteMircServersIniImport(KviModuleExtensionDescriptor * d)
+: KviMircServersIniImport(d)
+{
+ m_pWizard = 0;
+}
+
+KviRemoteMircServersIniImport::~KviRemoteMircServersIniImport()
+{
+ if(m_pWizard)delete m_pWizard;
+ g_pRemoteMircServersIniImport = 0;
+}
+
+void KviRemoteMircServersIniImport::start()
+{
+ if(m_pWizard)delete m_pWizard;
+ m_pWizard = new KviRemoteMircServerImportWizard(this);
+ m_pWizard->show();
+}
+
+void KviRemoteMircServersIniImport::die()
+{
+ delete this;
+}
+
+
+static KviModuleExtension * mircimport_local_filter_alloc(KviModuleExtensionAllocStruct * s)
+{
+ if(g_pMircServersIniImport)delete g_pMircServersIniImport;
+ g_pMircServersIniImport = new KviMircServersIniImport(s->pDescriptor);
+ return g_pMircServersIniImport;
+}
+
+static KviModuleExtension * mircimport_remote_filter_alloc(KviModuleExtensionAllocStruct * s)
+{
+ if(g_pRemoteMircServersIniImport)delete g_pRemoteMircServersIniImport;
+ g_pRemoteMircServersIniImport = new KviRemoteMircServersIniImport(s->pDescriptor);
+ return g_pRemoteMircServersIniImport;
+}
+
+static bool mircimport_module_init(KviModule * m)
+{
+ QString szPath;
+ QPixmap * pix = 0;
+ if(g_pApp->findImage(szPath,"kvi_mircimport.png"))
+ {
+ pix = new QPixmap(szPath);
+ if(pix->isNull())
+ {
+ delete pix;
+ pix = 0;
+ }
+ }
+
+ KviModuleExtensionDescriptor * d = m->registerExtension("serverimport",
+ "mIRC servers.ini import filter",
+ __tr("Import from servers.ini"),
+ mircimport_local_filter_alloc);
+
+ if(d && pix)d->setIcon(*pix);
+
+ d = m->registerExtension("serverimport",
+ "Remote mIRC servers.ini import filter",
+ __tr("Import from http://www.mirc.co.uk/servers.ini"),
+ mircimport_remote_filter_alloc);
+
+ if(d && pix)d->setIcon(*pix);
+
+ if(pix)delete pix;
+ return true;
+}
+
+static bool mircimport_module_cleanup(KviModule *m)
+{
+ if(g_pMircServersIniImport)delete g_pMircServersIniImport;
+ if(g_pRemoteMircServersIniImport)delete g_pRemoteMircServersIniImport;
+ g_pMircServersIniImport = 0;
+ g_pRemoteMircServersIniImport = 0;
+
+ return true;
+}
+
+static bool mircimport_module_can_unload(KviModule * m)
+{
+ return ((!g_pMircServersIniImport) && (!g_pRemoteMircServersIniImport));
+}
+
+/*
+KVIMODULEEXPORTFUNC KviIrcServerImport * mircimport_module_createIrcServerImport(const char *filterName)
+{
+ if(kvi_strEqualCI(filterName,__tr("Import from servers.ini")))
+ {
+ if(!g_pMircServersIniImport)g_pMircServersIniImport = new KviMircServersIniImport();
+ return g_pMircServersIniImport;
+ } else {
+ if(!g_pRemoteMircServersIniImport)g_pRemoteMircServersIniImport = new KviRemoteMircServersIniImport("http://www.mirc.co.uk/servers.ini");
+ return g_pRemoteMircServersIniImport;
+ }
+ return 0;
+}
+*/
+
+
+
+KVIRC_MODULE(
+ "File", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "mIRC servers.ini importer",
+ mircimport_module_init,
+ mircimport_module_can_unload,
+ 0,
+ mircimport_module_cleanup
+)
+
+#include "libkvimircimport.moc"
diff --git a/src/modules/mircimport/libkvimircimport.h b/src/modules/mircimport/libkvimircimport.h
new file mode 100644
index 00000000..360e8346
--- /dev/null
+++ b/src/modules/mircimport/libkvimircimport.h
@@ -0,0 +1,82 @@
+#ifndef _LIBKVIMIRCIMPORT_H_
+#define _LIBKVIMIRCIMPORT_H_
+//
+// File : libkvimircimport.h
+// Creation date : Tue Aug 27 01:28:02 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)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under 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_mexserverimport.h"
+#include "kvi_string.h"
+#include "kvi_http.h"
+
+#include <kvi_tal_wizard.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+
+class KviMircServersIniImport : public KviMexServerImport
+{
+ Q_OBJECT
+public:
+ KviMircServersIniImport(KviModuleExtensionDescriptor * d);
+ ~KviMircServersIniImport();
+public:
+ int doImport(const QString& filename);
+ virtual void start();
+ virtual void die();
+};
+
+class KviRemoteMircServerImportWizard;
+
+class KviRemoteMircServersIniImport : public KviMircServersIniImport
+{
+ Q_OBJECT
+public:
+ KviRemoteMircServersIniImport(KviModuleExtensionDescriptor * d);
+ ~KviRemoteMircServersIniImport();
+protected:
+ KviRemoteMircServerImportWizard * m_pWizard;
+public:
+ virtual void start();
+ virtual void die();
+};
+
+class KviRemoteMircServerImportWizard : public KviTalWizard
+{
+ Q_OBJECT
+public:
+ KviRemoteMircServerImportWizard(KviRemoteMircServersIniImport * f);
+ ~KviRemoteMircServerImportWizard();
+protected:
+ QLineEdit * m_pUrlEdit;
+ QLabel * m_pOutput;
+ KviRemoteMircServersIniImport * m_pFilter;
+ KviHttpRequest * m_pRequest;
+ QString m_szTmpFileName;
+protected:
+ virtual void closeEvent(QCloseEvent *e);
+ virtual void done(int r);
+ void start();
+protected slots:
+ void getListMessage(const QString &message);
+ void getListTerminated(bool bSuccess);
+ void pageSelected(const QString &title);
+};
+
+#endif //_LIBKVIMIRCIMPORT_H_
diff --git a/src/modules/mircimport/pics/Makefile.am b/src/modules/mircimport/pics/Makefile.am
new file mode 100644
index 00000000..839e9668
--- /dev/null
+++ b/src/modules/mircimport/pics/Makefile.am
@@ -0,0 +1,9 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir = $(picsdir)
+
+tmp_DATA= kvi_mircimport.png
+
+EXTRA_DIST = $(tmp_DATA)
diff --git a/src/modules/mircimport/pics/kvi_mircimport.png b/src/modules/mircimport/pics/kvi_mircimport.png
new file mode 100644
index 00000000..e671256f
--- /dev/null
+++ b/src/modules/mircimport/pics/kvi_mircimport.png
Binary files differ
diff --git a/src/modules/my/Makefile.am b/src/modules/my/Makefile.am
new file mode 100644
index 00000000..4c179e48
--- /dev/null
+++ b/src/modules/my/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvimy.la
+
+libkvimy_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvimy_la_SOURCES = libkvimy.cpp idle_x11.cpp idle_mac.cpp idle.cpp
+libkvimy_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= idle.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+idle.cpp: idle.moc
diff --git a/src/modules/my/idle.cpp b/src/modules/my/idle.cpp
new file mode 100644
index 00000000..56720c77
--- /dev/null
+++ b/src/modules/my/idle.cpp
@@ -0,0 +1,133 @@
+/*
+ * 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<qcursor.h>
+#include<qdatetime.h>
+#include<qtimer.h>
+
+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());
+}
+
+#include "idle.moc"
diff --git a/src/modules/my/idle.h b/src/modules/my/idle.h
new file mode 100644
index 00000000..647b2691
--- /dev/null
+++ b/src/modules/my/idle.h
@@ -0,0 +1,84 @@
+/*
+ * 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
+ *
+ */
+
+#ifndef IDLE_H
+#define IDLE_H
+
+#include "kvi_settings.h"
+#include<qobject.h>
+#include<qcursor.h>
+#include<qdatetime.h>
+#include<qtimer.h>
+
+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();
+ int secondsIdle();
+
+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 00000000..92de564d
--- /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 Q_OS_MACX
+
+#include"idle.h"
+#include <Carbon/Carbon.h>
+
+// 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() {
+ return d->mSecondsIdle;
+}
+#endif \ No newline at end of file
diff --git a/src/modules/my/idle_x11.cpp b/src/modules/my/idle_x11.cpp
new file mode 100644
index 00000000..fa2f1f15
--- /dev/null
+++ b/src/modules/my/idle_x11.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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 Q_OS_MACX
+#ifndef COMPILE_ON_WINDOWS
+
+#include"idle.h"
+
+#ifndef COMPILE_XSS_SUPPORT
+
+IdlePlatform::IdlePlatform() {}
+IdlePlatform::~IdlePlatform() {}
+bool IdlePlatform::init() { return false; }
+int IdlePlatform::secondsIdle() { return 0; }
+
+#else
+
+#include<qapplication.h>
+
+#include<X11/Xlib.h>
+#include<X11/Xutil.h>
+#include<X11/extensions/scrnsaver.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <qdesktopwidget.h>
+#endif
+
+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()
+{
+ if(d->ss_info)
+ return true;
+
+ old_handler = XSetErrorHandler(xerrhandler);
+
+ int event_base, error_base;
+ if(XScreenSaverQueryExtension(QApplication::desktop()->screen()->x11Display(), &event_base, &error_base)) {
+ d->ss_info = XScreenSaverAllocInfo();
+ return true;
+ }
+ return false;
+}
+
+#ifdef COMPILE_USE_QT4
+ #include <qx11info_x11.h>
+#endif
+
+int IdlePlatform::secondsIdle()
+{
+ if(!d->ss_info)
+ return 0;
+#ifdef COMPILE_USE_QT4
+ if(!XScreenSaverQueryInfo(QApplication::desktop()->screen()->x11Display(), QX11Info::appRootWindow(), d->ss_info))
+#else
+ if(!XScreenSaverQueryInfo(QApplication::desktop()->screen()->x11Display(), qt_xrootwin(), d->ss_info))
+#endif
+ 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
new file mode 100644
index 00000000..d98d44af
--- /dev/null
+++ b/src/modules/my/libkvimy.cpp
@@ -0,0 +1,430 @@
+//
+// File : libkvimy.cpp
+// Creation date : Mon Jul 1 02:46:49 2002 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_module.h"
+
+#include "kvi_console.h"
+
+#include "kvi_app.h"
+#include "kvi_locale.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_ircconnectionserverinfo.h"
+#include "kvi_ircserver.h"
+#include "idle.h"
+Idle* g_pIdle;
+#ifdef COMPILE_NEW_KVS
+#define GET_KVS_CONSOLE \
+ kvs_uint_t uiWnd; \
+ KviConsole *wnd =0; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER("context_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uiWnd) \
+ KVSM_PARAMETERS_END(c) \
+ if(!c->parameterList()->count()) \
+ { \
+ if(c->window()->console()) wnd = c->window()->console(); \
+ else c->warning(__tr2qs("This window has no associated irc context")); \
+ } \
+ else \
+ { \
+ wnd = g_pApp->findConsole(uiWnd); \
+ if(!wnd)c->warning(__tr2qs("No such irc context (%d)"),uiWnd); \
+ }
+#endif
+/*
+ @doc: my.nick
+ @type:
+ function
+ @title:
+ $my.nick
+ @short:
+ Returns the current nickname
+ @syntax:
+ <string> $my.nick([irc_context_id:uint])
+ @description:
+ Returns the nickname of the current irc context.[br]
+ If the irc context is not connected then an empty string is returned.[br]
+ If <irc_context_id> is specified this function returns acts as it was called
+ in that irc_context.[br]
+ Note that this function is different from [fnc]$me[/fnc] that will work also in a DCC CHAT.[br]
+*/
+
+
+static bool my_kvs_fnc_nick(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_CONSOLE
+ if(wnd)
+ {
+ if(wnd->connection())
+ c->returnValue()->setString(wnd->connection()->userInfo()->nickName());
+ }
+ return true;
+}
+
+/*
+ @doc: my.startIdleTimer
+ @type:
+ command
+ @title:
+ my.startIdleTimer
+ @short:
+ Starts a global idle hook
+ @syntax:
+ my.startIdleTimer()
+ @description:
+ Starts a global idle hook. Allows to detect a global user idle time
+*/
+
+static bool my_kvs_cmd_startIdleTimer(KviKvsModuleCommandCall * c)
+{
+ if(!g_pIdle)
+ g_pIdle = new Idle();
+ g_pIdle->start();
+ return true;
+}
+
+/*
+ @doc: my.stopIdleTimer
+ @type:
+ command
+ @title:
+ my.stopIdleTimer
+ @short:
+ Stops a global idle hook
+ @syntax:
+ my.stopIdleTimer()
+ @description:
+ Stops a global idle hook. Allows to detect a global user idle time
+*/
+
+static bool my_kvs_cmd_stopIdleTimer(KviKvsModuleCommandCall * c)
+{
+ if(!g_pIdle) return true;
+ g_pIdle->stop();
+ //delete g_pIdle;
+ return true;
+}
+
+/*
+ @doc: my.globalIdle
+ @type:
+ function
+ @title:
+ $my.globalIdle
+ @short:
+ Returns the current user global idle time
+ @syntax:
+ <int> $my.globalIdle()
+ @description:
+ Returns the current user global idle time
+*/
+
+static bool my_kvs_fnc_globalIdle(KviKvsModuleFunctionCall * c)
+{
+ if(g_pIdle)
+ {
+ c->returnValue()->setInteger(g_pIdle->secondsIdle());
+ } else {
+ c->error(__tr2qs("Global idle timer must be started before using $my.globalIdle function"));
+ }
+ return true;
+}
+
+/*
+ @doc: my.umode
+ @type:
+ function
+ @title:
+ $my.umode
+ @short:
+ Returns the current user mode flags
+ @syntax:
+ <string> $my.umode([irc_context_id:uint])
+ @description:
+ Returns the user mode flags of the current irc context.[br]
+ If the irc context is not connected then an empty string is returned.[br]
+ If <irc_context_id> is specified this function returns acts as it was called
+ in that irc_context.[br]
+*/
+
+static bool my_kvs_fnc_umode(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_CONSOLE
+ if(wnd)
+ {
+ if(wnd->connection())
+ c->returnValue()->setString(wnd->connection()->userInfo()->userMode());
+ }
+ return true;
+}
+
+/*
+ @doc: my.user
+ @type:
+ function
+ @title:
+ $my.user
+ @short:
+ Returns the current username
+ @syntax:
+ <string> $my.user([irc_context_id:uint])
+ @description:
+ Returns the username of the current irc context.[br]
+ If the irc context is not connected then an empty string is returned.[br]
+ If <irc_context_id> is specified this function returns acts as it was called
+ in that irc_context.[br]
+*/
+
+static bool my_kvs_fnc_user(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_CONSOLE
+ if(wnd)
+ {
+ if(wnd->connection())
+ c->returnValue()->setString(wnd->connection()->userInfo()->userName());
+ }
+ return true;
+}
+
+/*
+ @doc: my.host
+ @type:
+ function
+ @title:
+ $my.host
+ @short:
+ Returns the current hostname
+ @syntax:
+ <string> $my.host([irc_context_id:uint])
+ @description:
+ Returns the hostname of the current irc context as known by the IRC server.[br]
+ If the irc context is not connected then an empty string is returned.[br]
+ If <irc_context_id> is specified this function returns acts as it was called
+ in that irc_context.[br]
+*/
+
+
+static bool my_kvs_fnc_host(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_CONSOLE
+ if(wnd)
+ {
+ if(wnd->connection())
+ c->returnValue()->setString(wnd->connection()->userInfo()->hostName());
+ }
+ return true;
+}
+
+/*
+ @doc: my.ip
+ @type:
+ function
+ @title:
+ $my.ip
+ @short:
+ Returns the current ip address
+ @syntax:
+ <string> $my.ip([irc_context_id:uint])
+ @description:
+ Returns the ip address of the current irc context as known by the IRC server.[br]
+ The ip address is resolved as soon as the hostname is received from the server.
+ If the hostname is masked or there is an error in the DNS lookup then
+ you may get the real local host ip address as determined at connection startup.[br]
+ If the irc context is not connected then an empty string is returned.[br]
+ If <irc_context_id> is specified this function returns acts as it was called
+ in that irc_context.[br]
+*/
+
+
+static bool my_kvs_fnc_ip(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_CONSOLE
+ if(wnd)
+ {
+ if(wnd->connection())
+ c->returnValue()->setString(wnd->connection()->userInfo()->hostIp());
+ }
+ return true;
+}
+
+/*
+ @doc: my.serverIsIPV6
+ @type:
+ function
+ @title:
+ $my.serverIsSSL
+ @short:
+ Returns 1 if the current server connection use IPV6.
+ @syntax:
+ <boolean> $my.serverIsIPV6([irc_context_id:uint])
+ @description:
+ Returns 1 if the server connection use IPV6.[br]
+ If the irc context is not connected then an empty string is returned.[br]
+ If <irc_context_id> is specified this function returns acts as it was called
+ in that irc_context.[br]
+*/
+
+static bool my_kvs_fnc_serverIsIPV6(KviKvsModuleFunctionCall * c)
+{
+
+ GET_KVS_CONSOLE
+ if(wnd)
+ {
+ if(wnd->connection())
+ c->returnValue()->setBoolean(wnd->connection()->server()->isIpV6());
+ }
+ return true;
+}
+
+
+/*
+ @doc: my.serverIsSSL
+ @type:
+ function
+ @title:
+ $my.serverIsSSL
+ @short:
+ Returns 1 if the current server connection use SSL.
+ @syntax:
+ <boolean> $my.serverIsSSL([irc_context_id:uint])
+ @description:
+ Returns 1 if the server connection use SSL.[br]
+ If the irc context is not connected then an empty string is returned.[br]
+ If <irc_context_id> is specified this function returns acts as it was called
+ in that irc_context.[br]
+*/
+
+static bool my_kvs_fnc_serverIsSSL(KviKvsModuleFunctionCall * c)
+{
+
+ GET_KVS_CONSOLE
+ if(wnd)
+ {
+ if(wnd->connection())
+ c->returnValue()->setBoolean(wnd->connection()->socket()->usingSSL());
+ }
+ return true;
+}
+
+/*
+ @doc: my.server
+ @type:
+ function
+ @title:
+ $my.server
+ @short:
+ Returns the current server name
+ @syntax:
+ <string> $my.server([irc_context_id:uint])
+ @description:
+ Returns the server name of the current irc context.[br]
+ If the irc context is not connected then an empty string is returned.[br]
+ If <irc_context_id> is specified this function returns acts as it was called
+ in that irc_context.[br]
+ Please note that this function returns the name of the server as reported
+ by the server itself. Some servers report a bogus value for this field.
+ You should take a look at $context.serverIpAddress or $context.serverHostName
+ if you want a value that can be used to really reconnect to this server.
+*/
+
+static bool my_kvs_fnc_server(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_CONSOLE
+ if(wnd)
+ {
+ if(wnd->connection())
+ c->returnValue()->setString(wnd->connection()->serverInfo()->name());
+ }
+ return true;
+}
+
+/*
+ @doc: my.network
+ @type:
+ function
+ @title:
+ $my.network
+ @short:
+ Returns the current network name
+ @syntax:
+ <string> $my.network([irc_context_id:uint])
+ @description:
+ Returns the network name of the current irc context.[br]
+ If the irc context is not connected then an empty string is returned.[br]
+ If <irc_context_id> is specified this function returns acts as it was called
+ in that irc_context.[br]
+*/
+
+static bool my_kvs_fnc_network(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_CONSOLE
+ if(wnd)
+ {
+ if(wnd->connection())
+ c->returnValue()->setString(wnd->currentNetworkName().utf8().data());
+ }
+ return true;
+}
+
+static bool my_module_init(KviModule * m)
+{
+ g_pIdle = 0;
+ KVSM_REGISTER_FUNCTION(m,"nick",my_kvs_fnc_nick);
+ KVSM_REGISTER_FUNCTION(m,"user",my_kvs_fnc_user);
+ KVSM_REGISTER_FUNCTION(m,"host",my_kvs_fnc_host);
+ KVSM_REGISTER_FUNCTION(m,"ip",my_kvs_fnc_ip);
+ KVSM_REGISTER_FUNCTION(m,"server",my_kvs_fnc_server);
+ KVSM_REGISTER_FUNCTION(m,"network",my_kvs_fnc_network);
+ KVSM_REGISTER_FUNCTION(m,"umode",my_kvs_fnc_umode);
+ KVSM_REGISTER_FUNCTION(m,"serverIsSSL",my_kvs_fnc_serverIsSSL);
+ KVSM_REGISTER_FUNCTION(m,"serverIsIPV6",my_kvs_fnc_serverIsIPV6);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"stopIdleTimer",my_kvs_cmd_stopIdleTimer);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"startIdleTimer",my_kvs_cmd_startIdleTimer);
+ return true;
+}
+
+static bool my_module_cleanup(KviModule *m)
+{
+ if(g_pIdle)
+ delete g_pIdle;
+ g_pIdle = 0;
+ return true;
+}
+
+static bool my_module_can_unload(KviModule *)
+{
+ return !g_pIdle;
+}
+
+KVIRC_MODULE(
+ "My", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)" \
+ " (C) 2005 Tonino Imbesi (grifisx at barmes dot net)" \
+ " (C) 2005 Alessandro Carbone (noldor at barmes dot net)", // author & (C)
+ "Scripting irc-context related functions",
+ my_module_init,
+ my_module_can_unload,
+ 0,
+ my_module_cleanup
+)
diff --git a/src/modules/notifier/Makefile.am b/src/modules/notifier/Makefile.am
new file mode 100644
index 00000000..59639aca
--- /dev/null
+++ b/src/modules/notifier/Makefile.am
@@ -0,0 +1,44 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+SUBDIRS = pics
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvinotifier.la
+
+libkvinotifier_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvinotifier_la_SOURCES = libkvinotifier.cpp \
+ notifierwindow.cpp \
+ notifiermessage.cpp \
+ notifierwindowtabs.cpp \
+ notifierwindowbody.cpp \
+ notifierwindowborder.cpp \
+ notifierwindowprogressbar.cpp
+
+libkvinotifier_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= \
+ notifiersettings.h \
+ notifierwindow.h \
+ notifiermessage.h \
+ notifierwindowtabs.h \
+ notifierwindowbody.h \
+ notifierwindowborder.h \
+ notifierwindowprogressbar.h
+
+confdir = $(configmodulesdir)
+
+conf_DATA = libkvinotifier.kvc
+
+EXTRA_DIST = $(conf_DATA)
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+notifierwindow.cpp: m_notifierwindow.moc
+notifierwindowtabs.cpp: m_notifierwindowtabs.moc
+
diff --git a/src/modules/notifier/libkvinotifier.cpp b/src/modules/notifier/libkvinotifier.cpp
new file mode 100644
index 00000000..edc27f0f
--- /dev/null
+++ b/src/modules/notifier/libkvinotifier.cpp
@@ -0,0 +1,323 @@
+//==================================================================================
+//
+// File : libkvinotifier.cpp
+// Creation date : Tue Jul 7 2004 20:21:12 CEST by Szymon Stefanek
+//
+// Copyright (C) 2005 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 "kvi_module.h"
+
+
+#include "notifierwindow.h"
+#include "notifiermessage.h"
+
+#include "kvi_kvs_variant.h"
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_window.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_time.h"
+#include "kvi_options.h"
+
+#include <qsplitter.h>
+
+KviNotifierWindow * g_pNotifierWindow = 0;
+kvi_time_t g_tNotifierDisabledUntil = 0;
+
+/*
+ @doc: notifier.message
+ @type:
+ command
+ @title:
+ notifier.message
+ @short:
+ Adds a message to the notifier window
+ @syntax:
+ notifier.message [-q|quiet] [-n|noanim] [-w[=<window_id:string>]!] [-i=<image_id:string>] [-t=<timeout:integer>] <messag:string>
+ @description:
+ Adds a message to the notifier window.
+ The notifier window is shown (if not already visible)
+ unless the -q switch is present.
+ The new message becomes the current message of the notifier
+ unless the user is already typing in the input window
+ and the typed message would be directed to a different window.
+ In that case the message is appended at the end of the
+ message queue and the user will be able to scroll to it
+ by using the proper notifier buttons.[br]
+ The &lt;message&gt; text can contain simple html tags: basically you are
+ allowed to use &lt;b&gt; and &lt;i&gt;. The usage of other
+ tags is possible but is discouraged since it tends to
+ mess up the message display. In particular you should avoid
+ any color and/or font specification since the notifier is
+ skinnable and you don't know which color will result in a visible text.
+ [b]Please note that the user can forcibly disable the notifier
+ for a limited period of time (a sort of "don't bug me" option).[/b]
+ @switches:
+ !sw: -n | --noanim
+ Do not animate
+ !sw: -w | --windowid
+ Causes the message gets attacched to the specified window and
+ the user is able to type commands in that window after
+ showing up the notifier input. If the "=&lt;window_id&gt;" part
+ is omitted then the current window is used.[br]
+ !sw: -i | --icon
+ If the -i=&lt;image_id&gt; switch is present then the
+ message has the specified image displayed.
+ See the [doc:image_id]documentation on the image identifier[/doc]
+ for more informations about the image_id parameter.[br]
+ !sw: -q | --quiet
+ If you use -q then you must explicitly call [cmd]notifier.show[/cmd] to
+ show the notifier. If the -n switch is present then
+ the show action will not be animated (the notifier
+ will be shown immediately instead of fading in).
+ Obviously -n has no meaning if -q is used.[br]
+ !sw: -t | --timeout
+ Set the message lifetime to <timeout>
+ Obviously this option has no meaning if the window is not going to be shown.
+ The timeout may be overriddent by new messages but only in the future.
+ If the timeout expires and is not overridden by any new message
+ then the window will be automatically hidden.
+ A zero timeout disables auto-hiding.
+ @seealso:
+ [cmd]notifier.show[/cmd] [cmd]notifier.hide[/cmd] [fnc]$notifier.isEnabled[/fnc]()
+ @examples:
+ [example]
+ notifier.message Hello world!
+ [cmd]notifier.hide[/cmd]
+ notifier.message -q This is a hidden message!
+ notifier.message -q -i=14 This is a second hidden message with an icon
+ [cmd]notifier.show[/cmd]
+ notifier.message -w This message has the current window associated
+ notifier.message -w=[fnc]$window[/fnc] This is equivalent to the above
+ notifier.message &lt;b&gt;Bold text&lt;/b&gt; and normal text
+ [cmd]notifier.hide[/cmd]
+ notifier.message -t=10 This message will be shown only for 10 seconds
+ [/example]
+*/
+
+static bool notifier_kvs_cmd_message(KviKvsModuleCommandCall * c)
+{
+ QString szMessage;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("message",KVS_PT_STRING,0,szMessage)
+ KVSM_PARAMETERS_END(c)
+
+ if(!g_pNotifierWindow)
+ g_pNotifierWindow = new KviNotifierWindow();
+
+ QString szIco="";
+ QString szWnd="";
+
+ KviWindow * pWnd = c->window();
+
+ if(c->hasSwitch('w',"window_id"))
+ {
+ c->switches()->getAsStringIfExisting('w',"window_id",szWnd);
+ if(!szWnd.isEmpty())
+ {
+ pWnd=g_pApp->findWindow(szWnd);
+ if(!pWnd)
+ c->warning(__tr2qs_ctx("The specified window does not exist","notifier"));
+ }
+ }
+ c->switches()->getAsStringIfExisting('i',"icon",szIco);
+ kvs_int_t uTime=0;
+ if(c->hasSwitch('t',"timeout"))
+ {
+ KviKvsVariant *time=c->getSwitch('t',"timeout");
+ if(time)
+ {
+ bool bOk=time->asInteger(uTime);
+ if(!bOk)
+ {
+ uTime = 0;
+ c->warning(__tr2qs_ctx("The specified timeout is not valid, assuming 0","notifier"));
+ }
+ } else {
+ c->warning(__tr2qs_ctx("The -t switch expects a timeout in seconds","notifier"));
+ }
+ }
+
+ g_pNotifierWindow->addMessage(pWnd,szIco,szMessage,uTime);
+
+ if(!c->hasSwitch('q',"quiet"))
+ g_pNotifierWindow->doShow(!(c->hasSwitch('n',"new")));
+ return true;
+}
+
+/*
+ @doc: notifier.hide
+ @type:
+ command
+ @title:
+ notifier.hide
+ @short:
+ Hides the notifier window
+ @syntax:
+ notifier.hide [-n|--noanim]
+ @switches:
+ !sw: -n
+ Causes the hide operation is not animated.
+ @description:
+ Hide the notifier window
+ [b]Please note that the user can forcibly disable the notifier
+ for a limited period of time (a sort of "don't bug me" option).[/b]
+ @seealso:
+ [cmd]notifier.show[/cmd] [cmd]notifier.message[/cmd] [fnc]$notifier.isEnabled[/fnc]
+*/
+
+static bool notifier_kvs_cmd_hide(KviKvsModuleCommandCall * c)
+{
+ if(g_pNotifierWindow) g_pNotifierWindow->doHide(!(c->hasSwitch('n',"notanimated")));
+ return true;
+}
+
+/*
+ @doc: notifier.show
+ @type:
+ command
+ @title:
+ notifier.show
+ @short:
+ Shows the notifier window
+ @syntax:
+ notifier.show [-n|--noanim]
+ @switches:
+ !sw: -n
+ Disables the animation
+ @description:
+ Shows the notifier window if it is not already visible
+ If the -n switch is present then the show operation is
+ not animated.[br]
+ The notifier is shown ONLY if it contains some messages.
+ [b]Please note that the user can forcibly disable the notifier
+ for a limited period of time (a sort of "don't bug me" option).[/b]
+ @seealso:
+ [cmd]notifier.hide[/cmd] [cmd]notifier.message[/cmd] [fnc]$notifier.isEnabled[/fnc]
+*/
+
+static bool notifier_kvs_cmd_show(KviKvsModuleCommandCall * c)
+{
+ if(!g_pNotifierWindow)return true;
+ if(!g_pNotifierWindow->countTabs())return true;
+
+ g_pNotifierWindow->setDisableHideOnMainWindowGotAttention(true);
+ g_pNotifierWindow->doShow(!(c->hasSwitch('n',"noanim")));
+
+ return true;
+}
+/*
+ @doc: notifier.isEnabled
+ @type:
+ function
+ @title:
+ $notifier.isEnabled
+ @short:
+ Returns 1 if the notifier window is enabled
+ @syntax:
+ <boolean> $notifier.isEnabled
+ @description:
+ Returns 1 if the notifier window is enabled and 0 otherwise.
+ The user can forcibly disable the notifier as a sort of "don't bug me"
+ feature for a limited period of time. When the notifier
+ is disabled the messages sent to it will not be shown.[br]
+ The only method that you (scripter) can use to forcibly
+ re-enable the notifier is to unload the module and
+ reload it...but [b]DON'T do it[/b] :)[br]
+ There is also a global option that allows forcibly disabling
+ the notifier forever, this option could be overridden with [cmd]option[/cmd]
+ instead.. but again [b]DON'T do it[/b] :)[br]
+
+*/
+
+static bool notifier_kvs_fnc_isEnabled(KviKvsModuleFunctionCall * c)
+{
+ bool bCheck;
+ if(KVI_OPTION_BOOL(KviOption_boolForciblyDisableNotifier))
+ bCheck=false;
+ else
+ bCheck=g_tNotifierDisabledUntil < kvi_unixTime();
+ c->returnValue()->setBoolean(bCheck);
+ return true;
+}
+
+static bool notifier_module_init(KviModule * m)
+{
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"message",notifier_kvs_cmd_message);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"show",notifier_kvs_cmd_show);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"hide",notifier_kvs_cmd_hide);
+ KVSM_REGISTER_FUNCTION(m,"isEnabled",notifier_kvs_fnc_isEnabled);
+
+ return true;
+}
+
+static bool notifier_module_cleanup(KviModule *m)
+{
+ if(g_pNotifierWindow)
+ {
+ delete g_pNotifierWindow;
+ g_pNotifierWindow = 0;
+ }
+ return true;
+}
+
+static bool notifier_module_can_unload(KviModule *m)
+{
+ return (!g_pNotifierWindow);
+}
+
+typedef struct _NotifierMessageSupaDupaParameterStruct
+{
+ KviWindow * pWindow;
+ QString szIcon;
+ QString szMessage;
+ unsigned int uMessageLifetime; // 0 means no hide
+} NotifierMessageSupaDupaParameterStruct;
+
+static bool notifier_module_ctrl(KviModule *,const char *operation,void *param)
+{
+ if(kvi_strEqualCI("notifier::message",operation))
+ {
+ NotifierMessageSupaDupaParameterStruct * p = (NotifierMessageSupaDupaParameterStruct *)param;
+ if(!p)return false;
+
+ if(!g_pNotifierWindow)
+ g_pNotifierWindow = new KviNotifierWindow();
+
+ g_pNotifierWindow->addMessage(p->pWindow,p->szIcon,p->szMessage,p->uMessageLifetime);
+ g_pNotifierWindow->doShow(KVI_OPTION_BOOL(KviOption_boolDisableNotifierFadein)?false:true);
+
+ return true;
+ }
+ return false;
+}
+
+KVIRC_MODULE(
+ "Notifier",
+ "2.0.0",
+ "Copyright (C) 2005:\n" \
+ " Iacopo Palazzi (iakko at siena dot linux dot it)",
+ "KVIrc Client - Taskbar Notifier",
+ notifier_module_init,
+ notifier_module_can_unload,
+ notifier_module_ctrl,
+ notifier_module_cleanup
+)
diff --git a/src/modules/notifier/libkvinotifier.kvc b/src/modules/notifier/libkvinotifier.kvc
new file mode 100644
index 00000000..4625fe3b
--- /dev/null
+++ b/src/modules/notifier/libkvinotifier.kvc
@@ -0,0 +1,28 @@
+[NotifierSkin]
+CloseX=233
+CloseY=5
+PrevX=233
+PrevY=26
+NextX=233
+NextY=82
+WriteX=233
+WriteY=103
+TextRect=6,22,223,97
+TitleRect=6,5,223,20
+TextFontFamily=Arial
+TextFontSize=9
+TitleFontFamily=Arial
+TitleFontSize=9
+CurTextColor=45,0,0
+OldTextColor1=40,20,20
+OldTextColor2=40,40,40
+OldTextColor3=60,60,60
+OldTextColor4=85,85,85
+OldTextColor5=90,90,90
+OldTextColor6=95,95,95
+HistoricTextColor=125,125,125
+TitleColor=120,70,70
+InputFontFamily=Arial
+InputFontSize=9
+InputHeight=19
+BlinkTimeout=650
diff --git a/src/modules/notifier/notifiermessage.cpp b/src/modules/notifier/notifiermessage.cpp
new file mode 100644
index 00000000..1e91b5de
--- /dev/null
+++ b/src/modules/notifier/notifiermessage.cpp
@@ -0,0 +1,107 @@
+//=============================================================================
+//
+// File : notifiermessage.cpp
+// Created on mar 02 nov 2004 02:41:18 by Iacopo
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2004 Iacopo <iakko@siena.linux.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 "notifiermessage.h"
+#include "notifierwindow.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_config.h"
+#include "kvi_app.h"
+#include "kvi_window.h"
+
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_options.h"
+
+/*
+#ifdef COMPILE_ON_WINDOWS
+ #include <windows.h>
+#endif
+
+#ifdef COMPILE_KDE_SUPPORT
+ #include <netwm.h>
+#endif
+*/
+
+#include <qapplication.h>
+#include <qpainter.h>
+#include <qimage.h>
+#include <qdesktopwidget.h>
+#include <qtooltip.h>
+
+#ifdef COMPILE_USE_QT4
+ #define QPopupMenu Q3PopupMenu
+ #include <q3popupmenu.h>
+#else
+ #include <qpopupmenu.h>
+#endif
+
+extern kvi_time_t g_tNotifierDisabledUntil;
+
+KviNotifierMessage::KviNotifierMessage(KviNotifierWindow * pNotifierWindow, QPixmap * pImage, const QString &szText)
+{
+ m_pText = new QSimpleRichText(KviMircCntrl::stripControlBytes(szText),pNotifierWindow->defaultFont());
+ m_pText->setWidth(pNotifierWindow->textWidth());
+ m_pImage = pImage;
+ m_bHistoric = false;
+}
+
+KviNotifierMessage::~KviNotifierMessage()
+{
+ delete m_pText;
+ if(m_pImage)delete m_pImage;
+}
+
+static void increase_transparency(QImage &buffer,QImage &srcimg,int iDivisor)
+{
+ buffer.create(srcimg.width(),srcimg.height(),32);
+ buffer.setAlphaBuffer(true);
+
+ for(int y = 0;y < buffer.height();y++)
+ {
+ QRgb * dst = (QRgb *)buffer.scanLine(y);
+ QRgb * end = dst + buffer.width();
+ QRgb * src = (QRgb *)srcimg.scanLine(y);
+
+ while(dst < end)
+ {
+ *dst = qRgba(qRed(*src),qGreen(*src),qBlue(*src),qAlpha(*src) / iDivisor);
+ dst++;
+ src++;
+ }
+ }
+}
+
+void KviNotifierMessage::setHistoric()
+{
+ m_bHistoric = true;
+ if(!m_pImage)return;
+ if(!m_pImage->hasAlphaChannel())return;
+ QImage tmp;
+ QImage out = m_pImage->convertToImage();
+ increase_transparency(tmp,out,2);
+ m_pImage->convertFromImage(tmp);
+}
+
diff --git a/src/modules/notifier/notifiermessage.h b/src/modules/notifier/notifiermessage.h
new file mode 100644
index 00000000..da4a6df2
--- /dev/null
+++ b/src/modules/notifier/notifiermessage.h
@@ -0,0 +1,97 @@
+#ifndef _NOTIFIERMESSAGE_H_
+#define _NOTIFIERMESSAGE_H_
+//=============================================================================
+//
+// File : notifiermessage.h
+// Created on mar 02 nov 2004 02:41:18 by
+// Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it >
+//
+// This file is part of the KVIrc distribution
+// Copyright (C) 2004 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 <qwidget.h>
+#include <qrect.h>
+#include <qtimer.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qfont.h>
+#include <qcolor.h>
+#include <qlineedit.h>
+
+#include "kvi_qstring.h"
+#include "kvi_pointerlist.h"
+#include "kvi_time.h"
+
+#ifdef COMPILE_USE_QT4
+ #define QSimpleRichText Q3SimpleRichText
+ #define QPopupMenu Q3PopupMenu
+ #include <q3popupmenu.h>
+ #include <q3simplerichtext.h>
+#else
+ #include <qsimplerichtext.h>
+#endif
+
+class KviWindow;
+class KviNotifierWindow;
+
+class QPopupMenu;
+
+class KviNotifierMessage
+{
+ friend class KviNotifierWindow;
+public:
+ KviNotifierMessage(KviNotifierWindow * pNotifierWindow, QPixmap * pImage, const QString &szText);
+ ~KviNotifierMessage();
+
+// ================================
+// Put members declaration below...
+// ================================
+private:
+
+public:
+
+protected:
+ KviWindow * m_pWindow;
+ QPixmap * m_pImage;
+ QSimpleRichText * m_pText;
+ bool m_bHistoric;
+
+// ================================
+// Put methods declaration below...
+// ================================
+private:
+
+public:
+ bool historic(){ return m_bHistoric; };
+ void setHistoric();
+ void setWindow(KviWindow * pWnd){ m_pWindow = pWnd; };
+ QPixmap * image(){ return m_pImage; };
+ QSimpleRichText * text(){ return m_pText; };
+
+protected:
+
+
+};
+
+#define NUM_OLD_COLORS 6
+
+#endif //!_NOTIFIERMESSAGE_H_
diff --git a/src/modules/notifier/notifiersettings.h b/src/modules/notifier/notifiersettings.h
new file mode 100644
index 00000000..b694dc59
--- /dev/null
+++ b/src/modules/notifier/notifiersettings.h
@@ -0,0 +1,66 @@
+#ifndef _NOTIFIER_SETTINGS_H_
+#define _NOTIFIER_SETTINGS_H_
+//=============================================================================
+//
+// File : kvinotifierwindowcaption.h
+// Created on gio 30 dic 2004 21:21:33 by Iacopo Palazzi
+//
+// This file is part of the Notifier - KVIrc Distribution distribution
+// Copyright (C) 2004 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 150
+#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 00000000..d275be23
--- /dev/null
+++ b/src/modules/notifier/notifierwindow.cpp
@@ -0,0 +1,1427 @@
+//==================================================================================
+//
+// 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 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"
+
+#ifdef COMPILE_USE_QT4
+ #define QPopupMenu Q3PopupMenu
+ #define QSimpleRichText Q3SimpleRichText
+
+ #include <q3popupmenu.h>
+ #include <q3simplerichtext.h>
+#else
+ #include <qpopupmenu.h>
+ #include <qsimplerichtext.h>
+#endif
+
+ #include <qpainter.h>
+
+#include "notifiermessage.h"
+#include "notifierwindow.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_config.h"
+#include "kvi_app.h"
+#include "kvi_window.h"
+
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_options.h"
+#include "kvi_userinput.h"
+
+#include <qapplication.h>
+#include <qimage.h>
+#include <qdesktopwidget.h>
+#include <qtooltip.h>
+#include <qevent.h>
+#include <qpen.h>
+#include <qfontmetrics.h>
+#include <qregexp.h>
+
+#include "notifierwindowbody.h"
+#include "notifierwindowborder.h"
+#include "notifierwindowprogressbar.h"
+#include "notifierwindowtabs.h"
+
+extern KviNotifierWindow * g_pNotifierWindow;
+
+KviNotifierWindow::KviNotifierWindow()
+: QWidget(0,"kvirc_notifier_window",
+#ifdef COMPILE_ON_WINDOWS
+ Qt::WStyle_Customize |
+ Qt::WStyle_NoBorder |
+ Qt::WStyle_Tool |
+ Qt::WStyle_StaysOnTop)
+#else
+ Qt::WStyle_Customize |
+ Qt::WStyle_NoBorder |
+#ifndef Q_OS_MACX
+ Qt::WStyle_Tool |
+ Qt::WX11BypassWM |
+#endif
+ Qt::WStyle_StaysOnTop)
+#endif
+{
+
+ 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_pProgressTimer = 0;
+
+ m_pWndBorder = new KviNotifierWindowBorder();
+
+ reloadImages();
+
+ KviStr buffer;
+ g_pApp->getReadOnlyConfigPath(buffer,"libkvinotifier.kvc",KviApp::ConfigPlugins,true);
+
+ KviConfig cfg(buffer.ptr(),KviConfig::Read);
+
+ cfg.setGroup("NotifierSkin");
+
+ QString szFamily = cfg.readEntry("TextFontFamily","Arial");
+ m_pDefaultFont = new QFont(szFamily,cfg.readIntEntry("TextFontSize",9));
+ szFamily = cfg.readEntry("TitleFontFamily","Arial");
+ m_pTitleFont = new QFont(szFamily,cfg.readIntEntry("TitleFontSize",9));
+
+ m_clrCurText = cfg.readColorEntry("CurTextColor",QColor(40,0,0));
+ m_clrHistoricText = cfg.readColorEntry("HistoricTextColor",QColor(125,125,125));
+ m_clrTitle = QColor(255,255,255); //cfg.readColorEntry("TitleColor",QColor(0,0,0));
+ for(int i=0;i<NUM_OLD_COLORS;i++)
+ {
+ KviStr szKey;
+ szKey.sprintf("OldTextColor%d",i + 1);
+ m_clrOldText[i] = cfg.readColorEntry(szKey.ptr(),QColor(90,90,90));
+ }
+
+ m_iBlinkTimeout = cfg.readIntEntry("BlinkTimeout",650);
+ if(m_iBlinkTimeout < 100)m_iBlinkTimeout = 100;
+ m_iInputHeight = cfg.readIntEntry("InputHeight",20);
+ if(m_iInputHeight < 10)m_iInputHeight = 10;
+
+ setBackgroundMode(Qt::NoBackground);
+#ifdef COMPILE_USE_QT4
+ setFocusPolicy(Qt::NoFocus);
+#else
+ setFocusPolicy(QWidget::NoFocus);
+#endif
+ setMouseTracking(true);
+ //setCursor(m_cursor);
+
+ hide();
+ m_pLineEdit = new QLineEdit(this);
+ m_pLineEdit->setGeometry(0,0,0,0);
+ m_pLineEdit->hide();
+ m_pLineEdit->installEventFilter(this);
+ connect(m_pLineEdit,SIGNAL(returnPressed()),this,SLOT(returnPressed()));
+
+ szFamily = cfg.readEntry("InputFontFamily","Arial");
+ m_pLineEdit->setFont(QFont(szFamily,cfg.readIntEntry("InputFontSize",9)));
+
+ m_bBlinkOn = false;
+
+ m_bCloseDown = false;
+ m_bPrevDown = false;
+ m_bNextDown = false;
+ m_bWriteDown = false;
+
+ m_bKeyShiftPressed = 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
+ int iWidth = m_pixBackground.width();
+ int iHeight = m_pixBackground.height();
+ QDesktopWidget * w = QApplication::desktop();
+ QRect r = w->availableGeometry(w->primaryScreen()); //w->screenGeometry(w->primaryScreen());
+
+ /*debug("r.x(),r.y(): %d,%d",r.x(),r.y());
+ debug("r.width(),r.height(): %d,%d",r.width(),r.height());*/
+
+ m_wndRect.setRect( r.x() + r.width() - (iWidth + SPACING), r.y() + r.height() - (iHeight + SPACING), iWidth, iHeight );
+
+ //m_pWndBorder = new KviNotifierWindowBorder();
+ m_pWndTabs = new KviNotifierWindowTabs(m_pWndBorder->tabsRect());
+ m_pWndBody = new KviNotifierWindowBody(m_pWndBorder->bodyRect());
+
+ m_pProgressBar = new KviNotifierWindowProgressBar(m_pWndBorder->progressRect());
+
+ // FIXME: Ugly global-font initialization..
+ QFontMetrics titleFontMetrics(*m_pTitleFont);
+ m_pWndBorder->centerTitle(titleFontMetrics.height());
+
+ connect(g_pApp,SIGNAL(reloadImages()),this,SLOT(reloadImages()));
+}
+
+KviNotifierWindow::~KviNotifierWindow()
+{
+ stopShowHideTimer();
+ stopBlinkTimer();
+ stopAutoHideTimer();
+ delete m_pDefaultFont;
+ delete m_pTitleFont;
+ delete m_pWndBorder;
+ delete m_pWndTabs;
+ delete m_pWndBody;
+}
+
+int KviNotifierWindow::countTabs() {
+ return m_pWndTabs->count();
+}
+
+void KviNotifierWindow::reloadImages()
+{
+ m_pixBackground.resize(WDG_MIN_WIDTH,WDG_MIN_HEIGHT);
+ m_pixBackground.fill();
+ m_pixBackgroundHighlighted.resize(m_pixBackground.size());
+ m_pixBackgroundHighlighted.fill();
+
+ m_pWndBorder->resize(m_pixBackground.size());
+}
+
+
+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 * m = new KviNotifierMessage(this,pIcon ? new QPixmap(*pIcon) : 0,szMessage);
+
+ m_pWndTabs->addMessage(pWnd, m); // Adds a tab about the sender pWnd
+
+ 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;
+ }
+
+ //m_pWndTabs->setCurrentMessage(m);
+ if(isVisible())update();
+ // else the line edit was hidden
+}
+
+
+int KviNotifierWindow::textWidth() {
+ return m_pWndBody->textRect().width() - 20;
+};
+
+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_pProgressTimer) delete m_pProgressTimer;
+ m_pProgressTimer = 0;
+
+ if(!m_pAutoHideTimer)return;
+ delete m_pAutoHideTimer;
+ m_pAutoHideTimer = 0;
+ m_pProgressBar->setProgress(0);
+}
+
+void KviNotifierWindow::computeRect()
+{
+ int iWidth = m_pixBackground.width();
+ int iHeight = m_pixBackground.height();
+ m_pWndBorder->setGeometry(QPoint(x(),y()), QSize(iWidth,iHeight));
+ update();
+}
+
+void KviNotifierWindow::doShow(bool bDoAnimate)
+{
+ if(KVI_OPTION_BOOL(KviOption_boolForciblyDisableNotifier))return;
+
+ kvi_time_t tNow = kvi_unixTime();
+ if(g_tNotifierDisabledUntil > tNow)return;
+ g_tNotifierDisabledUntil = 0;
+
+ 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 (!defined COMPILE_USE_QT4) || !(defined(COMPILE_USE_QT4) && (defined(COMPILE_ON_WINDOWS) || defined(Q_OS_MACX)))
+ m_imgDesktop = QPixmap::grabWindow(
+ QApplication::desktop()->winId(),
+ m_wndRect.x(),
+ m_wndRect.y(),
+ m_wndRect.width(),
+ m_wndRect.height()).convertToImage();
+ #endif
+ // QPixmap tmp = QPixmap::grabWindow( QApplication::desktop()->winId(),m_wndRect.x(), m_wndRect.y(), m_wndRect.width(), m_wndRect.height());
+ // tmp.save("/root/pix.png","PNG");
+ m_pixForeground.resize(m_pixBackground.size());
+ m_imgBuffer.create(m_pixBackground.width(),m_pixBackground.height(),32);
+ if(bDoAnimate)
+ {
+ m_pShowHideTimer = new QTimer();
+ connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat()));
+ m_dOpacity = OPACITY_STEP;
+ m_eState = Showing;
+ m_bCrashShowWorkAround=true;
+ #if defined(COMPILE_USE_QT4) && (defined(COMPILE_ON_WINDOWS) || defined(Q_OS_MACX))
+ setWindowOpacity(m_dOpacity);
+ #endif
+ show();
+ #if defined(COMPILE_USE_QT4) && (defined(COMPILE_ON_WINDOWS) || defined(Q_OS_MACX))
+ m_pShowHideTimer->start(40);
+ #else
+ m_pShowHideTimer->start(100);
+ #endif
+ computeRect();
+ m_bCrashShowWorkAround=false;
+ //show();
+
+ } else {
+ m_dOpacity = 1.0;
+ m_eState = Visible;
+ show();
+ startBlinking();
+ startAutoHideTimer();
+ }
+ break;
+ }
+}
+
+bool KviNotifierWindow::shouldHideIfMainWindowGotAttention()
+{
+ if(m_bDisableHideOnMainWindowGotAttention)return false;
+ KviNotifierWindowTab * t = m_pWndTabs->currentTab();
+ if(!t)return false;
+ if(!t->window())return false;
+ return t->window()->hasAttention();
+}
+
+
+void KviNotifierWindow::heartbeat()
+
+{
+ bool bIncreasing;
+ double targetOpacity = 0; //qt4
+ switch(m_eState)
+ {
+ case Hidden:
+ hideNow();
+ break;
+ case Visible:
+ stopShowHideTimer();
+ m_dOpacity = 1.0;
+ if(!isVisible())show(); //!!!
+ 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;
+#ifdef COMPILE_USE_QT4
+ targetOpacity = isActiveWindow() ? KVI_OPTION_UINT(KviOption_uintNotifierActiveTransparency) : KVI_OPTION_UINT(KviOption_uintNotifierInactiveTransparency);
+
+ targetOpacity/=100;
+ if(m_dOpacity >= targetOpacity)
+ {
+ m_dOpacity = targetOpacity;
+#else
+ if(m_dOpacity >= 1.0)
+ {
+ m_dOpacity = 1.0;
+#endif
+ m_eState = Visible;
+ stopShowHideTimer();
+ startBlinking();
+ startAutoHideTimer();
+ }
+
+ if(!isVisible())show(); //!!!
+ if(m_pLineEdit->isVisible())m_pLineEdit->hide();
+ #if defined(COMPILE_USE_QT4) && (defined(COMPILE_ON_WINDOWS) || defined(Q_OS_MACX))
+ setWindowOpacity(m_dOpacity);
+ #endif
+ update();
+
+ }
+ break;
+#ifdef COMPILE_USE_QT4
+ 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);
+ //debug("%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;
+#endif
+ case Hiding:
+ m_dOpacity -= OPACITY_STEP;
+ #if defined(COMPILE_USE_QT4) && (defined(COMPILE_ON_WINDOWS) || defined(Q_OS_MACX))
+ setWindowOpacity(m_dOpacity);
+ #endif
+ if(m_pLineEdit->isVisible())m_pLineEdit->hide();
+ 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;
+
+ if(m_pLineEdit->isVisible())m_pLineEdit->hide();
+ hide();//if(isVisible())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(m_pLineEdit->isVisible())m_pLineEdit->hide();
+ if((!bDoAnimate) || (x() != m_pWndBorder->x()) || (y() != m_pWndBorder->y()))
+ {
+
+ //debug ("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 {
+ //debug ("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;
+ #if defined(COMPILE_USE_QT4) && (defined(COMPILE_ON_WINDOWS) || defined(Q_OS_MACX))
+ setWindowOpacity(m_dOpacity);
+ update();
+ m_pShowHideTimer->start(40);
+ #else
+ update();
+ m_pShowHideTimer->start(100);
+ #endif
+
+
+ }
+ break;
+ }
+}
+
+void KviNotifierWindow::showEvent(QShowEvent *e)
+{
+ computeRect();
+ setGeometry(m_wndRect); // w_win = w_wndRect
+
+}
+
+void KviNotifierWindow::hideEvent(QHideEvent * e)
+{
+ if (m_bCrashShowWorkAround) return;
+ stopBlinkTimer();
+ stopShowHideTimer();
+ stopAutoHideTimer();
+ m_eState = Hidden; // make sure it's true
+ m_tAutoHideAt = 0; // make sure it's true
+ markAllMessagesAsHistoric();
+ m_bDisableHideOnMainWindowGotAttention = false;
+}
+
+void KviNotifierWindow::startBlinking()
+{
+ stopBlinkTimer();
+ m_bBlinkOn = false;
+
+
+ if(!KVI_OPTION_BOOL(KviOption_boolDisableNotifierFlashing))
+ {
+ m_pBlinkTimer = new QTimer();
+ connect(m_pBlinkTimer,SIGNAL(timeout()),this,SLOT(blink()));
+ m_iBlinkCount = 0;
+ m_pBlinkTimer->start(m_iBlinkTimeout);
+ }
+}
+
+void KviNotifierWindow::startAutoHideTimer()
+{
+ stopAutoHideTimer();
+ m_tStartedAt = kvi_unixTime();
+ m_qtStartedAt.start();
+ if(m_tAutoHideAt <= m_tStartedAt)return;
+
+ int nSecs = m_tAutoHideAt - m_tStartedAt;
+ if(nSecs < 5)nSecs = 5;
+ m_pAutoHideTimer = new QTimer();
+ connect(m_pAutoHideTimer,SIGNAL(timeout()),this,SLOT(autoHide()));
+ m_pAutoHideTimer->start(nSecs * 1000);
+
+ m_pProgressTimer= new QTimer();
+ connect(m_pProgressTimer,SIGNAL(timeout()),this,SLOT(progressUpdate()));
+ m_pProgressTimer->start(60);
+}
+
+void KviNotifierWindow::autoHide()
+{
+ m_tAutoHideAt = 0;
+ stopAutoHideTimer();
+ doHide(true);
+}
+
+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::markAllMessagesAsHistoric()
+{
+ if (!m_pWndTabs) return;
+ m_pWndTabs->markAllMessagesAsHistoric();
+}
+
+
+static void blend_images(QImage &buffer,QImage &background,QImage &foreground,double dValue)
+{
+ for(int y = 0;y < buffer.height();y++)
+ {
+ QRgb * dst = (QRgb *)buffer.scanLine(y);
+ QRgb * end = dst + buffer.width();
+ QRgb * bkg = (QRgb *)background.scanLine(y);
+ QRgb * fgn = (QRgb *)foreground.scanLine(y);
+
+ double dRemaining = 1.0 - dValue;
+
+ while(dst < end)
+ {
+ *dst = qRgb(
+ (int)((qRed(*bkg) * dRemaining) + (qRed(*fgn) * dValue)),
+ (int)((qGreen(*bkg) * dRemaining) + (qGreen(*fgn) * dValue)),
+ (int)((qBlue(*bkg) * dRemaining) + (qBlue(*fgn) * dValue))
+ );
+ dst++;
+ bkg++;
+ fgn++;
+ }
+
+ }
+}
+
+void KviNotifierWindow::paintEvent(QPaintEvent * e)
+{
+
+/*
+ if(m_bBlinkOn)
+ bitBlt(&m_pixForeground,QPoint(0,0),&m_pixBackgroundHighlighted);
+ else
+ bitBlt(&m_pixForeground,QPoint(0,0),&m_pixBackground);
+
+ QPainter p(&m_pixForeground);
+*/
+ redrawWindow();
+ redrawText();
+ if(m_dOpacity < 1.0)
+ {
+ QPainter px(this);
+
+ #if defined(COMPILE_USE_QT4) && (defined(COMPILE_ON_WINDOWS) || defined(Q_OS_MACX))
+ px.drawPixmap(0,0,m_pixForeground);
+ #else
+ QImage temp_image = m_pixForeground.convertToImage();
+ blend_images(m_imgBuffer,m_imgDesktop,temp_image,m_dOpacity);
+ px.drawImage(0,0,m_imgBuffer);
+ #endif
+ px.end();
+ } else {
+#ifdef COMPILE_USE_QT4
+ QPainter px(this);
+ px.drawPixmap(0,0,m_pixForeground);
+#else
+ bitBlt(this,QPoint(0,0),&m_pixForeground);
+#endif
+ }
+}
+
+void KviNotifierWindow::redrawText()
+{
+ QPainter p(&m_pixForeground);
+
+ // the current tab
+ KviNotifierWindowTab * tab = m_pWndTabs->currentTab();
+ if(!tab)return;
+
+ // it's message list
+ KviPointerList<KviNotifierMessage> * l = tab->messageList();
+ if(!l)return;
+ if(l->isEmpty())return;
+
+ // the current message
+ KviNotifierMessage * cur = tab->currentMessage();
+ if(!cur)cur = l->last();
+
+ // this is useful in several places
+ KviNotifierMessage * last = l->last();
+
+ // make sure that we can loop
+ int iIdx = l->findRef(cur);
+ if(iIdx == -1)
+ {
+ tab->setCurrentMessage(last);
+ cur = last;
+ iIdx = l->findRef(cur);
+ }
+
+ int y = m_pWndBody->textRect().y() + m_pWndBody->textRect().height();
+
+ if(m_pLineEdit->isVisible())y -= (m_pLineEdit->height() + 4);
+
+ QColorGroup grp = colorGroup();
+
+ int idx = iIdx;
+ KviNotifierMessage * m = cur;
+ while(m && (y > m_pWndBody->textRect().y()))
+ {
+ int iHeight = m->text()->height();
+ if(iHeight < 18)iHeight = 18;
+ y -= iHeight;
+ if(m->historic())
+ {
+ grp.setColor(QColorGroup::Text,m_clrHistoricText);
+ } else {
+ if(m == last)
+ grp.setColor(QColorGroup::Text,m_clrCurText);
+ else {
+ int iClrIdx = l->count() - (idx + 2);
+ if(iClrIdx < 0)iClrIdx = 0;
+ else if(iClrIdx >= NUM_OLD_COLORS)iClrIdx = (NUM_OLD_COLORS - 1);
+ grp.setColor(QColorGroup::Text,m_clrOldText[iClrIdx]);
+ }
+ }
+ int iMaxY = y > m_pWndBody->textRect().y() ? y : m_pWndBody->textRect().y();
+ QRect clip(m_pWndBody->textRect().x() + 20,iMaxY,m_pWndBody->textRect().width() - 20,iHeight);
+
+ m->text()->draw(&p,m_pWndBody->textRect().x() + 20,y,clip,grp); //
+ if(y > m_pWndBody->textRect().y())
+ {
+ if(m->image())
+ p.drawPixmap(m_pWndBody->textRect().x() + 1,y + 1,*(m->image()),0,0,16,16);
+ }
+ m = l->prev();
+ idx--;
+ }
+
+ p.setPen(QPen(m_clrTitle));
+ p.setFont(*m_pTitleFont);
+ QString title;
+ KviQString::sprintf(title,"[%d/%d]",iIdx + 1,l->count());
+
+ if(tab->window())
+ {
+ title += " ";
+ title += tab->window()->plainTextCaption();
+ }
+ p.drawText(m_pWndBorder->titleRect(),Qt::AlignLeft | Qt::SingleLine,title);
+ p.end();
+}
+
+void KviNotifierWindow::mouseMoveEvent(QMouseEvent * e)
+{
+
+ //debug ("move on x,y: %d,%d", e->pos().x(), e->pos().y());
+
+ if (!m_bLeftButtonIsPressed) {
+
+ if(checkResizing(e->pos())) goto sartelo;
+
+ /* ### MOUSE-MOVE-EVENT -> m_pWndBorder ### */
+ 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;
+ }
+
+ if(m_pWndTabs->currentTab())
+ {
+ /* ### MOUSE-MOVE-EVENT -> m_pWndTabs ### */
+ if (m_pWndTabs->rect().contains(e->pos())) {
+ m_pWndTabs->mouseMoveEvent(e);
+ goto sartelo;
+ }
+
+ /* ### MOUSE-MOVE-EVENT -> m_pWndBody ### */
+ if (m_pWndBody->rect().contains(e->pos())) {
+ if (m_pWndBody->rctWriteIcon().contains(e->pos())) {
+ m_pWndBody->setWriteIcon(WDG_ICON_ON);
+ } else {
+ m_pWndBody->setWriteIcon(WDG_ICON_OFF);
+ }
+ goto sartelo;
+ }
+ }
+ /* ### END ### */
+
+sartelo:
+
+ update();
+
+ }
+
+ if(m_bDragging) {
+ setCursor(Qt::SizeAllCursor);
+
+ int w = m_wndRect.width();
+ int h = 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(w);
+ m_wndRect.setHeight(h);
+
+ setGeometry(m_wndRect);
+
+ return;
+ } 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();
+
+ setActiveWindow();
+ 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)) goto sartelo;
+
+ if(m_pWndTabs->rect().contains(e->pos()))
+ {
+ m_pWndTabs->mousePressEvent(e);
+ goto sartelo;
+ }
+
+ if(m_pWndBorder->captionRect().contains(e->pos())) {
+ //debug ("Clicked on m_pWndBorder->rect()");
+ if(m_pWndBorder->closeRect().contains(e->pos())) {
+ //debug ("\tClicked on m_pWndBorder->closeRect()");
+ m_bCloseDown = true;
+ m_pWndBorder->setCloseIcon(WDG_ICON_CLICKED);
+ goto sartelo;
+ }
+
+ if( !m_bResizing) {
+ m_bDragging = true;
+ m_pntDrag = cursor().pos();
+ m_pntPos = pos();
+ goto sartelo;
+ }
+ }
+
+ //debug ("x,y: %d,%d - width,height: %d,%d", m_pWndBorder->rect().x(),m_pWndBorder->rect().y(),m_pWndBorder->rect().width(),m_pWndBorder->rect().height());
+
+ if (m_pWndBorder->rect().contains(e->pos())) {
+ if(m_pWndTabs->currentTab())
+ {
+ //debug ("Clicked on m_pWndBody->textRect()");
+ if(m_pWndBody->rctWriteIcon().contains(e->pos()))
+ {
+ m_pWndBody->setWriteIcon(WDG_ICON_CLICKED);
+ showLineEdit(!(m_pLineEdit->isVisible()));
+ }
+
+ if(m_pWndBody->rctPrevIcon().contains(e->pos()) && m_pWndBody->prevIconState()!=WDG_ICON_OFF)
+ {
+ m_bPrevDown = true;
+ m_pWndBody->setPrevIcon(WDG_ICON_CLICKED);
+ prevButtonClicked();
+ }
+
+ if(m_pWndBody->rctNextIcon().contains(e->pos()) && m_pWndBody->nextIconState()!=WDG_ICON_OFF)
+ {
+ m_bNextDown = true;
+ m_pWndBody->setNextIcon(WDG_ICON_CLICKED);
+ nextButtonClicked();
+ }
+ }
+ goto sartelo;
+ }
+
+ if(bWasBlinkOn) goto sartelo; else return;
+
+sartelo:
+ update();
+
+}
+
+void KviNotifierWindow::mouseReleaseEvent(QMouseEvent * e)
+{
+ m_bWriteDown = false;
+ m_bNextDown = false;
+ m_bPrevDown = false;
+ m_bCloseDown = false;
+ m_bLeftButtonIsPressed = false;
+ m_bResizing = false;
+
+ //m_pWndBody->setWriteIcon(WDG_ICON_ON);
+ m_pWndBody->setNextIcon(WDG_ICON_ON);
+ m_pWndBody->setPrevIcon(WDG_ICON_ON);
+ m_pWndTabs->setCloseTabIcon(WDG_ICON_OFF);
+
+ 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())) {
+ //debug ("hide now from release event");
+ hideNow();
+ } else {
+ update();
+ }
+
+ }
+
+ if(m_pWndTabs->rect().contains(e->pos()))
+ {
+ m_pWndTabs->mouseReleaseEvent(e);
+ }
+
+ setCursor(-1);
+
+}
+
+void KviNotifierWindow::mouseDoubleClickEvent(QMouseEvent * e)
+{
+ if(!m_pWndBody->textRect().contains(e->pos()))
+ {
+ QWidget::mouseDoubleClickEvent(e);
+ return;
+ }
+
+ KviNotifierWindowTab * tab = m_pWndTabs->currentTab();
+ if(!tab)return;
+
+ if(!tab->window())return;
+
+ hideNow();
+ delayedRaise(tab->window());
+}
+
+void KviNotifierWindow::keyPressEvent(QKeyEvent * e)
+{
+ if (e->key()==Qt::Key_Shift) {
+ m_bKeyShiftPressed = true;
+ return;
+ }
+
+ if (e->key()==Qt::Key_Left && m_bKeyShiftPressed) {
+ m_pWndTabs->prev();
+ return;
+ }
+ if (e->key()==Qt::Key_Right && m_bKeyShiftPressed) {
+ m_pWndTabs->next();
+ return;
+ }
+
+ if (e->key()==Qt::Key_Escape) {
+ hideNow();
+ return;
+ }
+}
+
+void KviNotifierWindow::keyReleaseEvent(QKeyEvent * e)
+{
+ if (e->key()==Qt::Key_Shift) {
+ m_bKeyShiftPressed = false;
+ }
+}
+
+void KviNotifierWindow::delayedRaise(KviWindow * pWnd)
+{
+ m_pWindowToRaise = pWnd;
+ QTimer::singleShot(0,this,SLOT(delayedRaiseSlot()));
+}
+
+void KviNotifierWindow::delayedRaiseSlot()
+{
+ if(!m_pWindowToRaise)return;
+ if(!g_pApp->windowExists(m_pWindowToRaise))return;
+
+ if(m_pWindowToRaise->mdiParent())
+ {
+ if(!m_pWindowToRaise->frame()->isVisible())
+ m_pWindowToRaise->frame()->show();
+
+ m_pWindowToRaise->frame()->raise();
+ //((QWidget *)(m_pWindowToRaise->frame()))->setActiveWindow();
+ m_pWindowToRaise->frame()->setFocus();
+ }
+
+ m_pWindowToRaise->delayedAutoRaise();
+}
+
+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 p, bool up)
+{
+ //QPoint aux = mapToGlobal(p);
+
+ 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);
+}
+
+void KviNotifierWindow::redrawWindow()
+{
+ if(m_pixBackground.size()!=m_wndRect.size())
+ {
+ // Redraw only if size was modified..
+ m_pixBackground.resize(m_wndRect.size());
+ m_pixForeground.resize(m_wndRect.size());
+ m_pixBackgroundHighlighted.resize(m_wndRect.size());
+
+ m_pWndBorder->resize( m_wndRect.size() );
+ m_pWndTabs->setWidth( m_pWndBorder->tabsRect().width() );
+ m_pWndBody->resize( m_pWndBorder->bodyRect() );
+ m_pProgressBar->setHeight(m_pWndBorder->bodyRect().height() + m_pWndBorder->tabsRect().height());
+ }
+
+ QPainter paint;
+ if(m_bBlinkOn)
+ {
+ m_pWndBorder->touch();
+ m_pWndTabs->touch();
+ m_pWndBody->touch();
+ paint.begin(&m_pixBackgroundHighlighted);
+ m_pWndBorder->draw(&paint,true);
+ m_pWndTabs->draw(&paint);
+ m_pWndBody->draw(&paint);
+ m_pProgressBar->draw(&paint);
+ paint.end();
+ bitBlt(&m_pixForeground, 0,0, &m_pixBackgroundHighlighted);
+ m_pWndBorder->touch();
+ m_pWndTabs->touch();
+ m_pWndBody->touch();
+ } else {
+ paint.begin(&m_pixBackground);
+ m_pWndBorder->draw(&paint);
+ m_pWndTabs->draw(&paint);
+ m_pWndBody->draw(&paint);
+ m_pProgressBar->draw(&paint);
+ paint.end();
+ bitBlt(&m_pixForeground, 0,0, &m_pixBackground);
+ }
+
+}
+
+inline void KviNotifierWindow::setCursor(int cur) {
+ if (m_cursor.shape() != cur) {
+ if(QApplication::overrideCursor()) QApplication::restoreOverrideCursor();
+ m_cursor.setShape((Qt::CursorShape)cur);
+ QApplication::setOverrideCursor(m_cursor);
+ } else if (cur==-1)
+ if(QApplication::overrideCursor()) QApplication::restoreOverrideCursor();
+}
+
+void KviNotifierWindow::enterEvent(QEvent * e)
+{
+#ifdef COMPILE_USE_QT4
+ if(!m_pShowHideTimer) {
+ m_pShowHideTimer = new QTimer();
+ connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat()));
+ }
+ m_eState = FocusingOn;
+ m_pShowHideTimer->start(40);
+#endif
+}
+
+void KviNotifierWindow::leaveEvent(QEvent * e)
+{
+ // Leaving the widget area, restore default cursor
+ m_pWndBorder->resetIcons();
+ m_pWndTabs->resetIcons();
+ if (!m_bResizing)
+ setCursor(-1);
+#ifdef COMPILE_USE_QT4
+ if(!m_pShowHideTimer) {
+ m_pShowHideTimer = new QTimer();
+ connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat()));
+ }
+ m_eState = FocusingOff;
+ m_pShowHideTimer->start(40);
+#endif
+}
+
+void KviNotifierWindow::contextPopup(const QPoint &pos)
+{
+ if(!m_pContextPopup)
+ {
+ m_pContextPopup = new QPopupMenu(this);
+ connect(m_pContextPopup,SIGNAL(aboutToShow()),this,SLOT(fillContextPopup()));
+ m_pDisablePopup = new QPopupMenu(this);
+ }
+
+ m_pContextPopup->popup(pos);
+}
+
+void KviNotifierWindow::fillContextPopup()
+{
+ m_pContextPopup->clear();
+
+ 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_boolForciblyDisableNotifier) = true;
+ hideNow();
+}
+
+void KviNotifierWindow::wheelEvent(QWheelEvent * e)
+{
+ if(e->delta() > 0)prevButtonClicked();
+ else nextButtonClicked();
+}
+
+
+void KviNotifierWindow::prevButtonClicked()
+{
+ KviNotifierWindowTab * tab = m_pWndTabs->currentTab();
+ if(!tab)return;
+ tab->setPrevMessageAsCurrent();
+ update();
+}
+
+void KviNotifierWindow::nextButtonClicked()
+{
+ KviNotifierWindowTab * tab = m_pWndTabs->currentTab();
+ if(!tab)return;
+ tab->setNextMessageAsCurrent();
+ update();
+}
+
+void KviNotifierWindow::showLineEdit(bool bShow)
+{
+ if(bShow)
+ {
+ //if(m_pLineEdit->isVisible())return;
+ if(!m_pWndTabs->currentMessage())return;
+ if(!m_pWndTabs->currentTab()->window())return;
+ QToolTip::remove(m_pLineEdit);
+ QString tip = __tr2qs_ctx("Write text or commands to window","notifier");
+ tip += " \"";
+ tip += m_pWndTabs->currentTab()->window()->plainTextCaption();
+ tip += "\"";
+ QToolTip::add(m_pLineEdit,tip);
+ m_pLineEdit->setGeometry(m_pWndBody->textRect().x(),m_pWndBody->textRect().y() + m_pWndBody->textRect().height() - m_iInputHeight,m_pWndBody->textRect().width(),m_iInputHeight);
+ m_pLineEdit->show();
+ m_pLineEdit->setFocus();
+ redrawWindow();
+ setActiveWindow();
+ } else {
+ if(!m_pLineEdit->isVisible())return;
+ m_pLineEdit->hide();
+ setFocus();
+ KviNotifierWindowTab * tab = m_pWndTabs->currentTab();
+ if(tab)tab->setLastMessageAsCurrent();
+ 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();
+ setActiveWindow();
+ 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 * tab = m_pWndTabs->currentTab();
+ if(!tab)return;
+ if(!tab->currentMessage())return;
+ if(!tab->window())return;
+
+ QString txt = m_pLineEdit->text();
+ if(txt.isEmpty())return;
+ QString html = txt;
+ html.replace("<","&lt;");
+ html.replace(">","&gt;");
+ KviStr tmp(KviStr::Format,"%d",KVI_SMALLICON_OWNPRIVMSG);
+
+ addMessage(tab->window(),tmp.ptr(),html,0); //m_pCurrentFocusedWindowTab on place of m_pCurrentMessage->window()
+ m_pLineEdit->setText("");
+ KviUserInput::parse(txt,tab->window(),QString::null,1);
+}
+
+void KviNotifierWindow::progressUpdate()
+{
+ double dProgress = m_qtStartedAt.elapsed()/(m_tAutoHideAt - m_tStartedAt);
+ dProgress/=1000;
+ m_pProgressBar->setProgress(dProgress);
+ QPainter p(this);
+ m_pProgressBar->draw(&p);
+}
+#include "m_notifierwindow.moc"
+
diff --git a/src/modules/notifier/notifierwindow.h b/src/modules/notifier/notifierwindow.h
new file mode 100644
index 00000000..be5e3b6e
--- /dev/null
+++ b/src/modules/notifier/notifierwindow.h
@@ -0,0 +1,194 @@
+#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) 2005 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 "kvi_settings.h"
+
+#include <qbitmap.h>
+#include <qcolor.h>
+#include <qcursor.h>
+#include <qdatetime.h>
+#include <qfont.h>
+#include <qimage.h>
+#include <qlineedit.h>
+#include <qpixmap.h>
+#include <qrect.h>
+#include <qtimer.h>
+#include <qwidget.h>
+
+#include "kvi_qstring.h"
+#include "kvi_pointerlist.h"
+#include "kvi_time.h"
+
+#include "notifiersettings.h"
+
+class KviWindow;
+class KviNotifierMessage;
+
+class KviNotifierWindowBody;
+class KviNotifierWindowBorder;
+class KviNotifierWindowProgressBar;
+class KviNotifierWindowTabs;
+
+class QPainter;
+class QPopupMenu;
+
+extern kvi_time_t g_tNotifierDisabledUntil;
+
+class KviNotifierWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ KviNotifierWindow();
+ ~KviNotifierWindow();
+protected:
+ QTimer * m_pShowHideTimer;
+ QTimer * m_pProgressTimer;
+ QTimer * m_pBlinkTimer;
+ QTimer * m_pAutoHideTimer;
+ State m_eState;
+ bool m_bBlinkOn;
+ double m_dOpacity;
+ QImage m_imgDesktop; // the desktop screenshot
+ QPixmap m_pixBackground; // our background image
+ QPixmap m_pixBackgroundHighlighted;
+ QPixmap m_pixForeground; // we paint the stuff HERE
+
+ // Notifier graphic layout
+ QPixmap m_pixBckgrnd;
+
+ QImage m_imgBuffer; // here we merge the two images
+
+ bool m_bCloseDown;
+ bool m_bPrevDown;
+ bool m_bNextDown;
+ bool m_bWriteDown;
+ bool m_bCrashShowWorkAround;
+
+ bool m_bKeyShiftPressed;
+
+ QFont * m_pDefaultFont;
+ QFont * m_pTitleFont;
+
+ QRect m_wndRect;
+
+ QColor m_clrCurText;
+ QColor m_clrOldText[NUM_OLD_COLORS];
+ QColor m_clrHistoricText;
+ QColor m_clrTitle;
+
+ KviNotifierMessage * m_pCurrentMessage;
+ QLineEdit * 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_iInputHeight;
+ int m_iBlinkTimeout;
+ int m_iBlinkCount;
+ QPopupMenu * m_pContextPopup;
+ QPopupMenu * m_pDisablePopup;
+ KviWindow * m_pWindowToRaise;
+ kvi_time_t m_tAutoHideAt;
+ kvi_time_t m_tStartedAt;
+ QTime m_qtStartedAt;
+ bool m_bDisableHideOnMainWindowGotAttention;
+ //bool m_bForceShowing;
+
+ QCursor m_cursor;
+
+ KviNotifierWindowTabs * m_pWndTabs;
+ KviNotifierWindowProgressBar * m_pProgressBar;
+ KviNotifierWindowBody * m_pWndBody;
+ KviNotifierWindowBorder * m_pWndBorder;
+public:
+ void doShow(bool bDoAnimate);
+ void doHide(bool bDoAnimate);
+ const QFont & defaultFont(){ return *m_pDefaultFont; };
+ int textWidth();
+ void addMessage(KviWindow * pWnd,const QString &szImageId,const QString &szText,unsigned int uMessageTime);
+ State state() { return m_eState; };
+ void setDisableHideOnMainWindowGotAttention(bool b){ m_bDisableHideOnMainWindowGotAttention = b; };
+ int countTabs();
+ void showLineEdit(bool bShow);
+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 void mouseDoubleClickEvent(QMouseEvent * e);
+ virtual void wheelEvent(QWheelEvent * e);
+ virtual bool eventFilter(QObject * pEdit,QEvent * e);
+ virtual void keyPressEvent ( QKeyEvent * e );
+ virtual void keyReleaseEvent ( QKeyEvent * e );
+protected slots:
+ void blink();
+ void heartbeat();
+ void returnPressed();
+ void reloadImages();
+ void fillContextPopup();
+ void hideNow();
+ void disableFor1Minute();
+ void disableFor5Minutes();
+ void disableFor15Minutes();
+ void disableFor30Minutes();
+ void disableFor60Minutes();
+ void disableUntilKVIrcRestarted();
+ void disablePermanently();
+ void delayedRaiseSlot();
+ void autoHide();
+ void progressUpdate();
+private:
+ void contextPopup(const QPoint &pos);
+ void startBlinking();
+ void markAllMessagesAsHistoric();
+ void computeRect();
+ void stopShowHideTimer();
+ void stopBlinkTimer();
+ void stopAutoHideTimer();
+ void startAutoHideTimer();
+ void delayedRaise(KviWindow * pWnd);
+ void prevButtonClicked();
+ void nextButtonClicked();
+ bool shouldHideIfMainWindowGotAttention();
+ void setCursor(int);
+ void resize(QPoint p, bool = true);
+ void redrawWindow();
+ void redrawText();
+ bool checkResizing(QPoint);
+};
+
+#endif //_NOTIFIERWINDOW_H_
diff --git a/src/modules/notifier/notifierwindowbody.cpp b/src/modules/notifier/notifierwindowbody.cpp
new file mode 100644
index 00000000..7449aa9e
--- /dev/null
+++ b/src/modules/notifier/notifierwindowbody.cpp
@@ -0,0 +1,232 @@
+//=============================================================================
+//
+// File : kvinotifierwindowbody.cpp
+// Created on dom 02 gen 2005 17:53:29 by Iacopo Palazzi
+//
+// This file is part of the KVIrc distribution
+// Copyright (C) 2005 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 "notifierwindowbody.h"
+
+#include "kvi_iconmanager.h"
+
+#include <qbrush.h>
+#include <qcolor.h>
+#include <qpainter.h>
+
+/*
+#ifdef QT3_SUPPORT
+ #include <Q3Painter>
+#else
+ #include <qpainter.h>
+#endif
+*/
+
+KviNotifierWindowBody::KviNotifierWindowBody(QRect r)
+{
+ loadImages();
+ setHeight(r.height());
+ setWidth(r.width());
+ m_pnt.setX(r.x());
+ m_pnt.setY(r.y());
+ recalculatePositions();
+}
+
+KviNotifierWindowBody::~KviNotifierWindowBody()
+{
+}
+
+
+void KviNotifierWindowBody::loadImages()
+{
+ QPixmap * p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_body_dx.png")))
+ m_pixDX = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_body_sx.png")))
+ m_pixSX = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_body_dwnsx.png")))
+ m_pixDWNSX = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_body_dwndx.png")))
+ m_pixDWNDX = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_body_dwn.png")))
+ m_pixDWN = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_body_kvirc_sx.png")))
+ m_pixKVIrcSX = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_body_kvirc_dwn.png")))
+ m_pixKVIrcDWN = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_body_kvirc.png")))
+ m_pixKVIrc = *p;
+
+ if((p = g_pIconManager->getPixmap("notifier_icon_body_prev_off.png")))
+ m_pixIconPrev_off = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_body_prev_on.png")))
+ m_pixIconPrev_on = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_body_prev_clicked.png")))
+ m_pixIconPrev_clicked = *p;
+
+ m_pixIconPrev = m_pixIconPrev_off;
+
+ if((p = g_pIconManager->getPixmap("notifier_icon_body_next_off.png")))
+ m_pixIconNext_off = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_body_next_on.png")))
+ m_pixIconNext_on = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_body_next_clicked.png")))
+ m_pixIconNext_clicked = *p;
+
+ m_pixIconNext = m_pixIconNext_off;
+
+ if((p = g_pIconManager->getPixmap("notifier_icon_body_write_off.png")))
+ m_pixIconWrite_off = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_body_write_on.png")))
+ m_pixIconWrite_on = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_body_write_clicked.png")))
+ m_pixIconWrite_clicked = *p;
+
+ m_pixIconWrite = m_pixIconWrite_off;
+
+ needToRedraw();
+
+ m_prevIconState = WDG_ICON_OFF;
+ m_nextIconState = WDG_ICON_OFF;
+ m_writeIconState = WDG_ICON_OFF;
+
+}
+
+void KviNotifierWindowBody::setWidth(int w)
+{
+ m_rct.setWidth(w);
+ recalculatePositions();
+}
+
+void KviNotifierWindowBody::setHeight(int h)
+{
+ m_rct.setHeight(h);
+ recalculatePositions();
+}
+
+void KviNotifierWindowBody::recalculatePositions()
+{
+ m_textRect.setX(m_pnt.x()+m_pixSX.width());
+ m_textRect.setY(m_pnt.y());
+ m_textRect.setWidth(m_rct.width()-m_pixSX.width()-m_pixDX.width()-m_pixIconPrev.width());
+ m_textRect.setHeight(m_rct.height()-m_pixDWN.height());
+
+ m_rctWriteIcon.setX(m_textRect.x()+m_textRect.width());
+ m_rctWriteIcon.setY(m_pnt.y()+m_textRect.height()-m_pixIconWrite.height());
+ m_rctWriteIcon.setWidth(m_pixIconWrite.width());
+ m_rctWriteIcon.setHeight(m_pixIconWrite.height());
+
+ m_rctPrevIcon.setX(m_textRect.x()+m_textRect.width());
+ m_rctPrevIcon.setY(m_pnt.y()+2); //FIXME: Maybe the spacing should be calculated?
+ m_rctPrevIcon.setWidth(m_pixIconPrev.width());
+ m_rctPrevIcon.setHeight(m_pixIconPrev.height());
+
+ m_rctNextIcon.setX(m_textRect.x()+m_textRect.width());
+ m_rctNextIcon.setY(m_pnt.y()+m_textRect.height()-m_pixIconNext.height()-m_pixIconWrite.height());
+ m_rctNextIcon.setWidth(m_pixIconNext.width());
+ m_rctNextIcon.setHeight(m_pixIconNext.height());
+
+ needToRedraw();
+}
+
+void KviNotifierWindowBody::setPrevIcon(int state)
+{
+ //if (m_prevIconState==WDG_ICON_OFF && state!=WDG_ICON_OFF)
+ if (m_prevIconState!=state) {
+ switch (state) {
+ case WDG_ICON_ON: m_pixIconPrev = m_pixIconPrev_on; break;
+ case WDG_ICON_OFF: m_pixIconPrev = m_pixIconPrev_off; break;
+ case WDG_ICON_CLICKED: m_pixIconPrev = m_pixIconPrev_clicked; break;
+ };
+
+ m_prevIconState=state;
+ needToRedraw();
+ }
+};
+
+void KviNotifierWindowBody::setNextIcon(int state) {
+
+ //if (m_nextIconState==WDG_ICON_OFF && state!=WDG_ICON_OFF)
+ if (m_nextIconState!=state) {
+ switch (state) {
+ case WDG_ICON_ON: m_pixIconNext = m_pixIconNext_on; break;
+ case WDG_ICON_OFF: m_pixIconNext = m_pixIconNext_off; break;
+ case WDG_ICON_CLICKED: m_pixIconNext = m_pixIconNext_clicked; break;
+ };
+
+ needToRedraw();
+ m_nextIconState=state;
+ }
+};
+
+void KviNotifierWindowBody::setWriteIcon(int state) {
+
+ //if (m_writeIconState==WDG_ICON_OFF && state!=WDG_ICON_OFF)
+ if (m_writeIconState!=state) {
+ switch (state) {
+ case WDG_ICON_ON: m_pixIconWrite = m_pixIconWrite_on; break;
+ case WDG_ICON_OFF: m_pixIconWrite = m_pixIconWrite_off; break;
+ case WDG_ICON_CLICKED: m_pixIconWrite = m_pixIconWrite_clicked; break;};
+
+ needToRedraw();
+ m_writeIconState=state;
+ }
+};
+
+void KviNotifierWindowBody::draw(QPainter * p) {
+
+ if (m_bNeedToRedraw) {
+
+ p->fillRect(QRect(m_pnt,m_rct.size()),m_mac_bkgColor);
+
+ // Autotiled borders
+ p->drawTiledPixmap(m_pnt.x(), m_pnt.y(), m_pixSX.width(), m_rct.height() - m_pixDWNSX.height() - m_pixKVIrcSX.height(), m_pixSX);
+ p->drawTiledPixmap(m_pnt.x() + m_rct.width() - m_pixDX.width(), m_pnt.y(),m_pixDX.width(), m_rct.height() - m_pixDWNDX.height(), m_pixDX);
+ p->drawTiledPixmap(m_pnt.x() + m_pixKVIrcDWN.width() + m_pixDWNSX.width(), m_pnt.y() + m_rct.height() - m_pixDWN.height(), m_rct.width() - m_pixKVIrcDWN.width() - m_pixDWNSX.width() - m_pixDWNDX.width(), m_pixDWN.height(), m_pixDWN);
+
+ // Bottom corners
+ p->drawPixmap(m_pnt.x(), m_pnt.y() + m_rct.height() - m_pixDWNSX.height(), m_pixDWNSX);
+ p->drawPixmap(m_pnt.x() + m_rct.width() - m_pixDWNSX.width(), m_pnt.y() + m_rct.height() - m_pixDWNDX.height(), m_pixDWNDX);
+
+ // KVIrc image
+ p->drawPixmap(m_pnt.x(), m_pnt.y() + m_rct.height() - m_pixKVIrcSX.height() - m_pixDWNSX.height(), m_pixKVIrcSX);
+ p->drawPixmap(m_pnt.x() + m_pixKVIrcSX.width(), m_pnt.y() + m_rct.height() - m_pixKVIrcDWN.height(), m_pixKVIrcDWN);
+ p->drawPixmap(m_pnt.x() + m_pixKVIrcSX.width(), m_pnt.y() + m_rct.height() - m_pixKVIrc.height() - m_pixKVIrcDWN.height(), m_pixKVIrc, 0, 0, m_pixKVIrc.width(), m_pixKVIrc.height());
+
+ // Draw Icons
+ p->drawPixmap(m_rctPrevIcon.x(), m_rctPrevIcon.y(), m_pixIconPrev);
+ p->drawPixmap(m_rctNextIcon.x(), m_rctNextIcon.y(), m_pixIconNext);
+ p->drawPixmap(m_rctWriteIcon.x(), m_rctWriteIcon.y(), m_pixIconWrite);
+
+ m_bNeedToRedraw = false;
+
+ }
+}
+
+void KviNotifierWindowBody::mouseMoveEvent(QMouseEvent * e) {
+
+}
+
+void KviNotifierWindowBody::mousePressEvent(QMouseEvent * e) {
+
+}
+
+void KviNotifierWindowBody::mouseReleaseEvent(QMouseEvent * e) {
+
+}
diff --git a/src/modules/notifier/notifierwindowbody.h b/src/modules/notifier/notifierwindowbody.h
new file mode 100644
index 00000000..e59df9f9
--- /dev/null
+++ b/src/modules/notifier/notifierwindowbody.h
@@ -0,0 +1,147 @@
+#ifndef _KVINOTIFIERWINDOWBODY_H_
+#define _KVINOTIFIERWINDOWBODY_H_
+//=============================================================================
+//
+// File : kvinotifierwindowbody.h
+// Created on dom 02 gen 2005 17:53:29 by Iacopo Palazzi
+//
+// This file is part of the KVIrc distribution
+// Copyright (C) 2005 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 <qevent.h>
+#include <qrect.h>
+#include <qpoint.h>
+#include <qpixmap.h>
+
+#include "notifiersettings.h"
+
+/*
+#ifdef QT3_SUPPORT
+ #define QPainter Q3Painter
+#endif
+*/
+
+class QPainter;
+
+class KviNotifierWindowBody
+{
+public:
+ KviNotifierWindowBody(QRect r);
+ ~KviNotifierWindowBody();
+
+// ================================
+// Put members declaration below...
+// ================================
+private:
+ QRect m_rct;
+ QPoint m_pnt;
+
+ QRect m_textRect;
+
+ QRect m_rctWriteIcon;
+ QRect m_rctPrevIcon;
+ QRect m_rctNextIcon;
+ QRect m_rctCloseTabIcon;
+
+ // Pictures
+ QPixmap m_pixDX;
+ QPixmap m_pixSX;
+ QPixmap m_pixDWNSX;
+ QPixmap m_pixDWNDX;
+ QPixmap m_pixDWN;
+ QPixmap m_pixKVIrcSX;
+ QPixmap m_pixKVIrcDWN;
+ QPixmap m_pixKVIrc;
+
+ QPixmap m_pixIconPrev;
+ QPixmap m_pixIconPrev_off;
+ QPixmap m_pixIconPrev_on;
+ QPixmap m_pixIconPrev_clicked;
+
+ QPixmap m_pixIconNext;
+ QPixmap m_pixIconNext_off;
+ QPixmap m_pixIconNext_on;
+ QPixmap m_pixIconNext_clicked;
+
+ QPixmap m_pixIconWrite;
+ QPixmap m_pixIconWrite_off;
+ QPixmap m_pixIconWrite_on;
+ QPixmap m_pixIconWrite_clicked;
+
+ bool m_bNeedToRedraw;
+
+ int m_prevIconState;
+ int m_nextIconState;
+ int m_writeIconState;
+
+public:
+
+protected:
+
+
+// ================================
+// Put methods declaration below...
+// ================================
+private:
+ void loadImages();
+
+public:
+ void setWidth(int w);
+ void setHeight(int h);
+ void resize(int w, int h) { setWidth(w); setHeight(h); };
+ void resize(QRect r) { setWidth(r.width()); setHeight(r.height()); };
+ void setPoint(int x, int y) { m_pnt.setX(x); m_pnt.setY(y); };
+
+ void setPrevIcon(int state);
+ void setNextIcon(int state);
+ void setWriteIcon(int state);
+
+ int nextIconState() { return m_nextIconState; };
+ int prevIconState() { return m_prevIconState; };
+ int writeIconState() { return m_writeIconState; };
+
+ int x() { return m_pnt.x(); };
+ int y() { return m_pnt.y(); };
+ int width() { return m_rct.width(); };
+ int height() { return m_rct.height(); };
+ int baseLine() { return (y()+height()); };
+
+ QRect rect() { return m_rct; };
+ QRect textRect() { return m_textRect; };
+ QRect rctPrevIcon() { return m_rctPrevIcon; };
+ QRect rctNextIcon() { return m_rctNextIcon; };
+ QRect rctWriteIcon() { return m_rctWriteIcon; };
+
+ void needToRedraw() { m_bNeedToRedraw = true; };
+
+ void recalculatePositions();
+ void touch() { m_bNeedToRedraw = true; };
+ void draw(QPainter *);
+
+ void mouseMoveEvent(QMouseEvent * e);
+ void mousePressEvent(QMouseEvent * e);
+ void mouseReleaseEvent(QMouseEvent * e);
+
+
+
+protected:
+
+};
+
+#endif //!_KVINOTIFIERWINDOWBODY_H_
diff --git a/src/modules/notifier/notifierwindowborder.cpp b/src/modules/notifier/notifierwindowborder.cpp
new file mode 100644
index 00000000..efd9ec0d
--- /dev/null
+++ b/src/modules/notifier/notifierwindowborder.cpp
@@ -0,0 +1,220 @@
+//=============================================================================
+//
+// File : kvinotifierwindowborder.cpp
+// Created on lun 03 gen 2005 02:27:22 by Iacopo Palazzi
+//
+// This file is part of the KVIrc distribution
+// Copyright (C) 2005 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 "notifierwindowtabs.h"
+#include "kvi_iconmanager.h"
+
+#include <qpainter.h>
+
+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());
+
+ // We want to see the tabs height to calculate the appropriate rect..
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_sx.png")))
+ m_iTabsHeight = p->height();
+ else
+ m_iTabsHeight = 10;
+
+ m_bNeedToRedraw = true;
+
+}
+
+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_tabsRect.setTopLeft( QPoint(m_pixCaptionDX->width()+7,m_captionRect.height()) );
+ m_tabsRect.setSize( QSize(m_captionRect.width()-(2*m_pixCaptionDX->width())-7,m_iTabsHeight) );
+
+ m_bodyRect.setTopLeft( QPoint(m_pixCaptionDX->width()+7,m_captionRect.height()+m_tabsRect.height()) );
+ m_bodyRect.setSize( QSize(m_captionRect.width()-(2*m_pixCaptionDX->width())-7,m_rct.height()-m_captionRect.height()-m_pixDWN->height()-m_tabsRect.height()) );
+
+ m_titleRect.setTopLeft( QPoint(m_pixCaptionSX->width(), (m_captionRect.height()-m_iTitleFontHeight)/2 ) );
+ m_titleRect.setSize( QSize(m_rct.width()-m_pixCaptionSX->width()-m_pixCaptionDX->width(),m_iTitleFontHeight) );
+
+ m_progressRect.setTopLeft( QPoint(m_pixCaptionDX->width(),m_pixCaptionDX->height()));
+ m_progressRect.setSize( QSize(6,m_iRctHeight-m_pixCaptionDX->height()-m_pixDWN->height()));
+
+ m_bNeedToRedraw = true;
+}
+
+void KviNotifierWindowBorder::setCloseIcon(int state) {
+ m_bNeedToRedraw = true; 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) {
+
+ if (m_bNeedToRedraw) {
+ 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_iTabsHeight, *m_pixSX);
+ p->drawTiledPixmap(m_bodyRect.width() + m_bodyRect.x(), m_captionRect.height(), m_pixDX->width(), m_bodyRect.height() + m_iTabsHeight, *m_pixDX);
+ p->drawTiledPixmap(m_pixDWNSX->width(), m_captionRect.height() + m_bodyRect.height() + m_iTabsHeight, m_bodyRect.width() + m_progressRect.width() + 1, m_pixDWN->height(), *m_pixDWN);
+
+ // Draw down corners
+ p->drawPixmap(0, m_captionRect.height() + m_bodyRect.height() + m_iTabsHeight, *m_pixDWNSX);
+ p->drawPixmap(m_bodyRect.width() + m_bodyRect.x(), m_captionRect.height() + m_bodyRect.height() + m_iTabsHeight, *m_pixDWNDX);
+
+ //Drawing icons
+ p->drawPixmap(m_closeIconRect.x(), m_closeIconRect.y(), *m_pixIconClose);
+
+ m_bNeedToRedraw = false;
+ }
+
+}
diff --git a/src/modules/notifier/notifierwindowborder.h b/src/modules/notifier/notifierwindowborder.h
new file mode 100644
index 00000000..5c36827b
--- /dev/null
+++ b/src/modules/notifier/notifierwindowborder.h
@@ -0,0 +1,154 @@
+#ifndef _KVINOTIFIERWINDOWBORDER_H_
+#define _KVINOTIFIERWINDOWBORDER_H_
+//=============================================================================
+//
+// File : kvinotifierwindowborder.h
+// Created on lun 03 gen 2005 02:27:22 by Iacopo Palazzi
+//
+// This file is part of the KVIrc distribution
+// Copyright (C) 2005 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 <qsize.h>
+#include <qrect.h>
+#include <qpixmap.h>
+
+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_tabsRect;
+ QRect m_titleRect;
+
+ QRect m_progressRect;
+
+ // 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_iTabsHeight;
+ int m_iTitleFontHeight;
+ int m_eIconState;
+ int m_iRctWidth;
+ int m_iRctHeight;
+
+ bool m_bNeedToRedraw;
+
+public:
+protected:
+
+
+// ================================
+// Put methods declaration below...
+// ================================
+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(); /*debug("x,y: %d,%d", r.x(), r.y()); debug("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...
+ int x() { return m_pnt.x(); };
+ int y() { return m_pnt.y(); };
+ int width() { return m_rct.width(); };
+ int height() { return m_rct.height(); };
+ int baseLine() { return (y()+height()); };
+
+ QRect bodyRect() { return m_bodyRect; };
+ QRect tabsRect() { return m_tabsRect; };
+ QRect captionRect() { return m_captionRect; };
+ QRect rect() { return m_rct; };
+ QRect closeRect() { return m_closeIconRect; };
+ QRect titleRect() { return m_titleRect; };
+ QRect progressRect() { return m_progressRect; };
+
+ void centerTitle(int h) { m_iTitleFontHeight = h; };
+
+ void touch() { m_bNeedToRedraw = true; };
+
+ void draw(QPainter *, bool b = false);
+ void setPics(bool b = false);
+
+protected:
+
+};
+
+#endif //!_KVINOTIFIERWINDOWBORDER_H_
diff --git a/src/modules/notifier/notifierwindowprogressbar.cpp b/src/modules/notifier/notifierwindowprogressbar.cpp
new file mode 100644
index 00000000..72bbdecf
--- /dev/null
+++ b/src/modules/notifier/notifierwindowprogressbar.cpp
@@ -0,0 +1,51 @@
+//=============================================================================
+//
+// File : notifierwindowprogressbar.cpp
+// Created on Tue 17 Apr 2007 10:24:01 by Iacopo Palazzi
+//
+// This file is part of the KVIrc distribution
+// Copyright (C) 2007 Iacopo Palazzi < iakko(at)siena.linux.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 "notifierwindowprogressbar.h"
+
+KviNotifierWindowProgressBar::KviNotifierWindowProgressBar(QRect r)
+: m_rect(r)
+{
+
+}
+
+KviNotifierWindowProgressBar::~KviNotifierWindowProgressBar()
+{
+ m_dProgress = 0;
+}
+
+void KviNotifierWindowProgressBar::draw(QPainter *p)
+{
+ p->fillRect(m_rect, QColor(236, 233, 216));
+ p->fillRect(
+ QRect(
+ m_rect.x()+1,
+ m_rect.y()+1 + m_rect.height() * (1 - m_dProgress),
+ m_rect.width() - 2,
+ (m_rect.height() - 2) * m_dProgress
+ ),
+ QColor(175, 28, 95)
+ );
+ p->drawRect(m_rect);
+}
diff --git a/src/modules/notifier/notifierwindowprogressbar.h b/src/modules/notifier/notifierwindowprogressbar.h
new file mode 100644
index 00000000..ec527d2e
--- /dev/null
+++ b/src/modules/notifier/notifierwindowprogressbar.h
@@ -0,0 +1,67 @@
+#ifndef _NOTIFIERWINDOWPROGRESSBAR_H_
+#define _NOTIFIERWINDOWPROGRESSBAR_H_
+//=============================================================================
+//
+// File : notifierwindowprogressbar.h
+// Created on Tue 17 Apr 2007 10:24:01 by Iacopo Palazzi
+//
+// This file is part of the KVIrc distribution
+// Copyright (C) 2007 Iacopo Palazzi < iakko(at)siena.linux.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 <qrect.h>
+#include <qpainter.h>
+
+class KviNotifierWindowProgressBar
+{
+public:
+ KviNotifierWindowProgressBar(QRect r);
+ ~KviNotifierWindowProgressBar();
+
+// ================================
+// Put members declaration below...
+// ================================
+private:
+
+public:
+
+protected:
+ QRect m_rect;
+ double m_dProgress;
+
+// ================================
+// Put methods declaration below...
+// ================================
+private:
+
+public:
+ int x() { return m_rect.x(); };
+ int y() { return m_rect.y(); };
+ int width() { return m_rect.width(); };
+ int height() { return m_rect.height(); };
+
+ void setHeight(int p_iHeight) { m_rect.setHeight(p_iHeight); };
+ void setProgress(double progress) { m_dProgress=progress; };
+ void draw(QPainter *);
+
+protected:
+
+
+};
+
+#endif //!_NOTIFIERWINDOWPROGRESSBAR_H_
diff --git a/src/modules/notifier/notifierwindowtabs.cpp b/src/modules/notifier/notifierwindowtabs.cpp
new file mode 100644
index 00000000..9eaa2f12
--- /dev/null
+++ b/src/modules/notifier/notifierwindowtabs.cpp
@@ -0,0 +1,705 @@
+//=============================================================================
+//
+// File : kvinotifierwindowtabs.cpp
+// Created on dom 02 gen 2005 15:30:50 by Iacopo Palazzi
+//
+// This file is part of the KVIrc irc client distribution
+// Copyright (C) 2005 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 "kvi_app.h"
+#include "kvi_config.h"
+#include "kvi_qstring.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_window.h"
+
+#include <qevent.h>
+#include <qpainter.h>
+#include <qbrush.h>
+#include <qcolor.h>
+#include <qfontmetrics.h>
+
+#include "notifiermessage.h"
+#include "notifierwindowtabs.h"
+
+extern KviNotifierWindow * g_pNotifierWindow;
+KviNotifierWindowTabs * g_pTabs;
+
+
+// --- tab object definition class
+
+KviNotifierWindowTab::KviNotifierWindowTab(KviWindow * pWnd, QString label)
+{
+ m_pWnd = pWnd;
+ m_label = label;
+ m_pMessageList = new KviPointerList<KviNotifierMessage>;
+ m_pMessageList->setAutoDelete(true);
+ m_bFocused = false;
+ m_pCurrentMessage = 0;
+
+ KviStr buffer;
+ g_pApp->getReadOnlyConfigPath(buffer,"libkvinotifier.kvc",KviApp::ConfigPlugins,true);
+ KviConfig cfg(buffer.ptr(),KviConfig::Read);
+ cfg.setGroup("NotifierSkin");
+ m_clrHighlightedLabel = cfg.readColorEntry("HighlightedTabLablerColor",QColor(200,0,0));
+ m_clrNormalLabel = cfg.readColorEntry("NormalTabLablerColor",QColor(0,0,0));
+ m_clrChangedLabel = cfg.readColorEntry("ChangedTabLablerColor",QColor(0,0,100));
+
+ if(pWnd)
+ {
+ connect(pWnd,SIGNAL(windowNameChanged()),this,SLOT(labelChanged()));
+ connect(pWnd,SIGNAL(destroyed()),this,SLOT(closeMe()));
+ }
+}
+
+KviNotifierWindowTab::~KviNotifierWindowTab()
+{
+ delete m_pMessageList;
+}
+
+void KviNotifierWindowTab::setNextMessageAsCurrent()
+{
+ if(!m_pCurrentMessage)return;
+ if(m_pMessageList->findRef(m_pCurrentMessage) == -1)return;
+ m_pCurrentMessage = m_pMessageList->next();
+ if(!m_pCurrentMessage)m_pCurrentMessage = m_pMessageList->last();
+}
+
+void KviNotifierWindowTab::setPrevMessageAsCurrent()
+{
+ if(!m_pCurrentMessage)return;
+ if(!m_pMessageList->findRef(m_pCurrentMessage) == -1)return;
+ m_pCurrentMessage = m_pMessageList->prev();
+ if(!m_pCurrentMessage)m_pCurrentMessage = m_pMessageList->first();
+}
+
+void KviNotifierWindowTab::setLastMessageAsCurrent()
+{
+ m_pCurrentMessage = m_pMessageList->last();
+}
+
+void KviNotifierWindowTab::appendMessage(KviNotifierMessage * m)
+{
+ if(m_pCurrentMessage == m_pMessageList->last())m_pCurrentMessage = m;
+ m_pMessageList->append(m);
+ // avoid having too much messages floating around
+ while(m_pMessageList->count() > MAX_MESSAGES_IN_WINDOW)
+ {
+ m = m_pMessageList->first();
+ m_pMessageList->removeFirst();
+ if(m == m_pCurrentMessage)
+ m_pCurrentMessage = m_pMessageList->first();
+ }
+ if(focused())setState(Normal);
+ else setState(Highlighted);
+}
+
+void KviNotifierWindowTab::labelChanged()
+{
+ if(!m_pWnd)return;
+ m_label = m_pWnd->windowName();
+ setState(Changed);
+ g_pTabs->needToRedraw();
+ g_pNotifierWindow->update();
+}
+
+void KviNotifierWindowTab::closeMe()
+{
+ g_pTabs->closeTab(this);
+}
+
+void KviNotifierWindowTab::setFocused(bool b)
+{
+ m_bFocused = b;
+ if(m_bFocused)setState(Normal);
+}
+
+void KviNotifierWindowTab::setState(TabState state)
+{
+ m_eState=state;
+ switch (m_eState) {
+ case Normal:
+ m_cLabel = m_clrNormalLabel;
+ break;
+ case Highlighted:
+ m_cLabel = m_clrHighlightedLabel;
+ break;
+ case Changed:
+ m_cLabel = m_clrChangedLabel;
+ break;
+ }
+};
+
+int KviNotifierWindowTab::width(bool b) {
+ int width = 0;
+ QFont * font;
+
+ QPixmap * sx;
+ QPixmap * dx;
+
+ if (focused()) {
+ font = g_pTabs->fontFocused();
+ sx = g_pTabs->tabFocusedPixSx();
+ dx = g_pTabs->tabFocusedPixSx();
+ } else {
+ sx = g_pTabs->tabUnfocusedPixSx();
+ dx = g_pTabs->tabUnfocusedPixSx();
+ font = g_pTabs->fontUnfocused();
+ }
+
+ QFontMetrics fm(*font);
+ width = fm.width(label())+2;
+ if (!b) width += sx->width() + dx->width();
+
+ return width;
+}
+
+// ##################################################################################à
+// ### end of tab object definition class
+// ##################################################################################à
+
+
+KviNotifierWindowTabs::KviNotifierWindowTabs(QRect r)
+{
+ g_pTabs = this;
+ m_pPixmap = new QPixmap();
+ m_pPainter = new QPainter();
+ m_pTabFocused = 0;
+ m_pWndTabFocused = 0;
+ m_iTabToStartFrom = 0;
+
+ m_tabPtrList.setAutoDelete(false); // FIXME: should take a closer look at this
+ m_lastVisitedTabPtrList.setAutoDelete(false);
+
+ loadImages();
+ initConfig();
+ resize(r);
+}
+
+KviNotifierWindowTabs::~KviNotifierWindowTabs()
+{
+ QMap<KviWindow *, KviNotifierWindowTab *>::Iterator tab;
+ for(tab = m_tabMap.begin(); tab != m_tabMap.end(); tab++ )
+ delete tab.data();
+ m_tabMap.clear();
+ delete m_pFocusedFont;
+ delete m_pUnfocusedFont;
+ delete m_pPainter;
+ delete m_pPixmap;
+}
+
+void KviNotifierWindowTabs::initConfig()
+{
+ KviStr buffer;
+ g_pApp->getReadOnlyConfigPath(buffer,"libkvinotifier.kvc",KviApp::ConfigPlugins,true);
+
+ KviConfig cfg(buffer.ptr(),KviConfig::Read);
+
+ cfg.setGroup("NotifierSkin");
+
+ QString szFamily = cfg.readEntry("TextFontFocusedTab","Arial");
+ m_pFocusedFont = new QFont(szFamily,cfg.readIntEntry("TextFocusedFontSize",10));
+ m_pFocusedFont->setBold(true);
+ szFamily = cfg.readEntry("TextFontUnfocusedTab","Arial");
+ m_pUnfocusedFont = new QFont(szFamily,cfg.readIntEntry("TextUnfocusedFontSize",9));
+}
+
+void KviNotifierWindowTabs::loadImages()
+{
+ QPixmap * p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_dx.png")))
+ m_pixDX = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_sx.png")))
+ m_pixSX = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_bkg.png")))
+ m_pixBKG = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_focused_sx.png")))
+ m_pixSXFocused = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_focused_dx.png")))
+ m_pixDXFocused = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_focused_bkg.png")))
+ m_pixBKGFocused = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_unfocused_sx.png")))
+ m_pixSXUnfocused = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_unfocused_dx.png")))
+ m_pixDXUnfocused = *p;
+ if((p = g_pIconManager->getPixmap("notifier_pix_tab_unfocused_bkg.png")))
+ m_pixBKGUnfocused = *p;
+
+ if((p = g_pIconManager->getPixmap("notifier_icon_tab_next_out.png")))
+ m_pixIconTabNext_out = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_tab_next_over.png")))
+ m_pixIconTabNext_over = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_tab_next_clicked.png")))
+ m_pixIconTabNext_clicked = *p;
+
+ m_pixIconTabNext = m_pixIconTabNext_out;
+
+ if((p = g_pIconManager->getPixmap("notifier_icon_tab_prev_out.png")))
+ m_pixIconTabPrev_out = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_tab_prev_over.png")))
+ m_pixIconTabPrev_over = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_tab_prev_clicked.png")))
+ m_pixIconTabPrev_clicked = *p;
+
+ m_pixIconTabPrev = m_pixIconTabPrev_out;
+
+ if((p = g_pIconManager->getPixmap("notifier_icon_tab_close_off.png")))
+ m_pixIconCloseTab_off = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_tab_close_on.png")))
+ m_pixIconCloseTab_on = *p;
+ if((p = g_pIconManager->getPixmap("notifier_icon_tab_close_clicked.png")))
+ m_pixIconCloseTab_clicked = *p;
+
+ m_pixIconCloseTab = m_pixIconCloseTab_off;
+
+ m_closeTabIconState = WDG_ICON_OFF;
+
+}
+
+
+
+void KviNotifierWindowTabs::addMessage(KviWindow * pWnd, KviNotifierMessage * message)
+{
+ QString sender = pWnd ? pWnd->windowName() : "----";
+
+ // Qui servirebbe anche una lista... perche' quando si inserisce
+ // un tab lui lo piazza dove gli pare nell'ordine
+ // e quindi iterando i tab nuovi possono trovarsi PRIMA dei tab vecchi
+ // il che' confonde un po
+ KviNotifierWindowTab * tab;
+ if (!m_tabMap.contains(pWnd)) {
+ m_tabMap.insert(pWnd, tab = new KviNotifierWindowTab(pWnd, sender));
+ m_tabPtrList.append(tab);
+ } else {
+ tab = m_tabMap[pWnd];
+ }
+
+ tab->appendMessage(message);
+
+ if((g_pNotifierWindow->state()==Hidden) || (!m_pTabFocused))
+ {
+ setFocusOn(tab);
+ } else {
+ needToRedraw();
+ }
+}
+
+void KviNotifierWindowTabs::resize(QRect r)
+{
+ m_rct.setX(r.x());
+ m_rct.setY(r.y());
+ m_rct.setHeight(r.height());
+ setWidth(r.width());
+
+ recalculatePositions();
+}
+
+void KviNotifierWindowTabs::setWidth(int w) {
+ m_rct.setWidth(w);
+ recalculatePositions();
+}
+
+void KviNotifierWindowTabs::recalculatePositions()
+{
+ m_rctCloseTabIcon.setX(m_rct.x()+m_rct.width()-m_pixIconCloseTab.width());
+ m_rctCloseTabIcon.setY(m_rct.y());
+ m_rctCloseTabIcon.setWidth(m_pixIconCloseTab.width());
+ m_rctCloseTabIcon.setHeight(m_pixIconCloseTab.height());
+ // The sensible area for the Close Icon
+ m_rctCloseTabIconHotArea.setX(m_rctCloseTabIcon.x()+6);
+ m_rctCloseTabIconHotArea.setY(m_rctCloseTabIcon.y()+3);
+ m_rctCloseTabIconHotArea.setWidth(16);
+ m_rctCloseTabIconHotArea.setHeight(16);
+
+ if (m_bIsOverRightBound) {
+ m_rctNextIcon.setX(m_rct.x() + m_rct.width() - m_rctCloseTabIcon.width() - m_pixIconTabNext.width());
+ m_rctNextIcon.setY(m_rct.y());
+ m_rctNextIcon.setWidth(m_pixIconTabNext.width());
+ m_rctNextIcon.setHeight(m_pixIconTabNext.height());
+ }
+
+ if (m_bIsOverLeftBound) {
+ m_rctPrevIcon.setX(m_rct.x());
+ m_rctPrevIcon.setY(m_rct.y());
+ m_rctPrevIcon.setWidth(m_pixIconTabPrev.width());
+ m_rctPrevIcon.setHeight(m_pixIconTabPrev.height());
+ }
+
+ int tmpX, tmpWidth;
+
+ tmpWidth = m_rctCloseTabIcon.x() - m_rct.x();
+
+ if (m_bIsOverRightBound) {
+ tmpWidth -= m_rctNextIcon.width();
+ }
+
+ if (m_bIsOverLeftBound) {
+ tmpWidth -= m_rctPrevIcon.width();
+ tmpX = m_rct.x() + m_rctPrevIcon.width();
+ } else {
+ tmpX = m_rct.x();
+ }
+
+ m_rctTabs.setX(tmpX);
+ m_rctTabs.setY(m_rct.y());
+
+ m_rctTabs.setWidth(tmpWidth);
+ m_rctTabs.setHeight(m_rct.height());
+
+ needToRedraw();
+}
+
+void KviNotifierWindowTabs::prev()
+{
+ if(!m_pTabFocused)return;
+
+ KviNotifierWindowTab * tab;
+ KviPointerListIterator<KviNotifierWindowTab> tabIterator (m_tabPtrList);
+
+ tab = m_tabMap[m_pTabFocused->wnd()];
+
+ tabIterator.moveFirst();
+
+ while ((tabIterator.current()) != tab) {
+ ++tabIterator;
+ }
+
+ if (!tabIterator.moveFirst()) {
+ --tabIterator;
+ tab = tabIterator.current();
+ setFocusOn(tab);
+ }
+
+}
+
+void KviNotifierWindowTabs::next()
+{
+ if(!m_pTabFocused)return;
+
+ KviNotifierWindowTab * tab;
+ KviPointerListIterator<KviNotifierWindowTab> tabIterator (m_tabPtrList);
+
+ tab = m_tabMap[m_pTabFocused->wnd()];
+ tabIterator.moveFirst();
+ while ((tabIterator.current()) != tab) {
+ ++tabIterator;
+ }
+
+ if (!tabIterator.moveLast()) {
+ ++tabIterator;
+ tab = tabIterator.current();
+ setFocusOn(tab);
+ }
+
+}
+
+void KviNotifierWindowTabs::mousePressEvent(QMouseEvent * e) {
+
+ if (m_bIsOverRightBound && m_rctNextIcon.contains(e->pos())) {
+ return;
+ }
+
+ if (m_bIsOverLeftBound && m_rctPrevIcon.contains(e->pos())) {
+ return;
+ }
+
+ if(m_rctTabs.contains(e->pos()))
+ {
+ QMap<KviWindow *, KviNotifierWindowTab *>::Iterator tab;
+ for (tab = m_tabMap.begin(); tab != m_tabMap.end(); tab++ ) {
+ if (tab.data()->rect().contains(e->pos())) {
+ setFocusOn(tab.data());
+ return;
+ }
+ }
+ }
+
+ if (m_rctCloseTabIconHotArea.contains(e->pos())) {
+ setCloseTabIcon(WDG_ICON_CLICKED);
+ return;
+ }
+
+}
+
+void KviNotifierWindowTabs::mouseMoveEvent(QMouseEvent * e)
+{
+ if (m_rctCloseTabIconHotArea.contains(e->pos()))
+ {
+ setCloseTabIcon(WDG_ICON_ON);
+ } else {
+ if (closeTabIconState()!=WDG_ICON_OFF)
+ setCloseTabIcon(WDG_ICON_OFF);
+ }
+}
+
+void KviNotifierWindowTabs::mouseReleaseEvent(QMouseEvent * e)
+{
+
+ if (m_bIsOverRightBound && m_rctNextIcon.contains(e->pos())) {
+ scrollTabsLeft();
+ return;
+ }
+
+ if (m_bIsOverLeftBound && m_rctPrevIcon.contains(e->pos())) {
+ scrollTabsRight();
+ return;
+ }
+
+ if(currentTab())
+ {
+ if (rctCloseTabIconHotArea().contains(e->pos()))
+ {
+ closeCurrentTab();
+ g_pNotifierWindow->update();
+ }
+ }
+
+}
+
+void KviNotifierWindowTabs::scrollTabsLeft() {
+ if (m_bIsOverRightBound) {
+ m_iTabToStartFrom++;
+ }
+ needToRedraw();
+ g_pNotifierWindow->update();
+};
+
+void KviNotifierWindowTabs::scrollTabsRight() {
+ if (m_bIsOverLeftBound) {
+ m_iTabToStartFrom--;
+ }
+ needToRedraw();
+ g_pNotifierWindow->update();
+};
+
+void KviNotifierWindowTabs::setCloseTabIcon(int state) {
+
+ //if (m_writeIconState==WDG_ICON_OFF && state!=WDG_ICON_OFF)
+ if (m_closeTabIconState!=state) {
+ switch (state) {
+ case WDG_ICON_ON: m_pixIconCloseTab = m_pixIconCloseTab_on; break;
+ case WDG_ICON_OFF: m_pixIconCloseTab = m_pixIconCloseTab_off; break;
+ case WDG_ICON_CLICKED: m_pixIconCloseTab = m_pixIconCloseTab_clicked; break;
+ }
+ needToRedraw();
+ m_closeTabIconState = state;
+ }
+}
+
+void KviNotifierWindowTabs::resetIcons()
+{
+ setCloseTabIcon(WDG_ICON_OFF);
+}
+
+void KviNotifierWindowTabs::setFocusOn(KviNotifierWindowTab * tab)
+{
+ if(m_pTabFocused)m_pTabFocused->setFocused(false);
+ m_pTabFocused = tab;
+ if(m_pTabFocused)m_pTabFocused->setFocused();
+
+ m_lastVisitedTabPtrList.removeRef(tab);
+
+ m_lastVisitedTabPtrList.insert(0, tab);
+
+ needToRedraw();
+
+ g_pNotifierWindow->update();
+}
+
+void KviNotifierWindowTabs::draw(QPainter * p)
+{
+ if(!m_bNeedToRedraw)return;
+
+ m_pPixmap->resize(m_rct.width(), m_rct.height());
+
+ m_pPainter->begin(m_pPixmap);
+
+ QFont tmpFont;
+ tmpFont = p->font();
+
+ m_pPainter->setFont(tmpFont);
+
+ QString str;
+
+ bool isBigger = false;
+
+ int offset = 0;
+
+ int closeIcon_X = m_rct.width() - m_rctCloseTabIcon.width();
+ int nextIcon_X = closeIcon_X - m_pixIconTabNext_out.width();
+ int prevIcon_X = m_rct.x();
+
+ int tmpTabsWidth = 0;
+
+ m_pPainter->drawPixmap(0,0,m_pixSX);
+ m_pPainter->drawPixmap(m_rct.width()-m_pixDX.width(),0,m_pixDX);
+ m_pPainter->drawTiledPixmap(m_pixSX.width(),0,m_rct.width()-m_pixSX.width()-m_pixDX.width(),m_rct.height(),m_pixBKG);
+
+ KviPointerListIterator<KviNotifierWindowTab> tabIterator (m_tabPtrList);
+
+ //m_tabPtrList.findRef(m_tabMap[m_pTabFocused->wnd()]);
+
+// QMap<KviWindow *, KviNotifierWindowTab *>::Iterator tab;
+ KviNotifierWindowTab * tab;
+ //for (tab = m_tabMap.begin(); tab != m_tabMap.end() && !isBigger; tab++ )
+ tabIterator.moveFirst();
+
+ int i = 0;
+ while(m_iTabToStartFrom!=i) {
+ i++;
+ ++tabIterator;
+ }
+
+ while ( ((tab = tabIterator.current()) != 0) && !isBigger)
+ {
+ ++tabIterator;
+
+ if (tab->focused()) {
+
+ m_pPainter->setFont(*m_pFocusedFont);
+
+ tab->setRect(m_rct.x() + offset, m_rctTabs.y(), tab->width(), m_rctTabs.height());
+
+ m_pPainter->drawPixmap(offset,0,m_pixSXFocused);
+ m_pPainter->drawTiledPixmap(offset+m_pixSXFocused.width(),0,tab->width(true),m_rctTabs.height(),m_pixBKGFocused);
+ m_pPainter->drawPixmap(offset+m_pixSXFocused.width()+tab->width(true),0,m_pixDXFocused);
+ QPen tmpP = m_pPainter->pen(); m_pPainter->setPen(tab->labelColor());
+ m_pPainter->drawText(offset+m_pixSXFocused.width()+1,m_rctTabs.height()-NTF_TABS_FONT_BASELINE,tab->label());
+ m_pPainter->setPen(tmpP);
+
+ offset += tab->width();
+
+ } else {
+
+ m_pPainter->setFont(*m_pUnfocusedFont);
+
+ tab->setRect(m_rct.x() + offset, m_rctTabs.y(), tab->width(), m_rctTabs.height());
+
+ m_pPainter->drawPixmap(offset, 0, m_pixSXUnfocused);
+ m_pPainter->drawTiledPixmap(offset+m_pixSXUnfocused.width(), 0, tab->width(true), m_rctTabs.height(), m_pixBKGUnfocused);
+ m_pPainter->drawPixmap(offset+m_pixSXUnfocused.width()+tab->width(true), 0, m_pixDXUnfocused);
+ QPen tmpP = m_pPainter->pen(); m_pPainter->setPen(tab->labelColor());
+ m_pPainter->drawText(offset+m_pixSXUnfocused.width()+1,m_rctTabs.height()-NTF_TABS_FONT_BASELINE+1,tab->label());
+ m_pPainter->setPen(tmpP);
+ offset += tab->width();
+ }
+
+ if (offset > m_rctTabs.width()) isBigger = true; else isBigger = false;
+ }
+
+ if (m_iTabToStartFrom) {
+ // Draw the left arrow for more tabs
+ m_bIsOverLeftBound = true;
+ m_pPainter->drawPixmap(0, 0, m_pixIconTabPrev);
+ } else {
+ m_bIsOverLeftBound = false;
+ }
+
+ if (isBigger) {
+ // Draw the right arrow for more tabs
+ m_bIsOverRightBound = true;
+ m_pPainter->drawPixmap(nextIcon_X, 0, m_pixIconTabNext);
+ } else {
+ m_bIsOverRightBound = false;
+ }
+
+ m_pPainter->drawPixmap(closeIcon_X, 0, m_pixIconCloseTab);
+
+ m_pPainter->end();
+
+ p->drawPixmap(m_rct.x(), m_rct.y(), *m_pPixmap, 0, 0, m_pPixmap->width(), m_pPixmap->height());
+
+ m_bNeedToRedraw = false;
+
+}
+
+void KviNotifierWindowTabs::markAllMessagesAsHistoric()
+{
+/*
+ QMap<KviWindow *, KviNotifierWindowTab *>::Iterator tab;
+ // Iterating every tab
+ for (tab = m_tabMap.begin(); tab != m_tabMap.end(); ++tab) {
+
+ if (!tab.value()) break;
+
+ KviPointerList<KviNotifierMessage> * tmpMessageList = tab.value()->messageList();
+
+ if (!tmpMessageList) break;
+
+ for(KviNotifierMessage * m = tmpMessageList->last(); m; m = tmpMessageList->prev()) {
+ if(m->historic()) break;;
+ m->setHistoric();
+ }
+ }
+*/
+}
+
+void KviNotifierWindowTabs::closeTab(KviWindow * pWnd)
+{
+ KviNotifierWindowTab * pTab = m_tabMap.find(pWnd).data();
+ closeTab(pWnd, pTab);
+}
+
+void KviNotifierWindowTabs::closeTab(KviNotifierWindowTab * pTab)
+{
+ KviWindow * pWnd = pTab->wnd();
+ closeTab(pWnd, pTab);
+}
+
+void KviNotifierWindowTabs::closeCurrentTab()
+{
+ // Paranoic checks...
+ if (!m_pTabFocused) return; // The current tab is null? Please, kill me...
+ KviNotifierWindowTab * pTab = m_pTabFocused;
+ if (m_tabMap.isEmpty()) return; // Empty??? The World is ending...
+ KviWindow * pWnd = pTab->wnd();
+ if (!m_tabMap.contains(pWnd)) return; // The current tab is not on the map??? Call 911!!
+ // End paranoic stuff, go back to sanity...
+
+ closeTab(pWnd, pTab);
+}
+
+void KviNotifierWindowTabs::closeTab(KviWindow * pWnd, KviNotifierWindowTab * pTab)
+{
+ // Ok, we should be sure to delete the right tab...
+ m_tabPtrList.removeRef(pTab);
+ m_lastVisitedTabPtrList.removeRef(pTab);
+ m_tabMap.remove(pWnd);
+ delete pTab;
+
+ if(m_tabMap.empty())
+ {
+ m_pTabFocused = 0;
+ g_pNotifierWindow->showLineEdit(false);
+ g_pNotifierWindow->doHide(false);
+ } else {
+
+ if (m_lastVisitedTabPtrList.count()) {
+ m_pTabFocused = m_lastVisitedTabPtrList.first();
+ } else {
+ m_pTabFocused = m_tabPtrList.last();
+ }
+
+ m_pTabFocused->setFocused(true);
+ }
+}
+
+#include "m_notifierwindowtabs.moc"
diff --git a/src/modules/notifier/notifierwindowtabs.h b/src/modules/notifier/notifierwindowtabs.h
new file mode 100644
index 00000000..555906b8
--- /dev/null
+++ b/src/modules/notifier/notifierwindowtabs.h
@@ -0,0 +1,263 @@
+#ifndef _KVINOTIFIERWINDOWTABS_H_
+#define _KVINOTIFIERWINDOWTABS_H_
+//=============================================================================
+//
+// File : kvinotifierwindowtabs.h
+// Created on dom 02 gen 2005 15:30:50 by Iacopo Palazzi
+//
+// This file is part of the KVIrc distribution
+// Copyright (C) 2005 Iacopo Palazzi < iakko(at)siena.linux.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 <qfont.h>
+#include <qmap.h>
+#include <qobject.h>
+#include <qpixmap.h>
+#include <qpoint.h>
+#include <qrect.h>
+#include "kvi_settings.h"
+#include "kvi_pointerlist.h"
+#include "notifiersettings.h"
+#include "notifierwindow.h"
+
+#include "notifiermessage.h"
+
+
+class QPainter;
+class KviWindow;
+class KviNotifierWindowTab;
+
+typedef struct wndTabPair_s {
+ KviNotifierWindowTab * pTab;
+ KviWindow * pWnd;
+} wndTabPair;
+
+class KviNotifierWindowTab : public QObject // this class defines an object for every single tab about the tabs area
+{
+ Q_OBJECT
+public:
+ KviNotifierWindowTab(KviWindow *, QString);
+ ~KviNotifierWindowTab();
+
+// ================================
+// Put members declaration below...
+// ================================
+private:
+ bool m_bFocused;
+
+ QColor m_cLabel;
+ QColor m_clrHighlightedLabel;
+ QColor m_clrNormalLabel;
+ QColor m_clrChangedLabel;
+
+ QRect m_rect;
+
+ QString m_label;
+
+ KviPointerList<KviNotifierMessage> * m_pMessageList;
+ KviWindow * m_pWnd;
+ KviNotifierMessage * m_pCurrentMessage;
+
+ TabState m_eState;
+
+public:
+
+protected:
+
+
+// ================================
+// Put methods declaration below...
+// ================================
+private:
+
+private slots:
+ void labelChanged();
+ void closeMe();
+
+public:
+ bool focused() { return m_bFocused; };
+
+ int countMessage() { return m_pMessageList->count(); };
+ int width(bool b = false);
+
+ void appendMessage(KviNotifierMessage * m);
+ void setCurrentMessage(KviNotifierMessage * m) { m_pCurrentMessage = m; };
+ void setFocused(bool b = true);
+ void setLastMessageAsCurrent();
+ void setNextMessageAsCurrent();
+ void setPrevMessageAsCurrent();
+ void setState(TabState state);
+ void setRect(int x, int y, int w, int h) { m_rect.setX(x); m_rect.setY(y); m_rect.setWidth(w); m_rect.setHeight(h); };
+
+ QColor labelColor() {return m_cLabel; }
+ QRect rect() { return m_rect; };
+ QString label() { return m_label; };
+
+ KviNotifierMessage * currentMessage() { return m_pCurrentMessage; };
+ KviPointerList<KviNotifierMessage> * messageList() { return m_pMessageList; };
+ KviWindow * window() { return m_pWnd; };
+ KviWindow * wnd() {return m_pWnd; };
+
+ TabState state() { return m_eState; };
+
+protected:
+
+
+
+};
+
+
+//####################################################################################################
+//## Tabs Manager
+//####################################################################################################
+
+
+class KviNotifierWindowTabs // this class defines the tabs area
+{
+public:
+ KviNotifierWindowTabs(QRect r);
+ ~KviNotifierWindowTabs();
+
+// ================================
+// Put members declaration below...
+// ================================
+private:
+ QRect m_rct;
+ QPoint m_pnt;
+
+ QMap<KviWindow *, KviNotifierWindowTab *> m_tabMap;
+ KviPointerList<KviNotifierWindowTab> m_tabPtrList;
+ KviPointerList<KviNotifierWindowTab> m_lastVisitedTabPtrList;
+
+ QFont * m_pFocusedFont;
+ QFont * m_pUnfocusedFont;
+
+ KviNotifierWindowTab * m_pTabFocused;
+ KviWindow * m_pWndTabFocused;
+
+ QRect m_rctNextIcon;
+ QRect m_rctPrevIcon;
+ QRect m_rctCloseTabIcon;
+ QRect m_rctCloseTabIconHotArea;
+ QRect m_rctTabs;
+
+ QPainter * m_pPainter;
+ QPixmap * m_pPixmap;
+
+ QPixmap m_pixDX;
+ QPixmap m_pixSX;
+ QPixmap m_pixBKG;
+ QPixmap m_pixSXFocused;
+ QPixmap m_pixDXFocused;
+ QPixmap m_pixBKGFocused;
+ QPixmap m_pixSXUnfocused;
+ QPixmap m_pixDXUnfocused;
+ QPixmap m_pixBKGUnfocused;
+
+ QPixmap m_pixIconTabPrev;
+ QPixmap m_pixIconTabPrev_out;
+ QPixmap m_pixIconTabPrev_over;
+ QPixmap m_pixIconTabPrev_clicked;
+
+ QPixmap m_pixIconTabNext;
+ QPixmap m_pixIconTabNext_out;
+ QPixmap m_pixIconTabNext_over;
+ QPixmap m_pixIconTabNext_clicked;
+
+ QPixmap m_pixIconCloseTab;
+ QPixmap m_pixIconCloseTab_off;
+ QPixmap m_pixIconCloseTab_on;
+ QPixmap m_pixIconCloseTab_clicked;
+
+ int m_closeTabIconState;
+ int m_iTabToStartFrom;
+
+ bool m_bIsOverLeftBound;
+ bool m_bIsOverRightBound;
+ bool m_bNeedToRedraw;
+
+public:
+
+protected:
+
+
+// ================================
+// Put methods declaration below...
+// ================================
+private:
+ void initConfig();
+ void loadImages();
+
+public:
+ void addMessage(KviWindow *, KviNotifierMessage *);
+ void closeCurrentTab();
+ void closeTab(KviWindow * pWnd); // referes to void closeTab(KviWindow * pWnd, KviNotifierWindowTab * pTab);
+ void closeTab(KviNotifierWindowTab * pTab); // referes to void closeTab(KviWindow * pWnd, KviNotifierWindowTab * pTab);
+ void closeTab(KviWindow * pWnd, KviNotifierWindowTab * pTab);
+ void draw(QPainter *);
+ void needToRedraw() { m_bNeedToRedraw = true; };
+ void markAllMessagesAsHistoric();
+ void mouseMoveEvent(QMouseEvent * e);
+ void mousePressEvent(QMouseEvent * e);
+ void mouseReleaseEvent(QMouseEvent * e);
+ void next();
+ void prev();
+ void recalculatePositions();
+ void resetIcons();
+ void resize(QRect);
+ void scrollTabsLeft();
+ void scrollTabsRight();
+ void setCloseTabIcon(int state);
+ void setCurrentMessage(KviNotifierMessage * m) { if(m_pTabFocused)m_pTabFocused->setCurrentMessage(m); };
+ void setFocusOn(KviNotifierWindowTab *);
+ void setPoint(int x, int y) { m_pnt.setX(x); m_pnt.setY(y); };
+ void setWidth(int w);
+ void touch() { m_bNeedToRedraw = true; };
+
+ int baseLine() { return (y()+height()); };
+ int closeTabIconState() { return m_closeTabIconState; };
+ int count() { return (int)m_tabMap.count(); };
+ int height() { return m_rct.height(); };
+ int width() { return m_rct.width(); };
+ int x() { return m_pnt.x(); };
+ int y() { return m_pnt.y(); };
+
+ QFont * fontFocused() { return m_pFocusedFont; };
+ QFont * fontUnfocused() { return m_pUnfocusedFont; };
+
+ QPixmap * tabFocusedPixSx() {return &m_pixSXFocused; };
+ QPixmap * tabFocusedPixDx() {return &m_pixDXFocused; };
+ QPixmap * tabUnfocusedPixSx() {return &m_pixSXUnfocused; };
+ QPixmap * tabUnfocusedPixDx() {return &m_pixDXUnfocused; };
+
+ QRect rect() {return m_rct;};
+ QRect rctCloseTabIconHotArea() {return m_rctCloseTabIconHotArea; };
+
+ KviNotifierWindowTab * currentTab() { return m_pTabFocused; };
+
+ KviNotifierMessage * currentMessage() { return m_pTabFocused ? m_pTabFocused->currentMessage() : 0; };
+
+ KviWindow * window() { return m_pTabFocused->wnd(); };
+
+
+
+protected:
+
+};
+
+#endif //!_KVINOTIFIERWINDOWTABS_H_
diff --git a/src/modules/notifier/pics/Makefile.am b/src/modules/notifier/pics/Makefile.am
new file mode 100755
index 00000000..26f8bf9b
--- /dev/null
+++ b/src/modules/notifier/pics/Makefile.am
@@ -0,0 +1,9 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir = $(picsdir)
+
+tmp_DATA= *.png
+
+EXTRA_DIST = $(tmp_DATA)
diff --git a/src/modules/notifier/pics/notifier_background.png b/src/modules/notifier/pics/notifier_background.png
new file mode 100755
index 00000000..2787f64c
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_background.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_close.png b/src/modules/notifier/pics/notifier_close.png
new file mode 100644
index 00000000..95ce3d8b
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_close.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_down.png b/src/modules/notifier/pics/notifier_down.png
new file mode 100644
index 00000000..01e11383
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_down.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_body_next_clicked.png b/src/modules/notifier/pics/notifier_icon_body_next_clicked.png
new file mode 100644
index 00000000..2cab5af8
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_body_next_clicked.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_body_next_off.png b/src/modules/notifier/pics/notifier_icon_body_next_off.png
new file mode 100644
index 00000000..6a93e780
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_body_next_off.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_body_next_on.png b/src/modules/notifier/pics/notifier_icon_body_next_on.png
new file mode 100644
index 00000000..86dfe01e
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_body_next_on.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_body_prev_clicked.png b/src/modules/notifier/pics/notifier_icon_body_prev_clicked.png
new file mode 100644
index 00000000..ab8a9af3
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_body_prev_clicked.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_body_prev_off.png b/src/modules/notifier/pics/notifier_icon_body_prev_off.png
new file mode 100644
index 00000000..af9e5307
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_body_prev_off.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_body_prev_on.png b/src/modules/notifier/pics/notifier_icon_body_prev_on.png
new file mode 100644
index 00000000..10cc8f18
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_body_prev_on.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_body_write_clicked.png b/src/modules/notifier/pics/notifier_icon_body_write_clicked.png
new file mode 100644
index 00000000..1dc06165
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_body_write_clicked.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_body_write_off.png b/src/modules/notifier/pics/notifier_icon_body_write_off.png
new file mode 100644
index 00000000..1096b7a8
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_body_write_off.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_body_write_on.png b/src/modules/notifier/pics/notifier_icon_body_write_on.png
new file mode 100644
index 00000000..55fe9d9e
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_body_write_on.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_close_clicked.png b/src/modules/notifier/pics/notifier_icon_close_clicked.png
new file mode 100644
index 00000000..f68f16f0
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_close_clicked.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_close_clicked_hl.png b/src/modules/notifier/pics/notifier_icon_close_clicked_hl.png
new file mode 100644
index 00000000..d7bcc291
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_close_clicked_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_close_out.png b/src/modules/notifier/pics/notifier_icon_close_out.png
new file mode 100644
index 00000000..ccec0bdb
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_close_out.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_close_out_hl.png b/src/modules/notifier/pics/notifier_icon_close_out_hl.png
new file mode 100644
index 00000000..89917dae
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_close_out_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_close_over.png b/src/modules/notifier/pics/notifier_icon_close_over.png
new file mode 100644
index 00000000..e3cffc0f
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_close_over.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_close_over_hl.png b/src/modules/notifier/pics/notifier_icon_close_over_hl.png
new file mode 100644
index 00000000..6a7f1bc0
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_close_over_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_tab_close_clicked.png b/src/modules/notifier/pics/notifier_icon_tab_close_clicked.png
new file mode 100644
index 00000000..ac647250
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_tab_close_clicked.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_tab_close_off.png b/src/modules/notifier/pics/notifier_icon_tab_close_off.png
new file mode 100644
index 00000000..105c728b
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_tab_close_off.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_tab_close_on.png b/src/modules/notifier/pics/notifier_icon_tab_close_on.png
new file mode 100644
index 00000000..dfd87ffe
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_tab_close_on.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_tab_next_clicked.png b/src/modules/notifier/pics/notifier_icon_tab_next_clicked.png
new file mode 100644
index 00000000..b6d98d3e
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_tab_next_clicked.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_tab_next_out.png b/src/modules/notifier/pics/notifier_icon_tab_next_out.png
new file mode 100644
index 00000000..4e4cf075
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_tab_next_out.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_tab_next_over.png b/src/modules/notifier/pics/notifier_icon_tab_next_over.png
new file mode 100644
index 00000000..9f1f8f90
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_tab_next_over.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_tab_prev_clicked.png b/src/modules/notifier/pics/notifier_icon_tab_prev_clicked.png
new file mode 100644
index 00000000..a24139b5
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_tab_prev_clicked.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_tab_prev_out.png b/src/modules/notifier/pics/notifier_icon_tab_prev_out.png
new file mode 100644
index 00000000..20e4a06f
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_tab_prev_out.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_icon_tab_prev_over.png b/src/modules/notifier/pics/notifier_icon_tab_prev_over.png
new file mode 100644
index 00000000..68b390f7
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_icon_tab_prev_over.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_left.png b/src/modules/notifier/pics/notifier_left.png
new file mode 100644
index 00000000..b0887a7f
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_left.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pen.png b/src/modules/notifier/pics/notifier_pen.png
new file mode 100644
index 00000000..31978d1b
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pen.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_body_dwn.png b/src/modules/notifier/pics/notifier_pix_body_dwn.png
new file mode 100644
index 00000000..4a96de08
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_body_dwn.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_body_dwndx.png b/src/modules/notifier/pics/notifier_pix_body_dwndx.png
new file mode 100644
index 00000000..5b8ca523
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_body_dwndx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_body_dwnsx.png b/src/modules/notifier/pics/notifier_pix_body_dwnsx.png
new file mode 100644
index 00000000..ffa3c980
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_body_dwnsx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_body_dx.png b/src/modules/notifier/pics/notifier_pix_body_dx.png
new file mode 100644
index 00000000..c2ca5ce0
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_body_dx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_body_kvirc.png b/src/modules/notifier/pics/notifier_pix_body_kvirc.png
new file mode 100644
index 00000000..1a304b0a
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_body_kvirc.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_body_kvirc_dwn.png b/src/modules/notifier/pics/notifier_pix_body_kvirc_dwn.png
new file mode 100644
index 00000000..37168c57
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_body_kvirc_dwn.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_body_kvirc_sx.png b/src/modules/notifier/pics/notifier_pix_body_kvirc_sx.png
new file mode 100644
index 00000000..acd39ab5
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_body_kvirc_sx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_body_sx.png b/src/modules/notifier/pics/notifier_pix_body_sx.png
new file mode 100644
index 00000000..c1a5315a
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_body_sx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_caption_bkg.png b/src/modules/notifier/pics/notifier_pix_caption_bkg.png
new file mode 100644
index 00000000..96b691df
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_caption_bkg.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_caption_bkg_hl.png b/src/modules/notifier/pics/notifier_pix_caption_bkg_hl.png
new file mode 100644
index 00000000..0c5f155c
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_caption_bkg_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_caption_dx.png b/src/modules/notifier/pics/notifier_pix_caption_dx.png
new file mode 100644
index 00000000..76a37a61
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_caption_dx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_caption_dx_hl.png b/src/modules/notifier/pics/notifier_pix_caption_dx_hl.png
new file mode 100644
index 00000000..ceca1a1d
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_caption_dx_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_caption_sx.png b/src/modules/notifier/pics/notifier_pix_caption_sx.png
new file mode 100644
index 00000000..2939f96b
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_caption_sx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_caption_sx_hl.png b/src/modules/notifier/pics/notifier_pix_caption_sx_hl.png
new file mode 100644
index 00000000..78be4e71
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_caption_sx_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_tab_bkg.png b/src/modules/notifier/pics/notifier_pix_tab_bkg.png
new file mode 100644
index 00000000..3918b044
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_tab_bkg.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_tab_dx.png b/src/modules/notifier/pics/notifier_pix_tab_dx.png
new file mode 100644
index 00000000..112d9604
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_tab_dx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_tab_focused_bkg.png b/src/modules/notifier/pics/notifier_pix_tab_focused_bkg.png
new file mode 100644
index 00000000..ef42ef68
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_tab_focused_bkg.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_tab_focused_dx.png b/src/modules/notifier/pics/notifier_pix_tab_focused_dx.png
new file mode 100644
index 00000000..e8dee6b9
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_tab_focused_dx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_tab_focused_sx.png b/src/modules/notifier/pics/notifier_pix_tab_focused_sx.png
new file mode 100644
index 00000000..f94cbb55
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_tab_focused_sx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_tab_sx.png b/src/modules/notifier/pics/notifier_pix_tab_sx.png
new file mode 100644
index 00000000..0f693bdd
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_tab_sx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_tab_unfocused_bkg.png b/src/modules/notifier/pics/notifier_pix_tab_unfocused_bkg.png
new file mode 100644
index 00000000..36a5f22e
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_tab_unfocused_bkg.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_tab_unfocused_dx.png b/src/modules/notifier/pics/notifier_pix_tab_unfocused_dx.png
new file mode 100644
index 00000000..f7ba1ee1
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_tab_unfocused_dx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_tab_unfocused_sx.png b/src/modules/notifier/pics/notifier_pix_tab_unfocused_sx.png
new file mode 100644
index 00000000..aa01c4c6
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_tab_unfocused_sx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_dwn.png b/src/modules/notifier/pics/notifier_pix_wnd_dwn.png
new file mode 100644
index 00000000..7f94fef4
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_dwn.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_dwn_hl.png b/src/modules/notifier/pics/notifier_pix_wnd_dwn_hl.png
new file mode 100644
index 00000000..6090316b
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_dwn_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_dwndx.png b/src/modules/notifier/pics/notifier_pix_wnd_dwndx.png
new file mode 100644
index 00000000..429fa4a0
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_dwndx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_dwndx_hl.png b/src/modules/notifier/pics/notifier_pix_wnd_dwndx_hl.png
new file mode 100644
index 00000000..2c392742
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_dwndx_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_dwnsx.png b/src/modules/notifier/pics/notifier_pix_wnd_dwnsx.png
new file mode 100644
index 00000000..3fb987ef
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_dwnsx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_dwnsx_hl.png b/src/modules/notifier/pics/notifier_pix_wnd_dwnsx_hl.png
new file mode 100644
index 00000000..eb51c09a
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_dwnsx_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_dx.png b/src/modules/notifier/pics/notifier_pix_wnd_dx.png
new file mode 100644
index 00000000..0a1c4f4b
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_dx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_dx_hl.png b/src/modules/notifier/pics/notifier_pix_wnd_dx_hl.png
new file mode 100644
index 00000000..24d1cde6
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_dx_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_sx.png b/src/modules/notifier/pics/notifier_pix_wnd_sx.png
new file mode 100644
index 00000000..01fb63fd
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_sx.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_pix_wnd_sx_hl.png b/src/modules/notifier/pics/notifier_pix_wnd_sx_hl.png
new file mode 100644
index 00000000..9a18f058
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_pix_wnd_sx_hl.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_right.png b/src/modules/notifier/pics/notifier_right.png
new file mode 100644
index 00000000..85819102
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_right.png
Binary files differ
diff --git a/src/modules/notifier/pics/notifier_up.png b/src/modules/notifier/pics/notifier_up.png
new file mode 100644
index 00000000..f846b624
--- /dev/null
+++ b/src/modules/notifier/pics/notifier_up.png
Binary files differ
diff --git a/src/modules/objects/Makefile.am b/src/modules/objects/Makefile.am
new file mode 100644
index 00000000..c4574582
--- /dev/null
+++ b/src/modules/objects/Makefile.am
@@ -0,0 +1,143 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviobjects.la
+
+libkviobjects_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviobjects_la_SOURCES = libkviobjects.cpp \
+ class_button.cpp \
+ class_buttongroup.cpp \
+ class_checkbox.cpp \
+ class_combobox.cpp \
+ class_dialog.cpp \
+ class_dockwindow.cpp \
+ class_file.cpp \
+ class_groupbox.cpp \
+ class_label.cpp \
+ class_layout.cpp \
+ class_lcd.cpp \
+ class_lineedit.cpp \
+ class_list.cpp \
+ class_listbox.cpp \
+ class_listview.cpp \
+ class_listviewitem.cpp \
+ class_mainwindow.cpp \
+ class_menubar.cpp \
+ class_multilineedit.cpp \
+ class_popupmenu.cpp \
+ class_process.cpp \
+ class_progressbar.cpp \
+ class_radiobutton.cpp \
+ class_slider.cpp \
+ class_socket.cpp \
+ class_spinbox.cpp \
+ class_tabwidget.cpp \
+ class_toolbar.cpp \
+ class_toolbutton.cpp \
+ class_painter.cpp \
+ class_pixmap.cpp \
+ class_tbrowser.cpp \
+ class_widget.cpp \
+ class_window.cpp \
+ class_wizard.cpp \
+ class_workspace.cpp \
+ class_wrapper.cpp \
+ class_urllabel.cpp \
+ class_xmlreader.cpp \
+ class_vbox.cpp \
+ class_hbox.cpp
+
+
+libkviobjects_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= class_button.h \
+ class_buttongroup.h \
+ class_checkbox.h \
+ class_combobox.h \
+ class_dialog.h \
+ class_dockwindow.h \
+ class_file.h \
+ class_groupbox.h \
+ class_label.h \
+ class_layout.h \
+ class_lcd.h \
+ class_lineedit.h \
+ class_list.h \
+ class_listbox.h \
+ class_listview.h \
+ class_listviewitem.h \
+ class_mainwindow.h \
+ class_menubar.h \
+ class_multilineedit.h \
+ class_painter.h \
+ class_pixmap.h \
+ class_popupmenu.h \
+ class_process.h \
+ class_progressbar.h \
+ class_radiobutton.h \
+ class_slider.h \
+ class_socket.h \
+ class_spinbox.h \
+ class_tabwidget.h \
+ class_tbrowser.h \
+ class_toolbar.h \
+ class_toolbutton.h \
+ class_urllabel.h \
+ class_widget.h \
+ class_window.h \
+ class_wizard.h \
+ class_workspace.h \
+ class_wrapper.h \
+ class_xmlreader.h \
+ class_vbox.h \
+ class_hbox.h \
+ object_macros.h
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+class_checkbox.cpp: m_class_checkbox.moc
+class_combobox.cpp: m_class_combobox.moc
+class_button.cpp: m_class_button.moc
+class_dialog.cpp: m_class_dialog.moc
+class_dockwindow.cpp: m_class_dockwindow.moc
+class_file.cpp: m_class_file.moc
+class_groupbox.cpp: m_class_groupbox.moc
+class_label.cpp: m_class_label.moc
+class_layout.cpp: m_class_layout.moc
+class_lcd.cpp: m_class_lcd.moc
+class_lineedit.cpp: m_class_lineedit.moc
+class_list.cpp: m_class_list.moc
+class_listbox.cpp: m_class_listbox.moc
+class_listview.cpp: m_class_listview.moc
+class_listviewitem.cpp: m_class_listviewitem.moc
+class_listbox.cpp: m_class_listbox.moc
+class_mainwindow.cpp: m_class_mainwindow.moc
+class_menubar.cpp: m_class_menubar.moc
+class_multilineedit.cpp: m_class_multilineedit.moc
+class_painter.cpp: m_class_painter.moc
+class_pixmap.cpp: m_class_pixmap.moc
+class_popupmenu.cpp: m_class_popupmenu.moc
+class_process.cpp: m_class_process.moc
+class_progressbar.cpp: m_class_progressbar.moc
+class_radiobutton.cpp: m_class_radiobutton.moc
+class_slider.cpp: m_class_slider.moc
+class_socket.cpp: m_class_socket.moc
+class_spinbox.cpp: m_class_spinbox.moc
+class_tabwidget.cpp: m_class_tabwidget.moc
+class_tbrowser.cpp: m_class_tbrowser.moc
+class_toolbar.cpp: m_class_toolbar.moc
+class_toolbutton.cpp: m_class_toolbutton.moc
+class_urllabel.cpp: m_class_urllabel.moc
+class_widget.cpp: m_class_widget.moc
+class_window.cpp: m_class_window.moc
+class_wizard.cpp: m_class_wizard.moc
+class_workspace.cpp: m_class_workspace.moc
+class_wrapper.cpp: m_class_wrapper.moc
+class_xmlreader.cpp: m_class_xmlreader.moc
+
diff --git a/src/modules/objects/class_button.cpp b/src/modules/objects/class_button.cpp
new file mode 100644
index 00000000..54d1525a
--- /dev/null
+++ b/src/modules/objects/class_button.cpp
@@ -0,0 +1,178 @@
+//
+// File : class_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) 1999-2000 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 "kvi_error.h"
+#include <qiconset.h>
+#include "kvi_iconmanager.h"
+
+#include "class_button.h"
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_button,"button","widget")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"setText", functionSetText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"text", functionText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"setAutoDefault", functionSetAutoDefault)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"setToggleButton", functionSetToggleButton)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"setOn", functionSetOn)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"isOn", functionIsOn)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"toggle", functionToggle)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"setIsMenuButton", functionSetIsMenuButton)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"isMenuButton", functionIsMenuButton)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"clickEvent", functionclickEvent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_button,"setImage", functionSetImage)
+
+
+KVSO_END_REGISTERCLASS(KviKvsObject_button)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_button,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_button)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_button)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_button)
+
+bool KviKvsObject_button::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QPushButton(parentScriptWidget(),name()),true);
+ connect(widget(),SIGNAL(clicked()),this,SLOT(slotClicked()));
+ return true;
+}
+
+bool KviKvsObject_button::functionText(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) c->returnValue()->setString(((QPushButton *)widget())->text());
+ return true;
+}
+
+bool KviKvsObject_button::functionSetText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((QPushButton *)widget())->setText(szText);
+ return true;
+}
+bool KviKvsObject_button::functionSetAutoDefault(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QPushButton *)widget())->setAutoDefault(bEnabled);
+ return true;
+}
+bool KviKvsObject_button::functionSetToggleButton(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QPushButton *)widget())->setToggleButton(bEnabled);
+ return true;
+}
+bool KviKvsObject_button::functionSetOn(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QPushButton *)widget())->setOn(bEnabled);
+ return true;
+}
+// FIX ME
+bool KviKvsObject_button::functionSetIsMenuButton(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ /*if(widget())
+ ((QPushButton *)widget())->setIsMenuButton(bEnabled);
+ */
+
+ return true;
+}
+bool KviKvsObject_button::functionIsMenuButton(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setBoolean(((QPushButton *)widget())->isMenuButton());
+ return true;
+}
+//
+bool KviKvsObject_button::functionIsOn(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setBoolean(((QPushButton *)widget())->isOn());
+ return true;
+}
+bool KviKvsObject_button::functionToggle(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) ((QPushButton *)widget())->toggle();
+ return true;
+}
+// FIX ME
+bool KviKvsObject_button::functionSetImage(KviKvsObjectFunctionCall *c)
+{
+ QString icon;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("icon",KVS_PT_STRING,0,icon)
+ KVSO_PARAMETERS_END(c)
+ if (!widget()) return true;
+ QPixmap * pix = g_pIconManager->getImage(icon);
+ if(pix){
+ #ifdef COMPILE_USE_QT4
+ ((QPushButton *)widget())->setIconSet(*pix);
+ #else
+ ((QPushButton *)widget())->setIconSet(QIconSet(*pix,QIconSet::Small));
+ #endif
+ }
+ else{
+ #ifdef COMPILE_USE_QT4
+ ((QPushButton *)widget())->setIcon(QIconSet());
+ #else
+ ((QPushButton *)widget())->setIconSet(QIconSet());
+ #endif
+ }
+ return true;
+}
+bool KviKvsObject_button::functionclickEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("clicked",c);
+ return true;
+}
+
+void KviKvsObject_button::slotClicked()
+{
+ KviKvsVariantList *params=0;
+ callFunction(this,"clickEvent",params);
+}
+
+
+#include "m_class_button.moc"
diff --git a/src/modules/objects/class_button.h b/src/modules/objects/class_button.h
new file mode 100644
index 00000000..5c752e48
--- /dev/null
+++ b/src/modules/objects/class_button.h
@@ -0,0 +1,58 @@
+#ifndef _CLASS_BUTTON_H_
+#define _CLASS_BUTTON_H_
+//
+// File : class_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) 1999-2000 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 <qpushbutton.h>
+#include "class_widget.h"
+#include "object_macros.h"
+
+class KviKvsObject_button : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_button)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionSetText(KviKvsObjectFunctionCall *c);
+ bool functionIsChecked(KviKvsObjectFunctionCall *c);
+ bool functionText(KviKvsObjectFunctionCall *c);
+ bool functionSetAutoDefault(KviKvsObjectFunctionCall *c);
+ bool functionSetToggleButton(KviKvsObjectFunctionCall *c);
+ bool functionSetOn(KviKvsObjectFunctionCall *c);
+ bool functionIsOn(KviKvsObjectFunctionCall *c);
+ bool functionToggle(KviKvsObjectFunctionCall *c);
+ bool functionSetIsMenuButton(KviKvsObjectFunctionCall *c);
+ bool functionIsMenuButton(KviKvsObjectFunctionCall *c);
+ bool functionSetImage(KviKvsObjectFunctionCall *c);
+ bool functionclickEvent(KviKvsObjectFunctionCall *c);
+
+protected slots:
+ void slotClicked();
+};
+
+#endif // !_CLASS_BUTTON_H_
diff --git a/src/modules/objects/class_buttongroup.cpp b/src/modules/objects/class_buttongroup.cpp
new file mode 100644
index 00000000..5f9f1756
--- /dev/null
+++ b/src/modules/objects/class_buttongroup.cpp
@@ -0,0 +1,87 @@
+//
+// File : class_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) 1999-2005 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 <qbuttongroup.h>
+#include "class_buttongroup.h"
+#include <qradiobutton.h>
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+
+/*
+ @doc: buttongroup
+ @keyterms:
+ buttongroup object class,
+ @title:
+ buttongroup class
+ @type:
+ class
+ @short:
+ Provides a buttongroup bar.
+ @inherits:
+ [class]groupbox[/class]
+ [class]object[/class]
+ [class]widget[/class]
+ @description:
+ This widget organizes buttons in a group.
+ 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 function to manage the layout automatically.
+ The class ineriths groupbox.
+
+ @functions:
+
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_buttongroup,"buttongroup","groupbox")
+
+KVSO_END_REGISTERCLASS(KviKvsObject_buttongroup)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_buttongroup,KviKvsObject_groupbox)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_buttongroup)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_buttongroup)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_buttongroup)
+
+// CHECK ME
+bool KviKvsObject_buttongroup::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ #ifdef COMPILE_USE_QT4
+ QButtonGroup *group=new QButtonGroup(parentScriptWidget());
+ group->setObjectName(name());
+ setObject(group,true);
+ #else
+ setObject(new QButtonGroup(name(),parentScriptWidget()), true);
+ #endif
+
+
+ return true;
+}
+
+
diff --git a/src/modules/objects/class_buttongroup.h b/src/modules/objects/class_buttongroup.h
new file mode 100644
index 00000000..472051ec
--- /dev/null
+++ b/src/modules/objects/class_buttongroup.h
@@ -0,0 +1,44 @@
+#ifndef _CLASS_BUTTONGROUP_H_
+#define _CLASS_BUTTONGROUP_H_
+//
+// File : class_buttongroup.h
+// Creation date : Jan 23 CEST 2007
+// by Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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 <qbuttongroup.h>
+#include "class_groupbox.h"
+#include "object_macros.h"
+
+class KviKvsObject_buttongroup : public KviKvsObject_groupbox
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_buttongroup)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+
+};
+#endif //!_CLASS_GROUPBOX_H_
+
diff --git a/src/modules/objects/class_checkbox.cpp b/src/modules/objects/class_checkbox.cpp
new file mode 100644
index 00000000..a651adb8
--- /dev/null
+++ b/src/modules/objects/class_checkbox.cpp
@@ -0,0 +1,128 @@
+//vim: ts=8
+// File : class_checkbox.cpp
+// Creation date : Wed Sep 20 23:01:47 CEST 2000 by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_styled_controls.h"
+
+#include "class_checkbox.h"
+
+/*
+ @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: <bool> $isChecked()
+ Returns '1' if the check box is checked, '0' otherwise.[br]
+ See also [classfnc]$setChecked[/classfnc]().
+ !fn: $setChecked([<bChecked:bool>])
+ Sets the check box 'checked state' to <bool>.
+ !fn: $setText([<text:string>])
+ Sets the check box 'checked state' to <bool>.[br]
+ See also [classfnc]$isChecked[/classfnc]().
+ !fn: $toggleEvent(<bToggled:bool>)
+ Called by KVIrc when the checkbox state is toggled.
+ The default implementation emits the toggled(<bool>) signal.
+*/
+
+//---------------------------------------------------------------------------------
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_checkbox,"checkbox","button")
+ // appearance
+ KVSO_REGISTER_HANDLER(KviKvsObject_checkbox,"setChecked",function_setChecked)
+ KVSO_REGISTER_HANDLER(KviKvsObject_checkbox,"isChecked",function_isChecked)
+ KVSO_REGISTER_HANDLER(KviKvsObject_checkbox,"toggleEvent",function_toggleEvent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_checkbox,"setText",function_setText)
+KVSO_END_REGISTERCLASS(KviKvsObject_checkbox)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_checkbox,KviKvsObject_button)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_checkbox)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_checkbox)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_checkbox)
+
+bool KviKvsObject_checkbox::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ KviStyledCheckBox * cb = new KviStyledCheckBox(parentScriptWidget(), name());
+ setObject(cb, true);
+ connect(cb,SIGNAL(toggled(bool)),this,SLOT(toggled(bool)));
+ connect(widget(),SIGNAL(clicked()),this,SLOT(slotClicked()));
+ return true;
+}
+
+bool KviKvsObject_checkbox::function_isChecked(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) c->returnValue()->setBoolean(((KviStyledCheckBox *)widget())->isChecked());
+ return true;
+}
+
+bool KviKvsObject_checkbox::function_setChecked(KviKvsObjectFunctionCall *c)
+{
+ bool bChecked;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bChecked",KVS_PT_BOOL,KVS_PF_OPTIONAL,bChecked)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) ((KviStyledCheckBox *)widget())->setChecked(bChecked);
+ return true;
+}
+
+bool KviKvsObject_checkbox::function_setText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) ((KviStyledCheckBox *)widget())->setText(szText);
+ return true;
+}
+
+bool KviKvsObject_checkbox::function_toggleEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("toggled",c,c->params());
+ return true;
+}
+
+void KviKvsObject_checkbox::toggled(bool b)
+{
+ KviKvsVariantList params(new KviKvsVariant(b));
+ callFunction(this,"toggleEvent",&params);
+}
+
+
+#include "m_class_checkbox.moc"
diff --git a/src/modules/objects/class_checkbox.h b/src/modules/objects/class_checkbox.h
new file mode 100644
index 00000000..1d19a432
--- /dev/null
+++ b/src/modules/objects/class_checkbox.h
@@ -0,0 +1,48 @@
+#ifndef _CLASS_CHECKBOX_H_
+#define _CLASS_CHECKBOX_H_
+
+//vim: ts=8
+// File : class_checkbox.h
+// Creation date : Wed Sep 20 23:02:11 CEST 2000 by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 <qcheckbox.h>
+#include "class_button.h"
+#include "object_macros.h"
+
+class KviKvsObject_checkbox : public KviKvsObject_button
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_checkbox)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+ bool function_setChecked(KviKvsObjectFunctionCall *c);
+ bool function_isChecked(KviKvsObjectFunctionCall *c);
+ bool function_toggleEvent(KviKvsObjectFunctionCall *c);
+ bool function_setText(KviKvsObjectFunctionCall *c);
+protected slots:
+ void toggled(bool b);
+};
+#endif // !_CLASS_CHECKBOX_H_
diff --git a/src/modules/objects/class_combobox.cpp b/src/modules/objects/class_combobox.cpp
new file mode 100644
index 00000000..9c8ffadf
--- /dev/null
+++ b/src/modules/objects/class_combobox.cpp
@@ -0,0 +1,368 @@
+//vim: ts=8
+// File : class_combobox.cpp
+// Creation date : Thu Mar 22 20:57:45 CET 2001 by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_error.h"
+#include "kvi_locale.h"
+#include "kvi_debug.h"
+
+
+#include "class_list.h"
+#include "class_combobox.h"
+#include <qlineedit.h>
+#include <qstring.h>
+
+/*
+ @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(<text:string>, <index:int>)
+ Inserts a text item at position <index>. If index is negative or
+ not specified the item is appended.
+ !fn: $changeItem(<text:string>, <index:uint>)
+ Changes text of item at <index> to <text>.
+ !fn: $removeItem(<index:uint>)
+ Removes item at given index.
+ !fn: $setMaxCount(<num:uint>)
+ Sets the maximum number of items the combo box can hold to
+ <num>. If <num> is smaller than the current number of items,
+ the list is truncated at the end. There is no limit by default.
+ !fn: <integer> $maxCount()
+ Returns the current maximum number of items in the combo box.
+ !fn: <integer> $count()
+ Returns number of items in the widget.
+ !fn: <string> $current()
+ Returns currently selected item.
+ !fn: <integer> $currentItem()
+ Returns index of currently selected item.
+ !fn: $setEditable(<bflag:boolean>)
+ Make the input field editable, if <bflag>. 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: <boolean> $editable()
+ Returns whether the combobox is editable or not.
+ !fn: $setEditText(<text:string>,[<quiet:bool>])
+ 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(<index:uint>)
+ Returns item at given index.
+ !fn: $setCurrentItem(<index:uint>)
+ Sets the current combobox item. This is the item to be
+ displayed on the combobox button.
+ !fn: $activatedEvent(<index:integer>)
+ 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(<text:string>)
+ 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(KviKvsObject_combobox,"combobox","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"insertItem", functioninsertItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"changeItem", functionchangeItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"removeItem", functionremoveItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"clear", functionclear)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"setMaxCount", functionsetMaxCount)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"maxCount", functionmaxCount)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"count", functioncount)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"current", functioncurrent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"currentItem", functioncurrentItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"setEditable", functionsetEditable);
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"editable", functioneditable)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"setEditText", functionsetEditText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"textAt", functiontextAt)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"textLineEdit", functiontextLineEdit)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"setTextLineEdit", functionsetTextLineEdit)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"setCurrentItem", functionsetCurrentItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"popup", functionpopup)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"setInsertionPolicy", functionsetInsertionPolicy)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"textChangedEvent", functiontextChangedEvent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_combobox,"activatedEvent", functionactivatedEvent)
+
+KVSO_END_REGISTERCLASS(KviKvsObject_combobox)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_combobox,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_combobox)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_combobox)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_combobox)
+
+bool KviKvsObject_combobox::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QComboBox(parentScriptWidget(), name()), true);
+ connect (((QComboBox *)widget()),SIGNAL(activated( int )),this,SLOT(slotActivated( int )));
+ return true;
+}
+
+bool KviKvsObject_combobox::functioninsertItem(KviKvsObjectFunctionCall *c)
+{
+ 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(widget())
+ if(c->paramCount()==1)
+ ((QComboBox *)widget())->insertItem(szItem);
+ else
+ ((QComboBox *)widget())->insertItem(szItem, iIndex);
+ return true;
+}
+bool KviKvsObject_combobox::functionclear(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) ((QComboBox *)widget())->clear();
+ return true;
+}
+bool KviKvsObject_combobox::functionchangeItem(KviKvsObjectFunctionCall *c)
+{
+
+ 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(!widget()) return true;
+ if (szText.isEmpty()) c->warning(__tr2qs("No string parameter given - using empty string"));
+ if(uIndex >= (cnt = ((QComboBox *)widget())->count()))
+ {
+ c->warning(__tr2qs("Item index [%d] is too big - defaulting to " \
+ "$count() - 1 [%d]"), uIndex, cnt);
+ uIndex = cnt - 1;
+ }
+
+ ((QComboBox *)widget())->changeItem(szText, uIndex);
+
+ return true;
+
+}
+bool KviKvsObject_combobox::functionremoveItem(KviKvsObjectFunctionCall *c)
+{
+
+ kvs_uint_t uIndex,cnt;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ if(uIndex >= (cnt = ((QComboBox *)widget())->count()))
+ {
+ c->warning(__tr2qs("Item index [%d] is too big - defaulting to " \
+ "$count() - 1 [%d]"), uIndex, cnt);
+ uIndex = cnt - 1;
+ }
+
+ ((QComboBox *)widget())->removeItem(uIndex);
+
+ return true;
+
+}
+bool KviKvsObject_combobox::functionsetMaxCount(KviKvsObjectFunctionCall *c)
+{
+
+ kvs_uint_t iMax;
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("count",KVS_PT_UNSIGNEDINTEGER,0,iMax)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QComboBox *)widget())->setMaxCount(iMax);
+ return true;
+}
+bool KviKvsObject_combobox::functionmaxCount(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QComboBox *)widget())->maxCount());
+ return true;
+}
+bool KviKvsObject_combobox::functioncount(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QComboBox *)widget())->count());
+ return true;
+}
+bool KviKvsObject_combobox::functioncurrent(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setString(((QComboBox *)widget())->currentText().local8Bit().data());
+ return true;
+}
+bool KviKvsObject_combobox::functioncurrentItem(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QComboBox *)widget())->currentItem());
+ return true;
+}
+bool KviKvsObject_combobox::functiontextLineEdit(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setString(((QComboBox *)widget())->lineEdit()->text());
+ return true;
+}
+
+bool KviKvsObject_combobox::functionsetEditable(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bflag",KVS_PT_BOOLEAN,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ {
+ ((QComboBox *)widget())->setEditable(bFlag);
+ if (bFlag) connect (((QComboBox *)widget())->lineEdit(),SIGNAL(textChanged(const QString & )),this,SLOT(slottextChanged(const QString & )));
+ else
+ disconnect (((QComboBox *)widget())->lineEdit(),SIGNAL(textChanged(const QString & )),this,SLOT(slottextChanged(const QString & )));
+ }
+
+ return true;
+}
+bool KviKvsObject_combobox::functionsetTextLineEdit(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QComboBox *)widget())->lineEdit()->setText(szText);
+ return true;
+}
+
+bool KviKvsObject_combobox::functioneditable(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((QComboBox *)widget())->editable());
+ return true;
+}
+bool KviKvsObject_combobox::functionsetEditText(KviKvsObjectFunctionCall *c)
+{
+ 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(!widget()) return true;
+ if (szText.isEmpty() && !bQuiet) c->warning("No string parameter given - using empty string");
+ ((QComboBox *)widget())->setEditText(szText);
+ return true;
+}
+bool KviKvsObject_combobox::functiontextAt(KviKvsObjectFunctionCall *c)
+{
+
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ c->returnValue()->setString(((QComboBox *)widget())->text(uIndex));
+ return true;
+}
+bool KviKvsObject_combobox::functionsetCurrentItem(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QComboBox *)widget())->setCurrentItem(uIndex);
+ return true;
+}
+bool KviKvsObject_combobox::functionpopup(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QComboBox *)widget())->popup();
+ return true;
+}
+bool KviKvsObject_combobox::functionsetInsertionPolicy(KviKvsObjectFunctionCall *c)
+{
+ QString szPolicy;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("policy",KVS_PT_STRING,0,szPolicy)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ if(KviQString::equalCI(szPolicy,"NoInsertion"))
+ ((QComboBox *)widget())->setInsertionPolicy(QComboBox::NoInsertion);
+ else if(KviQString::equalCI(szPolicy,"AtTop"))
+ ((QComboBox *)widget())->setInsertionPolicy(QComboBox::AtTop);
+ else if(KviQString::equalCI(szPolicy,"AtBotton"))
+ ((QComboBox *)widget())->setInsertionPolicy(QComboBox::AtBottom);
+ else if(KviQString::equalCI(szPolicy,"AtCurrent"))
+ ((QComboBox *)widget())->setInsertionPolicy(QComboBox::AtCurrent);
+ else if(KviQString::equalCI(szPolicy,"AfterCurrent"))
+ ((QComboBox *)widget())->setInsertionPolicy(QComboBox::AfterCurrent);
+ else if(KviQString::equalCI(szPolicy,"BeforeCurrent"))
+ ((QComboBox *)widget())->setInsertionPolicy(QComboBox::BeforeCurrent);
+ else c->warning(__tr2qs("Invalid insertion Policy %Q"),&szPolicy);
+ return true;
+}
+
+
+
+bool KviKvsObject_combobox::functiontextChangedEvent(KviKvsObjectFunctionCall *c)
+{
+
+ emitSignal("textChanged",c,c->params());
+ return true;
+
+}
+
+void KviKvsObject_combobox::slottextChanged(const QString &text)
+{
+ KviKvsVariantList params(new KviKvsVariant(text));
+ callFunction(this,"textChangedEvent",&params);
+}
+
+bool KviKvsObject_combobox::functionactivatedEvent(KviKvsObjectFunctionCall *c)
+{
+
+ emitSignal("activated",c,c->params());
+ return true;
+
+}
+
+void KviKvsObject_combobox::slotActivated(int i)
+{
+ KviKvsVariantList params(new KviKvsVariant((kvs_int_t)i));
+ callFunction(this,"activatedEvent",&params);
+}
+
+
+#include "m_class_combobox.moc"
diff --git a/src/modules/objects/class_combobox.h b/src/modules/objects/class_combobox.h
new file mode 100644
index 00000000..d4da7c6b
--- /dev/null
+++ b/src/modules/objects/class_combobox.h
@@ -0,0 +1,71 @@
+#ifndef _CLASS_COMBOBOX_H_
+#define _CLASS_COMBOBOX_H_
+
+//vim: ts=8
+// File : class_combobox.h
+// Creation date : Thu Mar 22 20:57:28 CET 2001 by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 <qcombobox.h>
+#include "class_widget.h"
+#include "object_macros.h"
+
+class KviKvsObject_combobox : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_combobox)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functioninsertItem(KviKvsObjectFunctionCall *c);
+ bool functionchangeItem(KviKvsObjectFunctionCall *c);
+ bool functionremoveItem(KviKvsObjectFunctionCall *c);
+ bool functionclear(KviKvsObjectFunctionCall *c);
+//#warning "$insertPixItem"
+//#warning "$changePixItem"
+
+ bool functioncount(KviKvsObjectFunctionCall *c);
+ bool functionsetMaxCount(KviKvsObjectFunctionCall *c);
+ bool functionmaxCount(KviKvsObjectFunctionCall *c);
+ bool functioncurrent(KviKvsObjectFunctionCall *c);
+ bool functioncurrentItem(KviKvsObjectFunctionCall *c);
+ bool functionsetEditable(KviKvsObjectFunctionCall *c);
+ bool functioneditable(KviKvsObjectFunctionCall *c);
+ bool functionsetEditText(KviKvsObjectFunctionCall *c);
+ bool functiontextAt(KviKvsObjectFunctionCall *c);
+ bool functiontextLineEdit(KviKvsObjectFunctionCall *c);
+ bool functionsetTextLineEdit(KviKvsObjectFunctionCall *c);
+
+ bool functionsetInsertionPolicy(KviKvsObjectFunctionCall *c);
+
+ bool functionsetCurrentItem(KviKvsObjectFunctionCall *c);
+ bool functionpopup(KviKvsObjectFunctionCall *c);
+ bool functiontextChangedEvent(KviKvsObjectFunctionCall *c);
+ bool functionactivatedEvent(KviKvsObjectFunctionCall *c);
+protected slots:
+ void slottextChanged(const QString &);
+ void slotActivated(int);
+};
+
+#endif // !_CLASS_COMBOBOX_H_
diff --git a/src/modules/objects/class_dialog.cpp b/src/modules/objects/class_dialog.cpp
new file mode 100644
index 00000000..f062f004
--- /dev/null
+++ b/src/modules/objects/class_dialog.cpp
@@ -0,0 +1,89 @@
+//
+// File : class_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) 2005 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_dialog.h"
+
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+#include "kvi_app.h"
+
+#include <qdialog.h>
+
+
+/*
+ @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 taskbar entry.
+ 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(KviKvsObject_dialog,"dialog","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_dialog,"setModal",functionSetModal)
+KVSO_END_REGISTERCLASS(KviKvsObject_dialog)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_dialog,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_dialog)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_dialog)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_dialog)
+
+bool KviKvsObject_dialog::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ QWidget * w = g_pApp->activeModalWidget();
+ if(!w)w = g_pFrame;
+ QDialog * d = new QDialog(parentScriptWidget() ? parentScriptWidget() : w,name());
+ //d->setModal(true);
+ setObject(d);
+ return true;
+}
+bool KviKvsObject_dialog::functionSetModal(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QDialog *)widget())->setModal(bEnabled);
+ return true;
+}
+
+
diff --git a/src/modules/objects/class_dialog.h b/src/modules/objects/class_dialog.h
new file mode 100644
index 00000000..b284baf3
--- /dev/null
+++ b/src/modules/objects/class_dialog.h
@@ -0,0 +1,44 @@
+#ifndef _CLASS_DIALOG_H_
+#define _CLASS_DIALOG_H_
+//
+// File : class_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) 2005 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"
+
+class QDialog;
+
+#include "object_macros.h"
+
+class KviKvsObject_dialog : public KviKvsObject_widget
+{
+
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_dialog)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+ bool functionSetModal(KviKvsObjectFunctionCall *c);
+};
+
+#endif // !_CLASS_DIALOG_H_
+
diff --git a/src/modules/objects/class_dockwindow.cpp b/src/modules/objects/class_dockwindow.cpp
new file mode 100644
index 00000000..fc439b23
--- /dev/null
+++ b/src/modules/objects/class_dockwindow.cpp
@@ -0,0 +1,276 @@
+//=============================================================================
+//
+// File : class_dockwindow.cpp
+// Created on Thu 29 Dec 2005 23:45:11 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2005 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_dockwindow.h"
+
+#include "kvi_frame.h"
+#include "kvi_locale.h"
+#include "kvi_qstring.h"
+#ifdef COMPILE_USE_QT4
+ #include <QDockWidget>
+ #define QT_DOCK_WINDOW QDockWidget
+#else
+ #include <qdockwindow.h>
+ #define QT_DOCK_WINDOW QDockWindow
+#endif
+#include <qlayout.h>
+
+/*
+ @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).
+ The window has an implicit layout that will automatically manage
+ the children depending on the dock window's orientation.
+ @functions:
+ !fn: $addWidget(<widget:hobject>)
+ Adds <widget> 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: <string> $orientation()
+ Returns the string "vertical" or "horizontal" depending on the orientation of this dock window.
+ !fn: $setOrientation(<orientation:string>)
+ Forces the orentation of this dock window. <ordientation> must be either "horizontal" or "vertical".[br]
+ Please note that KVIrc sets the orientation automatically when it is moved between the main frame docks by the user.
+ !fn: <bool> $resizeEnabled()
+ Returns $true if resizing of this window is enabled and false otherwise.
+ !fn: $setResizeEnabled(<bEnabled:bool>)
+ Enabled or disabled resizing of this window.
+ !fn: $setAllowedDockAreas(<docks:string>)
+ Sets the allowed main window dock areas for this dock window.[br]
+ <docks> 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(<dockarea:string>)
+ 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(KviKvsObject_dockwindow,"dockwindow","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_dockwindow,"addWidget",function_addWidget)
+ KVSO_REGISTER_HANDLER(KviKvsObject_dockwindow,"orientation",function_orientation)
+ KVSO_REGISTER_HANDLER(KviKvsObject_dockwindow,"setOrientation",function_setOrientation)
+ KVSO_REGISTER_HANDLER(KviKvsObject_dockwindow,"resizeEnabled",function_resizeEnabled)
+ KVSO_REGISTER_HANDLER(KviKvsObject_dockwindow,"setResizeEnabled",function_setResizeEnabled)
+ KVSO_REGISTER_HANDLER(KviKvsObject_dockwindow,"setAllowedDockAreas",function_setAllowedDockAreas)
+ KVSO_REGISTER_HANDLER(KviKvsObject_dockwindow,"dock",function_dock)
+KVSO_END_REGISTERCLASS(KviKvsObject_dockwindow)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_dockwindow,KviKvsObject_widget)
+KVSO_END_CONSTRUCTOR(KviKvsObject_dockwindow)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_dockwindow)
+KVSO_END_DESTRUCTOR(KviKvsObject_dockwindow)
+
+#define _pDockWindow ((QT_DOCK_WINDOW *)widget())
+
+bool KviKvsObject_dockwindow::init(KviKvsRunTimeContext * pContext,KviKvsVariantList * pParams)
+{
+#ifdef COMPILE_USE_QT4
+ QDockWidget * pWidget = new QDockWidget(g_pFrame);
+ pWidget->setObjectName(getName());
+ setObject(pWidget);
+#else //!COMPILE_USE_QT4
+ setObject(new QT_DOCK_WINDOW(g_pFrame,getName()),true);
+#endif //!COMPILE_USE_QT4
+ return true;
+}
+
+bool KviKvsObject_dockwindow::function_addWidget(KviKvsObjectFunctionCall *c)
+{
+ kvs_hobject_t hWidget;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hWidget)
+ KVSO_PARAMETERS_END(c)
+
+ if(!widget())return true; // hum ? dead ?
+
+ if(hWidget == (kvs_hobject_t)0)
+ {
+ // null widget ?
+ c->warning(__tr2qs("Can't add a null object"));
+ return true;
+ }
+
+ KviKvsObject * pWidget = KviKvsKernel::instance()->objectController()->lookupObject(hWidget);
+ if(!pWidget)
+ {
+ c->warning(__tr2qs("Invalid object handle passed as parameter (the object is no longer existing ?)"));
+ return true;
+ }
+
+ if(!pWidget->object())
+ {
+ c->warning(__tr2qs("Object in invalid state"));
+ return true;
+ }
+
+ if(!pWidget->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't set a non-widget object to be the main widget of a dock window"));
+ return true;
+ }
+
+ if(((QWidget *)(pWidget->object()))->parent() != (QObject *)_pDockWindow)
+ {
+ c->warning(__tr2qs("The added widget is not a child of this dock window"));
+ }
+
+#ifdef COMPILE_USE_QT4
+ _pDockWindow->setWidget((QWidget *)(pWidget->object()));
+#else //!COMPILE_USE_QT4
+ _pDockWindow->boxLayout()->addWidget((QWidget *)(pWidget->object()));
+ ((QWidget *)(pWidget->object()))->show();
+#endif //!COMPILE_USE_QT4
+ return true;
+}
+
+bool KviKvsObject_dockwindow::function_orientation(KviKvsObjectFunctionCall * c)
+{
+ if(!widget())return true; // hum ? dead ?
+#ifdef COMPILE_USE_QT4
+ c->returnValue()->setString(QString("horizontal"));
+#else //!COMPILE_USE_QT4
+ c->returnValue()->setString(_pDockWindow->orientation() == Qt::Horizontal ? QString("horizontal") : QString("vertical"));
+#endif //!COMPILE_USE_QT4
+ return true;
+}
+
+bool KviKvsObject_dockwindow::function_setOrientation(KviKvsObjectFunctionCall * c)
+{
+ QString szOrientation;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("orientation",KVS_PT_NONEMPTYSTRING,0,szOrientation)
+ KVSO_PARAMETERS_END(c)
+
+ if(!widget())return true; // hum ? dead ?
+#ifndef COMPILE_USE_QT4
+ _pDockWindow->setOrientation(KviQString::equalCI(szOrientation,"vertical") ? Qt::Vertical : Qt::Horizontal);
+#endif //!COMPILE_USE_QT4
+ return true;
+}
+
+bool KviKvsObject_dockwindow::function_resizeEnabled(KviKvsObjectFunctionCall * c)
+{
+ if(!widget())return true; // hum ? dead ?
+#ifdef COMPILE_USE_QT4
+ c->returnValue()->setBoolean(false);
+#else //!COMPILE_USE_QT4
+ c->returnValue()->setBoolean(_pDockWindow->isResizeEnabled());
+#endif //!COMPILE_USE_QT4
+ return true;
+}
+
+bool KviKvsObject_dockwindow::function_setResizeEnabled(KviKvsObjectFunctionCall * c)
+{
+ bool bResizeEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bResizeEnabled)
+ KVSO_PARAMETERS_END(c)
+
+ if(!widget())return true; // hum ? dead ?
+
+#ifndef COMPILE_USE_QT4
+ _pDockWindow->setResizeEnabled(bResizeEnabled);
+#endif //!COMPILE_USE_QT4
+ return true;
+}
+
+bool KviKvsObject_dockwindow::function_setAllowedDockAreas(KviKvsObjectFunctionCall * c)
+{
+ QString szFlags;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("docks",KVS_PT_STRING,0,szFlags)
+ KVSO_PARAMETERS_END(c)
+
+ if(!widget())return true; // hum ? dead ?
+
+#ifdef COMPILE_USE_QT4
+ Qt::DockWidgetAreas fAreas = Qt::NoDockWidgetArea;
+ if(szFlags.find('t',false))fAreas |= Qt::TopDockWidgetArea;
+ if(szFlags.find('l',false))fAreas |= Qt::LeftDockWidgetArea;
+ if(szFlags.find('r',false))fAreas |= Qt::RightDockWidgetArea;
+ if(szFlags.find('b',false))fAreas |= Qt::BottomDockWidgetArea;
+ _pDockWindow->setAllowedAreas(fAreas);
+ QDockWidget::DockWidgetFeatures fFeatures = _pDockWindow->features();
+ if(szFlags.find('f',false))
+ fFeatures |= QDockWidget::DockWidgetFloatable;
+ else
+ fFeatures &= ~QDockWidget::DockWidgetFloatable;
+ // no support for minimized dock widgets
+ _pDockWindow->setFeatures(fFeatures);
+#else //!COMPILE_USE_QT4
+ g_pFrame->setDockEnabled(_pDockWindow,Qt::DockTop,szFlags.find('t',false) != -1);
+ g_pFrame->setDockEnabled(_pDockWindow,Qt::DockLeft,szFlags.find('l',false) != -1);
+ g_pFrame->setDockEnabled(_pDockWindow,Qt::DockRight,szFlags.find('r',false) != -1);
+ g_pFrame->setDockEnabled(_pDockWindow,Qt::DockBottom,szFlags.find('b',false) != -1);
+ g_pFrame->setDockEnabled(_pDockWindow,Qt::DockTornOff,szFlags.find('f',false) != -1);
+ g_pFrame->setDockEnabled(_pDockWindow,Qt::DockMinimized,szFlags.find('m',false) != -1);
+#endif //!COMPILE_USE_QT4
+
+ return true;
+}
+
+
+bool KviKvsObject_dockwindow::function_dock(KviKvsObjectFunctionCall * c)
+{
+ QString szDock;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("dock",KVS_PT_STRING,0,szDock)
+ KVSO_PARAMETERS_END(c)
+
+ if(!widget())return true; // hum ? dead ?
+#ifdef COMPILE_USE_QT4
+ g_pFrame->removeDockWidget(_pDockWindow);
+ if(szDock.find('m',false) == -1)_pDockWindow->setFloating(false);
+ if(szDock.find('t',false) != -1)g_pFrame->addDockWidget(Qt::TopDockWidgetArea,_pDockWindow);
+ else if(szDock.find('l',false) != -1)g_pFrame->addDockWidget(Qt::LeftDockWidgetArea,_pDockWindow);
+ else if(szDock.find('r',false) != -1)g_pFrame->addDockWidget(Qt::RightDockWidgetArea,_pDockWindow);
+ else if(szDock.find('b',false) != -1)g_pFrame->addDockWidget(Qt::BottomDockWidgetArea,_pDockWindow);
+ else if(szDock.find('f',false) != -1)_pDockWindow->setFloating(true);
+ else if(szDock.find('m',false) != -1)qDebug("Sorry: no support for minimized dock widgets in Qt4");
+ else c->warning(__tr2qs("Invalid dock area specified"));
+
+#else //!COMPILE_USE_QT4
+ if(szDock.find('t',false) != -1)g_pFrame->moveDockWindow(_pDockWindow,Qt::DockTop,false,100);
+ else if(szDock.find('l',false) != -1)g_pFrame->moveDockWindow(_pDockWindow,Qt::DockLeft,false,100);
+ else if(szDock.find('r',false) != -1)g_pFrame->moveDockWindow(_pDockWindow,Qt::DockRight,false,100);
+ else if(szDock.find('b',false) != -1)g_pFrame->moveDockWindow(_pDockWindow,Qt::DockBottom,false,100);
+ else if(szDock.find('f',false) != -1)g_pFrame->moveDockWindow(_pDockWindow,Qt::DockTornOff,false,100);
+ else if(szDock.find('m',false) != -1)g_pFrame->moveDockWindow(_pDockWindow,Qt::DockMinimized,false,100);
+ else c->warning(__tr2qs("Invalid dock area specified"));
+#endif //!COMPILE_USE_QT4
+ return true;
+}
+
+#include "m_class_dockwindow.moc"
diff --git a/src/modules/objects/class_dockwindow.h b/src/modules/objects/class_dockwindow.h
new file mode 100644
index 00000000..4576a43d
--- /dev/null
+++ b/src/modules/objects/class_dockwindow.h
@@ -0,0 +1,49 @@
+#ifndef _CLASS_DOCKWINDOW_H_
+#define _CLASS_DOCKWINDOW_H_
+//=============================================================================
+//
+// File : class_dockwindow.h
+// Created on Thu 29 Dec 2005 23:45:11 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2005 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 "object_macros.h"
+
+#include "class_widget.h"
+
+class KviKvsObject_dockwindow : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_dockwindow)
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool function_addWidget(KviKvsObjectFunctionCall *c);
+ bool function_orientation(KviKvsObjectFunctionCall *c);
+ bool function_setOrientation(KviKvsObjectFunctionCall *c);
+ bool function_resizeEnabled(KviKvsObjectFunctionCall *c);
+ bool function_setResizeEnabled(KviKvsObjectFunctionCall * c);
+ bool function_setAllowedDockAreas(KviKvsObjectFunctionCall * c);
+ bool function_dock(KviKvsObjectFunctionCall * c);
+};
+
+#endif //!_CLASS_DOCKWINDOW_H_
diff --git a/src/modules/objects/class_file.cpp b/src/modules/objects/class_file.cpp
new file mode 100644
index 00000000..3429278e
--- /dev/null
+++ b/src/modules/objects/class_file.cpp
@@ -0,0 +1,488 @@
+//vim: ts=8
+// File : class_file.cpp
+// Creation date : Thu Sep 21 04:42:16 CEST 2000 by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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.
+//
+
+//#warning "Add QFILEINFO to this stuff ?"
+
+#include "class_file.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_error.h"
+#include "kvi_fileutils.h"
+#include <qstringlist.h>
+
+
+// needed for $open()
+const char * const mod_tbl[] = {
+ "Raw",
+ "ReadOnly",
+ "WriteOnly",
+ "ReadWrite",
+ "Append",
+ "Truncate"
+ };
+#ifdef COMPILE_USE_QT4
+#define IO_RAW QIODevice::Unbuffered
+#define IO_READONLY QIODevice::ReadOnly
+#define IO_WRITEONLY QIODevice::WriteOnly
+#define IO_READWRITE QIODevice::ReadWrite
+#define IO_APPEND QIODevice::Append
+#define IO_TRUNCATE QIODevice::Truncate
+//#define IO_TRANSLATE QIODevice::Text
+#else
+#define IO_RAW IO_Raw
+#define IO_READONLY IO_ReadOnly
+#define IO_WRITEONLY IO_WriteOnly
+#define IO_READWRITE IO_ReadWrite
+#define IO_APPEND IO_Append
+#define IO_TRUNCATE IO_Truncate
+#endif
+#ifdef COMPILE_USE_QT4
+const QIODevice::OpenMode mod_cod[] = {
+#else
+const int mod_cod[] = {
+#endif
+ IO_RAW,
+ IO_READONLY,
+ IO_WRITEONLY,
+ IO_READWRITE,
+ IO_APPEND,
+ IO_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(<file_name:string>)
+ Sets the file name to <file_name>. 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: <string> $name()
+ Returns name set by [classfnc]$setName[/classfnc]().[br]
+ See also: [classfnc]$setName[/classfnc]().
+ !fn: $open(<mode1:string>, <mode2:string>)
+ 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: <boolean> $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: <integer> $size()
+ Returns current file size.
+ !fn: <boolean> $atEnd()
+ Returns '1' if you have reached end of the file, '0' otherwise.
+ [br]See also: [classfnc]$seek[/classfnc](),
+ [classfnc]$where[/classfnc]().
+ !fn: <integer> $where()
+ Returns current position in the file (file index).[br]
+ See also: [classfnc]$seek[/classfnc]().
+ !fn: $seek(<index:integer>)
+ Sets the file index to <index>.[br]
+ See also: [classfnc]$where[/classfnc](),
+ [classfnc]$atEnd[/classfnc]().
+ !fn: $putch(<char>)
+ Writes character <char> to the file and increments file
+ index.[br]
+ See also: [classfnc]$getch[/classfnc](),
+ [classfnc]$ungetch[/classfnc]().
+ !fn: <char> $getch()
+ Reads a character from the file and increments file index.[br]
+ See also: [classfnc]$putch[/classfnc](),
+ [classfnc]$ungetch[/classfnc]().
+ !fn: $ungetch(<char>)
+ Puts the character <char> 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(<text_line:string>)
+ Reads a line of text from the file and increments file index.
+ !fn: $writeLine(<text_line:string>)
+ Appends a line of text to the end of the file.
+ $readBlock()
+ $writeBlock()
+ $writeHex()
+ $readHex()
+*/
+
+
+//---------------------------------------------------------------------------------
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_file,"file","object")
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"setName", functionsetName)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"name", functionname)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"open", functionopen)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"isOpen", functionisOpen)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"close", functionclose)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"flush", functionflush)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"size", functionsize)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"atEnd", functionatEnd)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"where", functionwhere)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"seek", functionseek)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"putch", functionputch)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"getch", functiongetch)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"ungetch", functionunGetch)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"readBlock", functionreadBlock)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"writeBlock", functionwriteBlock)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"readLine", functionreadLine)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"writeLine", functionwriteLine)
+/* KVSO_REGISTER_HANDLER(KviKvsObject_file,"hexWrite", functionHexWrite)
+ KVSO_REGISTER_HANDLER(KviKvsObject_file,"hexRead", functionHexRead)
+*/
+ KVSO_END_REGISTERCLASS(KviKvsObject_file)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_file,KviKvsObject)
+ m_pFile = new QFile();
+KVSO_END_CONSTRUCTOR(KviKvsObject_file)
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_file)
+if (m_pFile) delete m_pFile;
+m_pFile=0;
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_file)
+
+
+bool KviKvsObject_file::functionsetName(KviKvsObjectFunctionCall *c)
+{
+ QString szName;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("file_name",KVS_PT_STRING,0,szName)
+ KVSO_PARAMETERS_END(c)
+ if (m_pFile) m_pFile->setName(szName);
+ return true;
+}
+bool KviKvsObject_file::functionname(KviKvsObjectFunctionCall *c)
+{
+ if (m_pFile) c->returnValue()->setString(m_pFile->name());
+ return true;
+}
+
+bool KviKvsObject_file::functionopen(KviKvsObjectFunctionCall *c)
+{
+ QStringList modes;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("file_mode",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,modes)
+ KVSO_PARAMETERS_END(c)
+ if (!m_pFile) return true;
+ if(m_pFile->name().isEmpty())
+ {
+ c->warning(__tr2qs("Empty filename string"));
+ return true;
+ }
+ #ifdef COMPILE_USE_QT4
+ QIODevice::OpenMode mod,sum;
+ if (modes.empty()) sum = IO_READONLY; // if no parameters given, default to ReadWrite | Append
+ else
+ {
+ for ( int idx=0;idx<modes.count();idx++)
+ {
+ mod = IO_ReadOnly;
+ for(unsigned int j = 0; j < mod_num; j++)
+ {
+ if(KviQString::equalCI(modes.at(idx), mod_tbl[j]))
+ {
+ mod=mod_cod[j];
+ break;
+ }
+ }
+ if(mod!=IO_ReadOnly)
+ sum = sum | mod;
+ else
+ c->warning(__tr2qs("No such open mode: '%Q'"),&modes.at(idx));
+ }
+ }
+#else
+ int mod,sum=0;
+if (!modes.first()) sum = IO_READONLY; // if no parameters given, default to ReadWrite | Append
+ else
+ {
+ for ( QStringList::Iterator it = modes.begin(); it != modes.end(); ++it )
+ {
+
+ mod = 0;
+ for(unsigned int j = 0; j < mod_num; j++)
+ {
+ if(KviQString::equalCI((*it), mod_tbl[j]))
+ {
+ mod=mod_cod[j];
+ break;
+ }
+ }
+ if(mod)
+ sum = sum | mod;
+ else
+ c->warning(__tr2qs("No such open mode: '%Q'"),&(*it));
+ }
+ }
+#endif
+ m_pFile->open(sum);
+ return true;
+}
+
+bool KviKvsObject_file::functionisOpen(KviKvsObjectFunctionCall *c)
+{
+ if (m_pFile) c->returnValue()->setBoolean(m_pFile->isOpen());
+ return true;
+}
+
+bool KviKvsObject_file::functionclose(KviKvsObjectFunctionCall *c)
+{
+ if (!m_pFile->isOpen()) c->warning(__tr2qs("File is not open!"));
+ else m_pFile->close();
+ return true;
+}
+bool KviKvsObject_file::functionflush(KviKvsObjectFunctionCall *c)
+{
+ if (!m_pFile->isOpen()) c->warning(__tr2qs("File is not open!"));
+ else m_pFile->flush();
+ return true;
+}
+
+bool KviKvsObject_file::functionsize(KviKvsObjectFunctionCall *c)
+{
+ if (m_pFile) c->returnValue()->setInteger((kvs_int_t)(m_pFile->size()));
+ return true;
+}
+bool KviKvsObject_file::functionatEnd(KviKvsObjectFunctionCall *c)
+{
+ if (m_pFile) c->returnValue()->setInteger((kvs_int_t)(m_pFile->size()));
+ return true;
+}
+
+
+bool KviKvsObject_file::functionwhere(KviKvsObjectFunctionCall *c)
+{
+ if (!m_pFile->isOpen()) c->warning(__tr2qs("File is not open!"));
+ else c->returnValue()->setInteger((kvs_int_t)(m_pFile->at()));
+ return true;
+}
+bool KviKvsObject_file::functionseek(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if (!m_pFile) return true;
+ if(!m_pFile->isOpen())
+ c->warning(__tr("File is not open !"));
+ else m_pFile->at(uIndex);
+ return true;
+}
+
+bool KviKvsObject_file::functionputch(KviKvsObjectFunctionCall *c)
+{
+ QString szChar;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("char",KVS_PT_STRING,KVS_PF_OPTIONAL,szChar)
+ KVSO_PARAMETERS_END(c)
+ if (m_pFile)
+ {
+ if (szChar.length()>1)c->warning(__tr2qs("Argument to long, using only first char"));
+ const char *ch=szChar;
+ if (m_pFile->putch(ch[0])<0) c->warning(__tr2qs("Write error occured !"));
+ }
+
+ return true;
+}
+bool KviKvsObject_file::functiongetch(KviKvsObjectFunctionCall *c)
+{
+ if (!m_pFile) return true;
+ if(!m_pFile->isOpen())
+ c->warning(__tr("File is not open !"));
+ else
+ {
+ int chInt=m_pFile->getch();
+ if (chInt<0) c->warning(__tr("Read error occured !")); // c->error ?
+ QString szChar = QChar(chInt);
+ c->returnValue()->setString(szChar);
+ }
+ return true;
+}
+bool KviKvsObject_file::functionunGetch(KviKvsObjectFunctionCall *c)
+{
+ QString szChar;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("char",KVS_PT_STRING,0,szChar)
+ KVSO_PARAMETERS_END(c)
+ if (!m_pFile) return true;
+ if(!m_pFile->isOpen())
+ c->warning(__tr("File is not open !"));
+ else
+ {
+ if (szChar.length()>1) c->warning(__tr2qs("Argument to long, using only first char"));
+ const char *ch=szChar;
+ if (m_pFile->ungetch(ch[0])<0) c->warning(__tr2qs("An error occured !"));// c->error ?
+ }
+ return true;
+}
+bool KviKvsObject_file::functionreadBlock(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uLen;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("lenght",KVS_PT_UNSIGNEDINTEGER,0,uLen)
+ KVSO_PARAMETERS_END(c)
+ if (!m_pFile) return true;
+ if(!m_pFile->isOpen())
+ c->warning(__tr("File is not open !"));
+ else
+ {
+ char * buff = new char[uLen + 1];
+ m_pFile->flush(); // advice from QFile man page (to avoid trash)
+ int rlen = m_pFile->readBlock(buff, uLen);
+ buff[rlen] = '\0';
+ QString szBlock(buff);
+ c->returnValue()->setString(szBlock);
+ }
+ return true;
+}
+
+bool KviKvsObject_file::functionwriteBlock(KviKvsObjectFunctionCall *c)
+{
+ QString szBlock;
+ kvs_uint_t uLen;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("lenght",KVS_PT_UNSIGNEDINTEGER,0,uLen)
+ KVSO_PARAMETER("text_block",KVS_PT_STRING,0,szBlock)
+ KVSO_PARAMETERS_END(c)
+ if (!m_pFile) return true;
+ if(!m_pFile->isOpen())
+ c->warning(__tr("File is not open !"));
+ const char *block=szBlock;
+ int rlen = m_pFile->writeBlock(block, uLen);
+ c->returnValue()->setInteger(rlen);
+ m_pFile->flush();
+ return true;
+}
+bool KviKvsObject_file::functionreadLine(KviKvsObjectFunctionCall *c)
+{
+ if (!m_pFile) return true;
+ if(!m_pFile->isOpen())
+ c->warning(__tr("File is not open !"));
+ else
+ {
+ QString buffer;
+ KviFileUtils::readLine(m_pFile,buffer);
+ c->returnValue()->setString(buffer);
+ }
+ return true;
+}
+bool KviKvsObject_file::functionwriteLine(KviKvsObjectFunctionCall *c)
+{
+ QString szLine;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text_line",KVS_PT_STRING,0,szLine)
+ KVSO_PARAMETERS_END(c)
+ if (!m_pFile) return true;
+ if(!m_pFile->isOpen())
+ c->warning(__tr("File is not open !"));
+ else
+ {
+ QTextStream ts(m_pFile);
+ ts << szLine;
+ }
+ return true;
+}
+// fixme
+/*
+
+bool KviScriptFileObject::functionHexWrite(KviCommand * c, KviParameterList * p,
+ KviStr & b)
+{
+ ENTER_STACK_FRAME(c, "file::hexWrite");
+ if(!p->count())
+ return c->error(KviError_notEnoughParameters);
+
+ char * val = 0;
+ int len = p->first()->hexToBuffer(&val,false);
+
+ if(len < 1)
+ {
+ c->warning(__tr("Nothing to write"));
+ return c->leaveStackFrame();
+ }
+
+ if(!m_pFile->isOpen())
+ c->warning(__tr("File is not open !"));
+
+ if(m_pFile->putch(*val) < 0)
+ c->warning(__tr("Write error occured !")); // c->error ?
+
+ KviStr::freeBuffer(val);
+
+ return c->leaveStackFrame();
+}
+
+bool KviScriptFileObject::functionHexRead(KviCommand * c, KviParameterList * p,
+ KviStr & b)
+{
+ if(!m_pFile->isOpen())
+ c->warning(__tr("File is not open !"));
+
+ char ch = m_pFile->getch();
+
+ KviStr tmp;
+ tmp.bufferToHex(&ch, 1);
+ b.append(tmp);
+
+ return true;
+}
+
+*/
+#include "m_class_file.moc"
diff --git a/src/modules/objects/class_file.h b/src/modules/objects/class_file.h
new file mode 100644
index 00000000..01a54d19
--- /dev/null
+++ b/src/modules/objects/class_file.h
@@ -0,0 +1,113 @@
+#ifndef _CLASS_FILE_H_
+#define _CLASS_FILE_H_
+//vim: ts=8
+// File : class_file.h
+// Creation date : Thu Sep 21 04:43:01 CEST 2000 by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 <qfile.h>
+#include <qtextstream.h>
+#include "kvi_string.h"
+
+
+/*
+//class KviCommand;
+class KviParameterList;
+
+class KviScriptFileObject : public KviScriptObject
+{
+ Q_OBJECT
+public:
+ KviScriptFileObject(KviScriptObjectClass *, KviScriptObject *, const char *);
+ virtual ~KviScriptFileObject();
+
+ static void registerSelf();
+ static void unregisterSelf();
+
+protected:
+ bool functionSetName(KviCommand *, KviParameterList *, KviStr &);
+ bool functionName(KviCommand *, KviParameterList *, KviStr &);
+ bool functionOpen(KviCommand *, KviParameterList *, KviStr &);
+ bool functionIsOpen(KviCommand *, KviParameterList *, KviStr &);
+ bool functionClose(KviCommand *, KviParameterList *, KviStr &);
+ bool functionFlush(KviCommand *, KviParameterList *, KviStr &);
+ bool functionSize(KviCommand *, KviParameterList *, KviStr &);
+
+ bool functionAtEnd(KviCommand *, KviParameterList *, KviStr &);
+ // int QFile at() const
+ bool functionWhere(KviCommand *, KviParameterList *, KviStr &);
+ // void QFile at(int)
+ bool functionSeek(KviCommand *, KviParameterList *, KviStr &);
+ bool functionPutch(KviCommand *, KviParameterList *, KviStr &);
+ bool functionGetch(KviCommand *, KviParameterList *, KviStr &);
+ bool functionUngetch(KviCommand *, KviParameterList *, KviStr &);
+
+ bool functionReadBlock(KviCommand *, KviParameterList *, KviStr &);
+ bool functionWriteBlock(KviCommand *, KviParameterList *, KviStr &);
+
+ bool functionReadLine(KviCommand *, KviParameterList *, KviStr &);
+ bool functionWriteLine(KviCommand *, KviParameterList *, KviStr &);
+ bool functionHexWrite(KviCommand *, KviParameterList *, KviStr &);
+ bool functionHexRead(KviCommand *, KviParameterList *, KviStr &);
+
+protected:
+ QFile * m_pFile;
+};
+
+*/
+
+#include "object_macros.h"
+
+class KviKvsObject_file : public KviKvsObject
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_file)
+protected:
+ bool functionsetName(KviKvsObjectFunctionCall *c);
+ bool functionname(KviKvsObjectFunctionCall *c);
+ bool functionopen(KviKvsObjectFunctionCall *c);
+ bool functionisOpen(KviKvsObjectFunctionCall *c);
+ bool functionclose(KviKvsObjectFunctionCall *c);
+ bool functionflush(KviKvsObjectFunctionCall *c);
+ bool functionsize(KviKvsObjectFunctionCall *c);
+
+ bool functionatEnd(KviKvsObjectFunctionCall *c);
+ // int QFile at() const
+ bool functionwhere(KviKvsObjectFunctionCall *c);
+ // void QFile at(int)
+ bool functionseek(KviKvsObjectFunctionCall *c);
+ bool functionputch(KviKvsObjectFunctionCall *c);
+ bool functiongetch(KviKvsObjectFunctionCall *c);
+ bool functionunGetch(KviKvsObjectFunctionCall *c);
+
+ bool functionreadBlock(KviKvsObjectFunctionCall *c);
+ bool functionwriteBlock(KviKvsObjectFunctionCall *c);
+
+ bool functionreadLine(KviKvsObjectFunctionCall *c);
+ bool functionwriteLine(KviKvsObjectFunctionCall *c);
+/* bool functionHexWrite(KviKvsObjectFunctionCall *c);
+ bool functionHexRead(KviKvsObjectFunctionCall *c);
+*/
+protected:
+ QFile * m_pFile;
+};
+#endif // !_CLASS_FILE_H_
diff --git a/src/modules/objects/class_groupbox.cpp b/src/modules/objects/class_groupbox.cpp
new file mode 100644
index 00000000..14e640d1
--- /dev/null
+++ b/src/modules/objects/class_groupbox.cpp
@@ -0,0 +1,376 @@
+//
+// File : class_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) 1999-2005 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_tal_groupbox.h>
+#include "class_groupbox.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.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(<text:String>)
+ Sets the group box title to <text>.
+ !fn: <string> $title()
+ Returns the group box title text.
+ !fn: $setFlat(<bflag:boolean>)
+ Sets whether the group box is painted flat. Valid Values are 1 or 0.
+ !fn: <boolean> $isFlat()
+ Returns 1 (TRUE) if the group box is painted flat; otherwise returns 0 (FALSE).
+ !fn: <boolean> $isCheckable()
+ Returns 1 (TRUE) if the group box has a checkbox in its title; otherwise returns 0 (FALSE).
+ !fn: $setCheckable(<bflag:boolean>)
+ Sets whether the group box has a checkbox in its title: Valid values are 1 or 0.
+ !fn: $setInsideMargin(<margin:uint>)
+ Sets the the width of the inside margin to m pixels.
+ !fn: <integer> $insideMargin()
+ Returns the width of the empty space between the items in the group and margin of groupbox.
+ !fn: $setInsideSpacing(<spacing:uint>)
+ Sets the width of the empty space between each of the items in the group to m pixels.
+ !fn: <integer> $insideSpacing()
+ Returns the width of the empty space between each of the items in the group.
+ !fn: $setColumns(<columns:uint>)
+ Sets the number of columns or rows (depending of the orientation) in the group box.
+ !fn: <integer> $columns()
+ Returns the number of columns or rows in the groupbox.
+ !fn: $addSpace()
+ Adds an empty cell at the next free position.
+ !fn: <string> $alignment()
+ Returns the alignment of the group box title.
+ !fn: $setAlignment(<alignment:string>)
+ Set the alignment of the groupbox; Valid values are Left,Right,HCenter.
+ !fn: $setOrientation<orientation:string>
+ Sets the group box's orientation. Valid values are: Horizontal, Vertical.
+ !fn: $setColumnLayout(<columns:integer>,<orientation:string>)
+ Enables the automatic layout management. The children are arranged in n columns with the specified orientation.[br]
+ Valid values for <orientation> are: Horizontal, Vertical.
+ @examples:
+ [example]
+ |-Start:[br]
+ #Let's start.[br]
+ #first we'll create the main widget.[br]
+ %widget=$new(widget)[br]
+ [br]
+ #then the groupbox [br]
+ %gb=$new(groupbox,%widget)[br]
+ %gb->$setTitle(Login)[br]
+ %gb->$setAlignment("Left")[br]
+ [br]
+ #now we create the labels and lineedits.[br]
+ %labeluser=$new(label,%gb)[br]
+ %labeluser->$settext(User: )[br]
+ %labelpass=$new(label,%gb)[br]
+ %labelpass->$settext(Pass: )[br]
+ %inputuser=$new(lineedit,%gb)[br]
+ %inputpass=$new(lineedit,%gb)[br]
+ %inputpass->$setechomode("password")[br]
+ [br]
+ #now lets' layouting the groupbox's element's.[br]
+ %layoutgb=$new(layout,%gb)[br]
+ %layoutgb->$setmargin(20)[br]
+ %layoutgb->$addwidget(%labeluser,0,0)[br]
+ %layoutgb->$addwidget(%labelpass,1,0)[br]
+ %layoutgb->$addwidget(%inputuser,0,1)[br]
+ %layoutgb->$addwidget(%inputpass,1,1)[br]
+ [br]
+ # now we create a fake widget and managing the two buttons layout.[br]
+ %fakewidget=$new(widget,%widget)[br]
+ %layoutbtn=$new(layout,%fakewidget)[br]
+ %btnok=$new(button,%fakewidget)[br]
+ %btnok->$settext("OK")[br]
+ %btncancel=$new(button,%fakewidget)[br]
+ %btncancel->$settext("Cancel")[br]
+ %layoutbtn->$addwidget(%btnok,0,0)[br]
+ %layoutbtn->$addwidget(%btncancel,0,1)[br]
+ [br]
+ #And finally we create a main layout with the groupbox (and its "children")[br]
+ #and fakewiget (with its buttons children).
+ %mainlayout=$new(layout,%widget)[br]
+ %mainlayout->$setspacing(10)[br]
+ %mainlayout->$setmargin(10)[br]
+ %mainlayout->$addwidget(%gb,0,0)[br]
+ %mainlayout->$addwidget(%fakewidget,1,0)[br]
+ [br]
+ #Let's show our nice login request =D ! [br]
+ %widget->$show()[br]
+ [/example]
+
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_groupbox,"groupbox","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setTitle", functionSetTitle)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"title", functionTitle)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setFlat", functionSetFlat)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"isFlat", functionIsFlat)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setCheckable", functionSetCheckable)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"isCheckable", functionIsCheckable)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setInsideMargin", functionSetInsideMargin)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"insideMargin", functionInsideMargin)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setInsideSpacing", functionSetInsideSpacing)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"insideSpacing", functionInsideSpacing)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setColumns", functionSetColumns)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"columns", functionColumns)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"addSpace", functionAddSpace)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"alignment", functionAlignment)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setAlignment", functionSetAlignment)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setOrientation", functionSetOrientation)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"isChecked", functionIsChecked)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setChecked", functionSetChecked)
+ KVSO_REGISTER_HANDLER(KviKvsObject_groupbox,"setColumnLayout",functionSetColumnLayout)
+KVSO_END_REGISTERCLASS(KviKvsObject_groupbox)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_groupbox,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_groupbox)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_groupbox)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_groupbox)
+
+bool KviKvsObject_groupbox::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+#ifdef COMPILE_USE_QT4
+ KviTalGroupBox *groupbox=new KviTalGroupBox(name(),parentScriptWidget());
+ groupbox->setObjectName(name());
+ setObject(groupbox,true);
+#else
+ setObject(new KviTalGroupBox(name(),parentScriptWidget()), true);
+#endif
+ return true;
+}
+
+bool KviKvsObject_groupbox::functionSetTitle(KviKvsObjectFunctionCall *c)
+{
+ QString szTitle;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("title",KVS_PT_STRING,0,szTitle)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalGroupBox *)widget())->setTitle(szTitle);
+ return true;
+}
+bool KviKvsObject_groupbox::functionTitle(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setString(((KviTalGroupBox *)widget())->title());
+ return true;
+}
+bool KviKvsObject_groupbox::functionSetFlat(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bFlag",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalGroupBox *)widget())->setFlat(bEnabled);
+ return true;
+}
+bool KviKvsObject_groupbox::functionIsFlat(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setBoolean(((KviTalGroupBox *)widget())->isFlat());
+ return true;
+}
+bool KviKvsObject_groupbox::functionSetCheckable(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bFlag",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalGroupBox *)widget())->setCheckable(bEnabled);
+ return true;
+}
+bool KviKvsObject_groupbox::functionIsCheckable(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setBoolean(((KviTalGroupBox *)widget())->isCheckable());
+ return true;
+}
+bool KviKvsObject_groupbox::functionSetChecked(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bFlag",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalGroupBox *)widget())->setChecked(bEnabled);
+ return true;
+}
+bool KviKvsObject_groupbox::functionIsChecked(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setBoolean(((KviTalGroupBox *)widget())->isChecked());
+ return true;
+}
+bool KviKvsObject_groupbox::functionSetInsideMargin(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uMargin;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,uMargin)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalGroupBox *)widget())->setInsideMargin(uMargin);
+ return true;
+}
+bool KviKvsObject_groupbox::functionInsideMargin(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((KviTalGroupBox *)widget())->insideMargin());
+ return true;
+}
+bool KviKvsObject_groupbox::functionSetInsideSpacing(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uSpacing;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalGroupBox *)widget())->setInsideSpacing(uSpacing);
+ return true;
+}
+bool KviKvsObject_groupbox::functionInsideSpacing(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((KviTalGroupBox *)widget())->insideSpacing());
+ return true;
+}
+bool KviKvsObject_groupbox::functionSetColumns(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uColums;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("colums",KVS_PT_UNSIGNEDINTEGER,0,uColums)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalGroupBox *)widget())->setColumns(uColums);
+ return true;
+}
+bool KviKvsObject_groupbox::functionColumns(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((KviTalGroupBox *)widget())->columns());
+ return true;
+}
+bool KviKvsObject_groupbox::functionAddSpace(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t iSpace;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("colums",KVS_PT_UNSIGNEDINTEGER,0,iSpace)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) (((KviTalGroupBox *)widget())->addSpace(iSpace));
+ return true;
+}
+
+bool KviKvsObject_groupbox::functionSetAlignment(KviKvsObjectFunctionCall *c)
+{
+ QString szAlign;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("alignment",KVS_PT_STRING,0,szAlign)
+ KVSO_PARAMETERS_END(c)
+ if (!widget()) return true;
+ 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("Unknown alignment"));
+ return true;
+}
+bool KviKvsObject_groupbox::functionAlignment(KviKvsObjectFunctionCall *c)
+{
+ 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;
+}
+
+bool KviKvsObject_groupbox::functionSetOrientation(KviKvsObjectFunctionCall *c)
+{
+ QString szMode;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("orientation",KVS_PT_STRING,0,szMode)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ if(KviQString::equalCI(szMode, "Horizontal"))
+ ((KviTalGroupBox *)widget())->setOrientation(Qt::Horizontal);
+ else
+ if(KviQString::equalCI(szMode, "Vertical"))
+ ((KviTalGroupBox *)widget())->setOrientation(Qt::Vertical);
+ else c->warning( __tr2qs("Unknown orientation: "));
+ return true;
+}
+
+bool KviKvsObject_groupbox::functionSetColumnLayout(KviKvsObjectFunctionCall *c)
+{
+ QString szMode;
+ kvs_uint_t uCol;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("columns",KVS_PT_UNSIGNEDINTEGER,0,uCol)
+ KVSO_PARAMETER("orientation",KVS_PT_STRING,0,szMode)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ if(szMode=="Horizontal")
+ ((KviTalGroupBox *)widget())->setColumnLayout(uCol,Qt::Horizontal);
+ else
+ if(szMode=="Vertical")
+ ((KviTalGroupBox *)widget())->setColumnLayout(uCol,Qt::Vertical);
+ else c->warning( __tr2qs("Unknown orientation: "));
+ return true;
+}
+
diff --git a/src/modules/objects/class_groupbox.h b/src/modules/objects/class_groupbox.h
new file mode 100644
index 00000000..c63bb46b
--- /dev/null
+++ b/src/modules/objects/class_groupbox.h
@@ -0,0 +1,64 @@
+#ifndef _CLASS_GROUPBOX_H_
+#define _CLASS_GROUPBOX_H_
+//
+// File : class_groupbox.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) 1999-2005 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_tal_groupbox.h>
+#include "class_widget.h"
+#include "object_macros.h"
+
+class KviKvsObject_groupbox : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_groupbox)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+
+ bool functionSetTitle(KviKvsObjectFunctionCall *c);
+ bool functionTitle(KviKvsObjectFunctionCall *c);
+ bool functionSetFlat(KviKvsObjectFunctionCall *c);
+ bool functionIsFlat(KviKvsObjectFunctionCall *c);
+ bool functionSetCheckable(KviKvsObjectFunctionCall *c);
+ bool functionIsCheckable(KviKvsObjectFunctionCall *c);
+ bool functionSetInsideMargin(KviKvsObjectFunctionCall *c);
+ bool functionInsideMargin(KviKvsObjectFunctionCall *c);
+ bool functionSetInsideSpacing(KviKvsObjectFunctionCall *c);
+ bool functionInsideSpacing(KviKvsObjectFunctionCall *c);
+ bool functionSetColumns(KviKvsObjectFunctionCall *c);
+ bool functionColumns(KviKvsObjectFunctionCall *c);
+ bool functionAddSpace(KviKvsObjectFunctionCall *c);
+ bool functionAlignment(KviKvsObjectFunctionCall *c);
+ bool functionSetAlignment(KviKvsObjectFunctionCall *c);
+ bool functionSetOrientation(KviKvsObjectFunctionCall *c);
+ bool functionIsChecked(KviKvsObjectFunctionCall *c);
+ bool functionSetChecked(KviKvsObjectFunctionCall *c);
+ bool functionSetColumnLayout(KviKvsObjectFunctionCall *c);
+
+};
+#endif //!_CLASS_GROUPBOX_H_
+
diff --git a/src/modules/objects/class_hbox.cpp b/src/modules/objects/class_hbox.cpp
new file mode 100644
index 00000000..48174312
--- /dev/null
+++ b/src/modules/objects/class_hbox.cpp
@@ -0,0 +1,128 @@
+//
+// File : class_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) 2002-2006 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 "kvi_locale.h"
+
+#include "class_hbox.h"
+
+/*
+ @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(<spacing:uint>)
+ Sets the default spacing of the widgets in pixels
+ !fn: $setMargin(<margin:uint>)
+ Sets the dimension of the layout margin : the distance from the border to the outermost child widget edges.
+ !fn: $setStretchFactor(<widget:hobject>,<stretch:uint>)
+ Sets the stretch factor of widget to stretch.
+*/
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_hbox,"hbox","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_hbox,"setMargin", functionsetMargin)
+ KVSO_REGISTER_HANDLER(KviKvsObject_hbox,"setSpacing", functionsetSpacing)
+ KVSO_REGISTER_HANDLER(KviKvsObject_hbox,"setStretchFactor", functionsetStretchFactor )
+KVSO_END_REGISTERCLASS(KviKvsObject_hbox)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_hbox,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_hbox)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_hbox)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_hbox)
+
+bool KviKvsObject_hbox::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+
+ setObject(new KviTalHBox(parentScriptWidget()), true);
+ return true;
+}
+bool KviKvsObject_hbox::functionsetMargin(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uMargin;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,uMargin)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalHBox *)widget())->setMargin(uMargin);
+ return true;
+}
+
+bool KviKvsObject_hbox::functionsetSpacing(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uSpacing;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalHBox *)widget())->setSpacing(uSpacing);
+ return true;
+}
+bool KviKvsObject_hbox::functionsetStretchFactor(KviKvsObjectFunctionCall *c)
+{
+ 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);
+ if(!widget())return true;
+ if (!pObject)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!pObject->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!pObject->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ if(((KviKvsObject_widget *)pObject)->widget()->parentWidget() != widget())
+ {
+ c->warning(__tr2qs("The widget must be a child of this hbox"));
+ return true;
+ }
+ ((KviTalHBox *)widget())->setStretchFactor(((QWidget *)(pObject->object())),uStretch);
+ return true;
+}
+
+
diff --git a/src/modules/objects/class_hbox.h b/src/modules/objects/class_hbox.h
new file mode 100644
index 00000000..c0489f28
--- /dev/null
+++ b/src/modules/objects/class_hbox.h
@@ -0,0 +1,47 @@
+#ifndef _CLASS_HBOX_H_
+#define _CLASS_HBOX_H_
+//
+// File : class_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) 2002-2006 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_string.h"
+
+#include "kvi_tal_hbox.h"
+#include "object_macros.h"
+#include "class_widget.h"
+
+class KviKvsObject_hbox : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_hbox)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionsetMargin(KviKvsObjectFunctionCall *c);
+ bool functionsetSpacing(KviKvsObjectFunctionCall *c);
+ bool functionsetStretchFactor(KviKvsObjectFunctionCall *c);
+
+
+};
+
+
+#endif //_CLASS_HBOX_H_
diff --git a/src/modules/objects/class_label.cpp b/src/modules/objects/class_label.cpp
new file mode 100644
index 00000000..9c629818
--- /dev/null
+++ b/src/modules/objects/class_label.cpp
@@ -0,0 +1,409 @@
+//vim: ts=8
+// File : class_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) 1999-2000 Krzysztof Godlewski
+// Copyright (C) 1999-2000 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 <qfont.h>
+#include <qpixmap.h>
+#include <qmessagebox.h>
+#include "class_label.h"
+//#include "kvi_fileutils.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+
+
+// Tables used in $setAlignment & $alignment
+const char * const align_tbl[] = {
+ "Left",
+ "Right",
+ "HCenter",
+ "VCenter",
+ "Center",
+ "Top",
+ "Bottom",
+ "WordBreak"
+ };
+#ifdef COMPILE_USE_QT4
+ #define QT_LABEL_ALIGNLEFT Qt::AlignLeft
+ #define QT_LABEL_ALIGNRIGHT Qt::AlignRight
+ #define QT_LABEL_ALIGNHCENTER Qt::AlignHCenter
+ #define QT_LABEL_ALIGNVCENTER Qt::AlignVCenter
+ #define QT_LABEL_ALIGNCENTER Qt::AlignCenter
+ #define QT_LABEL_ALIGNTOP Qt::AlignTop
+ #define QT_LABEL_ALIGNBOTTOM Qt::AlignBottom
+ #define QT_LABEL_JUSTIFY Qt::AlignJustify
+#else
+ #define QT_LABEL_ALIGNLEFT QLabel::AlignLeft
+ #define QT_LABEL_ALIGNRIGHT QLabel::AlignRight
+ #define QT_LABEL_ALIGNHCENTER QLabel::AlignHCenter
+ #define QT_LABEL_ALIGNVCENTER QLabel::AlignVCenter
+ #define QT_LABEL_ALIGNCENTER QLabel::AlignCenter
+ #define QT_LABEL_ALIGNTOP QLabel::AlignTop
+ #define QT_LABEL_ALIGNBOTTOM QLabel::AlignBottom
+ #define QT_LABEL_JUSTIFY QLabel::WordBreak
+#endif
+
+const int align_cod[] = {
+ QT_LABEL_ALIGNLEFT,
+ QT_LABEL_ALIGNRIGHT,
+ QT_LABEL_ALIGNHCENTER,
+ QT_LABEL_ALIGNVCENTER,
+ QT_LABEL_ALIGNCENTER,
+ QT_LABEL_ALIGNTOP,
+ QT_LABEL_ALIGNBOTTOM,
+ QT_LABEL_JUSTIFY,
+ };
+
+#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(<text:string>)
+ Sets the text to be displayed by the label.
+ The text can contain limited html tags.
+ See also [classfnc]$text[/classfnc]().
+ !fn: <string> $text()
+ Returns the text currently displayed by the label.
+ See also [classfnc]$setText[/classfnc]().
+ !fn: <integer> $margin()
+ Returns current value of margin for this label (default is 0).
+ See also [classfnc]$setMargin[/classfnc]().
+ !fn: $setMargin(<margin:uint>)
+ Sets margin width / height to <margin>.
+ See also [classfnc]$margin[/classfnc]().
+ !fn: <boolean> $autoResize()
+ Returns 1, if auto-resize ability of the label is enabled.
+ See also [classfnc]$setAutoResize[/classfnc]().
+ !fn: $setAutoResize(<benabled:boolean>)
+ Sets auto-resize ability to enabled (if <benabled> is 1) or disabled
+ (if <benabled> is 0). If auto-resize is enabled, the label will
+ automagically resize itself accordingly to the 'size' of the
+ text it contains.
+ See also [classfnc]$autoResize[/classfnc]().
+ !fn: <string> $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(<flag1:string>, <flag2:string>, ...)
+ 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(<flag1>, <flag2>, ...)
+ 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(<image_id>)
+ 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 <image_id> parameter.
+
+*/
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_label,"label","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"setText",functionSetText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"text", functionText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"margin", functionMargin)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"setMargin", functionSetMargin)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"autoResize", functionAutoResize)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"setAutoResize", functionSetAutoResize)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"alignment", functionAlignment)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"setAlignment", functionSetAlignment)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"clear", functionClear)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"frameStyle", functionFrameStyle)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"setFrameStyle", functionSetFrameStyle)
+ KVSO_REGISTER_HANDLER(KviKvsObject_label,"setImage", functionSetImage)
+KVSO_END_REGISTERCLASS(KviKvsObject_label)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_label,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_label)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_label)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_label)
+
+bool KviKvsObject_label::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QLabel(parentScriptWidget(), name()), true);
+ return true;
+}
+
+bool KviKvsObject_label::functionSetText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((QLabel *)widget())->setText(szText);
+ return true;
+}
+bool KviKvsObject_label::functionText(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setString(((QLabel *)widget())->text());
+ return true;
+}
+
+bool KviKvsObject_label::functionSetMargin(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t iMargin;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,iMargin)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QLabel *)widget())->setMargin(iMargin);
+ return true;
+}
+bool KviKvsObject_label::functionMargin(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QLabel *)widget())->margin());
+ return true;
+}
+
+// FIX ME
+bool KviKvsObject_label::functionSetAutoResize(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ #ifdef COMPILE_USE_QT4
+ return true;
+ #else
+ if(widget())
+ ((QLabel *)widget())->setAutoResize(bEnabled);
+ return true;
+ #endif
+}
+bool KviKvsObject_label::functionAutoResize(KviKvsObjectFunctionCall *c)
+{
+ #ifdef COMPILE_USE_QT4
+ if (widget()) c->returnValue()->setBoolean(true);
+ #else
+ if (widget()) c->returnValue()->setBoolean(((QLabel *)widget())->autoResize());
+ #endif
+ return true;
+}
+//
+bool KviKvsObject_label::functionSetAlignment(KviKvsObjectFunctionCall *c)
+{
+ QStringList alignment;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("alignment",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,alignment)
+ KVSO_PARAMETERS_END(c)
+ if (!widget()) 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("Unknown alignment: '%Q'"),&(*it));
+
+ }
+ ((QLabel *)widget())->setAlignment(sum);
+ return true;
+}
+bool KviKvsObject_label::functionAlignment(KviKvsObjectFunctionCall *c)
+{
+ 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;
+}
+bool KviKvsObject_label::functionClear(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QLabel *)widget())->clear();
+ return true;
+}
+
+
+bool KviKvsObject_label::functionSetFrameStyle(KviKvsObjectFunctionCall *c)
+{
+
+ 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("Unknown style: '%Q'"),&(*it));
+
+ }
+ ((QLabel *)widget())->setFrameStyle(sum);
+ return true;
+
+
+
+
+}
+bool KviKvsObject_label::functionFrameStyle(KviKvsObjectFunctionCall *c)
+{
+ 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;
+}
+bool KviKvsObject_label::functionSetImage(KviKvsObjectFunctionCall *c)
+{
+
+ QString icon;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("icon",KVS_PT_STRING,0,icon)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ QPixmap * pix = g_pIconManager->getImage(icon);
+ if(pix) ((QLabel *)widget())->setPixmap(*pix);
+ return true;
+}
diff --git a/src/modules/objects/class_label.h b/src/modules/objects/class_label.h
new file mode 100644
index 00000000..38fa58a3
--- /dev/null
+++ b/src/modules/objects/class_label.h
@@ -0,0 +1,54 @@
+#ifndef _CLASS_LABEL_H_
+#define _CLASS_LABEL_H_
+//vim: ts=8
+// File : class_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) 1999-2000 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 <qlabel.h>
+#include "class_widget.h"
+#include "object_macros.h"
+
+class KviKvsObject_label : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_label)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionSetTitle(KviKvsObjectFunctionCall *c);
+ bool functionSetText(KviKvsObjectFunctionCall *c);
+ bool functionText(KviKvsObjectFunctionCall *c);
+ bool functionMargin(KviKvsObjectFunctionCall *c);
+ bool functionSetMargin(KviKvsObjectFunctionCall *c);
+ bool functionAutoResize(KviKvsObjectFunctionCall *c);
+ bool functionSetAutoResize(KviKvsObjectFunctionCall *c);
+ bool functionAlignment(KviKvsObjectFunctionCall *c);
+ bool functionSetAlignment(KviKvsObjectFunctionCall *c);
+ bool functionClear(KviKvsObjectFunctionCall *c);
+ bool functionFrameStyle(KviKvsObjectFunctionCall *c);
+ bool functionSetFrameStyle(KviKvsObjectFunctionCall *c);
+ bool functionSetImage(KviKvsObjectFunctionCall *c);
+};
+#endif // !_CLASS_LABEL_H_
diff --git a/src/modules/objects/class_layout.cpp b/src/modules/objects/class_layout.cpp
new file mode 100644
index 00000000..900b9856
--- /dev/null
+++ b/src/modules/objects/class_layout.cpp
@@ -0,0 +1,274 @@
+//
+// File : class_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 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 "kvi_locale.h"
+
+#include "class_layout.h"
+
+#ifdef COMPILE_USE_QT4
+#define QLAYOUT_AUTO_CONSTRAINT QLayout::SetDefaultConstraint
+#define QLAYOUT_FIXED QLayout::SetFixedSize
+#define QLAYOUT_FREE_RESIZE QLayout::SetNoConstraint
+#define QLAYOUT_MINIMUM QLayout::SetMinimumSize
+#else
+#define QLAYOUT_AUTO_CONSTRAINT QLayout::Auto
+#define QLAYOUT_FIXED QLayout::Fixed
+#define QLAYOUT_FREE_RESIZE QLayout::FreeResize
+#define QLAYOUT_MINIMUM QLayout::Minimum
+#endif
+
+
+/*
+ @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(<widget:object widget>,<row:uint>,<column:uint>)
+ Adds a widget to this layout placing it at position <row>,<column> in the grid
+ !fn: $addMultiCellWidget(<widget:object widget>,<start_row:uint>,<end_row:uint>,<start_col:uint>,<end_col:uint>)
+ Adds a widget to this layout spanning multiple grid cells
+ !fn: $setRowStretch(<row:uint>,<stretch:uint>)
+ Sets the stretch value for a particular row of this layout. The <stretch_value>
+ must be a positive integer. The rows with bigger stretch values will take more space
+ in the layout.
+ !fn: $setColStretch(<column:uint>,<stretch:uint>)
+ Sets the stretch value for a particular column in this layout. The <stretch_value>
+ must be a positive integer. The rows with bigger stretch values will take more space
+ in the layout.
+ !fn: $addRowSpacing(<row:uint>,<spacing:uint>)
+ Sets the minimum height of the specified <row> to <spacing> which must be a positive integer
+ !fn: $addColSpacing(<column:uint>,<spacing:uint>)
+ Sets the minimum width of the specigfied <column> to <spacing> which must be a positive integer
+ !fn: $setSpacing(<spacing:uint>)
+ Sets the default spacing of the widgets in pixels
+ !fn: $setMargin(<margin:uint>)
+ Sets the dimension of the layout margin : the distance from the border to the outermost child widget edges.
+ !fn: $setResizeMode(<resize_mode:string>)
+ Sets the resize mode of the parent widget in relation to this layout.
+ <mode> 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(KviKvsObject_layout,"layout","object")
+ KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addWidget", functionAddWidget)
+ KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addMultiCellWidget", functionAddMultiCellWidget)
+ KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setRowStretch", functionSetRowStretch)
+ KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setColStretch", functionSetColStretch)
+ KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addRowSpacing", functionAddRowSpacing)
+ KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addColSpacing", functionAddColSpacing)
+ KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setMargin", functionSetMargin)
+ KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setSpacing", functionSetSpacing)
+ KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setResizeMode", functionSetResizeMode)
+KVSO_END_REGISTERCLASS(KviKvsObject_layout)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_layout,KviKvsObject)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_layout)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_layout)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_layout)
+
+bool KviKvsObject_layout::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ QWidget * w = parentScriptWidget();
+
+ if(!w)
+ {
+ pContext->warning(__tr2qs("The parent of a layout must be a widget!"));
+ return false;
+ }
+ setObject(new QGridLayout(w));
+ return true;
+}
+
+bool KviKvsObject_layout::functionAddWidget(KviKvsObjectFunctionCall *c)
+{
+ 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);
+ if(!widget())return true;
+ if (!pObject)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!pObject->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!pObject->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ ((QGridLayout *)object())->addWidget(((QWidget *)(pObject->object())),uRow,uCol);
+ return true;
+}
+bool KviKvsObject_layout::functionAddMultiCellWidget(KviKvsObjectFunctionCall *c)
+{
+ 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);
+ if(!widget())return true;
+ if (!pObject)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!pObject->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!pObject->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ ((QGridLayout *)object())->addMultiCellWidget(((QWidget *)(pObject->object())),uStartRow,uEndRow,uStartCol,uEndCol);
+ return true;
+}
+bool KviKvsObject_layout::functionSetRowStretch(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(!widget())return true;
+ ((QGridLayout *)object())->setRowStretch(uRow,uStretch);
+ return true;
+}
+bool KviKvsObject_layout::functionSetColStretch(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(!widget())return true;
+ ((QGridLayout *)object())->setColStretch(uCol,uStretch);
+ return true;
+}
+
+bool KviKvsObject_layout::functionSetMargin(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uMargin;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,uMargin)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QGridLayout *)object())->setMargin(uMargin);
+ return true;
+}
+
+bool KviKvsObject_layout::functionSetSpacing(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uSpacing;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QGridLayout *)object())->setSpacing(uSpacing);
+ return true;
+}
+
+
+bool KviKvsObject_layout::functionAddRowSpacing(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if (widget()) ((QGridLayout *)object())->addRowSpacing(uRow,uSpacing);
+ return true;
+}
+
+bool KviKvsObject_layout::functionAddColSpacing(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if (widget()) ((QGridLayout *)object())->addColSpacing(uCol,uSpacing);
+ return true;
+}
+
+bool KviKvsObject_layout::functionSetResizeMode(KviKvsObjectFunctionCall *c)
+{
+ QString szMode;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("resize_mode",KVS_PT_STRING,0,szMode)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+#ifdef COMPILE_USE_QT4
+ QLayout::SizeConstraint r = QLAYOUT_AUTO_CONSTRAINT;
+#else
+ QLayout::ResizeMode r = QLAYOUT_AUTO_CONSTRAINT;
+#endif
+ if(KviQString::equalCI(szMode,"FreeResize")) r = QLAYOUT_FREE_RESIZE;
+ else if(KviQString::equalCI(szMode,"Minimum")) r = QLAYOUT_MINIMUM;
+ else if(KviQString::equalCI(szMode,"Fixed"))r = QLAYOUT_FIXED;
+ else c->warning(__tr2qs("Invalid resize mode defaulting to Auto"));
+ ((QGridLayout *)object())->setResizeMode(r);
+ return true;
+
+}
+
diff --git a/src/modules/objects/class_layout.h b/src/modules/objects/class_layout.h
new file mode 100644
index 00000000..e821316a
--- /dev/null
+++ b/src/modules/objects/class_layout.h
@@ -0,0 +1,52 @@
+#ifndef _CLASS_LAYOUT_H_
+#define _CLASS_LAYOUT_H_
+//
+// File : class_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 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_string.h"
+
+#include <qlayout.h>
+#include "object_macros.h"
+
+class KviKvsObject_layout : public KviKvsObject
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_layout)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionAddWidget(KviKvsObjectFunctionCall *c);
+ bool functionAddMultiCellWidget(KviKvsObjectFunctionCall *c);
+ bool functionSetRowStretch(KviKvsObjectFunctionCall *c);
+ bool functionSetColStretch(KviKvsObjectFunctionCall *c);
+ bool functionSetMargin(KviKvsObjectFunctionCall *c);
+ bool functionSetSpacing(KviKvsObjectFunctionCall *c);
+ bool functionAddRowSpacing(KviKvsObjectFunctionCall *c);
+ bool functionAddColSpacing(KviKvsObjectFunctionCall *c);
+ bool functionSetResizeMode(KviKvsObjectFunctionCall *c);
+
+
+};
+
+
+#endif //_CLASS_LAYOUT_H_
diff --git a/src/modules/objects/class_lcd.cpp b/src/modules/objects/class_lcd.cpp
new file mode 100644
index 00000000..0f0ba49a
--- /dev/null
+++ b/src/modules/objects/class_lcd.cpp
@@ -0,0 +1,180 @@
+//
+// File : class_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) 1999-2000 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_lcd.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+/*
+ @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: $setDisplayStr(<number:string>)
+ Displays the number represented by the string s.
+ !fn: $setDisplayInt(<number:integer>)
+ Sets the displayed value rounded to the nearest integer to number.
+ !fn: $setDisplayDouble(<number:double>)
+ Sets the displayed value to number (double).
+ !fn: $setMode(<mode:string>)
+ Sets the current display mode (number base): valid mode are HEX,BIN,OCT,DEC.
+ !fn: $setSegmentStyles(<style:string>)
+ Sets the style of the lcdnumber, valid styles are: Outline,Filled,Flat.
+ !fn: $setNumDigits(<number:integer>)
+ Sets the lcd number value.
+ !fn: <boolean> $checkOverflow()
+ Returns TRUE if num is too big to be displayed in its entirety;
+ otherwise returns FALSE.
+ !fn: $setSmallDecimalPoint(<bflag:boolean>)
+ Sets the the decimal point style, valid bool values are 1 or 0.
+ !fn: <boolean> $checkOverflow(<number:integer>)
+ Returns 1 (TRUE) if num is too big to be displayed in its entirety; otherwise returns 0 (FALSE).
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_lcd,"lcdnumber","widget")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_lcd,"setDisplayStr", functiondisplayStr)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lcd,"setDisplayInt", functiondisplayInt)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lcd,"setDisplayDouble", functiondisplayDouble)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lcd,"setMode", functionsetMode)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lcd,"setSegmentStyle", functionsetSegmentStyle)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lcd,"setNumDigits", functionsetNumDigits)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lcd,"setSmallDecimalPoint",functionsetSmallDecimalPoint)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lcd,"checkOverflow", functioncheckOverflow)
+KVSO_END_REGISTERCLASS(KviKvsObject_lcd)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_lcd,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_lcd)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_lcd)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_lcd)
+
+bool KviKvsObject_lcd::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QLCDNumber(parentScriptWidget(), name()), true);
+ return true;
+}
+
+bool KviKvsObject_lcd::functiondisplayInt(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iDigit;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("number",KVS_PT_INT,0,iDigit)
+ KVSO_PARAMETERS_END(c)
+ if(widget())((QLCDNumber *)widget())->display((int)iDigit);
+ return true;
+}
+
+bool KviKvsObject_lcd::functiondisplayStr(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("number",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) ((QLCDNumber *)widget())->display(szText);
+ return true;
+}
+
+bool KviKvsObject_lcd::functiondisplayDouble(KviKvsObjectFunctionCall *c)
+{
+ kvs_real_t dDigit;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("number",KVS_PT_DOUBLE,0,dDigit)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) ((QLCDNumber *)widget())->display(dDigit);
+ return true;
+}
+bool KviKvsObject_lcd::functionsetMode(KviKvsObjectFunctionCall *c)
+{
+ QString szMode;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("mode",KVS_PT_STRING,0,szMode)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ 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("Unknown mode "));
+ return true;
+}
+bool KviKvsObject_lcd::functionsetSegmentStyle(KviKvsObjectFunctionCall *c)
+{
+ QString szStyle;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("style",KVS_PT_STRING,0,szStyle)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ 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("Unknown segment style "));
+ return true;
+}
+bool KviKvsObject_lcd::functionsetNumDigits(KviKvsObjectFunctionCall *c)
+{
+ kvs_real_t digit;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("digit",KVS_PT_DOUBLE,0,digit)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) ((QLCDNumber *)widget())->setNumDigits(digit);
+ return true;
+}
+bool KviKvsObject_lcd::functionsetSmallDecimalPoint(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bflag",KVS_PT_BOOLEAN,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) ((QLCDNumber *)widget())->setSmallDecimalPoint(bFlag);
+ return true;
+}
+bool KviKvsObject_lcd::functioncheckOverflow(KviKvsObjectFunctionCall *c)
+{
+ kvs_real_t iDigit;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("digit",KVS_PT_DOUBLE,0,iDigit)
+ KVSO_PARAMETERS_END(c)
+ if(widget())c->returnValue()->setBoolean(((QLCDNumber *)widget())->checkOverflow(iDigit));
+ return true;
+}
+
+
diff --git a/src/modules/objects/class_lcd.h b/src/modules/objects/class_lcd.h
new file mode 100644
index 00000000..4976850a
--- /dev/null
+++ b/src/modules/objects/class_lcd.h
@@ -0,0 +1,51 @@
+#ifndef _CLASS_LCD_H_
+#define _CLASS_LCD_H_
+
+// File : class_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) 1999-2000 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 <qlcdnumber.h>
+#include "class_widget.h"
+
+
+class KviKvsObject_lcd : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_lcd)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functiondisplayStr(KviKvsObjectFunctionCall *c);
+ bool functionsetMode(KviKvsObjectFunctionCall *c);
+ bool functionsetSegmentStyle(KviKvsObjectFunctionCall *c);
+ bool functionsetNumDigits(KviKvsObjectFunctionCall *c);
+ bool functionsetSmallDecimalPoint(KviKvsObjectFunctionCall *c);
+ bool functioncheckOverflow(KviKvsObjectFunctionCall *c);
+ bool functiondisplayInt(KviKvsObjectFunctionCall *c);
+ bool functiondisplayDouble(KviKvsObjectFunctionCall *c);
+};
+
+#endif // !_CLASS_LCD_H_
diff --git a/src/modules/objects/class_lineedit.cpp b/src/modules/objects/class_lineedit.cpp
new file mode 100644
index 00000000..c8ba58ff
--- /dev/null
+++ b/src/modules/objects/class_lineedit.cpp
@@ -0,0 +1,461 @@
+//vim: ts=8
+// File : class_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) 1999-2000 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_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+
+#include "class_lineedit.h"
+
+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: <string> $text()
+ Returns text contained by the widget.[br]
+ See also [classfnc]$setText[/classfnc]().
+ !fn: $setText(<text:string>)
+ Sets editor text to <text>.[br]
+ See also [classfnc]$text[/classfnc]().
+ !fn: $setEchoMode(<echo_mode:string>)
+ 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: <string> $echoMode()
+ Return the line edit's echo mode.
+ See also [classfnc]$setEchoMode[/classfnc]().
+ !fn: <integer> $maxLength()
+ Returns the current maximum length of the text that can be typed
+ in the editor.[br]
+ See also [classfnc]$setMaxLength[/classfnc]().
+ !fn: $setMaxLength(<max_lenght:integer>)
+ Sets maximum length of the text that can be typed in the
+ editor.[br]
+ See also [classfnc]$maxLength[/classfnc]().
+ !fn: <boolean> $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(<bframe:boolean>)
+ Sets editor frame drawing to <bool>.[br]
+ See also [classfnc]$frame[/classfnc]().
+ !fn: <integer> $cursorPosition()
+ Returns current cursor position in the editor.[br]
+ See also [classfnc]$setCursorPosition[/classfnc]().
+ !fn: $setCursorPosition(<index:integer>)
+ Moves the cursor to place pointed by <index>.[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(<start:integer>, <length:integer>)
+ Selects <length> characters in the editor starting at position
+ <start>.[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(<bEnabled:bool>)
+ With this property user can drag text in the lineedit.
+ !fn: $setReadOnly(<bReadonly:boolean>)
+ Sets the lineedit to read only mode.
+ !fn: $setInputMask(<mask:string>)
+ Sets the validation input mask to inputMask.[br]
+ Example:[br]
+ [br]
+ %esempio->$setInputMask( "+99 99 99 99 99;_" );[br]
+ %esempio->$setInputMask( "000.000.000.000;_" );[br]
+ %esempio->Ip Number Mask.[br]
+ %esempio->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(<new text:string>)
+ This event is called when the text changed, In $0 there is the new text.
+ @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(KviKvsObject_lineedit,"lineedit","widget")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"text", functionText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"setText", functionSetText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"maxLength", functionMaxLength)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"setMaxLength", functionSetMaxLength)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"frame", functionFrame)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"setCursorPosition", functionSetCursorPosition)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"cursorPosition", functionCursorPosition)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"setFrame", functionSetFrame)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"selectAll" , functionSelectAll)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"setSelection", functionSetSelection)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"copy", functionCopy)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"cut", functionCut)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"paste", functionPaste)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"echoMode", functionEchoMode)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"setEchoMode", functionSetEchoMode)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"clear", functionClear)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"setDragEnabled", functionDragAndDrop)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"setInputMask", functionSetInputMask)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"setReadOnly", functionSetReadOnly)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"returnPressedEvent", functionreturnPressedEvent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"lostFocusEvent", functionlostFocusEvent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_lineedit,"textChangedEvent", functiontextChangedEvent)
+
+
+KVSO_END_REGISTERCLASS(KviKvsObject_lineedit)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_lineedit,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_lineedit)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_lineedit)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_lineedit)
+
+
+bool KviKvsObject_lineedit::init(KviKvsRunTimeContext * pContext,KviKvsVariantList * pParams)
+{
+ setObject(new QLineEdit(parentScriptWidget(),getName()),true);
+ connect(widget(),SIGNAL(returnPressed()),this,SLOT(slotreturnPressed()));
+ connect(widget(),SIGNAL(lostFocus()),this,SLOT(slotlostFocus()));
+ connect(widget(),SIGNAL(textChanged(const QString & )),this,SLOT(slottextChanged(const QString & )));
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionText(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setString(((QLineEdit *)widget())->text());
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionSetText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((QLineEdit *)widget())->setText(szText);
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionMaxLength(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setInteger(((QLineEdit *)widget())->maxLength());
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionSetMaxLength(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t iMaxlen;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("maxlen",KVS_PT_UNSIGNEDINTEGER,0,iMaxlen)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((QLineEdit *)widget())->setMaxLength(iMaxlen);
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionFrame(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((QLineEdit *)widget())->frame());
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionSetFrame(KviKvsObjectFunctionCall *c)
+{
+ bool bFrame;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bframe",KVS_PT_BOOL,0,bFrame)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QLineEdit *)widget())->setFrame(bFrame);
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionCursorPosition(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setInteger(((QLineEdit *)widget())->cursorPosition());
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionSetCursorPosition(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t iPos;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("position",KVS_PT_UNSIGNEDINTEGER,0,iPos)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((QLineEdit *)widget())->setCursorPosition(iPos);
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionSelectAll(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QLineEdit *)widget())->selectAll();
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionSetSelection(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if (widget())
+ ((QLineEdit *)widget())->setSelection(uStart, uLen);
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionCopy(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QLineEdit *)widget())->copy();
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionCut(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QLineEdit *)widget())->cut();
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionPaste(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QLineEdit *)widget())->paste();
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionEchoMode(KviKvsObjectFunctionCall *c)
+{
+ 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;
+}
+
+bool KviKvsObject_lineedit::functionSetEchoMode(KviKvsObjectFunctionCall *c)
+{
+ QString szMode;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("mode",KVS_PT_STRING,0,szMode)
+ KVSO_PARAMETERS_END(c)
+ if (!widget()) return true;
+ 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("Unknown echo mode %Q"),&szMode);
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionClear(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QLineEdit *)widget())->clear();
+ return true;
+}
+
+//-| Grifisx & Noldor |-Start:
+bool KviKvsObject_lineedit::functionDragAndDrop(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QLineEdit *)widget())->setDragEnabled(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionSetReadOnly(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bReadonly",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QLineEdit *)widget())->setReadOnly(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionSetInputMask(KviKvsObjectFunctionCall *c)
+{
+ QString szMask;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("mask",KVS_PT_STRING,0,szMask)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((QLineEdit *)widget())->setInputMask(szMask);
+ return true;
+}
+
+bool KviKvsObject_lineedit::functionreturnPressedEvent(KviKvsObjectFunctionCall *c)
+{
+
+ emitSignal("returnPressed",c);
+ return true;
+
+}
+
+void KviKvsObject_lineedit::slotreturnPressed()
+{
+ KviKvsVariantList * params = 0;
+ callFunction(this,"returnPressedEvent",params);
+
+}
+// FIND ME
+bool KviKvsObject_lineedit::functionlostFocusEvent(KviKvsObjectFunctionCall *c)
+{
+
+
+ emitSignal("lostFocus",c);
+ return true;
+
+}
+
+void KviKvsObject_lineedit::slotlostFocus()
+{
+ KviKvsVariantList * params = 0;
+ callFunction(this,"lostFocusEvent",params);
+}
+/////
+bool KviKvsObject_lineedit::functiontextChangedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("textChanged",c,c->params());
+ return true;
+
+}
+
+void KviKvsObject_lineedit::slottextChanged(const QString &text)
+{
+ KviKvsVariantList params(new KviKvsVariant(text));
+ callFunction(this,"textChangedEvent",&params);
+}
+
+
+#include "m_class_lineedit.moc"
diff --git a/src/modules/objects/class_lineedit.h b/src/modules/objects/class_lineedit.h
new file mode 100644
index 00000000..d7036824
--- /dev/null
+++ b/src/modules/objects/class_lineedit.h
@@ -0,0 +1,81 @@
+#ifndef _CLASS_LINEEDIT_H_
+#define _CLASS_LINEEDIT_H_
+//vim: ts=8
+// File : class_lineedit.h
+// Creation date : Wed 20 Sep 2000 04:34:22 CEST by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 <qlineedit.h>
+#include "class_widget.h"
+
+//#warning "Signals !"
+
+#include "object_macros.h"
+
+class KviKvsObject_lineedit : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_lineedit)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+
+
+ bool functionText(KviKvsObjectFunctionCall *c);
+ bool functionSetText(KviKvsObjectFunctionCall *c);
+ bool functionMaxLength(KviKvsObjectFunctionCall *c);
+ bool functionSetMaxLength(KviKvsObjectFunctionCall *c);
+ bool functionFrame(KviKvsObjectFunctionCall *c);
+ bool functionSetCursorPosition(KviKvsObjectFunctionCall *c);
+ bool functionCursorPosition(KviKvsObjectFunctionCall *c);
+ bool functionSetFrame(KviKvsObjectFunctionCall *c);
+ bool functionSelectAll(KviKvsObjectFunctionCall *c);
+ bool functionSetSelection(KviKvsObjectFunctionCall *c);
+ bool functionCopy(KviKvsObjectFunctionCall *c);
+ bool functionCut(KviKvsObjectFunctionCall *c);
+
+ bool functionPaste(KviKvsObjectFunctionCall *c);
+ bool functionEchoMode(KviKvsObjectFunctionCall *c);
+ bool functionSetEchoMode(KviKvsObjectFunctionCall *c);
+ bool functionClear(KviKvsObjectFunctionCall *c);
+ bool functionDragAndDrop(KviKvsObjectFunctionCall *c);
+ bool functionSetInputMask(KviKvsObjectFunctionCall *c);
+ bool functionSetReadOnly(KviKvsObjectFunctionCall *c);
+
+ bool functionreturnPressedEvent(KviKvsObjectFunctionCall *c);
+
+ bool functionlostFocusEvent(KviKvsObjectFunctionCall *c);
+
+ bool functiontextChangedEvent(KviKvsObjectFunctionCall *c);
+
+protected slots:
+ void slotreturnPressed();
+ void slotlostFocus();
+ void slottextChanged(const QString &);
+
+};
+
+
+#endif // ! _CLASS_LINEEDIT_H_
diff --git a/src/modules/objects/class_list.cpp b/src/modules/objects/class_list.cpp
new file mode 100644
index 00000000..2d6c9e84
--- /dev/null
+++ b/src/modules/objects/class_list.cpp
@@ -0,0 +1,392 @@
+//=============================================================================
+//
+// File : class_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) 1999-2000 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 "kvi_malloc.h"
+#include "kvi_locale.h"
+
+#include "class_list.h"
+
+#include <stdlib.h>
+
+
+/*
+ @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: <integer> $count()
+ Returns the number of items in the list
+
+ !fn: <boolean> $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(<item:variant>)
+ Inserts the <item> at the end (tail) of the list.
+
+ !fn: $prepend(<item:variant>)
+ Inserts the <item> at the beginning (head) of the list.
+
+ !fn: $insert(<index:uint>,<item:variant>)
+ Inserts the <item> at zero-based position <index> in the list.
+ If <index> is greater or equal to [classfnc:list]$count[/classfnc]()
+ then the item is simply appended to the end of the list.
+
+ !fn: $add(<index:uint>,<item:variant>)
+ This is exactly the same as [classfnc:list]$insert[/classfnc]().
+
+ !fn: <variant> $item(<index:uint>)
+ Returns the item at zero-based <index>. If <index> is greater
+ or equal to [classfnc:list]$count[/classfnc]() (beyond the end of the list)
+ then [fnc]$nothing[/fnc] is returned.
+
+ !fn: <boolean> $remove(<index:uint>)
+ Removes the item at zero-based <index>. Returns $true
+ if the item was succesfully removed and $false otherwise (i.e. <index>
+ pointed beyond the end of the list).
+
+ !fn: <boolean> $removeFirst()
+ Removes the first item from the list. Returns $true
+ if the item was succesfully removed (the list was not empty)
+ and $false otherwise.
+
+ !fn: <boolean> $removeLast()
+ Removes the last item from the list. Returns $true
+ if the item was succesfully removed (the list was not empty)
+ and $false otherwise.
+
+ !fn: <boolean> $removeCurrent()
+ Removes the current item from the list. Returns $true
+ if the item was succesfully removed or $false otherwise.
+ Invalidates any iteration operation.
+
+ !fn: <boolean> $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: <boolean> $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: <boolean> $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: <boolean> $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: <boolean> $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: <boolean> $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(KviKvsObject_list,"list","object")
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"count",function_count)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"isEmpty",function_isEmpty)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"clear",function_clear)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"removeAll",function_clear)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"append",function_append)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"prepend",function_prepend)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"insert",function_insert)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"add",function_insert)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"at",function_at)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"item",function_at)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"remove",function_remove)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"removeFirst",function_removeFirst)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"removeLast",function_removeLast)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"removeCurrent",function_removeCurrent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"moveFirst",function_moveFirst)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"moveNext",function_moveNext)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"movePrev",function_movePrev)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"moveLast",function_moveLast)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"sort",function_sort)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"eof",function_eof)
+ KVSO_REGISTER_HANDLER(KviKvsObject_list,"current",function_current)
+KVSO_END_REGISTERCLASS(KviKvsObject_list)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_list,KviKvsObject)
+ m_pDataList = new KviPointerList<KviKvsVariant>;
+ m_pDataList->setAutoDelete(true);
+KVSO_END_CONSTRUCTOR(KviKvsObject_list)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_list)
+ delete m_pDataList;
+ m_pDataList = 0;
+KVSO_END_CONSTRUCTOR(KviKvsObject_list)
+
+bool KviKvsObject_list::function_current(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setNothing();
+ return true;
+ }
+ KviKvsVariant * v = m_pDataList->current();
+ if(v)c->returnValue()->copyFrom(*v);
+ else c->returnValue()->setNothing();
+ return true;
+}
+
+bool KviKvsObject_list::function_eof(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(true);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pDataList->current() != 0);
+ return true;
+}
+
+bool KviKvsObject_list::function_moveLast(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pDataList->last() != 0);
+ return true;
+}
+
+bool KviKvsObject_list::function_movePrev(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pDataList->prev() != 0);
+ return true;
+}
+
+bool KviKvsObject_list::function_moveNext(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pDataList->next() != 0);
+ return true;
+}
+
+bool KviKvsObject_list::function_moveFirst(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pDataList->first() != 0);
+ return true;
+}
+
+bool KviKvsObject_list::function_removeLast(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pDataList->removeLast());
+ return true;
+}
+
+bool KviKvsObject_list::function_removeCurrent(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ if(m_pDataList->current())
+ {
+ m_pDataList->removeCurrent();
+ c->returnValue()->setBoolean(true);
+ } else {
+ c->returnValue()->setBoolean(false);
+ }
+ return true;
+}
+
+bool KviKvsObject_list::function_removeFirst(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pDataList->removeFirst());
+ return true;
+}
+
+bool KviKvsObject_list::function_remove(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UINT,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pDataList->remove(uIndex));
+ return true;
+}
+
+bool KviKvsObject_list::function_at(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UINT,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pDataList)
+ {
+ c->returnValue()->setNothing();
+ return true;
+ }
+ KviKvsVariant * v = m_pDataList->at(uIndex);
+ if(v)c->returnValue()->copyFrom(*v);
+ else c->returnValue()->setNothing();
+ return true;
+}
+
+bool KviKvsObject_list::function_insert(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(!m_pDataList)return true;
+ m_pDataList->insert(uIndex,new KviKvsVariant(*pVar));
+ return true;
+}
+
+bool KviKvsObject_list::function_prepend(KviKvsObjectFunctionCall *c)
+{
+ KviKvsVariant * pVar;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("item",KVS_PT_VARIANT,0,pVar)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pDataList)return true;
+ m_pDataList->prepend(new KviKvsVariant(*pVar));
+ return true;
+}
+
+bool KviKvsObject_list::function_append(KviKvsObjectFunctionCall *c)
+{
+ KviKvsVariant * pVar;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("item",KVS_PT_VARIANT,0,pVar)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pDataList)return true;
+ m_pDataList->append(new KviKvsVariant(*pVar));
+ return true;
+}
+
+bool KviKvsObject_list::function_clear(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)return true;
+ m_pDataList->clear();
+ return true;
+}
+
+inline int kvi_compare(const KviKvsVariant * p1,const KviKvsVariant * p2)
+{
+ return p1->compare(p2);
+}
+
+bool KviKvsObject_list::function_sort(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)return true;
+ m_pDataList->sort();
+ return true;
+}
+
+bool KviKvsObject_list::function_isEmpty(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setBoolean(true);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pDataList->isEmpty());
+ return true;
+}
+
+bool KviKvsObject_list::function_count(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pDataList)
+ {
+ c->returnValue()->setInteger(0);
+ return true;
+ }
+ c->returnValue()->setInteger(m_pDataList->count());
+ return true;
+}
+
diff --git a/src/modules/objects/class_list.h b/src/modules/objects/class_list.h
new file mode 100644
index 00000000..41d2816e
--- /dev/null
+++ b/src/modules/objects/class_list.h
@@ -0,0 +1,64 @@
+#ifndef _CLASS_LIST_H_
+#define _CLASS_LIST_H_
+//=========================================================================================
+//
+// File : class_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-2005 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 "kvi_string.h"
+#include "kvi_pointerlist.h"
+#include "kvi_kvs_variant.h"
+#include "object_macros.h"
+
+
+class KviKvsObject_list : public KviKvsObject
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_list)
+protected:
+ KviPointerList<KviKvsVariant> * m_pDataList;
+protected:
+ KviPointerList<KviKvsVariant> * dataList() const { return m_pDataList; };
+public:
+ bool function_count(KviKvsObjectFunctionCall *c);
+ bool function_isEmpty(KviKvsObjectFunctionCall *c);
+ bool function_clear(KviKvsObjectFunctionCall *c);
+ bool function_append(KviKvsObjectFunctionCall *c);
+ bool function_prepend(KviKvsObjectFunctionCall *c);
+ bool function_insert(KviKvsObjectFunctionCall *c);
+ bool function_at(KviKvsObjectFunctionCall *c);
+ bool function_remove(KviKvsObjectFunctionCall *c);
+ bool function_removeFirst(KviKvsObjectFunctionCall *c);
+ bool function_removeLast(KviKvsObjectFunctionCall *c);
+ bool function_removeCurrent(KviKvsObjectFunctionCall *c);
+ bool function_moveFirst(KviKvsObjectFunctionCall *c);
+ bool function_moveNext(KviKvsObjectFunctionCall *c);
+ bool function_movePrev(KviKvsObjectFunctionCall *c);
+ bool function_moveLast(KviKvsObjectFunctionCall *c);
+ bool function_eof(KviKvsObjectFunctionCall *c);
+ bool function_current(KviKvsObjectFunctionCall *c);
+ bool function_sort(KviKvsObjectFunctionCall *c);
+};
+
+
+#endif //_CLASS_LIST_H_
diff --git a/src/modules/objects/class_listbox.cpp b/src/modules/objects/class_listbox.cpp
new file mode 100644
index 00000000..111f7952
--- /dev/null
+++ b/src/modules/objects/class_listbox.cpp
@@ -0,0 +1,390 @@
+//vim: ts=8
+// File : class_listbox.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 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_error.h"
+#include "kvi_locale.h"
+#include "kvi_debug.h"
+
+
+#include "kvi_tal_listbox.h"
+
+#include "class_list.h"
+#include "class_listbox.h"
+
+/*
+ @doc: listbox
+ @keyterms:
+ listbox object class
+ @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 listbox in "single" mode
+ (and this is the default mode set at widget creation).
+ @functions:
+ !fn: $setSelectionMode(<selection_mode:string>)
+ Sets the current selection mode specified by the parameter <mode>
+ 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: <string> $selectionMode()
+ Returns the current selection mode
+ !fn: $insertItem(<text:string>, <index:uint>)
+ Inserts a text item at position <index>. If index is negative or
+ not specified the item is appended.
+ !fn: $changeItem(<text:string>, <index:uint>)
+ Changes text of item at <index> to <text>.
+ !fn: $removeItem(<index:uindex>)
+ Removes item at given index.
+ !fn: $count()
+ Returns number of items in the widget.
+ !fn: <string> $currentText()
+ Returns the text of the currently selected item.
+ !fn: <integer> $currentItem()
+ Returns index of current item or -1 if no item is current.
+ !fn: $textAt(<index:integer>)
+ Returns item at given index.
+ !fn: $setCurrentItem(<index:integer>)
+ Sets the current listbox item.
+ !fn: $clear()
+ Removes all the items
+ !fn: <boolean> $isSelected(<index:integer>)
+ Returns 1 if the item at <index> is selected and 0 otherwise
+ !fn: $setSelected(<index:integer>,<bSelected:boolean>)
+ Changes the selection status of the item at <index> to the value
+ specified by <bSelected>. If <bSelected> is 1 the item is selected,
+ if <bSelected> is 0 the item is unselected.
+ !fn: $selectionChangeEvent()
+ This function is called by KVIrc when the selection in the listbox changes.
+ !fn: $currentItemChangeEvent()
+ This function is called by KVIrc when the current item changes.
+ !fn: <index:integer> $onItemEvent()
+ This function is called by KVIrc when the current item pointed by the mouse changes and gives in $0 the item index.
+ !fn: <array:x,y,width,height> $itemRect(<item:index>)
+ Returns the rectangle on the screen that item occupies, or an invalid rectangle if item is 0 or is not currently visible.
+
+ @signals:
+ !sg: <string> $currentItemChange()
+ This signal is emitted by the default implementation of [classfnc]$currentItemChangeEvent[/classfnc]().[br]
+ !sg: <string> $onItem()
+ This signal is emitted by the default implementation of [classfnc]$onItemEvent[/classfnc]().[br]
+
+ */
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_listbox,"listbox","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"insertItem", functioninsertItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"changeItem", functionchangeItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"removeItem", functionremoveItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"clear", functionclear)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"count", functioncount)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"currentText", functioncurrentText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"currentItem", functioncurrentItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"textAt", functiontextAt);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"itemAt", functionitemAt);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"itemRect", functionitemRect);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"setCurrentItem", functionsetCurrentItem);
+
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"setSelectionMode",functionsetSelectionMode);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"selectionMode",functionselectionMode);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"setSelected",functionsetSelected);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"isSelected",functionisSelected);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"currentItemChangeEvent",functioncurrentItemChangeEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listbox,"onItemEvent",functiononItemEvent);
+
+
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_listbox,"selectionChangeEvent")
+
+
+KVSO_END_REGISTERCLASS(KviKvsObject_listbox)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_listbox,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_listbox)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_listbox)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_listbox)
+
+bool KviKvsObject_listbox::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ KviTalListBox * b = new KviTalListBox(parentScriptWidget());
+ b->setSelectionMode(KviTalListBox::Single);
+ connect(b,SIGNAL(selectionChanged()),this,SLOT(selectionChanged()));
+ connect(b,SIGNAL(currentChanged(KviTalListBoxItem *)),this,SLOT(currentItemChanged(KviTalListBoxItem *)));
+
+ connect(b,SIGNAL(onItem(KviTalListBoxItem *)),this,SLOT(onItem(KviTalListBoxItem *)));
+
+ setObject(b,true);;
+ return true;
+}
+
+bool KviKvsObject_listbox::functioninsertItem(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iIndex;
+ QString szItem;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szItem)
+ KVSO_PARAMETER("index",KVS_PT_INT,KVS_PF_OPTIONAL,iIndex)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalListBox *)widget())->insertItem(szItem, iIndex);
+ return true;
+}
+bool KviKvsObject_listbox::functionclear(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) ((KviTalListBox *)widget())->clear();
+ return true;
+}
+bool KviKvsObject_listbox::functionchangeItem(KviKvsObjectFunctionCall *c)
+{
+
+ 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(!widget()) return true;
+ if (szText.isEmpty()) c->warning(__tr2qs("No string parameter given - using empty string"));
+ if(uIndex >= (cnt = ((KviTalListBox *)widget())->count()))
+ {
+ c->warning(__tr2qs("Item index [%d] is too big - defaulting to " \
+ "$count() - 1 [%d]"), uIndex, cnt);
+ uIndex = cnt - 1;
+ }
+
+ ((KviTalListBox *)widget())->changeItem(szText, uIndex);
+
+ return true;
+
+}
+bool KviKvsObject_listbox::functionremoveItem(KviKvsObjectFunctionCall *c)
+{
+
+ kvs_uint_t uIndex,cnt;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ if(uIndex >= (cnt = ((KviTalListBox *)widget())->count()))
+ {
+ c->warning(__tr2qs("Item index [%d] is too big - defaulting to " \
+ "$count() - 1 [%d]"), uIndex, cnt);
+ uIndex = cnt - 1;
+ }
+
+ ((KviTalListBox *)widget())->removeItem(uIndex);
+
+ return true;
+
+}
+
+bool KviKvsObject_listbox::functioncount(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((KviTalListBox *)widget())->count());
+ return true;
+}
+bool KviKvsObject_listbox::functioncurrentText(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setString(((KviTalListBox *)widget())->currentText().local8Bit().data());
+ return true;
+}
+bool KviKvsObject_listbox::functioncurrentItem(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((KviTalListBox *)widget())->currentItem());
+ return true;
+}
+
+bool KviKvsObject_listbox::functiontextAt(KviKvsObjectFunctionCall *c)
+{
+
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ c->returnValue()->setString(((KviTalListBox *)widget())->text(uIndex));
+ return true;
+}
+bool KviKvsObject_listbox::functionsetCurrentItem(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalListBox *)widget())->setCurrentItem(uIndex);
+ return true;
+}
+bool KviKvsObject_listbox::functionsetSelectionMode(KviKvsObjectFunctionCall *c)
+{
+ QString szMode;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("selection_mode",KVS_PT_STRING,0,szMode)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ KviTalListBox::SelectionMode iMode = KviTalListBox::Single;
+
+ if(KviQString::equalCI(szMode,"single")) iMode = KviTalListBox::Single;
+
+ else if(KviQString::equalCI(szMode,"multi")) iMode = KviTalListBox::Multi;
+
+ else if(KviQString::equalCI(szMode,"extended")) iMode = KviTalListBox::Extended;
+
+ else if(KviQString::equalCI(szMode,"none")) iMode = KviTalListBox::NoSelection;
+
+ else c->warning(__tr2qs("Invalid selection mode '%Q' assuming single"),&szMode);
+ ((KviTalListBox *)widget())->setSelectionMode(iMode);
+
+ return true;
+}
+bool KviKvsObject_listbox::functionselectionMode(KviKvsObjectFunctionCall *c)
+{
+
+ if(!widget()) return true;
+ switch(((KviTalListBox *)widget())->selectionMode())
+ {
+ case KviTalListBox::Single: c->returnValue()->setString("single"); break;
+ case KviTalListBox::Multi: c->returnValue()->setString("multi"); break;
+ case KviTalListBox::Extended: c->returnValue()->setString("extended"); break;
+ case KviTalListBox::NoSelection: c->returnValue()->setString("none"); break;
+ default: c->returnValue()->setString("single"); break;
+ }
+ return true;
+}
+
+bool KviKvsObject_listbox::functionisSelected(KviKvsObjectFunctionCall *c)
+{
+
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(widget())c->returnValue()->setBoolean(((KviTalListBox *)widget())->isSelected(uIndex));
+ return true;
+}
+bool KviKvsObject_listbox::functionsetSelected(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(widget()) ((KviTalListBox *)widget())->setSelected(uIndex,bSel);
+ return true;
+}
+bool KviKvsObject_listbox::functionitemAt(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(widget())
+ c->returnValue()->setInteger(((KviTalListBox *)widget())->index(((KviTalListBox *)widget())->itemAt(QPoint(uX,uY))));
+ return true;
+}
+
+bool KviKvsObject_listbox::functioncurrentItemChangeEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("currentItemChange",c,c->params());
+
+ return true;
+}
+
+void KviKvsObject_listbox::selectionChanged()
+{
+ KviKvsVariantList *params=0;
+ callFunction(this,"selectionChangeEvent",0,0);
+}
+
+void KviKvsObject_listbox::currentItemChanged(KviTalListBoxItem *item)
+{
+ if (!item) callFunction(this,"currentItemChangeEvent",0,0);
+ else
+ {
+ KviKvsVariantList params(new KviKvsVariant(item->text()));
+ callFunction(this,"currentItemChangeEvent",0,&params);
+ }
+
+}
+bool KviKvsObject_listbox::functiononItemEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("onItem",c,c->params());
+
+ return true;
+}
+
+void KviKvsObject_listbox::onItem(KviTalListBoxItem *item)
+{
+ KviTalListBox *lbx = (KviTalListBox *)(item->listBox());
+ KviKvsVariantList params(new KviKvsVariant((kvs_int_t)lbx->index(item)));
+ callFunction(this,"onItemEvent",0,&params);
+}
+
+
+bool KviKvsObject_listbox::functionitemRect(KviKvsObjectFunctionCall *c)
+{
+kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("uIndex",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ {
+ QRect rect=((KviTalListBox *)widget())->itemRect(((KviTalListBox *)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;
+}
+
+
+#include "m_class_listbox.moc"
diff --git a/src/modules/objects/class_listbox.h b/src/modules/objects/class_listbox.h
new file mode 100644
index 00000000..471337fd
--- /dev/null
+++ b/src/modules/objects/class_listbox.h
@@ -0,0 +1,70 @@
+#ifndef _CLASS_LISTBOX_H_
+#define _CLASS_LISTBOX_H_
+
+//vim: ts=8
+// File : class_listbox.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 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"
+
+class KviTalListBox;
+class KviTalListBoxItem;
+
+#include "object_macros.h"
+
+class KviKvsObject_listbox: public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_listbox)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+
+ bool functioninsertItem(KviKvsObjectFunctionCall *c);
+ bool functionchangeItem(KviKvsObjectFunctionCall *c);
+ bool functionremoveItem(KviKvsObjectFunctionCall *c);
+ bool functioncount(KviKvsObjectFunctionCall *c);
+ bool functioncurrentText(KviKvsObjectFunctionCall *c);
+ bool functioncurrentItem(KviKvsObjectFunctionCall *c);
+ bool functiontextAt(KviKvsObjectFunctionCall *c);
+ bool functionsetCurrentItem(KviKvsObjectFunctionCall *c);
+ bool functionclear(KviKvsObjectFunctionCall *c);
+ bool functionsetSelectionMode(KviKvsObjectFunctionCall *c);
+ bool functionselectionMode(KviKvsObjectFunctionCall *c);
+ bool functionsetSelected(KviKvsObjectFunctionCall *c);
+ bool functionisSelected(KviKvsObjectFunctionCall *c);
+ bool functioncurrentItemChangeEvent(KviKvsObjectFunctionCall *c);
+ bool functiononItemEvent(KviKvsObjectFunctionCall *c);
+
+ bool functionitemAt(KviKvsObjectFunctionCall *c);
+ bool functionitemRect(KviKvsObjectFunctionCall *c);
+protected slots:
+ void selectionChanged();
+ void currentItemChanged(KviTalListBoxItem *);
+ void onItem(KviTalListBoxItem *);
+};
+
+
+#endif // !_CLASS_COMBOBOX_H_
diff --git a/src/modules/objects/class_listview.cpp b/src/modules/objects/class_listview.cpp
new file mode 100644
index 00000000..f571788c
--- /dev/null
+++ b/src/modules/objects/class_listview.cpp
@@ -0,0 +1,557 @@
+//=================================================================================
+//
+// File : class_listview.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) 1999-2006 Szymon Stefanek (pragma at kvirc dot net)
+// Copyright (C) 2005-2006 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 "kvi_tal_listview.h"
+#ifdef COMPILE_USE_QT4
+#include <q3header.h>
+#include <qevent.h>
+#else
+#include <qheader.h>
+#endif
+#include "class_listview.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+
+
+/*
+ @doc: listview
+ @keyterms:
+ listview widget class
+ @title:
+ listview class
+ @type:
+ class
+ @short:
+ A listview 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]listviewitem[/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(<text_label:string> <width:unsigned integer>)
+ Adds a width pixels wide column with the column header label to the list view.
+
+ !fn: $setSorting(<column:integer>,<bAscending:boolean>)
+ Sets the list view to be sorted by column column in ascending order if ascending is 1 or descending order if it is FALSE.
+ If column is -1, sorting is disabled and the user cannot sort columns by clicking on the column headers
+
+ !fn: $hideListViewHeader()
+ Hide the listview column header.
+
+ !fn: $showListViewHeader()
+ Show the listview column header.
+
+ !fn: <boolean> $isListViewHeaderVisible()
+ Returns '1' if the listview header is currently visible. Otherwise this function returns '0'.
+
+ !fn: $setAllColumnsShowFocus(<bAllColumnsShowFocus:boolean>)
+ 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(<mode:string>)
+ Sets the selection mode for this listview. <mode> can be one of "Single","NoSelection","Multi" or "Extended".
+
+ !fn: <listviewitem> $selectedItem()
+ 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: <listviewitem> $currentItem()
+ Returns the current [class]listviewitem[/class] or $null if no item is current at the moment.
+
+ !fn: <listviewitem> $firstChild()
+ Returns the first child [class]listviewitem[/class] of this listview or $null if there are no items at all.
+
+ !fn: $clickEvent(<item:object>)
+ 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(<item:object>)
+ 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(<item:object>)
+ 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: $returnPressedEvent(<item:object>)
+ This function is called by the framework when the enter key is pressed.[br]
+ In its arument the currrent item.[br]
+ The default implementation emits the [classfnc]$returnPressed[/classfnc]() signal.
+
+ !fn: $spacePressedEvent(<item:object>)
+ 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(<item:object)
+ This event is called by framwork when the user moves the mouse cursor onto item.
+ The default implementation emits the [classfnc]$onItem[/classfnc]() signal.
+
+ !fn: $itemExpandedEvent(<item:object>)
+ 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(<item:object>)
+ 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: $itemRenamedEvent(<item:object>,<col:integer>,<text:string>)
+ 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]$itemRenamed[/classfnc]() signal.
+
+ !fn: $rightButtonClickEvent(<item:object>,<x:integer>,>y:integer>)
+ This signal is emitted when the right button is clicked.[br]
+ The arguments are the relevant item (may be 0), the point in global coordinates and the relevant column (or -1 if the click was outside the list).
+ The default implementation emits the [classfnc]$rightButtonClicked[/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: $returnPressed()
+ This signal is emitted by the default implementation of [classfnc]$returnPressedEvent[/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: $itemRenamed()
+ This signal is emitted by the default implementation of [classfnc]$itemRenamedEvent[/classfnc]().
+ !sg: $rightButtonClicked()
+ This signal is emitted by the default implementation of [classfnc]$rightButtonClickedEvent[/classfnc]().
+
+
+*/
+
+//---------------------------------------------------------------------------------
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_listview,"listview","widget")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"addColumn",function_addColumn)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"setColumnText",function_setColumnText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"setSorting",function_setSorting)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"setRootIsDecorated",function_setRootIsDecorated)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"setAllColumnsShowFocus",function_setAllColumnsShowFocus)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"clear",function_clear)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"selectedItem",function_selectedItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"currentItem",function_currentItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"setSelectionMode",function_setSelectionMode)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"listViewHeaderIsVisible",function_listViewHeaderIsVisible)
+
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"hideListViewHeader",function_hideListViewHeader)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"showListViewHeader",function_showListViewHeader)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"firstChild",function_firstChild)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"selectionChangedEvent",function_selectionChangedEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"currentChangedEvent",function_currentChangedEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"returnPressedEvent",function_returnPressedEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"spacePressedEvent",function_spacePressedEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"onItemEvent",function_onItemEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"itemClickedEvent",function_itemClickedEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"itemExpandedEvent",function_itemExpandedEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"itemCollapsedEvent",function_itemCollapsedEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"itemRenamedEvent",function_itemRenamedEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listview,"rightButtonClickedEvent",function_rightButtonClickedEvent);
+
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_listview,"fileDroppedEvent")
+
+KVSO_END_REGISTERCLASS(KviKvsObject_listview)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_listview,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_listview)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_listview)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_listview)
+
+bool KviKvsObject_listview::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new KviKvsMdmListView(parentScriptWidget(),name(),this),true);
+ connect(widget(),SIGNAL(clicked(KviTalListViewItem *)),this,SLOT(slotClicked(KviTalListViewItem *)));
+ connect(widget(),SIGNAL(selectionChanged(KviTalListViewItem *)),this,SLOT(slotSelectionChanged(KviTalListViewItem *)));
+ connect(widget(),SIGNAL(selectionChanged()),this,SLOT(slotMultipleSelectionChanged()));
+ connect(widget(),SIGNAL(currentChanged(KviTalListViewItem *)),this,SLOT(slotCurrentChanged(KviTalListViewItem *)));
+ connect(widget(),SIGNAL(returnPressed(KviTalListViewItem *)),this,SLOT(slotReturnPressed(KviTalListViewItem *)));
+ connect(widget(),SIGNAL(spacePressed(KviTalListViewItem *)),this,SLOT(slotSpacePressed(KviTalListViewItem *)));
+ connect(widget(),SIGNAL(onItem(KviTalListViewItem *)),this,SLOT(slotOnItem(KviTalListViewItem *)));
+ connect(widget(),SIGNAL(expanded(KviTalListViewItem *)),this,SLOT(slotItemExpanded(KviTalListViewItem *)));
+ connect(widget(),SIGNAL(collapsed(KviTalListViewItem *)),this,SLOT(slotItemCollapsed(KviTalListViewItem *)));
+ connect(widget(),SIGNAL(rightButtonClicked(KviTalListViewItem *,const QPoint &,int)),this,SLOT(slotRightButtonClicked(KviTalListViewItem *,const QPoint &,int)));
+ connect(widget(),SIGNAL(itemRenamed(KviTalListViewItem *,int,const QString &)),this,SLOT(slotItemRenamed(KviTalListViewItem *,int,const QString &)));
+ return true;
+}
+
+bool KviKvsObject_listview::function_addColumn(KviKvsObjectFunctionCall *c)
+{
+ QString szLabel;
+ kvs_int_t iW;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel)
+ KVSO_PARAMETER("width",KVS_PT_INT,0,iW)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalListView *)object())->addColumn(szLabel,iW);
+ return true;
+}
+/*
+bool KviKvsObject_listview::function_setAcceptDrops(KviKvsObjectFunctionCall *c)
+{
+ bool bEnable;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnable",KVS_PT_BOOLEAN,0,bEnable)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalListView *)object())->setAcceptDrops(bEnable);
+ return true;
+}
+*/
+bool KviKvsObject_listview::function_clear(KviKvsObjectFunctionCall *c)
+{
+ if (widget())
+ ((KviTalListView *)object())->clear();
+ return true;
+}
+
+bool KviKvsObject_listview::function_selectedItem(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setHObject(KviKvsObject_listviewitem::itemToHandle(((KviTalListView *)widget())->selectedItem()));
+ else
+ c->returnValue()->setHObject((kvs_hobject_t)0);
+ return true;
+}
+
+bool KviKvsObject_listview::function_firstChild(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setHObject(KviKvsObject_listviewitem::itemToHandle(((KviTalListView *)widget())->firstChild()));
+ else
+ c->returnValue()->setHObject((kvs_hobject_t)0);
+ return true;
+}
+
+bool KviKvsObject_listview::function_currentItem(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setHObject(KviKvsObject_listviewitem::itemToHandle(((KviTalListView *)widget())->currentItem()));
+ else
+ c->returnValue()->setHObject((kvs_hobject_t)0);
+ return true;
+}
+
+bool KviKvsObject_listview::function_setColumnText(KviKvsObjectFunctionCall *c)
+{
+ 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())((KviTalListView *)widget())->setColumnText(uCol,szText);
+ return true;
+}
+
+bool KviKvsObject_listview::function_setSelectionMode(KviKvsObjectFunctionCall *c)
+{
+ 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"))
+ ((KviTalListView *)widget())->setSelectionMode(KviTalListView::NoSelection);
+ else if(KviQString::equalCI(szMode,"Multi"))
+ ((KviTalListView *)widget())->setSelectionMode(KviTalListView::Multi);
+ else if(KviQString::equalCI(szMode,"Extended"))
+ ((KviTalListView *)widget())->setSelectionMode(KviTalListView::Extended);
+ else if(KviQString::equalCI(szMode,"Single"))
+ ((KviTalListView *)widget())->setSelectionMode(KviTalListView::Single);
+ else c->warning(__tr2qs("Invalid selection mode '%Q'"),&szMode);
+ return true;
+}
+
+bool KviKvsObject_listview::function_setSorting(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iCol;
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("column",KVS_PT_INT,0,iCol)
+ KVSO_PARAMETER("benabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalListView *)widget())->setSorting(iCol,bEnabled);
+ return true;
+}
+
+
+bool KviKvsObject_listview::function_setRootIsDecorated(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalListView *)widget())->setRootIsDecorated(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_listview::function_setAllColumnsShowFocus(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bAllColumnsShowFocus",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if (widget())((KviTalListView *)widget())->setAllColumnsShowFocus(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_listview::function_hideListViewHeader(KviKvsObjectFunctionCall *c)
+{
+// ((KviTalListView *)widget())->header()->hide();
+ return true;
+}
+bool KviKvsObject_listview::function_showListViewHeader(KviKvsObjectFunctionCall *c)
+{
+// ((KviTalListView *)widget())->header()->show();
+ return true;
+}
+bool KviKvsObject_listview::function_listViewHeaderIsVisible(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setBoolean(((KviTalListView *)widget())->header()->isVisible());
+ return true;
+}
+
+bool KviKvsObject_listview::function_itemClickedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("itemClicked",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotClicked(KviTalListViewItem * i)
+{
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(i)));
+ callFunction(this,"itemClickedEvent",0,&params);
+}
+
+bool KviKvsObject_listview::function_selectionChangedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("selectionChanged",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotSelectionChanged(KviTalListViewItem * i)
+{
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(i)));
+ callFunction(this,"selectionChangedEvent",0,&params);
+}
+
+void KviKvsObject_listview::slotMultipleSelectionChanged()
+{
+ KviKvsVariantList params(new KviKvsVariant((kvs_hobject_t)0));
+ callFunction(this,"selectionChangedEvent",0,&params);
+}
+
+
+bool KviKvsObject_listview::function_currentChangedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("currentChanged",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotCurrentChanged(KviTalListViewItem * i)
+{
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(i)));
+ callFunction(this,"currentChangedEvent",0,&params);
+}
+
+
+bool KviKvsObject_listview::function_returnPressedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("returnPressed",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotReturnPressed(KviTalListViewItem * i)
+{
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(i)));
+ callFunction(this,"returnPressedEvent",0,&params);
+}
+
+bool KviKvsObject_listview::function_spacePressedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("spacePressed",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotSpacePressed(KviTalListViewItem * i)
+{
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(i)));
+ callFunction(this,"spacePressedEvent",0,&params);
+}
+
+bool KviKvsObject_listview::function_onItemEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("onItem",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotOnItem(KviTalListViewItem * i)
+{
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(i)));
+ callFunction(this,"onItemEvent",0,&params);
+}
+
+
+bool KviKvsObject_listview::function_itemExpandedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("itemExpanded",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotItemExpanded(KviTalListViewItem * i)
+{
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(i)));
+ callFunction(this,"itemExpandedEvent",0,&params);
+}
+
+bool KviKvsObject_listview::function_itemCollapsedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("itemCollapsed",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotItemCollapsed(KviTalListViewItem * i)
+{
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(i)));
+ callFunction(this,"itemCollapsedEvent",0,&params);
+}
+
+bool KviKvsObject_listview::function_rightButtonClickedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("rightButtonClicked",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotRightButtonClicked(KviTalListViewItem * i,const QPoint &coor, int col)
+{
+ KviKvsVariant *xpos=new KviKvsVariant((kvs_int_t)coor.x());
+ KviKvsVariant *ypos=new KviKvsVariant((kvs_int_t)coor.y());
+ KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col);
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(i)),xpos,ypos,column);
+ callFunction(this,"rightButtonClickedEvent",0,&params);
+}
+
+bool KviKvsObject_listview::function_itemRenamedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("itemRenamed",c,c->params());
+ return true;
+}
+
+void KviKvsObject_listview::slotItemRenamed(KviTalListViewItem *item,int col,const QString & szText)
+{
+ KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col);
+ KviKvsVariant *txt=new KviKvsVariant(szText);
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(item)),column,txt);
+ callFunction(this,"itemRenamedEvent",0,&params);
+}
+void KviKvsObject_listview::fileDropped(QString &szFile,KviTalListViewItem *item)
+{
+ KviKvsVariant *file=new KviKvsVariant(szFile);
+ KviKvsVariantList params(new KviKvsVariant(KviKvsObject_listviewitem::itemToHandle(item)),file);
+ callFunction(this,"fileDroppedEvent",0,&params);
+}
+
+KviKvsMdmListView::KviKvsMdmListView(QWidget * par,const char * name,KviKvsObject_listview *parent)
+:KviTalListView(par)
+{
+ m_pParentScript=parent;
+ setAcceptDrops(true);
+ viewport()->setAcceptDrops( TRUE );
+
+}
+KviKvsMdmListView::~KviKvsMdmListView()
+{
+}
+
+void KviKvsMdmListView::contentsDragEnterEvent( QDragEnterEvent *e )
+{
+ if ( !KviUriDrag::canDecode(e))
+ {
+ e->ignore();
+ return;
+ }
+
+}
+
+
+void KviKvsMdmListView::contentsDropEvent(QDropEvent *e)
+{
+ QStringList list;
+ if(KviUriDrag::decodeLocalFiles(e,list))
+ {
+ if(!list.isEmpty())
+ {
+ QStringList::ConstIterator it = list.begin(); //kewl ! :)
+ for( ; it != list.end(); ++it )
+ {
+ QString tmp = *it; //wow :)
+ #ifndef COMPILE_ON_WINDOWS
+ if(tmp[0] != '/')tmp.prepend("/"); //HACK HACK HACK for Qt bug (?!?)
+ #endif
+ KviTalListViewItem *i = itemAt( contentsToViewport(e->pos()) );
+ m_pParentScript->fileDropped(tmp,i);
+ }
+ }
+ }
+
+}
+#include "m_class_listview.moc"
diff --git a/src/modules/objects/class_listview.h b/src/modules/objects/class_listview.h
new file mode 100644
index 00000000..7849f36c
--- /dev/null
+++ b/src/modules/objects/class_listview.h
@@ -0,0 +1,102 @@
+#ifndef _CLASS_LISTVIEW_H_
+#define _CLASS_LISTVIEW_H_
+//=================================================================================
+//
+// File : class_listview.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) 1999-2006 Szymon Stefanek (pragma at kvirc dot net)
+// Copyright (C) 2005-2006 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 "kvi_tal_listview.h"
+#include "kvi_draganddrop.h"
+#include "class_widget.h"
+#include "class_listviewitem.h"
+
+#include "object_macros.h"
+
+class KviKvsObject_listview : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_listview)
+
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+ void fileDropped(QString &,KviTalListViewItem *);
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool function_addColumn(KviKvsObjectFunctionCall *c);
+ bool function_setColumnText(KviKvsObjectFunctionCall *c);
+ bool function_takeItem(KviKvsObjectFunctionCall *c);
+ bool function_setSorting(KviKvsObjectFunctionCall *c);
+ bool function_setRootIsDecorated(KviKvsObjectFunctionCall *c);
+ bool function_clear(KviKvsObjectFunctionCall *c);
+ bool function_setAllColumnsShowFocus(KviKvsObjectFunctionCall *c);
+ bool function_itemClickedEvent(KviKvsObjectFunctionCall *c);
+ bool function_selectionChangedEvent(KviKvsObjectFunctionCall *c);
+ bool function_currentChangedEvent(KviKvsObjectFunctionCall *c);
+ bool function_returnPressedEvent(KviKvsObjectFunctionCall *c);
+ bool function_spacePressedEvent(KviKvsObjectFunctionCall *c);
+ bool function_onItemEvent(KviKvsObjectFunctionCall *c);
+ bool function_itemExpandedEvent(KviKvsObjectFunctionCall *c);
+ bool function_itemCollapsedEvent(KviKvsObjectFunctionCall *c);
+ bool function_itemRenamedEvent(KviKvsObjectFunctionCall *c);
+ bool function_rightButtonClickedEvent(KviKvsObjectFunctionCall *c);
+ bool function_selectedItem(KviKvsObjectFunctionCall *c);
+ bool function_currentItem(KviKvsObjectFunctionCall *c);
+ bool function_setSelectionMode(KviKvsObjectFunctionCall *c);
+ bool function_firstChild(KviKvsObjectFunctionCall *c);
+ bool function_listViewHeaderIsVisible(KviKvsObjectFunctionCall *c);
+ bool function_showListViewHeader(KviKvsObjectFunctionCall *c);
+ bool function_hideListViewHeader(KviKvsObjectFunctionCall *c);
+
+ bool function_setAcceptDrops(KviKvsObjectFunctionCall *c);
+
+protected slots:
+ void slotClicked(KviTalListViewItem *);
+ void slotSelectionChanged(KviTalListViewItem *);
+ void slotMultipleSelectionChanged();
+ void slotCurrentChanged(KviTalListViewItem *);
+ void slotReturnPressed(KviTalListViewItem *);
+ void slotSpacePressed(KviTalListViewItem *);
+ void slotOnItem(KviTalListViewItem *);
+ void slotItemExpanded(KviTalListViewItem *);
+ void slotItemCollapsed(KviTalListViewItem *);
+ void slotItemRenamed(KviTalListViewItem *,int,const QString &);
+ void slotRightButtonClicked(KviTalListViewItem * i,const QPoint &coor, int col);
+};
+
+class KviKvsMdmListView : public KviTalListView
+{
+ Q_OBJECT
+public:
+ KviKvsMdmListView(QWidget * par,const char * name,KviKvsObject_listview *);
+
+ virtual ~KviKvsMdmListView();
+protected:
+ KviKvsObject_listview *m_pParentScript;
+ void contentsDropEvent(QDropEvent *e);
+ void contentsDragEnterEvent( QDragEnterEvent *e );
+
+};
+#endif //!_CLASS_LISTVIEW_H_
diff --git a/src/modules/objects/class_listviewitem.cpp b/src/modules/objects/class_listviewitem.cpp
new file mode 100644
index 00000000..31df9020
--- /dev/null
+++ b/src/modules/objects/class_listviewitem.cpp
@@ -0,0 +1,421 @@
+//mdm:
+// File : class_ListViewItem.h
+// Creation date : Thu Feb 1 14:39:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_listviewitem.h"
+#include "class_pixmap.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+
+
+/*
+ @doc: listviewitem
+ @keyterms:
+ listview listviewitem class
+ @title:
+ listviewitem 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(<column:integer>,<text:string>)
+ Sets the text in column column to text, if column is a valid column number and text is different from the existing text.
+
+ !fn: <string> $text(<column:integer>)
+ Returs the text of the specified column.
+
+ !fn: $setPixmap(<column:integer>,<pixmap:hobject or imageID>)
+ 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: $setRenameEnabled(<col:integer>,<bEnabled:boolean>)
+ If b is TRUE (1), this item can be in-place renamed in the column col by the user; otherwise it cannot be renamed in-place.
+
+ !fn: $setEnabled(<bEnabled:boolean>)
+ Enables or disables the item
+
+ !fn: $isEnabled()
+ Returns $true if this item is enabled and $false otherwise
+
+ !fn: $setOpen(<bOpen:boolean>)
+ Opens or closes the item to show its children items
+
+ !fn: $isOpen()
+ Returns the open state of this item
+
+ !fn: $setCheckable(<bCheckable:boolean>)
+ 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(<bChecked:boolean>)
+ 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: <listviewitem> $firstChild()
+ Returns the first child item of this listviewitem or $null if this item has no children.
+
+ !fn: <listviewitem> $nextSibling()
+ Returns the next sibling item of this listviewitem or $null if there are no sibling items.
+ Next sibling stands for the item at the same tree level coming just after :)
+*/
+
+
+//===========================================================================================
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_listviewitem,"listviewitem","object")
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"setText",function_setText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"text",function_text)
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"setPixmap",function_setPixmap);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"setRenameEnabled",function_setRenameEnabled);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"setEnabled",function_setEnabled);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"isEnabled",function_isEnabled);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"setOpen",function_setOpen);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"isOpen",function_isOpen);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"setCheckable",function_setCheckable);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"isCheckable",function_isCheckable);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"setChecked",function_setChecked);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"isChecked",function_isChecked);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"firstChild",function_firstChild);
+ KVSO_REGISTER_HANDLER(KviKvsObject_listviewitem,"nextSibling",function_nextSibling);
+KVSO_END_REGISTERCLASS(KviKvsObject_listviewitem)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_listviewitem,KviKvsObject)
+
+ m_pListViewItem = 0;
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_listviewitem)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_listviewitem)
+
+ if(m_pListViewItem)delete m_pListViewItem;
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_listviewitem)
+
+bool KviKvsObject_listviewitem::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ if (!parentObject())
+ {
+ pContext->error(__tr2qs("The listviewitem cannot be parentless"));
+ return false;
+ }
+ if(parentObject()->inherits("KviKvsObject_listviewitem"))
+ {
+ m_pListViewItem = new KviKvsMdmStandardListViewItem(this,((KviKvsObject_listviewitem *)parentObject())->m_pListViewItem);
+ } else {
+ if(parentObject()->inherits("KviKvsObject_listview"))
+ m_pListViewItem = new KviKvsMdmStandardListViewItem(this,((KviTalListView *)parentScriptWidget()));
+ else {
+ pContext->error(__tr2qs("The parent of the listviewitem must be either another listviewitem or a listview"));
+ return false;
+ }
+ }
+ return true;
+}
+
+void KviKvsObject_listviewitem::childDestroyed()
+{
+ if(m_pListViewItem == 0)return;
+ m_pListViewItem = 0;
+ die();
+}
+
+KviKvsMdmStandardListViewItem::KviKvsMdmStandardListViewItem(KviKvsObject_listviewitem * ob,KviTalListView * par)
+:KviTalListViewItem(par), m_pMasterObject(ob)
+{
+}
+
+KviKvsMdmStandardListViewItem::KviKvsMdmStandardListViewItem(KviKvsObject_listviewitem * ob,KviTalListViewItem * par)
+:KviTalListViewItem(par), m_pMasterObject(ob)
+{
+}
+
+KviKvsMdmStandardListViewItem::~KviKvsMdmStandardListViewItem()
+{
+ if(m_pMasterObject)m_pMasterObject->childDestroyed();
+}
+
+
+
+KviKvsMdmCheckListViewItem::KviKvsMdmCheckListViewItem(KviKvsObject_listviewitem * ob,KviTalListView * par)
+:KviTalCheckListItem(par,QString::null,KviTalCheckListItem::CheckBox), m_pMasterObject(ob)
+{
+}
+
+KviKvsMdmCheckListViewItem::KviKvsMdmCheckListViewItem(KviKvsObject_listviewitem * ob,KviTalListViewItem * par)
+:KviTalCheckListItem(par,QString::null,KviTalCheckListItem::CheckBox), m_pMasterObject(ob)
+{
+}
+
+KviKvsMdmCheckListViewItem::~KviKvsMdmCheckListViewItem()
+{
+ if(m_pMasterObject)m_pMasterObject->childDestroyed();
+}
+
+
+kvs_hobject_t KviKvsObject_listviewitem::itemToHandle(KviTalListViewItem * it)
+{
+ if(!it)return (kvs_hobject_t)0;
+ KviKvsObject_listviewitem * pObject;
+ if(it->rtti() == 1)pObject = ((KviKvsMdmCheckListViewItem *)it)->masterObject();
+ else pObject = ((KviKvsMdmStandardListViewItem *)it)->masterObject();
+ if(!pObject)return (kvs_hobject_t)0;
+ return pObject->handle();
+}
+
+
+bool KviKvsObject_listviewitem::function_setText(KviKvsObjectFunctionCall *c)
+{
+ 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_pListViewItem)
+ m_pListViewItem->setText(uCol,szText);
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_firstChild(KviKvsObjectFunctionCall *c)
+{
+ if(m_pListViewItem)
+ c->returnValue()->setHObject(itemToHandle(m_pListViewItem->firstChild()));
+ else
+ c->returnValue()->setHObject((kvs_hobject_t)0);
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_nextSibling(KviKvsObjectFunctionCall *c)
+{
+ if(m_pListViewItem)
+ c->returnValue()->setHObject(itemToHandle(m_pListViewItem->nextSibling()));
+ else
+ c->returnValue()->setHObject((kvs_hobject_t)0);
+ return true;
+}
+
+
+bool KviKvsObject_listviewitem::function_setRenameEnabled(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uCol;
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(m_pListViewItem)
+ m_pListViewItem->setRenameEnabled(uCol,bEnabled);
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_setEnabled(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(m_pListViewItem)
+ m_pListViewItem->setEnabled(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_isEnabled(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pListViewItem)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pListViewItem->isEnabled());
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_setOpen(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(m_pListViewItem)
+ m_pListViewItem->setOpen(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_isOpen(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pListViewItem)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pListViewItem->isOpen());
+ return true;
+}
+
+
+bool KviKvsObject_listviewitem::function_setChecked(KviKvsObjectFunctionCall *c)
+{
+ bool bChecked;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bChecked",KVS_PT_BOOL,0,bChecked)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pListViewItem)return true;
+ if(m_pListViewItem->rtti() != 1)return true; // not a QCheckListItem
+ ((KviKvsMdmCheckListViewItem *)m_pListViewItem)->setOn(bChecked);
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_isChecked(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pListViewItem)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ if(m_pListViewItem->rtti() != 1)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(((KviKvsMdmCheckListViewItem *)m_pListViewItem)->isOn());
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_setCheckable(KviKvsObjectFunctionCall *c)
+{
+ bool bCheckable;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bCheckable",KVS_PT_BOOL,0,bCheckable)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pListViewItem)return true;
+ if(bCheckable)
+ {
+ if(m_pListViewItem->rtti() == 1)return true; // a QCheckListItem already
+ KviTalListViewItem * pParent = m_pListViewItem->parent();
+ KviTalListView * pLV = (KviTalListView *)m_pListViewItem->listView();
+ // swap the items, so we don't die now
+ KviTalListViewItem * pThis = m_pListViewItem;
+ m_pListViewItem = 0;
+ delete pThis;
+ if(pParent)
+ m_pListViewItem = new KviKvsMdmCheckListViewItem(this,pParent);
+ else
+ m_pListViewItem = new KviKvsMdmCheckListViewItem(this,pLV);
+ } else {
+ if(m_pListViewItem->rtti() != 1)return true; // not a QCheckListItem yet
+ KviTalListViewItem * pParent = m_pListViewItem->parent();
+ KviTalListView * pLV = (KviTalListView *)m_pListViewItem->listView();
+ // swap the items, so we don't die now
+ KviTalListViewItem * pThis = m_pListViewItem;
+ m_pListViewItem = 0;
+ delete pThis;
+ if(pParent)
+ m_pListViewItem = new KviKvsMdmStandardListViewItem(this,pParent);
+ else
+ m_pListViewItem = new KviKvsMdmStandardListViewItem(this,pLV);
+ }
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_isCheckable(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pListViewItem)
+ {
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ c->returnValue()->setBoolean(m_pListViewItem->rtti() == 1);
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_text(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uCol;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol)
+ KVSO_PARAMETERS_END(c)
+ if(m_pListViewItem)
+ c->returnValue()->setString(m_pListViewItem->text(uCol));
+ return true;
+}
+
+bool KviKvsObject_listviewitem::function_setPixmap(KviKvsObjectFunctionCall *c)
+{
+ 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->isHObject())
+ {
+ vPixmap->asHObject(obHpixmap);
+ obPixmap=KviKvsKernel::instance()->objectController()->lookupObject(obHpixmap);
+ if (!obPixmap->inherits("KviKvsObject_pixmap"))
+ {
+ c->warning(__tr2qs("Pixmap object or image Id required"));
+ return true;
+ }
+ pix=((KviKvsObject_pixmap *)obPixmap)->getPixmap();
+ } else {
+ QString szPix;
+ vPixmap->asString(szPix);
+ pix=g_pIconManager->getImage(szPix);
+ if(!pix)
+ {
+ c->warning(__tr2qs("Error occured: the suitable file '%Q' is not of the correct format or it is not a valid icon number."),&szPix);
+ return true;
+ }
+ }
+ m_pListViewItem->setPixmap(uCol,*pix);
+ return true;
+}
+
+#include "m_class_listviewitem.moc"
diff --git a/src/modules/objects/class_listviewitem.h b/src/modules/objects/class_listviewitem.h
new file mode 100644
index 00000000..eb806324
--- /dev/null
+++ b/src/modules/objects/class_listviewitem.h
@@ -0,0 +1,88 @@
+#ifndef _CLASS_LISTVIEWITEM_H_
+#define _CLASS_LISTVIEWITEM_H_
+//mdm:
+// File : class_ListViewItem.h
+// Creation date : Thu Feb 1 14:39:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_tal_listview.h"
+#include "class_widget.h"
+
+
+
+#include "object_macros.h"
+
+class KviKvsObject_listviewitem : public KviKvsObject
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_listviewitem)
+ void childDestroyed();
+protected:
+ KviTalListViewItem * m_pListViewItem;
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+protected:
+ bool function_setText(KviKvsObjectFunctionCall *c);
+ bool function_insertItem(KviKvsObjectFunctionCall *c);
+ bool function_setPixmap(KviKvsObjectFunctionCall *c);
+ bool function_setRenameEnabled(KviKvsObjectFunctionCall *c);
+ bool function_setEnabled(KviKvsObjectFunctionCall *c);
+ bool function_isEnabled(KviKvsObjectFunctionCall *c);
+ bool function_setOpen(KviKvsObjectFunctionCall *c);
+ bool function_isOpen(KviKvsObjectFunctionCall *c);
+ bool function_text(KviKvsObjectFunctionCall *c);
+ bool function_setCheckable(KviKvsObjectFunctionCall *c);
+ bool function_isCheckable(KviKvsObjectFunctionCall *c);
+ bool function_setChecked(KviKvsObjectFunctionCall *c);
+ bool function_isChecked(KviKvsObjectFunctionCall *c);
+ bool function_firstChild(KviKvsObjectFunctionCall *c);
+ bool function_nextSibling(KviKvsObjectFunctionCall *c);
+public:
+ static kvs_hobject_t itemToHandle(KviTalListViewItem * it);
+};
+
+
+
+class KviKvsMdmStandardListViewItem : public KviTalListViewItem
+{
+public:
+ KviKvsMdmStandardListViewItem(KviKvsObject_listviewitem * ob,KviTalListView * par);
+ KviKvsMdmStandardListViewItem(KviKvsObject_listviewitem * ob,KviTalListViewItem * par);
+ virtual ~KviKvsMdmStandardListViewItem();
+protected:
+ KviKvsObject_listviewitem * m_pMasterObject;
+public:
+ KviKvsObject_listviewitem * masterObject(){ return m_pMasterObject; }
+};
+
+class KviKvsMdmCheckListViewItem : public KviTalCheckListItem
+{
+public:
+ KviKvsMdmCheckListViewItem(KviKvsObject_listviewitem * ob,KviTalListView * par);
+ KviKvsMdmCheckListViewItem(KviKvsObject_listviewitem * ob,KviTalListViewItem * par);
+ virtual ~KviKvsMdmCheckListViewItem();
+protected:
+ KviKvsObject_listviewitem * m_pMasterObject;
+public:
+ KviKvsObject_listviewitem * masterObject(){ return m_pMasterObject; }
+};
+
+#endif // !_CLASS_LISTVIEWITEM_H_
diff --git a/src/modules/objects/class_mainwindow.cpp b/src/modules/objects/class_mainwindow.cpp
new file mode 100644
index 00000000..e30f480b
--- /dev/null
+++ b/src/modules/objects/class_mainwindow.cpp
@@ -0,0 +1,158 @@
+//mdm:
+// File : class_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) 1999-2005 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_tal_mainwindow.h"
+#include "class_mainwindow.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.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(<widget:object>)
+ Sets the central widget for the main window to <wid>.
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_mainwindow,"mainwindow","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_mainwindow,"setCentralWidget",functionsetCentralWidget)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mainwindow,"setDockEnabled",functionsetDockEnabled)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mainwindow,"isDockEnabled",functionisDockEnabled)
+
+KVSO_END_REGISTERCLASS(KviKvsObject_mainwindow)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_mainwindow,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_mainwindow)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_mainwindow)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_mainwindow)
+
+bool KviKvsObject_mainwindow::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new KviTalMainWindow(parentScriptWidget(), name()), true);
+ return true;
+}
+
+bool KviKvsObject_mainwindow::functionsetCentralWidget(KviKvsObjectFunctionCall *c)
+{
+ 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("Widget parameter is not an object"));
+ return true;
+ }
+ if (!pObject->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!pObject->object()->inherits("KviKvsObject_widget"))
+ {
+ c->warning(__tr2qs("Widget object required"));
+ return TRUE;
+ }
+ if(widget()) ((KviTalMainWindow *)widget())->setCentralWidget(((QWidget *)(pObject->object())));
+ return true;
+}
+bool KviKvsObject_mainwindow::functionsetDockEnabled(KviKvsObjectFunctionCall *c)
+{
+ QString szDockarea;
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("dock area",KVS_PT_STRING,0,szDockarea)
+ KVSO_PARAMETER("bool enabled",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ {
+#ifndef COMPILE_USE_QT4
+ if(KviQString::equalCI(szDockarea,"Top"))
+ ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockTop,bFlag);
+ else if(KviQString::equalCI(szDockarea,"Left"))
+ ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockLeft,bFlag);
+ else if(KviQString::equalCI(szDockarea,"Right"))
+ ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockRight,bFlag);
+ else if(KviQString::equalCI(szDockarea,"Bottom"))
+ ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockBottom,bFlag);
+ else if(KviQString::equalCI(szDockarea,"Minimized"))
+ ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockMinimized,bFlag);
+ else if(KviQString::equalCI(szDockarea,"TornOff"))
+ ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockTornOff,bFlag);
+ else if(KviQString::equalCI(szDockarea,"Unmanaged"))
+ ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockUnmanaged,bFlag);
+ else c->warning(__tr2qs("Unknown dock area '%Q'"),&szDockarea);
+#endif
+ }
+ return true;
+
+}
+bool KviKvsObject_mainwindow::functionisDockEnabled(KviKvsObjectFunctionCall *c)
+{
+
+ QString szDockarea;
+ bool bFlag = false;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("dock_area",KVS_PT_STRING,0,szDockarea)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+#ifndef COMPILE_USE_QT4
+ if(KviQString::equalCI(szDockarea,"Top")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockTop);
+ else if(KviQString::equalCI(szDockarea,"Left")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockLeft);
+ else if(KviQString::equalCI(szDockarea,"Right")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockRight);
+ else if(KviQString::equalCI(szDockarea,"Bottom"))bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockBottom);
+ else if(KviQString::equalCI(szDockarea,"Minimized")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockMinimized);
+ else if(KviQString::equalCI(szDockarea,"TornOff")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockTornOff);
+ else if(KviQString::equalCI(szDockarea,"Unmanaged")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockUnmanaged);
+ else
+ {
+ c->warning(__tr2qs("Unknown dock area '%Q'"),&szDockarea);
+ return true;
+ }
+#endif
+ c->returnValue()->setBoolean(bFlag);
+ return true;
+
+}
diff --git a/src/modules/objects/class_mainwindow.h b/src/modules/objects/class_mainwindow.h
new file mode 100644
index 00000000..7afddf8c
--- /dev/null
+++ b/src/modules/objects/class_mainwindow.h
@@ -0,0 +1,47 @@
+#ifndef _CLASS_MAINWINDOW_H_
+#define _CLASS_MAINWINDOW_H_
+//
+// File : class_mainwindow.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) 1999-2005 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 <qmainwindow.h>
+#include "class_widget.h"
+#include "object_macros.h"
+
+class KviKvsObject_mainwindow : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_mainwindow)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionsetCentralWidget(KviKvsObjectFunctionCall *c);
+ bool functionsetDockEnabled(KviKvsObjectFunctionCall *c);
+ bool functionisDockEnabled(KviKvsObjectFunctionCall *c);
+
+};
+
+
+#endif //!_CLASS_MAINWINDOW_H_
+
diff --git a/src/modules/objects/class_menubar.cpp b/src/modules/objects/class_menubar.cpp
new file mode 100644
index 00000000..90ad0e7d
--- /dev/null
+++ b/src/modules/objects/class_menubar.cpp
@@ -0,0 +1,76 @@
+//
+// File : class_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 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_menubar.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+
+/*
+ @doc: menubar
+ @title:
+ menubar class
+ @type:
+ class
+ @short:
+ A menu bar object implementation
+ @inherits:
+ [class]object[/class]
+ [class]widget[/class]
+ @description:
+
+ @functions:
+ !fn: <integer> $insertItem(<text:string>)
+ Returns an integer that identifies the inserted item.
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_menubar,"menubar","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_menubar,"inserItem",functionInsertItem)
+KVSO_END_REGISTERCLASS(KviKvsObject_menubar)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_menubar,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_menubar)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_menubar)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_menubar)
+
+bool KviKvsObject_menubar::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QMenuBar(parentScriptWidget(), name()));
+ return true;
+}
+
+bool KviKvsObject_menubar::functionInsertItem(KviKvsObjectFunctionCall *c)
+{
+ QString szItem;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("item",KVS_PT_STRING,0,szItem)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QMenuBar *)widget())->insertItem(szItem);
+ return true;
+}
diff --git a/src/modules/objects/class_menubar.h b/src/modules/objects/class_menubar.h
new file mode 100644
index 00000000..c959d272
--- /dev/null
+++ b/src/modules/objects/class_menubar.h
@@ -0,0 +1,40 @@
+#ifndef _CLASS_MENUBAR_H_
+#define _CLASS_MENUBAR_H_
+//
+// File : class_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 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 <qmenubar.h>
+#include "class_widget.h"
+#include "object_macros.h"
+
+class KviKvsObject_menubar : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_menubar)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionInsertItem(KviKvsObjectFunctionCall *c);
+};
+#endif // !_CLASS_MENUBAR_H_
diff --git a/src/modules/objects/class_multilineedit.cpp b/src/modules/objects/class_multilineedit.cpp
new file mode 100644
index 00000000..6b2f8af9
--- /dev/null
+++ b/src/modules/objects/class_multilineedit.cpp
@@ -0,0 +1,1217 @@
+//vim: ts=8
+// File : class_multilineedit.cpp
+// Creation date : Mon Feb 19 00:45:34 CET by Krzysztof Godlewski
+//
+// Modification date: Thu 15 Feb 2005 22:00 :00
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_error.h"
+#include "kvi_debug.h"
+#include "kvi_locale.h"
+#include "kvi_malloc.h"
+#include <qfile.h>
+#ifdef COMPILE_USE_QT4
+ #include <q3multilineedit.h>
+#include <QTextStream>
+
+#include <q3stylesheet.h>
+#define KviTalMultiLineEdit Q3MultiLineEdit
+#define QTEXTEDIT_AUTO_ALL Q3TextEdit::AutoAll
+#define QTEXTEDIT_AUTO_NONE Q3TextEdit::AutoNone
+#define QTEXTEDIT_AUTO_BULLET_LIST Q3TextEdit::AutoBulletList
+
+#else
+ #include <qtextstream.h>
+
+ #include <qmultilineedit.h>
+ #define KviTalMultiLineEdit QMultiLineEdit
+ #define QTEXTEDIT_AUTO_ALL QTextEdit::AutoAll
+ #define QTEXTEDIT_AUTO_NONE QTextEdit::AutoNone
+ #define QTEXTEDIT_AUTO_BULLET_LIST QTextEdit::AutoBulletList
+
+#endif
+
+
+#include "class_multilineedit.h"
+
+
+//->Tables for Text Format
+static char * const mod_tbl[] = {
+ "PlainText",
+ "RichText",
+ "AutoText",
+ "LogText"
+ };
+
+static int mod_cod[] = {
+ Qt::PlainText,
+ Qt::RichText,
+ Qt::AutoText,
+ Qt::LogText
+ };
+
+#define mod_num (sizeof(mod_tbl) / sizeof(mod_tbl[0]))
+
+
+
+/*
+ @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: <string> $textLine(<line:integer>)
+ Returns the string at line <line>. Note that it can be an empty
+ string.
+ !fn: $insertLine(<text:string>, <line:integer>)
+ Inserts <text> at line number <line>. If line is less than
+ zero, or larger than the number of rows, the new text is
+ put at the end. If txt contains newline characters, several
+ lines are inserted. The <line> parameter is optional. If it is
+ ommited, the line is put at end.
+ !fn: $removeLine(<line:integer>)
+ Removes line number <line>.
+ !fn: $insertAt(<txt:string>, <line:uinteger>, <col:uinteger>)
+ Inserts txt at line number line, after character number col in
+ the line. If txt contains newline characters, new lines are
+ inserted.
+ !fn: <integer> $numLines()
+ Returns number of lines in the widget.
+ !fn: $setCursorPosition(<line:integer>, <col:uinteger>, <mark:boolean>)
+ Sets the cursor position to character number col in line
+ number line. The parameters are adjusted to lie within the
+ legal range.[br]
+ If mark is 1, the selection is cleared. otherwise it
+ is extended
+ !fn: <line,col:integer> $cursorPosition()
+ Returns current cursor position in "<line:uinteger>, <col:uinteger>" format.
+ !fn: $setReadOnly(<bReadOnly:boolean>)
+ Sets the editor to be read-only if bReadOnly is 1 or
+ removes the read-only status is ReadOnly is 0
+ !fn: <boolean> $atBeginning()
+ Returns 1(TRUE) if the cursor is placed at the beginning of the text; otherwise returns 0(FALSE).
+ !fn: <boolean> $atEnd()
+ Returns 1(TRUE) if the cursor is placed at the end of the text; otherwise returns 0(FALSE).
+ !fn: $setWordWrap(<wrap_mode:string>)
+ 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: <string> $wordWrap()
+ Returns the word wrap mode. NoWrap, WidgetWidth, FixedPixelWidth, FixedColumnWidth.
+ !fn: <string> $text()
+ Returns the multiline edit's text.
+ !fn: <integer> $length()
+ Returns the number of characters in the text This function ignores newlines.
+ !fn: $setMaxLines(<mac_lines:integer>)
+ Sets the max number of the lines to <a>
+ !fn: <integer> $maxLines()
+ Returns the max number of the lines in the multiline edit.
+ !fn: $insert(<text:string>)
+ Inserts text at the current cursor position.
+ !fn: $append(<text:string>)
+ 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(<font_family:string>)
+ Sets the font family of the current format to fontFamily.
+ !fn: $setItalic(<bItalic:boolean>)
+ 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(<bBold:boolean>)
+ 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(<bUnderline:boolean>)
+ 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: <boolean> $italic()
+ Returns 1(TRUE) if the current format is italic; otherwise returns 0(FALSE).
+ !fn: <boolean> $bold()
+ Returns 1(TRUE) if the current format is bold; otherwise returns 0(FALSE).
+ !fn: <boolean> $underline()
+ Returns 1(TRUE) if the current format is underline; otherwise returns 0(FALSE).
+ !fn: $zoomIn(<zoom_range:integer>)
+ Zooms in on the text by making the base font size range points larger.
+ !fn: $zoomOut(<zoom_range:integer>)
+ Zooms out on the text by making the base font size range points smaller.
+ !fn: $zoomTo(<zoom_size:integer>)
+ Zooms the text by making the base font size <size> points.
+ !fn: $undo()
+ Undoes the last operation.
+ !fn: $redo()
+ Redoes the last operation.
+ !fn: $clear()
+ Deletes all the text in the multiline edit.
+ !fn: $setUndoRedoEnabled(<bUndoRedo:boolean>)
+ Sets whether undo/redo is enabled to the bool value.
+ !fn: $setUndoDepth(<undo_depth:integer>)
+ Sets the depth of the undo history to x.
+ !fn: <boolean> $isUndoRedoEnabled()
+ Returns 1 (TRUE) if undo/redo is enabled; otherwise returns 0 (FALSE).
+ !fn: <integer> $undoDepth()
+ Returns the depth of the undo history.
+ !fn: $indent()
+ Re-indents the current paragraph.
+ !fn: $setText(<txt:string>)
+ Sets the text edit's text to txt.
+ !fn: $setPointSize(<point_size:integer))
+ Sets the point size of the font.
+ // findme
+ !fn: $setColor(<rgb_value>)
+ Sets the foreground color of this widget to <rgb_value>: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.
+ !fn: $setModified(<bModified:boolean>)
+ Sets whether the document has been modified by the user. Valid Values are 1(TRUE) or 0(FALSE)
+ !fn: $insertParagraph(<text:string>,<paragraph:integer>)
+ Inserts text as a new paragraph at position <paragraph>.
+ !fn: $removeParagraph(<paragraph:integer>)
+ Removes the paragraph <paragraph>.
+ !fn: $setLinkUnderline(<bLinkUnderline:boolean>)
+ Sets to 1 if you want that hypertext links will be underlined; otherwise sets to 0.
+ !fn: $setOverwriteMode(<bOverwrite:boolean>)
+ Sets the Multilineedit edit's overwrite mode to b (1=Enabled or 0=Disabled) .
+ !fn: $setTextFormat(<textformat:string>)
+ Sets the text format. Correct values are RichText, PlainText, LogText or AutoText.
+ !fn: <string> $textFormat()
+ Returns the text format: rich text, plain text, log text or auto text.
+ // findme
+ !fn: $setParagraphBackgroundColor(<paragraph:integer>,<exadecimal color value>)
+ Sets the background color of the paragraph <paragraph> to color value specified.[br]
+ Example: %mymultiline->$setParagraphBackgroundColor(2,0C686F)
+ !fn: $clearParagraphBackground(<paragraph:integer>)
+ Clear the background color of the paragraph <paragraph>.
+ !fn: $loadFile(<path:string>)
+ Load the file specified in the <path>, also html files.
+ !fn: <boolean> $isUndoAvailable ()
+ Returns 1(TRUE) if undo is available; otherwise returns 0(FALSE).
+ !fn: <boolean> $isRedoAvailable ()
+ Returns 1(TRUE) if redo is available; otherwise returns 0(FALSE).
+ !fn: $setAlignment(<alignment:string>)
+ Sets the alignment of the current paragraph to <alignment>. Valid values are:[br]
+ - AlignAuto - Aligns according to the language.[br]
+ - Qt::AlignLeft - Aligns with the left edge.[br]
+ - Qt::AlignRight - Aligns with the right edge.[br]
+ - Qt::AlignCenter - Centers in both dimensions.
+ !fn: $setVerticalAlignment(<vertical_alignment:string>)
+ Sets the vertical alignment of the current format to <Valignemnt>. Valid Values are:[br]
+ - AlignNormal - Normal alignment.[br]
+ - AlignSuperScript - Superscript.[br]
+ - AlignSubScript - Subscript.
+ !fn: $setAutoFormatting(<afvalue:string>)
+ Sets the enabled set of auto formatting features to afvalue. Valid values are: [br]
+ - AutoNone - Do not perform any automatic formatting[br]
+ - AutoBulletList - Only automatically format bulletted lists[br]
+ - AutoAll - Apply all available autoformatting
+ !fn: $setWrapPolicy(<wraph_policy:string>)
+ Sets the word wrap policy, at <wrpl>. Valid values are:[br]
+ - AtWhiteSpace - Don't use this deprecated value (it is a synonym for AtWordBoundary which you should use instead).[br]
+ - Anywhere - Break anywhere, including within words.[br]
+ - AtWordBoundary - Break lines at word boundaries, e.g. spaces or newlines[br]
+ - AtWordOrDocumentBoundary - Break lines at whitespace, e.g. spaces or newlines if possible. Break it anywhere otherwise.[br]
+ !fn: <integer> $paragraphs()
+ Returns the number of paragraphs in the text.
+ !fn: <integer> $lines()
+ Returns the number of lines in the multilineedit.
+ !fn: <integer> $linesOfParagraph(<paragraph:integer>)
+ Returns the number of lines in paragraph <paragraph>, or -1 if there is no paragraph with index <paragraph>.
+ !fn: <integer> $lineOfChar(<paragraph:integer>,<index:integer>)
+ 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: <integer> $paragraphLenght(<paragraph:integer>)
+ Returns the length of the paragraph par, or -1 if there is no paragraph with index par.
+
+*/
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_mledit,"multilineedit","widget")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"textLine", functionTextLine)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"insertLine", functionInsertLine)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"removeLine", functionRemoveLine)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"insertAt", functionInsertAt)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"numLines", functionNumLines)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setCursorPosition", functionSetCursorPosition)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"cursorPosition", functionCursorPosition)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"atBeginning", functionAtBeginning)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"atEnd", functionAtEnd)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setWordWrap", functionSetWordWrap)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"wordWrap", functionWordWrap)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"text", functionText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"length", functionLength);
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setMaxLines", functionSetMaxLines)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"maxLines", functionMaxLines)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"insert", functionInsert)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"append", functionAppend)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"copy", functionCopy)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"cut", functionCut)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"paste", functionPaste)
+
+//->Set Style
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setFamily" , functionsetFamily)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setItalic", functionsetItalic)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setBold", functionsetBold)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setUnderline", functionsetUnderline)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"italic", functionitalic)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"bold", functionbold)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"underline", functionunderline)
+//->Zoom In, Out, To
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"zoomIn", functionzoomIn)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"zoomOut", functionzoomOut)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"zoomTo", functionzoomTo)
+//->Undo & Redo
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"undo", functionundo)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"redo", functionredo)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"del", functiondel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"clear", functionclear)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setUndoRedoEnabled", functionsetUndoRedoEnabled)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setUndoDepth", functionsetUndoDepth)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"isUndoRedoEnabled", functionsetUndoRedoEnabled)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"undoDepth", functionundoDepth)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"indent", functionundoDepth)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"isUndoAvailable", functionisUndoAvailable)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"isUndoRedoAvailable", functionisRedoAvailable)
+//->Text color & others
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setText", functionsetText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setPointSize", functionsetPointSize)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setColor", functionsetColor)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setModified" , functionsetModified)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setLinkUnderline" , functionsetLinkUnderline)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setOverwriteMode" , functionsetOverwriteMode)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setReadOnly",functionSetReadOnly)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setTextFormat" , functionsetTextFormat)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"textFormat" , functiontextFormat)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setParagraphBackgroundColor", functionsetParagraphBackgroundColor)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"clearParagraphBackgroundColor", functionsetParagraphBackgroundColor)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"loadFile" , functionloadFile); // let's fantasy
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setAlignment" , functionsetAlignment)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setAutoFormatting" , functionsetAutoFormatting)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setVerticalAlignment" , functionsetVerticalAlignment)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"setWrapPolicy" , functionsetWrapPolicy)
+//->Paragraph & line
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"paragraphs" , functionparagraphs)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"paragraphLength" , functionparagraphLength)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"insertParagraph" , functioninsertParagraph)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"removeParagraph" , functionremoveParagraph)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"lines" , functionlines)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"lineOfChar" , functionlineOfChar)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"linesOfParagraph" , functionlinesOfParagraph)
+ KVSO_REGISTER_HANDLER(KviKvsObject_mledit,"selectAll" , functionselectAll)
+
+
+KVSO_END_REGISTERCLASS(KviKvsObject_mledit)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_mledit,KviKvsObject_widget)
+
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_mledit)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_mledit)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_mledit)
+
+bool KviKvsObject_mledit::init(KviKvsRunTimeContext * pContext,KviKvsVariantList * pParams)
+{
+ setObject(new KviTalMultiLineEdit(parentScriptWidget(),getName()),true);
+ return true;
+}
+
+
+bool KviKvsObject_mledit::functionSetReadOnly(KviKvsObjectFunctionCall *c)
+
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->setReadOnly(bEnabled);
+ return true;
+}
+
+
+bool KviKvsObject_mledit::functionTextLine(KviKvsObjectFunctionCall *c)
+
+{
+ kvs_int_t iLine;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("line",KVS_PT_INT,0,iLine)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ if(iLine > ((KviTalMultiLineEdit *)widget())->numLines() || iLine < 0) c->warning(__tr2qs("No such line number"));
+ else
+ c->returnValue()->setString(((KviTalMultiLineEdit *)widget())->textLine(iLine));
+ return true;
+}
+
+bool KviKvsObject_mledit::functionInsertLine(KviKvsObjectFunctionCall *c)
+
+{
+ kvs_int_t iLine;
+ QString szInsert;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szInsert)
+ KVSO_PARAMETER("line",KVS_PT_INT,KVS_PF_OPTIONAL,iLine)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ ((KviTalMultiLineEdit *)widget())->insertLine(szInsert,iLine);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionRemoveLine(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iLine;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("line",KVS_PT_INT,0,iLine)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ if(iLine > ((KviTalMultiLineEdit *)widget())->numLines() || iLine < 0)
+ c->warning("No such line number");
+ else ((KviTalMultiLineEdit *)widget())->removeLine(iLine);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionInsertAt(KviKvsObjectFunctionCall *c)
+
+{
+ kvs_uint_t iLine,iCol;
+ QString szInsert;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szInsert)
+ KVSO_PARAMETER("line",KVS_PT_UNSIGNEDINTEGER,0,iLine)
+ KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,iCol)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ if(iLine < 0 || iCol < 0 || iLine > ((KviTalMultiLineEdit *)widget())->numLines())
+ c->warning("No such line number");
+ else
+ ((KviTalMultiLineEdit *)widget())->insertAt(szInsert,iLine,iCol);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionNumLines(KviKvsObjectFunctionCall *c)
+
+{
+ if(widget()) c->returnValue()->setInteger(((KviTalMultiLineEdit *)widget())->numLines());
+ return true;
+}
+
+bool KviKvsObject_mledit::functionSetCursorPosition(KviKvsObjectFunctionCall *c)
+{
+
+ bool bFlag;
+ kvs_uint_t iLine,iCol;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("line",KVS_PT_UNSIGNEDINTEGER,0,iLine)
+ KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,iCol)
+ KVSO_PARAMETER("mark",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->setCursorPosition(iLine, iCol, bFlag);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionCursorPosition(KviKvsObjectFunctionCall *c)
+{
+ if(!widget()) return true;
+ int line, col;
+ #if QT_VERSION >= 300
+ ((KviTalMultiLineEdit *)widget())->getCursorPosition(&line, &col);
+ #else
+ ((KviTalMultiLineEdit *)widget())->cursorPosition(&line, &col);
+ #endif
+ KviKvsArray * a = new KviKvsArray();
+ a->set(0,new KviKvsVariant((kvs_int_t)line));
+ a->set(1,new KviKvsVariant((kvs_int_t)col));
+ c->returnValue()->setArray(a);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionAtBeginning(KviKvsObjectFunctionCall *c)
+{
+ if(!widget()) return true;
+ c->returnValue()->setBoolean(((KviTalMultiLineEdit *)widget())->atBeginning());
+ return true;
+}
+
+bool KviKvsObject_mledit::functionAtEnd(KviKvsObjectFunctionCall *c)
+{
+ if(!widget()) return true;
+ c->returnValue()->setBoolean(((KviTalMultiLineEdit *)widget())->atEnd());
+ return true;
+}
+
+bool KviKvsObject_mledit::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"))
+ ((KviTalMultiLineEdit *)widget())->setWordWrap(KviTalMultiLineEdit::NoWrap);
+ else if(KviQString::equalCI(szWrap,"WidgetWidth"))
+ ((KviTalMultiLineEdit *)widget())->setWordWrap(KviTalMultiLineEdit::WidgetWidth);
+ else if(KviQString::equalCI(szWrap,"FixedPixelWidth"))
+ ((KviTalMultiLineEdit *)widget())->setWordWrap(KviTalMultiLineEdit::FixedPixelWidth);
+ else if(KviQString::equalCI(szWrap,"FixedColumnWidth"))
+ ((KviTalMultiLineEdit *)widget())->setWordWrap(KviTalMultiLineEdit::FixedColumnWidth);
+ else c->warning(__tr2qs("Unknown word wrap '%Q'"),&szWrap);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetWrapPolicy(KviKvsObjectFunctionCall *c)
+{
+ if(!widget())return true;
+ QString szPolicy;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("wrap_policy",KVS_PT_STRING,0,szPolicy)
+ KVSO_PARAMETERS_END(c)
+ if(KviQString::equalCI(szPolicy,"AtWhiteSpace)"))
+ ((KviTalMultiLineEdit *)widget())->setWrapPolicy(KviTalMultiLineEdit::AtWhiteSpace);
+ else if(KviQString::equalCI(szPolicy,"Anywhere"))
+ ((KviTalMultiLineEdit *)widget())->setWrapPolicy(KviTalMultiLineEdit::Anywhere);
+ else if(KviQString::equalCI(szPolicy,"AtWordBoundary"))
+ ((KviTalMultiLineEdit *)widget())->setWrapPolicy(KviTalMultiLineEdit::AtWordBoundary);
+ else if(KviQString::equalCI(szPolicy,"AtWordOrDocumentBoundary"))
+ ((KviTalMultiLineEdit *)widget())->setWrapPolicy(KviTalMultiLineEdit::AtWordOrDocumentBoundary);
+ else c->warning(__tr2qs("Unknown wrap policy'%Q'"),&szPolicy);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionWordWrap(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((KviTalMultiLineEdit *)widget())->wordWrap() & KviTalMultiLineEdit::WidgetWidth);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionText(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setString(((KviTalMultiLineEdit *)widget())->text());
+ return true;
+}
+
+bool KviKvsObject_mledit::functionLength(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setInteger(((KviTalMultiLineEdit *)widget())->length());
+ return true;
+}
+
+bool KviKvsObject_mledit::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())
+ ((KviTalMultiLineEdit *)widget())->setMaxLines(imaxLines);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionMaxLines(KviKvsObjectFunctionCall *c)
+
+{
+ if(widget())
+ c->returnValue()->setInteger(((KviTalMultiLineEdit *)widget())->maxLines());
+ return true;
+}
+
+bool KviKvsObject_mledit::functionInsert(KviKvsObjectFunctionCall *c)
+
+{
+ QString szInsert;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szInsert)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->insert(szInsert);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionAppend(KviKvsObjectFunctionCall *c)
+
+{
+ QString szAppend;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szAppend)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->append(szAppend);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionCopy(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->copy();
+ return true;
+}
+
+bool KviKvsObject_mledit::functionCut(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->cut();
+ return true;
+}
+
+bool KviKvsObject_mledit::functionPaste(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->paste();
+ return true;
+}
+//->Set Bold, Italic, Underline
+bool KviKvsObject_mledit::functionsetBold(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bBold",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setBold(bFlag);
+ return true;
+}
+bool KviKvsObject_mledit::functionsetUnderline(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bUnderline",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setUnderline(bFlag);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetItalic(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bItalic",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setItalic(bFlag);
+ return true;
+}
+
+
+//-->Returns Italic , Bold, Underline.
+bool KviKvsObject_mledit::functionbold(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((KviTalMultiLineEdit *)widget())->bold());
+ return true;
+}
+bool KviKvsObject_mledit::functionitalic(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((KviTalMultiLineEdit *)widget())->italic());
+ return true;
+}
+bool KviKvsObject_mledit::functionunderline(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((KviTalMultiLineEdit *)widget())->underline());
+ return true;
+}
+//->Zoom In, out at
+bool KviKvsObject_mledit::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)
+ ((KviTalMultiLineEdit *)object())->zoomIn();
+ else
+ ((KviTalMultiLineEdit *)object())->zoomIn(iZoom);
+ return true;
+}
+
+bool KviKvsObject_mledit::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)
+ ((KviTalMultiLineEdit *)object())->zoomOut();
+ else
+ ((KviTalMultiLineEdit *)object())->zoomOut(iZoom);
+ return true;
+}
+bool KviKvsObject_mledit::functionzoomTo(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iZoom;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("zoom_size",KVS_PT_INT,0,iZoom)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)object())->zoomTo(iZoom);
+ return true;
+}
+//-> Undo & Redo functions
+
+bool KviKvsObject_mledit::functionundo(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->undo();
+ return true;
+}
+bool KviKvsObject_mledit::functionredo(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->redo();
+ return true;
+}
+bool KviKvsObject_mledit::functionclear(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->clear();
+ return true;
+}
+bool KviKvsObject_mledit::functiondel(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->del();
+ return true;
+}
+bool KviKvsObject_mledit::functionindent(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->indent();
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetUndoRedoEnabled(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bUndoredo",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setUndoRedoEnabled(bFlag);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionisUndoRedoEnabled(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((KviTalMultiLineEdit *)widget())->isUndoRedoEnabled());
+ return true;
+}
+bool KviKvsObject_mledit::functionisUndoAvailable(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((KviTalMultiLineEdit *)widget())->isUndoAvailable());
+ return true;
+}
+bool KviKvsObject_mledit::functionisRedoAvailable(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((KviTalMultiLineEdit *)widget())->isRedoAvailable());
+ return true;
+}
+bool KviKvsObject_mledit::functionsetUndoDepth(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iDepth;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("undo_depth",KVS_PT_UNSIGNEDINTEGER,0,iDepth)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)object())->setUndoDepth(iDepth);
+ return true;
+
+}
+bool KviKvsObject_mledit::functionundoDepth(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setInteger(((KviTalMultiLineEdit *)widget())->undoDepth());
+ return true;
+}
+
+//-->Text & Color & Family
+// Findme
+bool KviKvsObject_mledit::functionsetText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setText(szText);
+ return true;
+}
+bool KviKvsObject_mledit::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("The array passed as parameter must contain at least 3 elements"));
+ 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("One of the colors array parameters is empty"));
+ return false;
+ }
+ if(!(pColR->asInteger(iColR) && pColG->asInteger(iColG) && pColB->asInteger(iColB)))
+ {
+ c->error(__tr2qs("One of the colors array parameters didn't evaluate to an integer"));
+ return false;
+ }
+
+ } else {
+ if (c->params()->count()==1)
+ {
+ bool bOk,bOk1,bOk2;
+ QString value;
+ pColArray->asString(value);
+ int i=0;
+ if (value.length()!=6)
+ {
+ c->warning(__tr2qs("A string of 6 digits hex is required"));
+ 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("Not an hex digits"));
+ return true;
+ }
+ if (widget()) ((KviTalMultiLineEdit *)widget())->setColor(QColor(iColR,iColG,iColB));
+ return true;
+ }
+ if(c->params()->count() < 3)
+ {
+ c->error(__tr2qs("$setColor requires either an array as first parameter or three integers"));
+ return false;
+ }
+ if(!pColArray->asInteger(iColR))
+ {
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));
+ return false;
+ }
+ }
+ if (widget()) ((KviTalMultiLineEdit *)widget())->setColor(QColor(iColR,iColG,iColB));
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetPointSize(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uPointSize;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("point_size",KVS_PT_UNSIGNEDINTEGER,0,uPointSize)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setPointSize(uPointSize);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetLinkUnderline(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bLinkunderline",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setLinkUnderline(bFlag);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetFamily(KviKvsObjectFunctionCall *c)
+{
+ QString szFamily;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("family",KVS_PT_STRING,0,szFamily)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setFamily(szFamily);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetModified(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bModified",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setModified(bFlag);
+ return true;
+}
+
+bool KviKvsObject_mledit::functioninsertParagraph(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iParagraph;
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETER("paragraph",KVS_PT_INT,0,iParagraph)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalMultiLineEdit *)widget())->insertParagraph(szText,iParagraph);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionremoveParagraph(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iParagraph;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("paragraph",KVS_PT_INT,0,iParagraph)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalMultiLineEdit*)widget())->removeParagraph(iParagraph);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetOverwriteMode(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bOverwritemode",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->setOverwriteMode(bFlag);
+ return true;
+}
+
+bool KviKvsObject_mledit::functiontextFormat(KviKvsObjectFunctionCall *c)
+
+{
+ if(!widget())return true;
+ int fstyle = ((KviTalMultiLineEdit *)widget())->textFormat();
+ QString format="";
+ for(unsigned int i = 0; i < mod_num; i++)
+ {
+ if(fstyle & mod_cod[i])
+ {
+ format=mod_tbl[i];
+ }
+ }
+ c->returnValue()->setString(format);
+ return true;
+
+}
+bool KviKvsObject_mledit::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"))
+ ((KviTalMultiLineEdit *)widget())->setTextFormat(Qt::PlainText);
+ else if(KviQString::equalCI(szFormat,"RichText"))
+ ((KviTalMultiLineEdit *)widget())->setTextFormat(Qt::RichText);
+ else if(KviQString::equalCI(szFormat,"LogText"))
+ ((KviTalMultiLineEdit *)widget())->setTextFormat(Qt::LogText);
+ else if(KviQString::equalCI(szFormat,"AutoText"))
+ ((KviTalMultiLineEdit *)widget())->setTextFormat(Qt::AutoText);
+ else c->warning(__tr2qs("Unknown text format '%Q'"),&szFormat);
+ return true;
+}
+// findme
+bool KviKvsObject_mledit::functionsetParagraphBackgroundColor(KviKvsObjectFunctionCall *c)
+{
+ KviKvsVariant * pColArray;
+ kvs_int_t iParagraph,iColR,iColG,iColB;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("paragraph",KVS_PT_INT,0,iParagraph)
+ 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("The array passed as parameter must contain at least 3 elements"));
+ 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("One of the colors array parameters is empty"));
+ return false;
+ }
+ if(!(pColR->asInteger(iColR) && pColG->asInteger(iColG) && pColB->asInteger(iColB)))
+ {
+ c->error(__tr2qs("One of the colors array parameters didn't evaluate to an integer"));
+ return false;
+ }
+
+ } else {
+ if (c->params()->count()==1)
+ {
+ bool bOk,bOk1,bOk2;
+ QString value;
+ pColArray->asString(value);
+ int i=0;
+ if (value.length()!=6)
+ {
+ c->warning(__tr2qs("A string of 6 digits hex is required"));
+ 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("Not an hex digits"));
+ return true;
+ }
+ if (widget()) ((KviTalMultiLineEdit *)widget())->setParagraphBackgroundColor(iParagraph,QColor(iColR,iColG,iColB));
+ return true;
+ }
+ if(c->params()->count() < 3)
+ {
+ c->error(__tr2qs("$setColor requires either an array as first parameter or three integers"));
+ return false;
+ }
+ if(!pColArray->asInteger(iColR))
+ {
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));
+ return false;
+ }
+ }
+ if (widget()) ((KviTalMultiLineEdit *)widget())->setParagraphBackgroundColor(iParagraph,QColor(iColR,iColG,iColB));
+ return true;
+}
+
+bool KviKvsObject_mledit::functionclearParagraphBackground(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iParagraph;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("paragraph",KVS_PT_INT,0,iParagraph)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviTalMultiLineEdit*)widget())->clearParagraphBackground(iParagraph);
+ return true;
+}
+
+bool KviKvsObject_mledit::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(" I can't find the specified file '%Q'."),&szFile);
+ return true;
+ }
+
+ QFile file( szFile );
+ if ( !file.open( IO_ReadOnly ) )
+ {
+ c->warning(__tr2qs(" I cannot read the file %Q'."),&szFile);
+ return true;
+ }
+
+ QTextStream ts( &file );
+ QString txt = ts.read();
+#ifdef COMPILE_USE_QT4
+ if ( !Q3StyleSheet::mightBeRichText( txt ) )
+ txt = Q3StyleSheet::convertFromPlainText( txt, Q3StyleSheetItem::WhiteSpacePre );
+#else
+ if ( !QStyleSheet::mightBeRichText( txt ) )
+ txt = QStyleSheet::convertFromPlainText( txt, QStyleSheetItem::WhiteSpacePre );
+#endif
+ ((KviTalMultiLineEdit *)widget())->setText( txt );
+
+ file.close();
+ return true;
+}
+
+bool KviKvsObject_mledit::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"))
+ ((KviTalMultiLineEdit *)widget())->setAlignment(Qt::AlignLeft);
+ else if(KviQString::equalCI(szAlignment,"Right"))
+ ((KviTalMultiLineEdit *)widget())->setAlignment(Qt::AlignRight);
+ else if(KviQString::equalCI(szAlignment,"Center"))
+ ((KviTalMultiLineEdit *)widget())->setAlignment(Qt::AlignCenter);
+ else if(KviQString::equalCI(szAlignment,"Justify"))
+ ((KviTalMultiLineEdit *)widget())->setAlignment(Qt::AlignJustify);
+ else c->warning(__tr2qs("Unknown alignment '%Q'"),&szAlignment);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetAutoFormatting(KviKvsObjectFunctionCall *c)
+
+{
+ QString szAutoformatting;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("autoformatting",KVS_PT_STRING,0,szAutoformatting)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ if(KviQString::equalCI(szAutoformatting,"AutoNone"))
+ ((KviTalMultiLineEdit *)widget())->setAutoFormatting(QTEXTEDIT_AUTO_NONE);
+ else if(KviQString::equalCI(szAutoformatting,"BulletList"))
+ ((KviTalMultiLineEdit *)widget())->setAutoFormatting(QTEXTEDIT_AUTO_BULLET_LIST);
+ else if(KviQString::equalCI(szAutoformatting,"AutoAll"))
+ ((KviTalMultiLineEdit *)widget())->setAutoFormatting(QTEXTEDIT_AUTO_ALL);
+ else c->warning(__tr2qs("Unknown auto formatting mode '%Q'"),&szAutoformatting);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionsetVerticalAlignment(KviKvsObjectFunctionCall *c)
+
+{
+ QString szValignment;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("alignment",KVS_PT_STRING,0,szValignment)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ if(KviQString::equalCI(szValignment,"Normal"))
+ ((KviTalMultiLineEdit *)widget())->setVerticalAlignment(KviTalMultiLineEdit::AlignNormal);
+ else if(KviQString::equalCI(szValignment,"SuperScript"))
+ ((KviTalMultiLineEdit *)widget())->setVerticalAlignment(KviTalMultiLineEdit::AlignSuperScript);
+ else if(KviQString::equalCI(szValignment,"SubScript"))
+ ((KviTalMultiLineEdit *)widget())->setVerticalAlignment(KviTalMultiLineEdit::AlignSubScript);
+ else c->warning(__tr2qs("Unknown vertical alignment '%Q'"),&szValignment);
+ return true;
+}
+
+bool KviKvsObject_mledit::functionparagraphs(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setInteger(((KviTalMultiLineEdit *)widget())->paragraphs());
+ return true;
+
+}
+
+bool KviKvsObject_mledit::functionlines(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setInteger(((KviTalMultiLineEdit *)widget())->lines());
+ return true;
+}
+
+bool KviKvsObject_mledit::functionlineOfChar(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iPara,iIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("paragraph",KVS_PT_INT,0,iPara)
+ KVSO_PARAMETER("index",KVS_PT_INT,0,iIndex)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ c->returnValue()->setInteger(((KviTalMultiLineEdit *)widget())->lineOfChar(iPara,iIndex));
+ return true;
+}
+
+bool KviKvsObject_mledit::functionlinesOfParagraph(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iLine;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("paragraph",KVS_PT_INT,0,iLine)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ c->returnValue()->setInteger(((KviTalMultiLineEdit *)widget())->linesOfParagraph(iLine));
+ return true;
+}
+
+
+bool KviKvsObject_mledit::functionparagraphLength(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iParagraph;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("paragraph",KVS_PT_INT,0,iParagraph)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ c->returnValue()->setInteger(((KviTalMultiLineEdit *)widget())->paragraphLength(iParagraph));
+ return true;
+
+}
+
+bool KviKvsObject_mledit::functionselectAll(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bSelectall",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalMultiLineEdit *)widget())->selectAll(bFlag);
+ return true;
+}
+
+
+
+#include "m_class_multilineedit.moc"
diff --git a/src/modules/objects/class_multilineedit.h b/src/modules/objects/class_multilineedit.h
new file mode 100644
index 00000000..8639266e
--- /dev/null
+++ b/src/modules/objects/class_multilineedit.h
@@ -0,0 +1,110 @@
+#ifndef _CLASS_MULTILINEEDIT_H_
+#define _CLASS_MULTILINEEDIT_H_
+//vim: ts=8
+// File : class_multilineedit.cpp
+// Creation date : Mon Feb 19 00:45:34 CET by Krzysztof Godlewski
+//
+// Modification date: Thu 15 Feb 2005 22:00 :00
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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"
+
+class KviKvsObject_mledit : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_mledit)
+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 functionInsertAt(KviKvsObjectFunctionCall *c);
+ bool functionNumLines(KviKvsObjectFunctionCall *c);
+ bool functionSetCursorPosition(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);
+// |-G&N add-|
+ 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 functionzoomTo(KviKvsObjectFunctionCall *c);
+ bool functionundo(KviKvsObjectFunctionCall *c);
+ bool functionredo(KviKvsObjectFunctionCall *c);
+ bool functiondel(KviKvsObjectFunctionCall *c);
+ bool functionclear(KviKvsObjectFunctionCall *c);
+ bool functionindent(KviKvsObjectFunctionCall *c);
+ bool functionsetUndoRedoEnabled(KviKvsObjectFunctionCall *c);
+ bool functionsetUndoDepth(KviKvsObjectFunctionCall *c);
+ bool functionisUndoRedoEnabled(KviKvsObjectFunctionCall *c);
+ bool functionundoDepth(KviKvsObjectFunctionCall *c);
+ bool functionsetText(KviKvsObjectFunctionCall *c);
+ bool functionsetPointSize(KviKvsObjectFunctionCall *c);
+ bool functionsetColor(KviKvsObjectFunctionCall *c);
+ bool functionisUndoAvailable(KviKvsObjectFunctionCall *c);
+ bool functionisRedoAvailable(KviKvsObjectFunctionCall *c);
+ bool functionsetLinkUnderline(KviKvsObjectFunctionCall *c);
+ bool functionsetFamily(KviKvsObjectFunctionCall *c);
+ bool functionsetModified(KviKvsObjectFunctionCall *c);
+ bool functioninsertParagraph(KviKvsObjectFunctionCall *c);
+ bool functionremoveParagraph(KviKvsObjectFunctionCall *c);
+ bool functionsetOverwriteMode(KviKvsObjectFunctionCall *c);
+ bool functionsetTextFormat(KviKvsObjectFunctionCall *c);
+ bool functiontextFormat(KviKvsObjectFunctionCall *c);
+ bool functionsetParagraphBackgroundColor(KviKvsObjectFunctionCall *c);
+ bool functionclearParagraphBackground(KviKvsObjectFunctionCall *c);
+ bool functionloadFile(KviKvsObjectFunctionCall *c);
+ bool functionsetAlignment(KviKvsObjectFunctionCall *c);
+ bool functionsetAutoFormatting(KviKvsObjectFunctionCall *c);
+ bool functionsetVerticalAlignment(KviKvsObjectFunctionCall *c);
+ bool functionsetWrapPolicy(KviKvsObjectFunctionCall *c);
+ bool functionparagraphs(KviKvsObjectFunctionCall *c);
+ bool functionparagraphLength(KviKvsObjectFunctionCall *c);
+ bool functionlines(KviKvsObjectFunctionCall *c);
+ bool functionlineOfChar(KviKvsObjectFunctionCall *c);
+ bool functionlinesOfParagraph(KviKvsObjectFunctionCall *c);
+ bool functionselectAll(KviKvsObjectFunctionCall *c);
+
+};
+
+#endif //!_CLASS_MULTILINEEDIT_H_
diff --git a/src/modules/objects/class_painter.cpp b/src/modules/objects/class_painter.cpp
new file mode 100644
index 00000000..b27a24a3
--- /dev/null
+++ b/src/modules/objects/class_painter.cpp
@@ -0,0 +1,1007 @@
+//mdm:
+// Painter : class_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) 1999-2000 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_painter.h"
+#include "class_pixmap.h"
+#include "class_widget.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_error.h"
+#include "kvi_iconmanager.h"
+#include "kvi_malloc.h"
+
+
+/*
+ @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(<x1:integer>,<y1_integer>,<x2:integer>,<y2:integer>)
+ Draws a line from (x1, y1) to (x2, y2) and sets the current pen position to (x2, y2).
+ !fn: $begin(<paint_device:object>)
+ Begins painting the paint device <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: $end()
+ Ends painting. Any resources used while painting are released.
+ !fn: $setPen(<rgb or hsv array value or [<red>,<green>,<blue>][<hue>,<saturation>,<value>],[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(<rgb or hsv array value or [<red>,<green>,<blue>][<hue>,<saturation>,<value>],[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(<x:integer>,<y:integer>,<w:unsigned integer>,<h:unsigned integer>)
+ Draws a rectangle with upper left corner at (x, y) and with width w and height h.
+ !fn: $drawWinFocusRect(<x:integer>,<y:integer>,<w:unsigned integer>,<h:unsigned integer>)
+ Draws a Windows focus rectangle with upper left corner at (x, y) and with width w and height h.[br]
+ This function draws nothing if the coordinate system has been rotated or sheared.
+ !fn: $drawRoundRect(<x:integer>,<y:integer>,<w:unsigned integer>,<h:unsigned integer>,<xCor:integer>,<yCor:integer>)
+ 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(<x:integer>,<y:integer>,<w:unsigned integer>,<h:unsigned integer>,<angle:integer>,<alen:integer>)
+ Draws a pie defined by the rectangle (x, y, w, h), the start angle a and the arc length alen.[br]
+ The angles <angle> and <alen> are 1/16th of a degree, i.e. a full circle equals 5760 (16*360).
+ !fn: $drawArc(<x:integer>,<y:integer>,<w:unsigned integer>,<h:unsigned integer>,<angle:integer>,<alen:integer>)
+ Draws an arc defined by the rectangle (x, y, w, h), the start angle a and the arc length alen.[br]
+ The angles <angle> and <alen> are 1/16th of a degree, i.e. a full circle equals 5760 (16*360).
+ !fn: $drawPoint(<x:integer>,<y:integer>)
+ Draws a point at x and y coordinates.
+ !fn: $drawEllipse(<x:integer>,<y:integer>,<sizew:unsigned integer>,<sizeh:unsigned integer>)
+ Draws an ellipse with center at (x + w/2, y + h/2) and size (w, h).
+ !fn: $drawChord(<x:integer>,<y:integer>,<w:unsigned integer>,<h:unsigned integer>,<angle:integer>,<alen:integer>)
+ Draws a chord defined by the rectangle (x, y, w, h), the start angle a and the arc length alen.[br]
+ The angles <angle> and <alen> are 1/16th of a degree, i.e. a full circle equals 5760 (16*360).
+ !fn: $drawText(<x:integer>,<y:integer>,<text:string>,<nr chars:integer>,<dir:enum>)
+ Draws the given <text> at position <x>, <y>.[br]
+ If <len> is -1 (the default) all the text is drawn, otherwise the first <len> characters are drawn.
+ The text's direction is given by <dir>, valid flag are:[br]
+ [pre]
+ Auto [br]
+ RTL (right to left) [br]
+ LTR (left to right) [br]
+ [/pre]
+ !fn: $drawPixmap(<x:integer>,<y:integer>,<pixmap:hobject>,<sx:integer>,<sy:integer>,<ex:integer>,<ey:integer>)
+ Draws a pixmap at x,y coordinates[br]
+ !fn: $setFont(<size:unsigned integer>,<family:string>,<style:enum>)[br]
+ Set the font's size, family and stile, valid flag for style are:[br]
+ [pre]
+ italic [br]
+ bold [br]
+ underline [br]
+ overline [br]
+ strikeout [br]
+ fixedpitch [br]
+ [/pre]
+ !fn: $setFontSize(<size:unsigned integer>)[br]
+ Set the current painter font's size.[br]
+ !fn: <integer>$fontAscent()
+ Return the distance from the baseline to the highest position characters extend to.
+ !fn: <integer>$fontDescent()
+ Return the distance from the baseline to the lowest point characters extend to.
+ !fn: <integer>$fontMetricsWidth(<text:string>)
+ Returns the font metrics width for the painter's current font.
+ !fn: <integer>$fontMetricsHeight()
+ Returns the font metrics height for the painter's current font.
+ !fn: $rotate(<angle:real>)
+ Rotates the coordinate system a degrees counterclockwise.
+ !fn: $translate(<dx:real>,<dy:real>)
+ Translates the coordinate system by <dx>, <dy>.
+ !fn: $shear(<dh:real>,<dv:real>)
+ Shears the coordinate system by <dh>, <dv>.
+ !fn: $scale(<dh:real>,<dw:real>)
+ Scales the coordinate system by <dh>, <dv>.
+ !fn: $setBackgroundMode(<bgMode:enum>)
+ Sets the background mode of the painter to <bgMode>: valid values are:[br]
+ - Transparent (that is the default value);[br]
+ - Opaque.[br]
+ !fn: $setOpacity(<opacity_factor:real>) [QT4 ONLY]
+ 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(<boolean>) [QT4 ONLY]
+ Enable/disable antialias in text if possible.
+ You must call the [classfnc]$begin[/classfnc] before using it.
+ !fn: $setAntialiasing(<boolean>) [QT4 ONLY]
+ Enable/disable antialias in edges of primitives if possible.
+ You must call the [classfnc]$begin[/classfnc] before using it.
+ !fn: $setSmoothPixmapTransform(<boolean>) [QT4 ONLY]
+ 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->$setcaption("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(KviKvsObject_painter,"painter","object")
+
+ // Fonts
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"setFont",functionSetFont)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"setFontSize",functionSetFontSize)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"setBrush",functionsetBrush)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"setPen",functionsetPen)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"fontAscent",functionfontAscent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"fontDescent",functionfontDescent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"fontMetricsHeight",functionfontMetricsHeight)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"fontMetricsWidth",functionfontMetricsWidth)
+ // Draws
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"setBackGroundMode",functionsetBackGroundMode)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawRect",functiondrawRect)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawLine",functiondrawLine)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawRoundRect",functiondrawRoundRect)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawWinFocusRect",functiondrawWinFocusRect)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawPoint",functiondrawPoint)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawArc",functiondrawArc)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawEllipse",functiondrawEllipse)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawPie",functiondrawPie)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawChord",functiondrawChord)
+ // Text & Pixmap
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawText",functiondrawText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"drawPixmap",functiondrawPixmap)
+
+
+ // MAtrix Operation
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"rotate",functionrotateMatrix)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"shear",functionshearMatrix)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"scale",functionscaleMatrix)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"translate",functiontranslateMatrix)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"reset",functionresetMatrix)
+
+#ifdef COMPILE_USE_QT4
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"setOpacity",functionsetOpacity)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"setTextAntialiasing",functionsetTextAntialiasing)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"setAntialiasing",functionsetAntialiasing)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"setSmoothPixmapTransform",functionsetSmoothPixmapTransform)
+#endif
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"begin",functionbegin)
+ KVSO_REGISTER_HANDLER(KviKvsObject_painter,"end",functionend)
+
+
+KVSO_END_REGISTERCLASS(KviKvsObject_painter)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_painter,KviKvsObject)
+
+ m_pPainter = new QPainter();
+
+ m_pDeviceObject=0;
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_painter)
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_painter)
+
+ if (m_pPainter) delete m_pPainter;
+ m_pPainter = 0;
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_painter)
+
+#define KVSO_PARAMETERS_PAINTER(__pXOrArray,__iY,__iW,__iH)\
+if(__pXOrArray->isArray())\
+ {\
+ if(__pXOrArray->array()->size() < 4)\
+ {\
+ c->error(__tr2qs("The array passed as parameter must contain at least 4 elements"));\
+ 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("One of the geometry array parameters is empty"));\
+ return false;\
+ }\
+ if(!(pX->asInteger(iX) && pY->asInteger(__iY) && pW->asInteger(__iW) && pH->asInteger(__iH)))\
+ {\
+ c->error(__tr2qs("One of the geometry array parameters didn't evaluate to an integer"));\
+ return false;\
+ }\
+ } else {\
+ if(c->params()->count() < 4)\
+ {\
+ QString error=function+" requires either an array as first parameter or four integers";\
+ c->error(__tr2qs(error));\
+ return false;\
+ }\
+ if(!__pXOrArray->asInteger(iX))\
+ {\
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));\
+ return false;\
+ }\
+ }\
+
+#define KVSO_2ARRAYPARAMETERS(__pXOrArray,__iY)\
+if(__pXOrArray->isArray())\
+ {\
+ if(__pXOrArray->array()->size() < 2)\
+ {\
+ c->error(__tr2qs("The array passed as parameter must contain at least 2 elements"));\
+ return false;\
+ }\
+ KviKvsVariant * pX = __pXOrArray->array()->at(0);\
+ KviKvsVariant * pY = __pXOrArray->array()->at(1);\
+ if(!(pX && pY ))\
+ {\
+ c->error(__tr2qs("One of the array parameters is empty"));\
+ return false;\
+ }\
+ if(!(pX->asInteger(iX) && pY->asInteger(__iY)))\
+ {\
+ c->error(__tr2qs("One of the array parameters didn't evaluate to an integer"));\
+ return false;\
+ }\
+ } else {\
+ if(c->params()->count() < 2)\
+ {\
+ QString error=function+" requires either an array as first parameter or two integers";\
+ c->error(__tr2qs(error));\
+ return false;\
+ }\
+ if(!__pXOrArray->asInteger(iX))\
+ {\
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));\
+ return false;\
+ }\
+ }\
+
+#define KVSO_3ARRAYPARAMETERS(__pCol1OrArray,__iCol2,__iCol3)\
+if(__pCol1OrArray->isArray())\
+ {\
+ if(__pCol1OrArray->array()->size() < 3)\
+ {\
+ c->error(__tr2qs("The array passed as parameter must contain at least 3 elements"));\
+ 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("One of the array parameters is empty"));\
+ return false;\
+ }\
+ if(!(c1->asInteger(iCol1) && c2->asInteger(__iCol2) && c3->asInteger(__iCol3)))\
+ {\
+ c->error(__tr2qs("One of the array parameters didn't evaluate to an integer"));\
+ return false;\
+ }\
+ } else {\
+ if(c->params()->count() < 3)\
+ {\
+ QString error=function+" requires either an array as first parameter or 3 integers";\
+ c->error(__tr2qs(error));\
+ return false;\
+ }\
+ if(!__pCol1OrArray->asInteger(iCol1))\
+ {\
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));\
+ return false;\
+ }\
+ }\
+
+bool KviKvsObject_painter::functionSetFont(KviKvsObjectFunctionCall *c)
+{
+ QString szFamily,szStyle;
+ kvs_int_t uSize;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("size",KVS_PT_UNSIGNEDINTEGER,0,uSize)
+ KVSO_PARAMETER("family",KVS_PT_STRING,0,szFamily)
+ KVSO_PARAMETER("style",KVS_PT_STRING,0,szStyle)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pPainter)return true;
+ QFont font=m_pPainter->font();
+ font.setFamily(szFamily);
+ font.setPointSize(uSize);
+ if(KviQString::equalCI(szStyle,"italic")) font.setItalic(TRUE);
+ if(KviQString::equalCI(szStyle,"bold")) font.setBold(TRUE);
+ if(KviQString::equalCI(szStyle,"underline"))font.setUnderline(TRUE);
+ if(KviQString::equalCI(szStyle,"overline")) font.setOverline(TRUE);
+ if(KviQString::equalCI(szStyle,"strikeout"))font.setStrikeOut(TRUE);
+ if(KviQString::equalCI(szStyle,"fixedpitch")) font.setFixedPitch(TRUE);
+ m_pPainter->setFont(font);
+ return true;
+}
+bool KviKvsObject_painter::functionSetFontSize(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uSize;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("size",KVS_PT_UNSIGNEDINTEGER,0,uSize)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pPainter)return true;
+ QFont font=m_pPainter->font();
+ font.setPointSize(uSize);
+ m_pPainter->setFont(font);
+ return true;
+}
+bool KviKvsObject_painter::functionsetBackGroundMode(KviKvsObjectFunctionCall *c)
+{
+ QString szMode;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("background mode",KVS_PT_STRING,0,szMode)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pPainter)return true;
+ 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("Unknown orientation"));
+ return true;
+
+}
+
+bool KviKvsObject_painter::functiondrawLine(KviKvsObjectFunctionCall *c)
+{
+ 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="$drawLine";
+ KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iW,iH)
+ if(m_pPainter) m_pPainter->drawLine(iX,iY,iW,iH);
+ return true;
+}
+bool KviKvsObject_painter::functiondrawRect(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(m_pPainter) m_pPainter->drawRect(iX,iY,iW,iH);
+ return true;
+}
+// FIX ME: REMOVE functiondrawWinFocusRect
+bool KviKvsObject_painter::functiondrawWinFocusRect(KviKvsObjectFunctionCall *c)
+{
+ 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="$drawWinFocusRect";
+ KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iW,iH)
+#ifndef COMPILE_USE_QT4
+ if(m_pPainter) m_pPainter->drawWinFocusRect(iX,iY,iW,iH);
+#endif
+ return true;
+}
+bool KviKvsObject_painter::functiondrawEllipse(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(m_pPainter) m_pPainter->drawEllipse(iX,iY,iW,iH);
+ return true;
+}
+bool KviKvsObject_painter::functiondrawRoundRect(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(m_pPainter)
+ m_pPainter->drawRoundRect(iX,iY,iW,iH,iXrnd,iYrnd);
+ return true;
+}
+bool KviKvsObject_painter::functiondrawArc(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(m_pPainter)
+ m_pPainter->drawArc(iX,iY,iW,iH,iSangle,iLena);
+ return true;
+}
+bool KviKvsObject_painter::functiondrawChord(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(m_pPainter)
+ m_pPainter->drawChord(iX,iY,iW,iH,iSangle,iLena);
+ return true;
+}
+bool KviKvsObject_painter::functionsetBrush(KviKvsObjectFunctionCall *c)
+{
+ KviKvsVariant * pCol1OrArray;
+ kvs_int_t iCol1,iCol2,iCol3;
+ QString szColorMode;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("Col1_or_array",KVS_PT_VARIANT,0,pCol1OrArray)
+ KVSO_PARAMETER("Color_2",KVS_PT_INT,KVS_PF_OPTIONAL,iCol2)
+ KVSO_PARAMETER("Colo3_3",KVS_PT_INT,KVS_PF_OPTIONAL,iCol3)
+ KVSO_PARAMETER("color_mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szColorMode)
+ KVSO_PARAMETERS_END(c)
+ QString function="$drawChord";
+ KVSO_3ARRAYPARAMETERS(pCol1OrArray,iCol2,iCol3)
+ if(!m_pPainter) return true;
+ if(KviQString::equalCI(szColorMode, "HSV"))
+ m_pPainter->setBrush(QColor(iCol1,iCol2,iCol3,QColor::Hsv));
+ else
+ m_pPainter->setBrush(QColor(iCol1,iCol2,iCol3,QColor::Rgb));
+ return true;
+}
+bool KviKvsObject_painter::functionsetPen(KviKvsObjectFunctionCall *c)
+{
+ KviKvsVariant * pCol1OrArray;
+ kvs_int_t iCol1,iCol2,iCol3;
+ QString szColorMode;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("Col1_or_array",KVS_PT_VARIANT,0,pCol1OrArray)
+ KVSO_PARAMETER("Color_2",KVS_PT_INT,KVS_PF_OPTIONAL,iCol2)
+ KVSO_PARAMETER("Colo3_3",KVS_PT_INT,KVS_PF_OPTIONAL,iCol3)
+ KVSO_PARAMETER("color_mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szColorMode)
+ KVSO_PARAMETERS_END(c)
+ QString function="$setPen";
+ KVSO_3ARRAYPARAMETERS(pCol1OrArray,iCol2,iCol3)
+ if(!m_pPainter) return true;
+ if(KviQString::equalCI(szColorMode, "HSV"))
+ m_pPainter->setPen(QColor(iCol1,iCol2,iCol3,QColor::Hsv));
+ else
+ m_pPainter->setPen(QColor(iCol1,iCol2,iCol3,QColor::Rgb));
+
+ return true;
+}
+bool KviKvsObject_painter::functiondrawPie(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(m_pPainter)
+ m_pPainter->drawPie(iX,iY,iW,iH,iSangle,iLena);
+ return true;
+}
+bool KviKvsObject_painter::functiondrawPoint(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(m_pPainter)
+ m_pPainter->drawPoint(iX,iY);
+ return true;
+}
+bool KviKvsObject_painter::functionfontDescent(KviKvsObjectFunctionCall * c)
+{
+ if(m_pPainter)
+ c->returnValue()->setInteger(m_pPainter->fontMetrics().descent());
+ return true;
+}
+
+bool KviKvsObject_painter::functionfontAscent(KviKvsObjectFunctionCall * c)
+{
+ if(m_pPainter)
+ c->returnValue()->setInteger(m_pPainter->fontMetrics().ascent());
+ return true;
+
+}
+
+bool KviKvsObject_painter::functionfontMetricsWidth(KviKvsObjectFunctionCall * c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if(m_pPainter)
+ c->returnValue()->setInteger(m_pPainter->fontMetrics().width(szText));
+ return true;
+}
+
+bool KviKvsObject_painter::functionfontMetricsHeight(KviKvsObjectFunctionCall * c)
+{
+ if(m_pPainter)
+ c->returnValue()->setInteger(m_pPainter->fontMetrics().height());
+ return true;
+}
+bool KviKvsObject_painter::functionbegin(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject * pObject;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("paint_device",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETERS_END(c)
+ pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!m_pPainter)return true;
+ if (!pObject)
+ {
+ c->warning(__tr2qs("Pixmap or Widget parameter is not an object"));
+ return true;
+ }
+
+ QPaintDevice * pd = 0;
+ if(pObject->inherits("KviKvsObject_pixmap"))pd =((KviKvsObject_pixmap *)pObject)->getPixmap();
+ else if (pObject->inherits("KviKvsObject_widget")) pd=((KviKvsObject_widget *)pObject)->widget();
+
+ if (!pd)
+ c->warning(__tr2qs("Widget or Pixmap required "));
+ else {
+ attachDevice(pObject,pd);
+ // m_pPainter->setOpacity(0.4);
+ if (pObject->inherits("KviKvsObject_pixmap")) ((KviKvsObject_pixmap *)pObject)->pixmapChanged();
+ }
+ return true;
+}
+void KviKvsObject_painter::attachDevice(KviKvsObject * o,QPaintDevice * p)
+{
+ if(!m_pPainter)return;
+ if(m_pDeviceObject)detachDevice();
+ m_pDeviceObject = o;
+ // KviKvsObject_pixmap and KviKvsObject_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 KviKvsObject_painter::detachDevice()
+{
+ if(!m_pDeviceObject)return;
+ if(!m_pPainter)return;
+ disconnect(m_pDeviceObject,SIGNAL(aboutToDie()),this,SLOT(detachDevice()));
+ m_pPainter->end();
+ m_pDeviceObject = 0;
+}
+
+bool KviKvsObject_painter::functionend(KviKvsObjectFunctionCall *c)
+{
+ detachDevice();
+ return true;
+}
+
+bool KviKvsObject_painter::functiondrawText(KviKvsObjectFunctionCall *c)
+{
+ QString szText,szMode;
+ kvs_int_t iX,iY,iLen;
+ 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("length",KVS_PT_INT,0,iLen)
+ KVSO_PARAMETER("mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szMode)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pPainter)return true;
+#ifdef COMPILE_USE_QT4
+ if (!szMode.isEmpty()){
+ 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("Invalid mode '%Q'"),&szMode);
+ return true;
+ }
+ }
+
+ m_pPainter->drawText(iX,iY,szText);
+#else
+ if(KviQString::equalCI(szMode,"Auto")) m_pPainter->drawText(iX,iY,szText,iLen,QPainter::Auto);
+ else if(KviQString::equalCI(szMode,"RTL")) m_pPainter->drawText(iX,iY,szText,iLen,QPainter::RTL);
+ else if(KviQString::equalCI(szMode,"LTR"))m_pPainter->drawText(iX,iY,szText,iLen,QPainter::LTR);
+ else c->warning(__tr2qs("Invalid mode '%Q'"),&szMode);
+
+#endif
+ return true;
+}
+
+bool KviKvsObject_painter::functiondrawPixmap(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iX,iY,iStartx,iStarty,iEndx,iEndy;
+ KviKvsObject *obj;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("x",KVS_PT_INT,0,iX)
+ KVSO_PARAMETER("y",KVS_PT_INT,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_PARAMETERS_END(c)
+ obj=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!m_pPainter)return true;
+ if (!obj)
+ {
+ c->warning(__tr2qs("Pixmap parameter is not an object"));
+ return true;
+ }
+ if (!obj->inherits("KviKvsObject_pixmap"))
+ {
+ c->warning(__tr2qs("Pixmap object required"));
+ return true;
+ }
+ QPixmap * pm=((KviKvsObject_pixmap *)obj)->getPixmap();
+ m_pPainter->drawPixmap(iX,iY,*((KviKvsObject_pixmap *)obj)->getPixmap(),iStartx,iStarty,iEndx,iEndy);
+ return true;
+}
+
+bool KviKvsObject_painter::functionrotateMatrix(KviKvsObjectFunctionCall *c)
+{
+ kvs_real_t dAngle;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("angle",KVS_PT_DOUBLE,0,dAngle)
+ KVSO_PARAMETERS_END(c)
+ if(!m_pPainter)return true;
+ m_pMatrix.rotate(dAngle);
+ m_pPainter->setWorldMatrix( m_pMatrix,false );
+ return true;
+}
+bool KviKvsObject_painter::functiontranslateMatrix(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(!m_pPainter)return true;
+ QWMatrix tmpMatrix;
+ tmpMatrix.translate(dXtrasl,dYtrasl);
+ tmpMatrix = m_pMatrix * tmpMatrix;
+ m_pPainter->setWorldMatrix( tmpMatrix );
+ m_pMatrix=tmpMatrix;
+ return true;
+}
+bool KviKvsObject_painter::functionshearMatrix(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(!m_pPainter)return true;
+ m_pMatrix.shear(dShearh,dShearv);
+ m_pPainter->setWorldMatrix(m_pMatrix);
+ return true;
+}
+bool KviKvsObject_painter::functionscaleMatrix(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(!m_pPainter)return true;
+ m_pMatrix.scale(dScalex,dScaley);
+ m_pPainter->setWorldMatrix(m_pMatrix);
+ return true;
+}
+bool KviKvsObject_painter::functionresetMatrix(KviKvsObjectFunctionCall *c)
+
+{
+ if(!m_pPainter)return true;
+ m_pMatrix.reset();
+ m_pPainter->setWorldMatrix( m_pMatrix );
+ return true;
+}
+
+#ifdef COMPILE_USE_QT4
+bool KviKvsObject_painter::functionsetOpacity(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pPainter)return true;
+ 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;
+}
+bool KviKvsObject_painter::functionsetTextAntialiasing(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pPainter)return true;
+
+ 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;
+}
+bool KviKvsObject_painter::functionsetAntialiasing(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pPainter)return true;
+
+ 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;
+}
+bool KviKvsObject_painter::functionsetSmoothPixmapTransform(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pPainter)return true;
+
+ 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;
+}
+#endif
+
+
+
+#include "m_class_painter.moc"
diff --git a/src/modules/objects/class_painter.h b/src/modules/objects/class_painter.h
new file mode 100644
index 00000000..2ee8a5bb
--- /dev/null
+++ b/src/modules/objects/class_painter.h
@@ -0,0 +1,96 @@
+#ifndef _CLASS_PAINTER_H_
+#define _CLASS_PAINTER_H_
+//mdm:
+// Painter : class_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) 1999-2000 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 <qpainter.h>
+#include <qpaintdevice.h>
+#include "kvi_string.h"
+
+
+#include "object_macros.h"
+
+
+class KviKvsObject_painter : public KviKvsObject
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_painter)
+protected:
+ QPainter * m_pPainter;
+ QWMatrix m_pMatrix;
+public:
+ bool functionSetFont(KviKvsObjectFunctionCall *c);
+ bool functionSetFontSize(KviKvsObjectFunctionCall *c);
+
+ bool functionfontAscent(KviKvsObjectFunctionCall *c);
+ bool functionfontDescent(KviKvsObjectFunctionCall *c);
+ bool functionfontMetricsWidth(KviKvsObjectFunctionCall *c);
+ bool functionfontMetricsHeight(KviKvsObjectFunctionCall *c);
+ bool functionsetBrush(KviKvsObjectFunctionCall *c);
+ bool functionsetPen(KviKvsObjectFunctionCall *c);
+ bool functionsetBackGroundMode(KviKvsObjectFunctionCall *c);
+
+ bool functiondrawRect(KviKvsObjectFunctionCall *c);
+ bool functiondrawWinFocusRect(KviKvsObjectFunctionCall *c);
+ bool functiondrawLine(KviKvsObjectFunctionCall *c);
+ bool functiondrawRoundRect(KviKvsObjectFunctionCall *c);
+ bool functiondrawPoint(KviKvsObjectFunctionCall *c);
+ bool functiondrawArc(KviKvsObjectFunctionCall *c);
+ bool functiondrawChord(KviKvsObjectFunctionCall *c);
+ bool functiondrawPie(KviKvsObjectFunctionCall *c);
+ bool functiondrawEllipse(KviKvsObjectFunctionCall *c);
+
+ bool functiondrawText(KviKvsObjectFunctionCall *c);
+ bool functiondrawPixmap(KviKvsObjectFunctionCall *c);
+
+
+ bool functionbegin(KviKvsObjectFunctionCall *c);
+ bool functionend(KviKvsObjectFunctionCall *c);
+
+ bool functionscaleMatrix(KviKvsObjectFunctionCall *c);
+ bool functionshearMatrix(KviKvsObjectFunctionCall *c);
+ bool functionrotateMatrix(KviKvsObjectFunctionCall *c);
+ bool functionresetMatrix(KviKvsObjectFunctionCall *c);
+ bool functiontranslateMatrix(KviKvsObjectFunctionCall *c);
+
+#ifdef COMPILE_USE_QT4
+ bool functionsetOpacity(KviKvsObjectFunctionCall *c);
+ bool functionsetSmoothPixmapTransform(KviKvsObjectFunctionCall *c);
+ bool functionsetTextAntialiasing(KviKvsObjectFunctionCall *c);
+ bool functionsetAntialiasing(KviKvsObjectFunctionCall *c);
+#endif
+
+
+
+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/class_pixmap.cpp b/src/modules/objects/class_pixmap.cpp
new file mode 100644
index 00000000..48aeb1e8
--- /dev/null
+++ b/src/modules/objects/class_pixmap.cpp
@@ -0,0 +1,317 @@
+//mdm:
+// Painter : class_pixmap.h
+// 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) 1999-2000 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_pixmap.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include <qfile.h>
+
+/*
+ @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(<widget:object>,<x_offset:integer>,<y:offset>)
+ 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(<width:integer>,<height:integer>)
+ Resizes the pixmap to w width and h height. Set wh or hg to 0, to have a null pixmap.
+ !fn: $scale(<sx:real>,<sy:real>)
+ Scales the pixmap by sx horizontally and sy vertically.
+ !fn: $rotate(<a:real>)
+ Rotates the pixmap by a degrees.
+ !fn: $load(<file_name:string>)
+ Load a pixmap from the <file>.
+ !fn: <integer> $height()
+ Return the height of the pixmap.
+ !fn: <integer> $width()
+ Return the width of the pixmap.
+
+*/
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_pixmap,"pixmap","object")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_pixmap,"fill",functionfill)
+ KVSO_REGISTER_HANDLER(KviKvsObject_pixmap,"resize",functionresize)
+ KVSO_REGISTER_HANDLER(KviKvsObject_pixmap,"load",functionload)
+ KVSO_REGISTER_HANDLER(KviKvsObject_pixmap,"height",functionheight)
+ KVSO_REGISTER_HANDLER(KviKvsObject_pixmap,"width",functionwidth)
+ KVSO_REGISTER_HANDLER(KviKvsObject_pixmap,"setOpacity",functionsetOpacity)
+ KVSO_REGISTER_HANDLER(KviKvsObject_pixmap,"scale",functionscale)
+ KVSO_REGISTER_HANDLER(KviKvsObject_pixmap,"rotate",functionrotate)
+
+KVSO_END_REGISTERCLASS(KviKvsObject_pixmap)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_pixmap,KviKvsObject)
+ m_pPixmap=new QPixmap();
+ m_pImage=new QImage();
+ bPixmapModified=false;
+ bImageModified=false;
+KVSO_END_CONSTRUCTOR(KviKvsObject_pixmap)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_pixmap)
+
+ emit aboutToDie();
+ delete m_pPixmap;
+ if (m_pImage) delete m_pImage;
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_pixmap)
+
+
+bool KviKvsObject_pixmap::functionfill(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ 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)
+
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Widget object required"));
+ return true;
+ }
+ bPixmapModified=true;
+ m_pPixmap->fill(((QWidget *)(ob->object())),iXoffset,iYoffset);
+ return true;
+}
+
+bool KviKvsObject_pixmap::functionscale(KviKvsObjectFunctionCall *c)
+{
+ kvs_real_t uScaleX,uScaleY;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("sx",KVS_PT_REAL,0,uScaleX)
+ KVSO_PARAMETER("sy",KVS_PT_REAL,0,uScaleY)
+ KVSO_PARAMETERS_END(c)
+ #ifdef COMPILE_USE_QT4
+ *m_pPixmap = m_pPixmap->scaled((m_pPixmap->width() * uScaleX), (m_pPixmap->height() * uScaleX));
+ #else
+ QWMatrix wm;
+ wm.scale(uScaleX, uScaleY);
+ *m_pPixmap = m_pPixmap->xForm(wm);
+ #endif
+ bPixmapModified=true;
+ return true;
+}
+
+bool KviKvsObject_pixmap::functionrotate(KviKvsObjectFunctionCall *c)
+{
+ kvs_real_t uDegrees;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("a",KVS_PT_REAL,0,uDegrees)
+ KVSO_PARAMETERS_END(c)
+ #ifdef COMPILE_USE_QT4
+ QMatrix m;
+ m.rotate(uDegrees);
+ *m_pPixmap = m_pPixmap->transformed(m);
+ #else
+ QWMatrix wm;
+ wm.rotate(uDegrees);
+ *m_pPixmap = m_pPixmap->xForm(wm);
+ #endif
+ bPixmapModified=true;
+ return true;
+}
+
+bool KviKvsObject_pixmap::functionresize(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t uWidth,uHeight;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("width",KVS_PT_UNSIGNEDINTEGER,0,uWidth)
+ KVSO_PARAMETER("height",KVS_PT_UNSIGNEDINTEGER,0,uHeight)
+ KVSO_PARAMETERS_END(c)
+ m_pPixmap->resize(uWidth,uHeight);
+ bPixmapModified=true;
+ return true;
+}
+
+
+bool KviKvsObject_pixmap::functionload(KviKvsObjectFunctionCall *c)
+{
+ 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("I can't find the specified file %Q."),&szFile);
+ return true;
+ }
+ m_pPixmap->load(szFile);
+ bPixmapModified=true;
+ return true;
+}
+bool KviKvsObject_pixmap::functionheight(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setInteger(m_pPixmap->height());
+ return true;
+}
+bool KviKvsObject_pixmap::functionwidth(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setInteger(m_pPixmap->width());
+ return true;
+}
+bool KviKvsObject_pixmap::functionsetOpacity(KviKvsObjectFunctionCall *c)
+{
+ if(!m_pPixmap)return true;
+ kvs_real_t dOpacity;
+ kvs_uint_t uXoffset,uYoffset;
+ kvs_uint_t uWidth,uHeight;
+
+ KviKvsObject * pObDest;
+ kvs_hobject_t hObject;
+
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("opacity_factor",KVS_PT_DOUBLE,0,dOpacity)
+ KVSO_PARAMETER("destination",KVS_PT_HOBJECT,0,hObject)
+
+ KVSO_PARAMETER("x_offset",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uXoffset)
+ KVSO_PARAMETER("y_offset",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uYoffset)
+ KVSO_PARAMETER("width",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uWidth)
+ KVSO_PARAMETER("height",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uHeight)
+ KVSO_PARAMETERS_END(c)
+ pObDest=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+
+ if (!pObDest)
+ {
+ c->warning(__tr2qs("Destination parameter is not an object"));
+ return true;
+ }
+
+ if(!pObDest->inherits("KviKvsObject_pixmap"))
+ {
+ c->warning(__tr2qs("Destination must be a pixmap object"));
+ return true;
+ }
+ QImage *buffer=((KviKvsObject_pixmap *)pObDest)->getImage();
+ ((KviKvsObject_pixmap *)pObDest)->imageChanged();
+ if (bPixmapModified) {
+ *m_pImage=m_pPixmap->convertToImage();
+ }
+ if (uWidth>buffer->width() || uHeight>buffer->height())
+ {
+ c->warning(__tr2qs("Area dimensions are out of destination size "));
+ return true;
+ }
+ if (!uWidth){
+ if(m_pImage->width()>buffer->width())
+ {
+ c->warning(__tr2qs("Pixmap dimensions are out of destination size "));
+ return true;
+ }
+ }
+
+ if (!uHeight)
+ {
+ if(m_pImage->height()>buffer->height())
+ {
+ c->warning(__tr2qs("Pixmap dimensions are out of destination size "));
+ return true;
+ }
+ }
+
+
+if(uXoffset+uWidth>m_pImage->width())
+ {
+ c->warning(__tr2qs("Offset width area is out of pixmap size "));
+ return true;
+ }
+ if( uYoffset+uHeight>m_pImage->height())
+ {
+ c->warning(__tr2qs("Offset height area is out of pixmap size "));
+ return true;
+ }
+
+ buffer->setAlphaBuffer(true);
+ int iHedge=uHeight?uHeight:m_pImage->height();
+ int iWedge=uWidth?uWidth:m_pImage->width();
+
+ for(int y = uYoffset;y<iHedge;y++)
+ {
+ QRgb * dst = (QRgb *)buffer->scanLine(y);
+ QRgb * src = (QRgb *)m_pImage->scanLine(y);
+ src += uXoffset;
+ QRgb * end;
+ end = src + iWedge;
+ while(src < end)
+ {
+ *dst = qRgba(
+ (int)(qRed(*src)),
+ (int)(qGreen(*src)),
+ (int)(qBlue(*src)),
+ (int)(qAlpha(*src)*dOpacity)
+ );
+ src++;
+ dst++;
+ }
+ }
+ return true;
+}
+
+
+QPixmap * KviKvsObject_pixmap::getPixmap()
+{
+ if (bImageModified) {
+ m_pPixmap->convertFromImage(*m_pImage);
+ bImageModified=false;
+ }
+ return m_pPixmap;
+}
+QImage * KviKvsObject_pixmap::getImage()
+{
+ if (bPixmapModified) {
+ *m_pImage=m_pPixmap->convertToImage();
+ //debug ("image info2 %d and %d",test.width(),test.height());
+
+ bPixmapModified=false;
+ }
+
+ return m_pImage;
+}
+
+#include "m_class_pixmap.moc"
diff --git a/src/modules/objects/class_pixmap.h b/src/modules/objects/class_pixmap.h
new file mode 100644
index 00000000..22d1b95d
--- /dev/null
+++ b/src/modules/objects/class_pixmap.h
@@ -0,0 +1,72 @@
+#ifndef _CLASS_PIXMAP_H_
+#define _CLASS_PIXMAP_H_
+//vim: ts=8
+// Pixmap : class_pixmap.h
+// Creation date : Thu Sep 21 04:43:01 CEST 2000 by Krzysztof Godlewski
+//
+// This pixmap is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 <qpixmap.h>
+#include <qimage.h>
+#ifdef COMPILE_USE_QT4
+ #include <QMatrix>
+#else
+ #include <qwmatrix.h>
+#endif
+#include "kvi_string.h"
+
+
+#include "object_macros.h"
+
+
+class KviKvsObject_pixmap : public KviKvsObject
+{
+ Q_OBJECT
+// Q_PROPERTY(QPixmap pixmap READ getPixmap)
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_pixmap);
+ QPixmap * getPixmap();
+ QImage * getImage();
+ void pixmapChanged(){bPixmapModified=true;}
+ void imageChanged(){bImageModified=true;}
+
+ QPixmap * pixmap(){ return m_pPixmap; }
+protected:
+ QPixmap * m_pPixmap;
+ QImage * m_pImage;
+ bool bImageModified;
+ bool bPixmapModified;
+signals:
+ void aboutToDie();
+
+protected:
+ bool functionfill(KviKvsObjectFunctionCall *c);
+ bool functionresize(KviKvsObjectFunctionCall *c);
+ bool functionscale(KviKvsObjectFunctionCall *c);
+ bool functionrotate(KviKvsObjectFunctionCall *c);
+ bool functionload(KviKvsObjectFunctionCall *c);
+ bool functionheight(KviKvsObjectFunctionCall *c);
+ bool functionwidth(KviKvsObjectFunctionCall *c);
+ bool functionsetOpacity(KviKvsObjectFunctionCall *c);
+
+ };
+
+#endif // !_CLASS_PIXMAP_H_
diff --git a/src/modules/objects/class_popupmenu.cpp b/src/modules/objects/class_popupmenu.cpp
new file mode 100644
index 00000000..a3db5339
--- /dev/null
+++ b/src/modules/objects/class_popupmenu.cpp
@@ -0,0 +1,361 @@
+//mdm :
+// File : class_popupmenu.cpp
+// Creation date : Mon Feb 01 21: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) 1999-2000 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_popupmenu.h"
+#include "kvi_error.h"
+
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+
+/*
+ @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(<text:string>,[icon_id:string])
+ Inserts menu items into a popup menu with optional icon and return the popup identifier.
+ !fn: $insertWidget(<widget:object>)[br]
+ Inserts widget items int a popup menu and return the popup identifier.[br]
+ The widget is treats as a separator; this means that the item is not selectable and you can, for example, simply insert a label if you need a popup menu with a title.
+ !fn: $insertHandle(<text_label:string>,<popupmenu:object>,[icon])
+ Inserts a submenu with optional icon into the popup menu.
+ !fn: $exec([<widget:objects>,<x:uinteger>,<y:integer>])
+ 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(<popup_id:Uinteger>)
+ Removes the menu item that has the identifier id.
+ !fn: $removeItemAt(<index:uinteger>)
+ Removes the menu item at position index.
+ !fn: $insertSeparator(<index:uinteger>)
+ Inserts a separator at position index.[br]
+ If the index is negative the separator becomes the last menu item.
+ !fn: $activatedEvent(<popup_id:uinteger>)
+ 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(<popup_id:uinteger>)
+ 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]
+ |-EXAMPLE POPUP MENU-|[br]
+ |--Start:
+ # First of all we create an array wich will be used to create random colors.[br]
+ %Hex[]=$array(0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)[br]
+ [br]
+ class (ws,widget)[br]
+ {[br]
+ #In the constructor we create everything that belong to the single widget.[br]
+ constructor[br]
+ {[br]
+ #Geometry of the widget and setting-up of popupmenu [br]
+ $$->$setGeometry(%X,%Y,100,100)[br]
+ $$->%lay=$new(layout,$$)[br]
+ #Here we generate a cicle to create our labels inside the widget.[br]
+ %i=0[br]
+ while (%i<10)[br]
+ {[br]
+ $$->%label=$new(label,$$)[br]
+ $$->%label->$settext("Another class by N\&G")[br]
+ #We set our foreground's coulor using the hex arrey in random way.[br]
+ %color=%Hex[$rand(14)]%Hex[$rand(14)]%Hex[$rand(14)]%Hex[$rand(14)]%Hex[$rand(14)]%Hex[$rand(14)][br]
+ $$->%label->$setforegroundcolor(%color)[br]
+ $$->%label->$setautoresize(1)[br]
+ #We add the label to the widget's popupmenu.[br]
+ $$->%lay->$addwidget($$->%label,%i,0)[br]
+ %i++;[br]
+ }[br]
+ #We make the popupmenu relative to this widget: this is merely demonstrative.[br]
+ #because it creates 25 identical popups.[br]
+ $$->%Popupmenu=$new(popupmenu,$$)[br]
+ #we create the label widget wich will be used as popup's title[br]
+ $$->%Popuptitle=$new(label)[br]
+ $$->%Popuptitle->$settext(<B><U>"Windows Options"</B></U>)[br]
+ $$->%Popuptitle->$setAlignment(Center)[br]
+ #and we add it.[br]
+ %A=$$->%Popuptitle[br]
+ $$->%Popupmenu->$insertwidget(%A)[br]
+ #Here we keep the various IDs in the arrays[br]
+ %Tile[%I]=$$->%Popupmenu->$insertItem("Tile",118)[br]
+ %Cascade[%I]=$$->%Popupmenu->$insertItem("Cascade",115)[br]
+ $$->%Popupmenu->$insertSeparator(3)[br]
+ %Closeactw[%I]=$$->%Popupmenu->$insertItem("Close Active Window",08)[br]
+ %Closeallw[%I]=$$->%Popupmenu->$insertItem("Close All Window",58)[br]
+ $$->$show()[br]
+ privateimpl($$->%Popupmenu,activatedEvent)[br]
+ {[br]
+ %id=$0[br]
+ %i = 0[br]
+ #with this cicle we control wich of the items has been called comparing the id given back by the event with our arrays created before;[br]
+ while (%i<20)[br]
+ {[br]
+ if (%id == %Tile[%i]) return %Workspace->$tile()[br]
+ if (%id == %Cascade[%i]) return %Workspace->$cascade()[br]
+ if (%id == %Closeactw[%i]) return %Workspace->$closeactivewindow()[br]
+ if (%id == %Closeallw[%i]) return %Workspace->$closeallwindows()[br]
+ %i ++[br]
+ }[br]
+ }[br]
+ }[br]
+ #we activate the popup pushing the right mouse button on the widget[br]
+ mousepressevent[br]
+ {[br]
+ if ($0 == 1) $$->%Popupmenu->$exec()[br]
+ }[br]
+ }[br]
+ %Workspace=$new(workspace)[br]
+ %Workspace->$resize(640,480)[br]
+ %I=0[br]
+ %Cicle=1[br]
+ while (%I<20)[br]
+ {[br]
+ %X=$rand(500)[br]
+ %Y=$rand(480)[br]
+ %Widget=$new(ws,%Workspace)[br]
+ %I++[br]
+ }[br]
+ #Let's show!
+ %Workspace->$show[br]
+ |--End.[br][br]
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_popupmenu,"popupmenu","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_popupmenu,"insertItem", functioninsertItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_popupmenu,"insertWidget", functioninsertWidget)
+ KVSO_REGISTER_HANDLER(KviKvsObject_popupmenu,"insertHandle", functioninsertHandle)
+ KVSO_REGISTER_HANDLER(KviKvsObject_popupmenu,"exec", functionexec)
+ KVSO_REGISTER_HANDLER(KviKvsObject_popupmenu,"insertSeparator", functioninsertSeparator)
+ KVSO_REGISTER_HANDLER(KviKvsObject_popupmenu,"removeItem", functionremoveItem)
+ KVSO_REGISTER_HANDLER(KviKvsObject_popupmenu,"removeItemAt", functionremoveItemAt)
+
+ // events
+ KVSO_REGISTER_HANDLER(KviKvsObject_popupmenu,"highlightedEvent", functionhighlightedEvent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_popupmenu,"activatedEvent", functionactivatedEvent)
+
+KVSO_END_REGISTERCLASS(KviKvsObject_popupmenu)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_popupmenu,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_popupmenu)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_popupmenu)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_popupmenu)
+
+bool KviKvsObject_popupmenu::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new KviTalPopupMenu(parentScriptWidget(), name()), true);
+ connect(widget(),SIGNAL(activated(int)),this,SLOT(slotactivated(int)));
+ connect(widget(),SIGNAL(highlighted(int)),this,SLOT(slothighlighted(int)));
+ return true;
+}
+
+bool KviKvsObject_popupmenu::functioninsertItem(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(!widget())return true;
+ QPixmap *pix = 0;
+ int id=0;
+ if(!szIcon.isEmpty())
+ {
+ pix = g_pIconManager->getImage(szIcon);
+ if (pix) id=((KviTalPopupMenu *)widget())->insertItem(*pix,szItem);
+ else c->warning(__tr2qs("pix '%Q' doesn't exists"),&szIcon);
+
+ }
+ else
+ id=((KviTalPopupMenu *)widget())->insertItem(szItem);
+ c->returnValue()->setInteger(id);
+ return true;
+}
+bool KviKvsObject_popupmenu::functioninsertWidget(KviKvsObjectFunctionCall *c)
+{
+ 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("Widget parameter is not an object"));
+ return true;
+ }
+ if (!pObject->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!pObject->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return TRUE;
+ }
+ if (widget()) ((KviTalPopupMenu *)widget())->insertItem(((KviTalPopupMenu *)(pObject->object())));
+ return true;
+}
+bool KviKvsObject_popupmenu::functioninsertHandle(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ QString szLabel,szIcon;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text_label",KVS_PT_STRING,0,szLabel)
+ KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETER("icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szIcon)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!ob->object()->inherits("KviKvsObject_popupmenu"))
+ {
+ c->warning(__tr2qs("Can't add a non - popupmenu object"));
+ return TRUE;
+ }
+ if(!widget())return true;
+ QPixmap *pix = 0;
+ int id=0;
+ if(!szIcon.isEmpty())
+ {
+ pix = g_pIconManager->getImage(szIcon);
+ if (pix) id=((KviTalPopupMenu *)widget())->insertItem(*pix,szLabel,((KviTalPopupMenu *)(ob->object())));
+ else c->warning(__tr2qs("pix '%Q' doesn't exists"),&szIcon);
+
+ }
+ else
+ id=((KviTalPopupMenu *)widget())->insertItem(szLabel,((KviTalPopupMenu *)(ob->object())));
+ c->returnValue()->setInteger(id);
+ return true;
+}
+bool KviKvsObject_popupmenu::functionexec(KviKvsObjectFunctionCall *c)
+{
+ if(!c->params()->count())
+ {
+ ((KviTalPopupMenu *)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);
+ if (!pObject)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!pObject->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!pObject->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Doesn't a widget object"));
+ return true;
+ }
+
+ ((KviTalPopupMenu *)widget())->exec(((QWidget *)(pObject->object()))->mapToGlobal(QPoint(iX,iY)) );
+
+ return true;
+}
+bool KviKvsObject_popupmenu::functionremoveItem(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uItem;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("item_id",KVS_PT_UNSIGNEDINTEGER,0,uItem)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) ((KviTalPopupMenu *)widget())->removeItem(uItem);
+ return true;
+}
+bool KviKvsObject_popupmenu::functionremoveItemAt(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(widget())((KviTalPopupMenu *)widget())->removeItemAt(uIndex);
+ return true;
+}
+
+bool KviKvsObject_popupmenu::functioninsertSeparator(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if(widget())((KviTalPopupMenu *)widget())->insertSeparator(uIndex);
+ return true;
+}
+
+void KviKvsObject_popupmenu::slothighlighted(int i)
+{
+ KviKvsVariantList params(new KviKvsVariant((kvs_int_t)i));
+ callFunction(this,"highlightedEvent",&params);
+}
+bool KviKvsObject_popupmenu::functionhighlightedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("highlighted",c,c->params());
+ return true;
+}
+void KviKvsObject_popupmenu::slotactivated(int i)
+{
+ KviKvsVariantList params(new KviKvsVariant((kvs_int_t)i));
+ callFunction(this,"activatedEvent",&params);
+}
+bool KviKvsObject_popupmenu::functionactivatedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("activated",c,c->params());
+ return true;
+}
+
+
+#include "m_class_popupmenu.moc"
diff --git a/src/modules/objects/class_popupmenu.h b/src/modules/objects/class_popupmenu.h
new file mode 100644
index 00000000..e5960119
--- /dev/null
+++ b/src/modules/objects/class_popupmenu.h
@@ -0,0 +1,58 @@
+#ifndef _CLASS_POPUPMENU_H_
+#define _CLASS_POPUPMENU_H_
+//mdm:
+// File : class_popupMenu.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) 1999-2000 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_tal_popupmenu.h"
+#include <qcursor.h>
+#include "class_widget.h"
+#include "object_macros.h"
+
+class KviKvsObject_popupmenu : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_popupmenu)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functioninsertItem(KviKvsObjectFunctionCall *c);
+ bool functioninsertWidget(KviKvsObjectFunctionCall *c);
+ bool functioninsertHandle(KviKvsObjectFunctionCall *c);
+ bool functionexec(KviKvsObjectFunctionCall *c);
+ bool functionremoveItem(KviKvsObjectFunctionCall *c);
+ bool functionremoveItemAt(KviKvsObjectFunctionCall *c);
+ bool functioninsertSeparator(KviKvsObjectFunctionCall *c);
+ bool functionactivatedEvent(KviKvsObjectFunctionCall *c);
+ bool functionhighlightedEvent(KviKvsObjectFunctionCall *c);
+
+protected slots:
+ void slotactivated(int);
+ void slothighlighted(int);
+};
+
+#endif // !_CLASS_POPUPMENU_H_
+
diff --git a/src/modules/objects/class_process.cpp b/src/modules/objects/class_process.cpp
new file mode 100644
index 00000000..81efaae4
--- /dev/null
+++ b/src/modules/objects/class_process.cpp
@@ -0,0 +1,317 @@
+//mdm:
+// File : class_process.h
+// Creation date : Thu Feb 1 14:39:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_process.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+#include "kvi_settings.h"
+#include "kvi_locale.h"
+#include <qtimer.h>
+#ifdef COMPILE_USE_QT4
+#include <q3process.h>
+#else
+#include <qprocess.h>
+#endif
+
+/*
+ @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: $addArg(<process-name:string>)
+ With this command you give the process name (or more arguments) for comunication.
+ Es: see the next example.
+ !fn: $start()
+ Tries to run the process.[br]
+ Es: [br]
+ %process=$new(process);[br]
+ %process->$addArg("cmd.exe");[br]
+ %process->$start();[br]
+ !fn: <string> $readStdout()
+ Reads the data that the process has written to standard output.
+ !fn: <string> $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->$addArg("cmd.exe")[br]
+ %Process->$start();[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(<command:string>)
+ 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: <boolean> $isRunning()
+ Return 1 if the process is running, else return 0.
+ !fn: <boolean> $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(KviKvsObject_process,"process","object")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"addArg", functionaddArgument);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"start", functionstartProcess);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"readStdout", functionreadStdout);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"readStderr", functionreadStderr);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"writeToStdin", functionwriteToStdin);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"closekill", functionclosekill);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"kill", functionkill);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"tryTerminate", functiontryTerminate);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"closeStdin", functioncloseStdin);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"isRunning",functionisRunning);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"normalExit",functionnormalExit);
+
+ // Events
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"readyReadStdoutEvent",functionreadyReadStdoutEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_process,"readyReadStderrEvent",functionreadyReadStderrEvent);
+
+ KVSO_END_REGISTERCLASS(KviKvsObject_process)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_process,KviKvsObject)
+
+#ifdef COMPILE_USE_QT4
+ m_pProcess = new Q3Process();
+#else
+ m_pProcess = new QProcess();
+#endif
+ connect(m_pProcess,SIGNAL(readyReadStdout()),this,SLOT(slotReadStdout()));
+ connect(m_pProcess,SIGNAL(readyReadStderr()),this,SLOT(slotReadStderr()));
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_process)
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_process)
+
+ delete m_pProcess;
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_process)
+
+
+
+bool KviKvsObject_process::functionaddArgument(KviKvsObjectFunctionCall *c)
+{
+
+ QString szArgument;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("argument",KVS_PT_NONEMPTYSTRING,0,szArgument)
+ KVSO_PARAMETERS_END(c)
+ if (m_pProcess) m_pProcess->addArgument(szArgument);
+ return true;
+}
+
+//->Start the process.
+bool KviKvsObject_process::functionstartProcess(KviKvsObjectFunctionCall *c)
+{
+
+ if(!(m_pProcess->start()))
+ c->warning( __tr2qs("Process could not be starded."));
+ return true;
+}
+//-->Read the standard output.
+bool KviKvsObject_process::functionreadStderr(KviKvsObjectFunctionCall *c)
+{
+ QString ng_Process =m_pProcess->readStderr();
+ c->returnValue()->setString(ng_Process);
+ return true;
+}
+
+//-->Read the standard error.
+bool KviKvsObject_process::functionreadStdout(KviKvsObjectFunctionCall *c)
+{
+ QString ng_Process =m_pProcess->readStdout();
+ c->returnValue()->setString(ng_Process);
+ return true;
+}
+//-->Signals and slot to manage reading output and error from the process.
+bool KviKvsObject_process::functionreadyReadStdoutEvent(KviKvsObjectFunctionCall *c)
+{
+
+ emitSignal("readyReadStdout",c);
+ return true;
+
+}
+
+bool KviKvsObject_process::functionreadyReadStderrEvent(KviKvsObjectFunctionCall *c)
+{
+
+ emitSignal("readyReadStderr",c);
+ return true;
+
+}
+bool KviKvsObject_process::functionwriteToStdin(KviKvsObjectFunctionCall *c)
+{
+
+ QString szCommand;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("command",KVS_PT_STRING,0,szCommand)
+ KVSO_PARAMETERS_END(c)
+ if (m_pProcess) m_pProcess->writeToStdin(szCommand);
+
+ return true;
+}
+//-->The 3 Closing process functions
+bool KviKvsObject_process::functionclosekill(KviKvsObjectFunctionCall *c)
+{
+ //I try to to terminate the process the nice way....
+ m_pProcess->tryTerminate();
+ //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;
+}
+bool KviKvsObject_process::functionkill(KviKvsObjectFunctionCall *c)
+{
+ m_pProcess->kill();
+ return true;
+}
+bool KviKvsObject_process::functiontryTerminate(KviKvsObjectFunctionCall *c)
+{
+ m_pProcess->tryTerminate();
+ return true;
+}
+//-->Close the standard input.
+bool KviKvsObject_process::functioncloseStdin(KviKvsObjectFunctionCall *c)
+{
+
+ m_pProcess->closeStdin();
+ return true;
+}
+//->Returns if the process still runnig
+bool KviKvsObject_process::functionisRunning(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setBoolean(m_pProcess->isRunning());
+ return true;
+}
+//->Returns if the process exited.
+bool KviKvsObject_process::functionnormalExit(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setBoolean(m_pProcess->normalExit());
+ return true;
+}
+
+void KviKvsObject_process::slotReadStdout()
+{
+ KviKvsVariantList *params=0;
+ callFunction(this,"readyReadStdoutEvent",params);
+}
+
+void KviKvsObject_process::slotReadStderr()
+{
+ KviKvsVariantList *params=0;
+ callFunction(this,"readyReadStderrEvent",params);
+}
+
+#include "m_class_process.moc"
diff --git a/src/modules/objects/class_process.h b/src/modules/objects/class_process.h
new file mode 100644
index 00000000..70842950
--- /dev/null
+++ b/src/modules/objects/class_process.h
@@ -0,0 +1,74 @@
+#ifndef _CLASS_PROCESS_H_
+#define _CLASS_PROCESS_H_
+//mdm:
+// File : class_process.h
+// Creation date : Thu Feb 1 14:39:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 <qtimer.h>
+#include "class_widget.h"
+
+
+#include "object_macros.h"
+#ifdef COMPILE_USE_QT4
+#include <q3process.h>
+#else
+#include <qprocess.h>
+#endif
+
+
+class KviKvsObject_process : public KviKvsObject
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_process)
+protected:
+
+#ifdef COMPILE_USE_QT4
+ Q3Process * m_pProcess;
+#else
+ QProcess * m_pProcess;
+#endif
+
+public:
+
+ bool functionaddArgument(KviKvsObjectFunctionCall *c);
+ bool functionstartProcess(KviKvsObjectFunctionCall *c);
+ bool functionreadStdout(KviKvsObjectFunctionCall *c);
+ bool functionreadStderr(KviKvsObjectFunctionCall *c);
+ bool functionwriteToStdin(KviKvsObjectFunctionCall *c);
+ bool functionclosekill(KviKvsObjectFunctionCall *c);
+ bool functioncloseStdin(KviKvsObjectFunctionCall *c);
+ bool functionkill(KviKvsObjectFunctionCall *c);
+ bool functiontryTerminate(KviKvsObjectFunctionCall *c);
+ bool functionnormalExit(KviKvsObjectFunctionCall *c);
+ bool functionisRunning(KviKvsObjectFunctionCall *c);
+
+ bool functionreadyReadStdoutEvent(KviKvsObjectFunctionCall *c);
+ bool functionreadyReadStderrEvent(KviKvsObjectFunctionCall *c);
+
+protected slots:
+ void slotReadStdout();
+ void slotReadStderr();
+};
+
+
+#endif // !_CLASS_PROCESS_H_
diff --git a/src/modules/objects/class_progressbar.cpp b/src/modules/objects/class_progressbar.cpp
new file mode 100644
index 00000000..12fc5b39
--- /dev/null
+++ b/src/modules/objects/class_progressbar.cpp
@@ -0,0 +1,162 @@
+//
+// File : class_progressbar.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) 1999-2005 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_progressbar.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#ifdef COMPILE_USE_QT4
+#include <q3progressbar.h>
+#define KVI_PROGRESS_BAR Q3ProgressBar
+#else
+#include <qprogressbar.h>
+#define KVI_PROGRESS_BAR QProgressBar
+#endif
+
+/*
+ @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(<steps_value:uinteger>)
+ Set the amount of steps completed.
+ See also [classfnc]$settotalSteps[/classfnc]()
+ !fn: $settotalSteps(<total_steps:uinteger>)
+ 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: $setCenterIndicator(<bEnabled:boolean>)
+ Sets whether the indicator string should be centered to on.
+ See also [classfnc]$isCenterIndicator[/classfnc]()
+ !fn: <boolean> $isCenterIndicator()
+ This property holds whether the indicator string should be centered.
+ See also [classfnc]$setCenterIndicator[/classfnc]()
+ !fn: $setPercentageVisible(<bVisible,boolean>)
+ Sets whether the current progress value is displayed.
+ See also [classfnc]$isPercentageVisible[/classfnc]()
+ !fn: <boolean> $ispercentageVisible()
+ This property holds whether the current progress value is displayed.
+ See also [classfnc]$setPercentageVisible[/classfnc]()
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_progressbar,"progressbar","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_progressbar,"setProgress", functionSetProgress)
+ KVSO_REGISTER_HANDLER(KviKvsObject_progressbar,"setTotalSteps", functionSetTotalSteps)
+ KVSO_REGISTER_HANDLER(KviKvsObject_progressbar,"reset", functionReset)
+ KVSO_REGISTER_HANDLER(KviKvsObject_progressbar,"setCenterIndicator", functionSetCenterIndicator)
+ KVSO_REGISTER_HANDLER(KviKvsObject_progressbar,"setPercentageVisible", functionSetPercentageVisible)
+ KVSO_REGISTER_HANDLER(KviKvsObject_progressbar,"isCenterIndicator", functionCenterIndicator)
+ KVSO_REGISTER_HANDLER(KviKvsObject_progressbar,"isPercentageVisible", functionPercentageVisible)
+KVSO_END_REGISTERCLASS(KviKvsObject_progressbar)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_progressbar,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_progressbar)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_progressbar)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_progressbar)
+
+bool KviKvsObject_progressbar::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ #ifdef COMPILE_USE_QT4
+ Q3ProgressBar *pbar=new Q3ProgressBar(parentScriptWidget());
+ pbar->setObjectName(name());
+ setObject(pbar,true);
+ #else
+ setObject(new QProgressBar(parentScriptWidget(), name()), true);
+ #endif
+return true;
+}
+
+bool KviKvsObject_progressbar::functionSetProgress(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t iProgress;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("step_value",KVS_PT_UNSIGNEDINTEGER,0,iProgress)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KVI_PROGRESS_BAR *)widget())->setProgress(iProgress);
+ return true;
+}
+bool KviKvsObject_progressbar::functionSetTotalSteps(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t iSteps;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("total_steps",KVS_PT_UNSIGNEDINTEGER,0,iSteps)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KVI_PROGRESS_BAR *)widget())->setTotalSteps(iSteps);
+ return true;
+}
+
+bool KviKvsObject_progressbar::functionReset(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) ((KVI_PROGRESS_BAR *)widget())->reset();
+ return true;
+}
+
+bool KviKvsObject_progressbar::functionSetCenterIndicator(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) ((KVI_PROGRESS_BAR *)widget())->setCenterIndicator(bFlag);
+ return true;
+}
+bool KviKvsObject_progressbar::functionCenterIndicator(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setBoolean(((KVI_PROGRESS_BAR *)widget())->centerIndicator());
+ return true;
+}
+
+bool KviKvsObject_progressbar::functionSetPercentageVisible(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KVI_PROGRESS_BAR *)widget())->setPercentageVisible(bEnabled);
+ return true;
+}
+bool KviKvsObject_progressbar::functionPercentageVisible(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setBoolean(((KVI_PROGRESS_BAR *)widget())->percentageVisible());
+ return true;
+}
diff --git a/src/modules/objects/class_progressbar.h b/src/modules/objects/class_progressbar.h
new file mode 100644
index 00000000..44c4eac8
--- /dev/null
+++ b/src/modules/objects/class_progressbar.h
@@ -0,0 +1,51 @@
+#ifndef _CLASS_PROGRESSBAR_H_
+
+#define _CLASS_PROGRESSBAR_H_
+//
+// File : class_progressbar.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) 1999-2005 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 <qprogressbar.h>
+#include "class_widget.h"
+#include "object_macros.h"
+
+class KviKvsObject_progressbar : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_progressbar)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionSetProgress(KviKvsObjectFunctionCall *c);
+ bool functionSetTotalSteps(KviKvsObjectFunctionCall *c);
+ bool functionReset(KviKvsObjectFunctionCall *c);
+ bool functionSetPercentageVisible(KviKvsObjectFunctionCall *c);
+ bool functionSetCenterIndicator(KviKvsObjectFunctionCall *c);
+ bool functionCenterIndicator(KviKvsObjectFunctionCall *c);
+ bool functionPercentageVisible(KviKvsObjectFunctionCall *c);
+};
+
+
+#endif //!_CLASS_PROGRESSBAR_H_
+
diff --git a/src/modules/objects/class_radiobutton.cpp b/src/modules/objects/class_radiobutton.cpp
new file mode 100644
index 00000000..08211e12
--- /dev/null
+++ b/src/modules/objects/class_radiobutton.cpp
@@ -0,0 +1,138 @@
+//
+// File : class_radiobutton.cpp
+// Creation date : Thu Feb 08 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) 1999-2005 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_radiobutton.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+/*
+ @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(<text:string>)
+ Sets the text that will appear in the radiobutton.
+ !fn: <boolean> $isChecked()
+ Returns 1 (TRUE) if the radio button is checked; otherwise returns 0 (FALSE).
+ !fn: $setChecked(<bChecked:boolean>)
+ Sets whether the radio button is checked to check.
+ !fn: $setPixmap(<image_id>)
+ Sets the pixmap shown on the radiobutton..See the [doc:image_id]image identifier[/doc] documentation for the explaination
+ of the <image_id> parameter.
+ !fn: <bool>$toggleEvent()
+ Called by KVIrc when the radibutton state is toggled.
+ The default implementation emits the toggled(<bool>) signal.
+ !sg: $toggled()
+ This signal is emitted by the default implementation of [classfnc]$toggleEvent[/classfnc]().[br]
+
+
+*/
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_radiobutton,"radiobutton","widget")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_radiobutton,"setText", functionSetText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_radiobutton,"setChecked", functionSetChecked)
+ KVSO_REGISTER_HANDLER(KviKvsObject_radiobutton,"isChecked", functionIsChecked)
+ KVSO_REGISTER_HANDLER(KviKvsObject_radiobutton,"setImage", functionSetImage)
+ KVSO_REGISTER_HANDLER(KviKvsObject_radiobutton,"toggleEvent",function_toggleEvent)
+
+KVSO_END_REGISTERCLASS(KviKvsObject_radiobutton)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_radiobutton,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_radiobutton)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_radiobutton)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_radiobutton)
+
+bool KviKvsObject_radiobutton::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QRadioButton(parentScriptWidget(),name()),true);
+ connect(widget(),SIGNAL(toggled(bool)),this,SLOT(toggled(bool)));
+ return true;
+}
+bool KviKvsObject_radiobutton::functionSetText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((QRadioButton *)widget())->setText(szText);
+ return true;
+}
+bool KviKvsObject_radiobutton::functionIsChecked(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) c->returnValue()->setBoolean(((QRadioButton *)widget())->isChecked());
+ return true;
+}
+
+bool KviKvsObject_radiobutton::functionSetChecked(KviKvsObjectFunctionCall *c)
+{
+ bool bChecked;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bChecked",KVS_PT_BOOL,0,bChecked)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) ((QRadioButton *)widget())->setChecked(bChecked);
+ return true;
+}
+bool KviKvsObject_radiobutton::functionSetImage(KviKvsObjectFunctionCall *c)
+{
+ QString icon;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("icon_id",KVS_PT_STRING,0,icon)
+ KVSO_PARAMETERS_END(c)
+ if (!widget()) return true;
+ QPixmap * pix = g_pIconManager->getImage(icon);
+ if(pix)widget()->setIcon(*pix);
+ return true;
+}
+bool KviKvsObject_radiobutton::function_toggleEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("toggled",c,c->params());
+ return true;
+}
+
+void KviKvsObject_radiobutton::toggled(bool b)
+{
+ KviKvsVariantList params(new KviKvsVariant(b));
+ callFunction(this,"toggleEvent",&params);
+}
+
+
+#include "m_class_radiobutton.moc"
diff --git a/src/modules/objects/class_radiobutton.h b/src/modules/objects/class_radiobutton.h
new file mode 100644
index 00000000..127af8cd
--- /dev/null
+++ b/src/modules/objects/class_radiobutton.h
@@ -0,0 +1,51 @@
+#ifndef _CLASS_RADIOBUTTON_H_
+#define _CLASS_RADIOBUTTON_H_
+//mdm:
+// File : class_radiobutton.h
+// Creation date :Thu Feb 08 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) 1999-2005 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 <qradiobutton.h>
+#include "class_widget.h"
+
+
+#include "object_macros.h"
+
+class KviKvsObject_radiobutton : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_radiobutton)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionSetText(KviKvsObjectFunctionCall *c);
+ bool functionIsChecked(KviKvsObjectFunctionCall *c);
+ bool functionSetChecked(KviKvsObjectFunctionCall *c);
+ bool functionSetImage(KviKvsObjectFunctionCall *c);
+ bool function_toggleEvent(KviKvsObjectFunctionCall *c);
+protected slots:
+ void toggled(bool b);
+
+};
+
+#endif //!_CLASS_RADIOBUTTON_H_
diff --git a/src/modules/objects/class_slider.cpp b/src/modules/objects/class_slider.cpp
new file mode 100644
index 00000000..603e4c9a
--- /dev/null
+++ b/src/modules/objects/class_slider.cpp
@@ -0,0 +1,287 @@
+//mdm :
+// File : class_Slider.cpp
+// Creation date : Mon Gen 27 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) 1999-2000 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_slider.h"
+#include "kvi_error.h"
+
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+
+/*
+@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(<orientation:string>)
+ Sets the slider's orientation.[br]
+ Orientation value can be "Horizontal" or "Vertical".
+ !fn: $setTracking(<bTracking:boolean>)
+ Sets whether slider tracking is enabled to enable.[br]
+ Value can be 1 or 0.
+ !fn: $setMaxValue(<value:integer>)
+ Sets maximum value for slider's range.
+ !fn: $setMinValue(<minv_value:integer>)
+ Sets minimum value for slider's range.
+ !fn: $setLineStep(<line_step:integer>)
+ Sets the line step to <line_step>.
+ !fn: $setPageStep(<page_step:integer>)
+ Sets the page step to <page_step>.
+ !fn: $setTickmarks(<tick_marks:string>)
+ 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(<value>)
+ Sets the interval between tickmarks.
+ !fn: <integer> $value()
+ Returns slider value.
+ !fn: <integer> $minValue()
+ Returns slider minValue.
+ !fn: <integer> $maxValue()
+ Returns slider maxValue.
+ !fn: <integer> $lineStep()
+ Returns slider lineStep value.
+ !fn: <integer>$pageStep()
+ Returns slider pageStep value.
+ !fn: $valueChangedEvent(<new slider value:integer>)
+ 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(KviKvsObject_slider,"slider","widget")
+
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"setTracking", functionsetTracking);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"setValue", functionsetValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"setMinValue", functionsetMinValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"setMaxValue", functionsetMaxValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"setLineStep", functionsetLineStep);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"setPageStep", functionsetPageStep);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"setTickInterval", functionsetTickInterval);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"value",functionvalue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"minValue", functionminValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"maxValue", functionmaxValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"lineStep", functionlineStep);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"pageStep", functionpageStep);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"setTickmarks", functionsetTickmarks);
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"setOrientation", functionsetOrientation);
+
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_slider,"valueChangedEvent", functionvalueChangedEvent);
+KVSO_END_REGISTERCLASS(KviKvsObject_slider)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_slider,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_slider)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_slider)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_slider)
+
+bool KviKvsObject_slider::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QSlider(parentScriptWidget(), name()), true);
+ connect(widget(),SIGNAL(valueChanged(int)),this,SLOT(valueChanged(int)));
+ return true;
+}
+
+bool KviKvsObject_slider::functionsetTracking(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QSlider *)widget())->setTracking(bEnabled);
+ return true;
+}
+
+
+bool KviKvsObject_slider::functionsetValue(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iValue;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("value",KVS_PT_INT,0,iValue)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QSlider *)widget())->setValue(iValue);
+ return true;
+}
+bool KviKvsObject_slider::functionsetMinValue(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iMinvalue;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("minimum_value",KVS_PT_INT,0,iMinvalue)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QSlider *)widget())->setMinValue(iMinvalue);
+ return true;
+}
+bool KviKvsObject_slider::functionsetMaxValue(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iMaxvalue;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("max_value",KVS_PT_INT,0,iMaxvalue)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QSlider *)widget())->setMaxValue(iMaxvalue);
+ return true;
+}
+
+bool KviKvsObject_slider::functionsetLineStep(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iLinestep;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("line_step",KVS_PT_INT,0,iLinestep)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QSlider *)widget())->setLineStep(iLinestep);
+ return true;
+}
+bool KviKvsObject_slider::functionsetPageStep(KviKvsObjectFunctionCall *c)
+{
+ 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;
+}
+
+bool KviKvsObject_slider::functionsetTickInterval(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iInterval;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("tick_interval",KVS_PT_INT,0,iInterval)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QSlider *)widget())->setTickInterval(iInterval);
+ return true;
+}
+
+bool KviKvsObject_slider::functionvalue(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QSlider *)widget())->value());
+ return true;
+}
+
+bool KviKvsObject_slider::functionminValue(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QSlider *)widget())->minValue());
+ return true;
+}
+bool KviKvsObject_slider::functionmaxValue(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QSlider *)widget())->maxValue());
+ return true;
+}
+bool KviKvsObject_slider::functionlineStep(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QSlider *)widget())->lineStep());
+ return true;
+}
+
+bool KviKvsObject_slider::functionpageStep(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QSlider *)widget())->pageStep());
+ return true;
+}
+
+
+bool KviKvsObject_slider::functionsetTickmarks(KviKvsObjectFunctionCall *c)
+{
+
+ QString szTick;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("tick_marks",KVS_PT_STRING,0,szTick)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ if(KviQString::equalCI(szTick,"NoMarks"))
+ ((QSlider *)widget())->setTickmarks(QSlider::NoMarks);
+ else if(KviQString::equalCI(szTick,"Both"))
+ ((QSlider *)widget())->setTickmarks(QSlider::Both);
+ else if(KviQString::equalCI(szTick,"Above"))
+ ((QSlider *)widget())->setTickmarks(QSlider::Above);
+ else if(KviQString::equalCI(szTick,"Below"))
+ ((QSlider *)widget())->setTickmarks(QSlider::Below);
+ else if(KviQString::equalCI(szTick,"Left"))
+ ((QSlider *)widget())->setTickmarks(QSlider::Left);
+ else if(KviQString::equalCI(szTick,"Right"))
+ ((QSlider *)widget())->setTickmarks(QSlider::Right);
+ else c->warning( __tr2qs("Unknown tickmark '%Q'"),&szTick);
+ return true;
+}
+bool KviKvsObject_slider::functionsetOrientation(KviKvsObjectFunctionCall *c)
+{
+
+ QString szOrientation;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("orientation",KVS_PT_STRING,0,szOrientation)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ 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("Unknown orientation '%Q'"),&szOrientation);
+ return true;
+}
+bool KviKvsObject_slider::functionvalueChangedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("valueChanged",c,c->params());
+ return true;
+}
+
+void KviKvsObject_slider::valueChanged(int value)
+{
+ KviKvsVariantList params(new KviKvsVariant((kvs_int_t)value));
+ callFunction(this,"valueChangedEvent",&params);
+}
+
+
+#include "m_class_slider.moc"
diff --git a/src/modules/objects/class_slider.h b/src/modules/objects/class_slider.h
new file mode 100644
index 00000000..e2c8c397
--- /dev/null
+++ b/src/modules/objects/class_slider.h
@@ -0,0 +1,64 @@
+#ifndef _CLASS_SLIDER_H_
+#define _CLASS_SLIDER_H_
+//mdm:
+// File : class_Slider.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) 1999-2000 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 <qslider.h>
+#include "class_widget.h"
+
+
+#include "object_macros.h"
+
+class KviKvsObject_slider : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_slider)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionsetTracking(KviKvsObjectFunctionCall *c);
+ bool functionsetValue(KviKvsObjectFunctionCall *c);
+ bool functionsetMinValue(KviKvsObjectFunctionCall *c);
+ bool functionsetMaxValue(KviKvsObjectFunctionCall *c);
+ bool functionsetLineStep(KviKvsObjectFunctionCall *c);
+ bool functionsetPageStep(KviKvsObjectFunctionCall *c);
+ bool functionsetTickInterval(KviKvsObjectFunctionCall *c);
+ bool functionvalue(KviKvsObjectFunctionCall *c);
+ bool functionminValue(KviKvsObjectFunctionCall *c);
+ bool functionmaxValue(KviKvsObjectFunctionCall *c);
+ bool functionlineStep(KviKvsObjectFunctionCall *c);
+ bool functionpageStep(KviKvsObjectFunctionCall *c);
+ bool functionsetTickmarks(KviKvsObjectFunctionCall *c);
+ bool functionsetOrientation(KviKvsObjectFunctionCall *c);
+ bool functionvalueChangedEvent(KviKvsObjectFunctionCall *c);
+
+protected slots:
+ void valueChanged(int);
+};
+
+
+
+#endif // !_CLASS_SLIDER_H_
+
diff --git a/src/modules/objects/class_socket.cpp b/src/modules/objects/class_socket.cpp
new file mode 100644
index 00000000..f0afe3a5
--- /dev/null
+++ b/src/modules/objects/class_socket.cpp
@@ -0,0 +1,1331 @@
+//
+// File : class_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 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 "kvi_qstring.h"
+
+#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+
+
+#include "kvi_locale.h"
+#include "kvi_error.h"
+#include "kvi_netutils.h"
+#include "kvi_dns.h"
+#include "kvi_error.h"
+#include "kvi_socket.h"
+#include "kvi_malloc.h"
+#include "kvi_memmove.h"
+#include "kvi_databuffer.h"
+#include "kvi_qcstring.h"
+
+#include "class_socket.h"
+
+//#include <stdlib.h>
+
+#define KVI_IN_BUFFER_ALLOC_CHUNK 4096
+#define KVI_READ_CHUNK 1024
+/*
+static KviScriptObjectClass * g_pSocketClass = 0;
+
+static KviScriptObject * socketClassCreateInstance(KviScriptObjectClass * cls,KviScriptObject *par,const char * nam)
+{
+ return new KviScriptSocketObject(cls,par,nam);
+}
+
+KviScriptSocketObject::KviScriptSocketObject(KviScriptObjectClass * cla,KviScriptObject * par,const char * nam)
+: KviScriptObject(cla,par,nam)
+{
+ 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()));
+}
+
+KviScriptSocketObject::~KviScriptSocketObject()
+{
+ delete m_pOutBuffer;
+ delete m_pFlushTimer;
+
+ if(m_pInBuffer)kvi_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);
+}
+
+void KviScriptSocketObject::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)
+ {
+ kvi_free(m_pInBuffer);
+ m_pInBuffer = 0;
+ }
+ if(m_secondarySock)
+ {
+ kvi_socket_close(m_secondarySock);
+ m_secondarySock = KVI_INVALID_SOCKET;
+ }
+ m_uSecondaryPort = 0;
+ m_szSecondaryIp.clear();
+ 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.clear();
+ m_uLocalPort = 0;
+ m_szLocalIp.clear();
+ m_bIpV6 = false;
+}
+
+/*
+ @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(<timeout>)
+ Sets the connect timeout for this socket. <timeout> must be a positive value in milliseconds.[br]
+ The default timeout is 60000.
+
+ !fn: $connect(<host>,<port>)
+ Attempts a connection to <host> on port <port>.[br]
+ <host> 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 succesfully initiated,
+ 0 otherwise.[br] In fact , this function returns 0 only if the supplied <port> parameter
+ is invalid or the socket is in an incoherent state (already connected or listening):
+ for a newly created socket and with a valid <port> 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([<port>[,<interface>[,<force_ipv6>]]])
+ Attempts to listen on the specified <port> and <interface>.[br]
+ If <port> is not passed it is assumed to be 0 , if <interface> 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 <interface> is recognized as IPV6 address , and IPV6 is supported , the socket listens
+ in IPV6 mode. If <interface> is an empty string and <force_ipv6> 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(<socketId>)
+ This function can be called only from inside $incomingConnectionEvent().[br]
+ <socketId> 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 succesfully 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(<reason>)
+ This function is called when a connection attempt fails for some reason. <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(<data_length>)
+ This function is called when some data is available to be read: the <data_length> 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(<length>)
+ Reads at most <length> bytes of data from the socket. If <length> is anything "outside" the
+ available data range (<length> < 0 or <length> > available_data_length), this function
+ returns all the available data.[br]
+ Please note that this function can't deal withi binary data: NULL characters are transformed to
+ ASCII characters 255.
+
+ !fn: $readHex(<length>)
+ Reads at most <length> bytes of data from the socket. If <length> is anything "outside" the
+ available data range (<length> < 0 or <length> > available_data_length), this function
+ returns all the available data.[br]
+ Returns the data encoded as hexadecimal digit string: this function can deal with binary data too.
+
+ !fn: $write(<data>)
+ Writes <data> to the socket.[br]
+ This function can't deal with binary data (you can't send a NULL character)[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]
+ 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: $writeHex(<hex_data>)
+ Writes <data> to the socket.[br]
+ <data> is expected to be a hexadecimal rappresentation of the bytes to be sent (two HEX characters
+ for each byte). This means that the length of <hex_data> string must be a multiple of 2.[br]
+ Returns the length of the actually decoded and sent data in bytes or -1 in case of error (the string
+ was not a valid hexadecimla rappresentation).[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]
+ If you're going to [cmd]delete[/cmd] this object just after the $writeHex 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(<protocol>)
+ Let KVIrc use TCP jr 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 80 port and answer to requests (multi-threaded)[br]
+[br]
+ class (webserver,socket) {[br]
+ constructor () {[br]
+ $$->$listen(80, "127.0.0.1")[br]
+ }[br]
+ incomingConnectionEvent()[br]
+ {[br]
+ %tmp = $new(socket)[br]
+ $$->$accept(%tmp)[br]
+ echo "Webserver incoming Conection from: %tmp->$remoteIp : %tmp->$remotePort"[br]
+ %tmp->$write("HTTP/1.1 200 OK\n\n<html><head></head><body><h1>KVIrc Webserver</h1></body></html>\n")[br]
+ %tmp->$close()[br]
+ delete %tmp[br]
+ }[br]
+ }[br]
+ [br]
+ #finally start webserver[br]
+ %WebS = $new(webserver)[br]
+ [br]
+ [/example]
+ [example]
+ #Client socket - go to google and grab request header[br]
+ class (httprequest,socket) {[br]
+ constructor () [br]
+ {[br]
+ # connect to the server[br]
+ $$->$connect("www.google.de",80)[br]
+ }[br]
+ destructor()[br]
+ {[br]
+ # if the socket is still open close it[br]
+ if($$->$status() == 4) $$->$close()[br]
+ }[br]
+ connectFailedEvent() [br]
+ {[br]
+ # the connection to the server failed[br]
+ echo "Connection failed: "$0[br]
+ delete $$[br]
+ }[br]
+ connectEvent() [br]
+ {[br]
+ # connection is complete[br]
+ # send a request to receive the headers only from http://www.google.de/[br]
+ $$->$write("HEAD / HTTP/1.1\r\nHost: www.google.de\r\nConnction: Close\r\nUser-Agent: KVIrc socket\r\n\r\n");[br]
+ }[br]
+ dataAvailableEvent() [br]
+ {[br]
+ # reading the received data[br]
+ %newdata = $$->$read($0)[br]
+ echo %newdata[br]
+ #close and delete the socket[br]
+ $$->$close()[br]
+ delete $$[br]
+ }[br]
+ disconnectEvent() [br]
+ {[br]
+ # connection has been closed[br]
+ echo "Connection closed"[br]
+ delete $$[br]
+ }[br]
+}[br]
+
+#Creating the socket[br]
+%Temp = $new(httprequest)[br]
+ [/example]
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_socket,"socket","object")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"status",functionStatus)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"remotePort",functionRemotePort)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"remoteIp",functionRemoteIp)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"localIp",functionLocalIp)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"localPort",functionLocalPort)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"connect",functionConnect)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"connectTimeout",functionConnectTimeout)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"setConnectTimeout",functionSetConnectTimeout)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"close",functionClose)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"read",functionRead)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"readHex",functionReadHex)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"write",functionWrite)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"writeHex",functionWriteHex)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"setProtocol",functionSetProtocol)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"listen",functionListen)
+ KVSO_REGISTER_HANDLER(KviKvsObject_socket,"accept",functionAccept)
+
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"connectEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"connectFailedEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"disconnectEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"dataAvailableEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"incomingConnectionEvent")
+
+KVSO_END_REGISTERCLASS(KviKvsObject_socket)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_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(KviKvsObject_socket)
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_socket)
+ delete m_pOutBuffer;
+ delete m_pFlushTimer;
+
+ if(m_pInBuffer)kvi_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(KviKvsObject_socket)
+//----------------------
+
+
+bool KviKvsObject_socket::functionStatus(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setInteger(m_iStatus);
+ return true;
+}
+
+bool KviKvsObject_socket::functionClose(KviKvsObjectFunctionCall *c)
+{
+ if((m_pOutBuffer->size() != 0) && (m_iStatus == KVI_SCRIPT_SOCKET_STATUS_CONNECTED))
+ tryFlush();
+
+ reset();
+ return true;
+}
+
+bool KviKvsObject_socket::functionConnectTimeout(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setInteger(m_uConnectTimeout);
+ return true;
+}
+
+bool KviKvsObject_socket::functionSetConnectTimeout(KviKvsObjectFunctionCall *c)
+{
+ 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;
+}
+
+bool KviKvsObject_socket::functionRemotePort(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setInteger(m_uRemotePort);
+ return true;
+}
+
+bool KviKvsObject_socket::functionRemoteIp(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setString(m_szRemoteIp);
+ return true;
+}
+
+bool KviKvsObject_socket::functionLocalPort(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setInteger(m_uLocalPort);
+ return true;
+}
+
+bool KviKvsObject_socket::functionLocalIp(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setString(m_szLocalIp);
+ return true;
+}
+
+bool KviKvsObject_socket::functionAccept(KviKvsObjectFunctionCall *c)
+{
+ 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("No socket object specified"));
+ return true;
+ }
+
+ if(!pObject->inherits("KviKvsObject_socket"))
+ {
+ c->warning(__tr2qs("Invalid socket object specified (it doesn't inherit from socket)"));
+ return true;
+ }
+
+ if(m_secondarySock != KVI_INVALID_SOCKET)
+ {
+ ((KviKvsObject_socket *)pObject)->acceptConnection(m_secondarySock,m_uSecondaryPort,m_szSecondaryIp);
+
+ m_secondarySock = KVI_INVALID_SOCKET;
+ m_uSecondaryPort = 0;
+ m_szSecondaryIp="";
+ } else {
+ c->warning(__tr2qs("There is no connection to accept!"));
+ }
+ return true;
+}
+
+
+bool KviKvsObject_socket::functionSetProtocol(KviKvsObjectFunctionCall *c)
+{
+ QString m_szHex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("hex_string",KVS_PT_STRING,0,m_szHex)
+ KVSO_PARAMETERS_END(c)
+
+ m_bUdp=KviQString::equalCI(m_szHex,"udp");
+ return false;
+}
+
+bool KviKvsObject_socket::functionWriteHex(KviKvsObjectFunctionCall *c)
+{
+ QString m_szHex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("hex_string",KVS_PT_STRING,0,m_szHex)
+ KVSO_PARAMETERS_END(c)
+
+ if(m_szHex.length() > 0)
+ {
+ bool bOk;
+ QString szTmp;
+ szTmp=m_szHex.setNum(m_szHex.toInt(&bOk,16),16);
+ if(szTmp.length()>0)
+ {
+ KviQCString szData8 = szTmp.utf8();
+ m_pOutBuffer->append((const unsigned char *)(szData8.data()),szData8.length());
+ delayedFlush(0);
+ c->returnValue()->setInteger(szData8.length());
+ }
+ }
+
+ /*
+ if(pszData)
+ {
+ if(pszData->len() > 0)
+ {
+ char * ptr;
+ len = pszData->hexToBuffer(&ptr);
+ if(len > 0)
+ {
+ m_pOutBuffer->append((const unsigned char *)(ptr),len);
+ delayedFlush(0);
+ KviStr::freeBuffer(ptr);
+ }
+ }
+ }
+ buffer.append(KviStr::Format,"%d",len);
+*/
+ return true;
+}
+
+
+
+
+
+bool KviKvsObject_socket::functionConnect(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ debug ("Function connect");
+
+
+ if (m_uRemotePort>65535)
+ {
+ c->warning(__tr2qs("Value %d for port is out of range (values allowed are from 0 to 65535"),m_uRemotePort);
+ return true;
+ }
+ if((m_sock != KVI_INVALID_SOCKET) || (m_iStatus != KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED))
+ {
+ c->warning(__tr2qs("Another connection in progress"));
+ c->returnValue()->setBoolean(true);
+ return true;
+ }
+
+
+#ifdef COMPILE_IPV6_SUPPORT
+ if(kvi_isValidStringIp(m_szRemoteIp) || kvi_isValidStringIp_V6(m_szRemoteIp))
+#else
+ if(kvi_isValidStringIp(m_szRemoteIp))
+#endif
+ {
+ debug ("ok connecting");
+ debug ("connectinhg on ip %s ",m_szRemoteIp.latin1());
+ debug ("non so ip");
+ m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTING;
+ delayedConnect();
+ } else {
+ debug ("connectinhg on ip %s port %d",m_szRemoteIp.latin1(),m_uRemotePort);
+ m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DNS;
+ delayedLookupRemoteIp();
+ }
+ c->returnValue()->setBoolean(true);
+ return true;
+}
+
+
+
+
+
+
+bool KviKvsObject_socket::functionListen(KviKvsObjectFunctionCall *c)
+{
+ if((m_sock != KVI_INVALID_SOCKET) || (m_iStatus != KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED))
+ {
+ c->warning(__tr2qs("Another connection in progress"));
+ 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("No IPV6 support in this executable"));
+ c->returnValue()->setBoolean(false);
+ reset();
+ return true;
+ }
+#endif
+
+ bool bGotIp = false;
+
+ if(!m_szLocalIp.isEmpty())
+ {
+
+ // Check the address type
+ if(kvi_isValidStringIp(m_szLocalIp))bGotIp = true;
+ else {
+#ifdef COMPILE_IPV6_SUPPORT
+ if(kvi_isValidStringIp_V6(m_szLocalIp))
+ {
+ bGotIp = true;
+ m_bIpV6 = true;
+ } else {
+#else
+ c->warning(__tr2qs("Invalid IP address specified ('%Q')"),&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("Socket creation failed"));
+ c->returnValue()->setBoolean(false);
+ reset();
+ return true;
+ }
+
+ if(!m_szLocalIp.isEmpty())
+ {
+#ifdef COMPILE_IPV6_SUPPORT
+ KviSockaddr sa(m_szLocalIp,m_uLocalPort,m_bIpV6,m_bUdp);
+#else
+ KviSockaddr sa(m_szLocalIp,m_uLocalPort,false,m_bUdp);
+#endif
+ if(!sa.socketAddress())
+ {
+ c->warning(__tr2qs("Invalid socket address"));
+ reset();
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+
+ if(!kvi_socket_bind(m_sock,sa.socketAddress(),((int)(sa.addressLength()))))
+ {
+ c->warning(__tr2qs("Bind failure"));
+ 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("Invalid socket address"));
+ reset();
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+
+ if(!kvi_socket_bind(m_sock,sa.socketAddress(),((int)(sa.addressLength()))))
+ {
+ c->warning(__tr2qs("Bind failure"));
+ reset();
+ c->returnValue()->setBoolean(false);
+ return true;
+ }
+ }
+
+
+ if(!kvi_socket_listen(m_sock,5))
+ {
+ c->warning(__tr2qs("Listen failure"));
+ 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 KviKvsObject_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(!kvi_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(!kvi_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 KviKvsObject_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 KviKvsObject_socket::delayedConnect()
+{
+ if(m_pDelayTimer)delete m_pDelayTimer;
+ m_pDelayTimer = new QTimer();
+ connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(doConnect()));
+ m_pDelayTimer->start(0,true);
+}
+
+void KviKvsObject_socket::doConnect()
+{
+ debug ("doConnect function");
+ if(m_pDelayTimer)delete m_pDelayTimer;
+ m_pDelayTimer = 0;
+
+
+ KviSockaddr sa(m_szRemoteIp,m_uRemotePort,!kvi_isValidStringIp(m_szRemoteIp),m_bUdp);
+
+ if(!sa.socketAddress())
+ {
+ unsigned int uOldConnectionId = m_uConnectionId;
+ QString ipAddressError=__tr2qs("Invalid ip address ");
+
+ ipAddressError.append(m_szRemoteIp);
+
+ KviKvsVariantList params;
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("Invalid ip address (%Q)"),&m_szRemoteIp);
+ params.append(new KviKvsVariant(tmp));
+ callFunction(this,"connectFailedEvent",&params);
+ /* callEventFunction("connectFailedEvent",0,new KviParameterList(
+ new KviStr(KviStr::Format,__tr("Invalid ip address (%s)"),m_szRemoteIp.ptr())));
+ */ if(m_uConnectionId == uOldConnectionId)reset();
+ // else it has already been called!
+ return;
+ }
+debug ("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;
+ callFunction(this,"connectFailedEvent",new KviKvsVariantList(
+ new KviKvsVariant(__tr2qs("Failed to create the socket"))));
+ if(m_uConnectionId == uOldConnectionId)reset();
+ // else it has already been called!
+ return;
+ }
+ debug ("Valid socket");
+
+ if(!kvi_socket_setNonBlocking(m_sock))
+ {
+ unsigned int uOldConnectionId = m_uConnectionId;
+
+ callFunction(this,"connectFailedEvent",new KviKvsVariantList(
+ new KviKvsVariant(__tr2qs("Failed to setup a nonblocking socket"))));
+ 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("Connect failure: ");
+
+ callBackError.append((KviError::getDescription(KviError::translateSystemError(sockError)).utf8().data()));
+ callFunction(this,"connectFailedEvent",new KviKvsVariantList(
+ new KviKvsVariant(callBackError)));
+
+/* callEventFunction("connectFailedEvent",0,new KviParameterList(
+ new KviStr(KviStr::Format,__tr("Connect failure: %s"),KviError::getDescription(KviError::translateSystemError(sockError)).utf8().data())));
+*/ if(m_uConnectionId == uOldConnectionId)reset();
+ // else it has already been called!
+ return;
+ }
+ }
+ debug ("Socket connected");
+ m_pDelayTimer = new QTimer();
+ connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(connectTimeout()));
+ m_pDelayTimer->start(m_uConnectTimeout,true);
+
+ 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 KviKvsObject_socket::connectTimeout()
+{
+ unsigned int uOldConnectionId = m_uConnectionId;
+
+ callFunction(this,"connectFailedEvent",new KviKvsVariantList(
+ new KviKvsVariant(__tr2qs("Connect attempt timed out"))));
+ if(m_uConnectionId == uOldConnectionId)reset();
+ // else it has already been called!
+}
+
+void KviKvsObject_socket::delayedLookupRemoteIp()
+{
+ if(m_pDelayTimer)delete m_pDelayTimer;
+ m_pDelayTimer = new QTimer();
+ connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(lookupRemoteIp()));
+ m_pDelayTimer->start(0,true);
+}
+
+void KviKvsObject_socket::lookupRemoteIp()
+{
+ debug ("Resolve dns");
+ if(m_pDelayTimer)delete m_pDelayTimer;
+ m_pDelayTimer = 0;
+ if(m_pDns)delete m_pDns;
+ m_pDns = new KviDns();
+ connect(m_pDns,SIGNAL(lookupDone(KviDns *)),this,SLOT(lookupDone(KviDns *)));
+ if(!m_pDns->lookup(m_szRemoteIp,KviDns::Any))
+ {
+ unsigned int uOldConnectionId = m_uConnectionId;
+
+ callFunction(this,"connectFailedEvent",new KviKvsVariantList(
+ new KviKvsVariant(__tr2qs("Can't start the DNS thread"))));
+ if(m_uConnectionId == uOldConnectionId)reset();
+ // else it has already been called!
+ }
+}
+
+void KviKvsObject_socket::lookupDone(KviDns *pDns)
+{
+
+ if(pDns->state() != KviDns::Success)
+ {
+ unsigned int uOldConnectionId = m_uConnectionId;
+
+ callFunction(this,"connectFailedEvent",new KviKvsVariantList(
+ new KviKvsVariant(KviError::getDescription(pDns->error()))));
+
+ if(m_uConnectionId == uOldConnectionId)reset();
+ // else it has already been called!
+ return;
+ }
+ m_szRemoteIp = pDns->firstIpAddress();
+ debug ("Dns resolved in %s",m_szRemoteIp.latin1());
+
+ delete m_pDns;
+ m_pDns = 0;
+ doConnect();
+}
+
+void KviKvsObject_socket::writeNotifierFired(int)
+{
+ debug ("Here in the writeNotifierFired");
+ 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)
+ {
+ //debug("Failed here %d",sockError);
+ //failed
+ if(sockError > 0)sockError = KviError::translateSystemError(sockError);
+ else sockError = KviError_unknownError; //Error 0 ?
+ unsigned int uOldConnectionId = m_uConnectionId;
+ callFunction(this,"connectFailedEvent",new KviKvsVariantList(
+ new KviKvsVariant(KviError::getDescription(sockError))));
+ 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 KviKvsObject_socket::readNotifierFired(int)
+{
+ debug ("here in the readNotifierFired");
+ //read data
+ if((m_uInBufferLen - m_uInDataLen) < KVI_READ_CHUNK)
+ {
+ m_uInBufferLen += KVI_IN_BUFFER_ALLOC_CHUNK;
+ m_pInBuffer = (char *)kvi_realloc(m_pInBuffer,m_uInBufferLen);
+ }
+
+ 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();
+#ifdef COMPILE_ON_WINDOWS
+ 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);
+ callFunction(this,"disconnectEvent",new KviKvsVariantList(
+ new KviKvsVariant((kvs_int_t)KviError::translateSystemError(err))));
+ } else {
+ callFunction(this,"disconnectEvent",new KviKvsVariantList(
+ new KviKvsVariant(KviError::getDescription(KviError_remoteEndClosedConnection))));
+
+ }
+ 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;
+
+ //KviStr * s = new KviStr();
+ QString s;
+ s.setNum(m_uInDataLen);
+
+
+ unsigned int uOldConnectionId = m_uConnectionId;
+ callFunction(this,"dataAvailableEvent",new KviKvsVariantList(new KviKvsVariant(s)));
+ if(m_uConnectionId == uOldConnectionId)
+ {
+ if(m_uInDataLen > (4096 * 1024)) // too much data in buffer (not reading)
+ {
+ callFunction(this,"disconnectEvent",new KviKvsVariantList(
+ new KviKvsVariant(__tr2qs("Too much unprocessed incoming data (you've left this socket unmanaged ?)"))));
+ reset();
+ }
+ }
+}
+
+void KviKvsObject_socket::eatInData(unsigned int uLen)
+{
+ if(uLen > m_uInDataLen)uLen = m_uInDataLen;
+
+ m_uInDataLen -= uLen;
+
+ if(m_uInDataLen > 0)
+ {
+ kvi_memmove(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 *)kvi_realloc(m_pInBuffer,m_uInBufferLen);
+ }
+}
+
+void KviKvsObject_socket::delayedFlush(unsigned int uTimeout)
+{
+ if(m_pFlushTimer->isActive())m_pFlushTimer->stop();
+ m_pFlushTimer->start(uTimeout);
+}
+
+void KviKvsObject_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();
+#ifdef COMPILE_ON_WINDOWS
+ 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;
+ callFunction(this,"disconnectEvent",0,new KviKvsVariantList(
+ new KviKvsVariant(KviError::getDescription(KviError::translateSystemError(err)))));
+ if(m_uConnectionId == uOldConnectionId)reset();
+ // else it has already been called!
+ return;
+ }
+ }
+}
+void KviKvsObject_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)
+ {
+ kvi_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;
+}
+unsigned int KviKvsObject_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;
+ }
+
+bool KviKvsObject_socket::functionRead(KviKvsObjectFunctionCall *c)
+{
+ unsigned int uLen = readGetLength(c);
+
+ 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;
+}
+
+bool KviKvsObject_socket::functionReadHex(KviKvsObjectFunctionCall *c)
+{
+ //??? funzioner�
+ unsigned int uLen = readGetLength(c);
+ bool bOk;
+ if(uLen > 0)
+ {
+ QString szTmp;
+ szTmp =m_pInBuffer;
+ szTmp.toInt(&bOk,16);
+ c->returnValue()->setString(szTmp);
+ eatInData(uLen);
+ }
+ return true;
+}
+
+bool KviKvsObject_socket::functionWrite(KviKvsObjectFunctionCall *c)
+{
+ QString szData;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("szData",KVS_PT_STRING,0,szData)
+ KVSO_PARAMETERS_END(c)
+
+KviQCString szData8 = szData.utf8();
+ if(szData8.length() > 0)
+ {
+ m_pOutBuffer->append((const unsigned char*)szData8.data(),szData8.length());
+ delayedFlush(0);
+ }
+ return true;
+}
+
+
+
+//--------------
+
+#include "m_class_socket.moc"
diff --git a/src/modules/objects/class_socket.h b/src/modules/objects/class_socket.h
new file mode 100644
index 00000000..7ed2e421
--- /dev/null
+++ b/src/modules/objects/class_socket.h
@@ -0,0 +1,185 @@
+#ifndef _CLASS_SOCKET_H_
+#define _CLASS_SOCKET_H_
+//
+// File : class_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 "kvi_pointerlist.h"
+#include <qsocketnotifier.h>
+#include <qtimer.h>
+
+#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 KviDns;
+class KviDataBuffer;
+/*
+class KviScriptSocketObject : public KviScriptObject
+{
+ Q_OBJECT
+public:
+ KviScriptSocketObject(KviScriptObjectClass * cla,KviScriptObject * par,const char * nam);
+ virtual ~KviScriptSocketObject();
+protected:
+ kvi_socket_t m_sock;
+ int m_iStatus;
+ KviStr m_szRemoteIp;
+ unsigned short int m_uRemotePort;
+ KviStr m_szLocalIp;
+ unsigned short int m_uLocalPort;
+ unsigned int m_uConnectTimeout;
+ QSocketNotifier * m_pSn;
+ KviDns * m_pDns;
+ QTimer * m_pDelayTimer;
+ char * m_pInBuffer;
+ unsigned int m_uInBufferLen;
+ unsigned int m_uInDataLen;
+ bool m_bIpV6;
+ unsigned int m_uConnectionId;
+
+ KviDataBuffer * m_pOutBuffer;
+ QTimer * m_pFlushTimer;
+
+ kvi_socket_t m_secondarySock;
+ unsigned short int m_uSecondaryPort;
+ KviStr m_szSecondaryIp;
+protected:
+ bool functionStatus(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionRemotePort(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionRemoteIp(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionLocalPort(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionLocalIp(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionConnect(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionSetConnectTimeout(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionConnectTimeout(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionClose(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionRead(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionReadHex(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionWrite(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionWriteHex(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionListen(KviCommand *c,KviParameterList * params,KviStr &buffer);
+ bool functionAccept(KviCommand *c,KviParameterList * params,KviStr &buffer);
+
+ void delayedConnect();
+ void delayedLookupRemoteIp();
+ void delayedFlush(unsigned int uTimeout);
+
+ void eatInData(unsigned int uLen);
+ unsigned int readGetLength(KviParameterList * params);
+
+ void acceptConnection(kvi_socket_t s,unsigned short int uPort,const char * szIp);
+
+ void reset();
+protected slots:
+ void doConnect();
+ void lookupRemoteIp();
+ void lookupDone(KviDns * pDns);
+ void connectTimeout();
+ void writeNotifierFired(int);
+ void readNotifierFired(int);
+ void tryFlush();
+ void incomingConnection(int);
+public:
+ static void registerSelf();
+ static void unregisterSelf();
+};
+*/
+//===============================================================
+#include "object_macros.h"
+
+
+class KviKvsObject_socket : public KviKvsObject
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_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;
+ KviDns * 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 functionStatus(KviKvsObjectFunctionCall *c);
+ bool functionRemotePort(KviKvsObjectFunctionCall *c);
+ bool functionRemoteIp(KviKvsObjectFunctionCall *c);
+ bool functionLocalPort(KviKvsObjectFunctionCall *c);
+ bool functionLocalIp(KviKvsObjectFunctionCall *c);
+ bool functionConnect(KviKvsObjectFunctionCall *c);
+ bool functionSetConnectTimeout(KviKvsObjectFunctionCall *c);
+ bool functionConnectTimeout(KviKvsObjectFunctionCall *c);
+
+ bool functionClose(KviKvsObjectFunctionCall *c);
+ bool functionRead(KviKvsObjectFunctionCall *c);
+ bool functionReadHex(KviKvsObjectFunctionCall *c);
+ bool functionWrite(KviKvsObjectFunctionCall *c);
+ bool functionWriteHex(KviKvsObjectFunctionCall *c);
+
+ bool functionSetProtocol(KviKvsObjectFunctionCall *c);
+
+ bool functionListen(KviKvsObjectFunctionCall *c);
+ bool functionAccept(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(KviDns * pDns);
+ void connectTimeout();
+ void writeNotifierFired(int);
+ void readNotifierFired(int);
+ void tryFlush();
+ void incomingConnection(int);
+};
+#endif //_CLASS_SOCKET_H_
diff --git a/src/modules/objects/class_spinbox.cpp b/src/modules/objects/class_spinbox.cpp
new file mode 100644
index 00000000..f87a3a51
--- /dev/null
+++ b/src/modules/objects/class_spinbox.cpp
@@ -0,0 +1,265 @@
+//
+// File : class_progressbar.cpp
+// Creation date : Fri Jan 30 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) 1999-2005 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 <qspinbox.h>
+#include "class_spinbox.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+/*
+ @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(<value:integer>)
+ Sets the value of the spin box.[br]
+ See also [classfnc]$value[/classfnc]()
+ !fn: $setMinValue(<min_value:integer>)
+ Sets the minimum value of the spin box.
+ See also [classfnc]$MinValue[/classfnc]()
+ !fn: $setMaxValue(<max_value:integer>)
+ Sets the maximum value of the spin box.[br]
+ See also [classfnc]$maxValue[/classfnc]()
+ !fn: $setLineStep(<line_step:integer>)
+ 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(<text:string>)
+ 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(<text:string>)
+ 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(<text:string>);
+ 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: <integer> $value()
+ Returns the value of the spin box.
+ See also [classfnc]$setValue[/classfnc]()
+ !fn: <integer> $minValue
+ Returns the minimum value of the spin box.
+ See also [classfnc]$setMinValue[/classfnc]()
+ !fn: <integer> $maxValue
+ Returns the maximum value of the spin box.
+ See also [classfnc]$setMaxValue[/classfnc]()
+ !fn: <integer> $lineStep()
+ Return the linestep.
+ !fn: <string> $specialValueText()
+ Returns the special-value text.
+ See also [classfnc]$setSpecialValueText[/classfnc]()
+ !fn: $valueChangedEvent(<new value:integer>)
+ 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(KviKvsObject_spinbox,"spinbox","widget")
+
+
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"setValue", functionsetValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"setMinValue", functionsetMinValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"setMaxValue", functionsetMaxValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"setLineStep", functionsetLineStep);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"setSpecialValueText", functionsetSpecialValueText);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"value",functionvalue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"minValue", functionminValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"maxValue", functionmaxValue);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"lineStep", functionlineStep);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"specialValueText", functionspecialValueText);
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"setPrefix", functionsetPrefix);
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"setSuffix", functionsetSuffix);
+
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_spinbox,"valueChangedEvent", functionvalueChangedEvent);
+KVSO_END_REGISTERCLASS(KviKvsObject_spinbox)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_spinbox,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_spinbox)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_spinbox)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_spinbox)
+
+bool KviKvsObject_spinbox::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QSpinBox(parentScriptWidget(), name()), true);
+ connect(widget(),SIGNAL(valueChanged(int)),this,SLOT(valueChanged(int)));
+ return true;
+}
+
+
+
+bool KviKvsObject_spinbox::functionsetValue(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iValue;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("value",KVS_PT_INT,0,iValue)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QSpinBox *)widget())->setValue(iValue);
+ return true;
+}
+bool KviKvsObject_spinbox::functionsetMinValue(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iMinvalue;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("min_value",KVS_PT_INT,0,iMinvalue)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QSpinBox *)widget())->setMinValue(iMinvalue);
+ return true;
+}
+bool KviKvsObject_spinbox::functionsetMaxValue(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iMaxvalue;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("max_value",KVS_PT_INT,0,iMaxvalue)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QSpinBox *)widget())->setMaxValue(iMaxvalue);
+ return true;
+}
+
+bool KviKvsObject_spinbox::functionsetLineStep(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iLinestep;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("line_step",KVS_PT_INT,0,iLinestep)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QSpinBox *)widget())->setLineStep(iLinestep);
+ return true;
+}
+
+
+bool KviKvsObject_spinbox::functionvalue(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QSpinBox *)widget())->value());
+ return true;
+}
+
+bool KviKvsObject_spinbox::functionminValue(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QSpinBox *)widget())->minValue());
+ return true;
+}
+bool KviKvsObject_spinbox::functionmaxValue(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setInteger(((QSpinBox *)widget())->maxValue());
+ return true;
+}
+bool KviKvsObject_spinbox::functionlineStep(KviKvsObjectFunctionCall *c)
+{
+ if (widget())
+ {
+ #ifdef COMPILE_USE_QT4
+ c->returnValue()->setInteger(((QSpinBox *)widget())->singleStep());
+ #else
+ c->returnValue()->setInteger(((QSpinBox *)widget())->lineStep());
+ #endif
+ }
+
+ return true;
+}
+
+
+bool KviKvsObject_spinbox::functionspecialValueText(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setString(((QSpinBox *)widget())->specialValueText());
+ return true;
+}
+
+
+bool KviKvsObject_spinbox::functionsetSpecialValueText(KviKvsObjectFunctionCall *c)
+{
+
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QSpinBox *)widget())->setSpecialValueText(szText);
+ return true;
+}
+bool KviKvsObject_spinbox::functionsetPrefix(KviKvsObjectFunctionCall *c)
+{
+
+ QString szPrefix;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szPrefix)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QSpinBox *)widget())->setPrefix(szPrefix);
+ return true;
+}
+bool KviKvsObject_spinbox::functionsetSuffix(KviKvsObjectFunctionCall *c)
+{
+
+ QString szSuffix;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szSuffix)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QSpinBox *)widget())->setSuffix(szSuffix);
+ return true;
+}
+
+bool KviKvsObject_spinbox::functionvalueChangedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("valueChanged",c,c->params());
+ return true;
+}
+
+void KviKvsObject_spinbox::valueChanged(int value)
+{
+ KviKvsVariantList params(new KviKvsVariant((kvs_int_t)value));
+ callFunction(this,"valueChangedEvent",&params);
+}
+
+#include "m_class_spinbox.moc"
diff --git a/src/modules/objects/class_spinbox.h b/src/modules/objects/class_spinbox.h
new file mode 100644
index 00000000..d5a6ee94
--- /dev/null
+++ b/src/modules/objects/class_spinbox.h
@@ -0,0 +1,64 @@
+#ifndef _CLASS_SPINBOX_H_
+#define _CLASS_SPINBOX_H_
+//
+// File : class_progressbar.h
+// Creation date : Fri Jan 30 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) 1999-2005 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 <qspinbox.h>
+#include "class_widget.h"
+
+#include "object_macros.h"
+
+class KviKvsObject_spinbox : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_spinbox)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionsetTracking(KviKvsObjectFunctionCall *c);
+
+ bool functionsetValue(KviKvsObjectFunctionCall *c);
+ bool functionsetMinValue(KviKvsObjectFunctionCall *c);
+ bool functionsetMaxValue(KviKvsObjectFunctionCall *c);
+ bool functionsetLineStep(KviKvsObjectFunctionCall *c);
+ bool functionsetPrefix(KviKvsObjectFunctionCall *c);
+ bool functionsetSuffix(KviKvsObjectFunctionCall *c);
+ bool functionvalue(KviKvsObjectFunctionCall *c);
+ bool functionminValue(KviKvsObjectFunctionCall *c);
+ bool functionmaxValue(KviKvsObjectFunctionCall *c);
+ bool functionlineStep(KviKvsObjectFunctionCall *c);
+ bool functionsetSpecialValueText(KviKvsObjectFunctionCall *c);
+ bool functionspecialValueText(KviKvsObjectFunctionCall *c);
+
+ bool functionvalueChangedEvent(KviKvsObjectFunctionCall *c);
+
+protected slots:
+ void valueChanged(int);
+};
+
+#endif //!_CLASS_SPINBOX_H_
diff --git a/src/modules/objects/class_tabwidget.cpp b/src/modules/objects/class_tabwidget.cpp
new file mode 100644
index 00000000..c5e97b60
--- /dev/null
+++ b/src/modules/objects/class_tabwidget.cpp
@@ -0,0 +1,541 @@
+//mdm:
+// File : class_tabwidget.cpp
+// Creation date : Fri Feb 11 10:21:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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_tabwidget.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+/*
+ @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(<widget:object>,<text_label:string>,[<icon_id>])
+ Adds another page to the tab view with the text label and optional icon.
+ !fn: $insertTab(<widget:object>,<tex_label:string>,<index:uinteger>)
+ 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(<tab_widget:object>,<tooltip:string>)
+ Sets the tab tool tip for the tabwidget to <tooltip>.
+ !fn: $removeTabToolTip(<tab_widget:object>)
+ Removes the tab tool tip for the tab. If the page does not have a tip, nothing happens.
+ !fn: $setTabLabel(<tab_widget>, <label:string>)
+ Sets the tab label for <tab_widget> to label.
+ !fn: $changeTab(<tab_widget:object>,<label:text>,[<icon_id>])
+ Defines a new label, and optional icon, for the tab .
+ !fn: $setCurrentPage(<index:uinteger>)
+ Sets the index position of the current tab page to <index>.
+ !fn: <integer> $currentPageIndex()
+ Returns the current page index.
+ !fn: <string> $label(<index:uinteger>)
+ Retunrs the label to the <index>.
+ !fn: <string> $currentTabLabel()
+ Returns the label of the current tab.
+ !fn: $setMargin(<margin:integer>)
+ Sets the margin in this tab widget to <margin>.
+ !fn: <integer> $margin()
+ Returns the margin in this tab widget.
+ !fn: $removePage(<tab_widget:object>)
+ Remove the page <tab_widget>.
+ !fn: $setTabPosition(<tab_position:string>)
+ Sets TabPosition. Valid parameters are : Top, Bottom.
+ !fn: <integer> $count()
+ This property holds the number of tabs in the tab bar.
+ !fn: $currentChangedEvent()
+ This function is invoched when the current tab was changed.[br]
+ The default implementation emits the [classfnc]$currentChange[/classfnc]() signal.
+ @examples:
+ [example]
+ # First we'll create the main tabwidget.
+ %Tabwidget=$new(tabwidget)
+ %Tabwidget->$setToolTip("Example of TabWidget class")
+ %Tabwidget->$setMargin(30)
+ %Tabwidget->$setTabPosition(Top)
+
+ # Now we'll create the new widgets and put they in to the main tabwidget.
+ %firsttab=$new(widget,%Tabwidget)
+ %secondtab=$new(widget,%Tabwidget)
+
+ # Now we'll create the item to put in to tab's pages.
+ %layoutfirsttab=$new(layout,%firsttab)
+ %labelbt=$new(label,%firsttab)
+ %labelbt->$settext(Botton Tab)
+ %labeltt=$new(label,%firsttab)
+ %labeltt->$settext(Top Tab)
+ %buttontb=$new(button,%firsttab)
+ %buttontb->$settext("To &Botton")
+ %buttontt=$new(button,%firsttab)
+ %buttontt->$settext("To &Top")
+
+ # Now we'll give a layout to all items.
+ # This also allows to use privateimpl without making buttons global variables
+ %layoutfirsttab->$addwidget(%labelbt,0,0)
+ %layoutfirsttab->$addwidget(%labeltt,0,1)
+ %layoutfirsttab->$addwidget(%buttontb,1,0)
+ %layoutfirsttab->$addwidget(%buttontt,1,1)
+
+ # 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.
+ %layoutsecondtab=$new(layout,%secondtab)
+ %labelwp=$new(label,%secondtab)
+ %labelwp->$settext("Enjoy the new Class provided by")
+ %layoutsecondtab->$addwidget(%labelwp,0,0)
+ %labelwp->$setalignment("Center")
+ %labelgen=$new(label,%secondtab)
+ %labelgen->$settext(Grifisx \& Noldor)
+ %labelgen->$setalignment("Center")
+ %layoutsecondtab->$addwidget(%labelgen,1,0)
+ %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]
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_tabwidget,"tabwidget","widget")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"addTab", functionaddTab)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"insertTab", functioninsertTab)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"setTabToolTip", functionsetTabToolTip)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"removeTabToolTip", functionremoveTabToolTip)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"setTabLabel", functionsetTabLabel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"changeTab", functionchangeTab)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"setCurrentPage", functionsetCurrentPage)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"currentPageIndex", functioncurrentPageIndex)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"label", functiontabLabel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"currentTabLabel", functioncurrentTabLabel)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"setMargin", functionsetMargin);
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"margin", functionmargin)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"count", functioncount)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"removePage", functionremovePage)
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"setTabPosition", functionsetTabPosition)
+
+ // events
+ KVSO_REGISTER_HANDLER(KviKvsObject_tabwidget,"currentChangedEvent", functionCurrentChangedEvent)
+
+
+
+KVSO_END_REGISTERCLASS(KviKvsObject_tabwidget)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_tabwidget,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_tabwidget)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_tabwidget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_tabwidget)
+
+bool KviKvsObject_tabwidget::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QTabWidget(parentScriptWidget(), name()), true);
+ connect(widget(),SIGNAL(currentChanged(int)),this,SLOT(slotcurrentChanged(int)));
+ return true;
+}
+bool KviKvsObject_tabwidget::functionaddTab(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ 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)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ QPixmap * pix = g_pIconManager->getImage(szIcon);
+
+ if(pix){
+#ifdef COMPILE_USE_QT4
+ ((QTabWidget *)widget())->addTab(((QWidget *)(ob->object())),QIconSet(*pix),szLabel);
+#else
+ ((QTabWidget *)widget())->addTab(((QWidget *)(ob->object())),QIconSet(*pix,QIconSet::Small),szLabel);
+#endif
+ }
+ else((QTabWidget *)widget())->addTab(((QWidget *)(ob->object())),szLabel);
+ return true;
+}
+
+bool KviKvsObject_tabwidget::functioninsertTab(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ 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)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ QPixmap * pix = g_pIconManager->getImage(szIcon);
+ if(pix){
+ #ifdef COMPILE_USE_QT4
+ ((QTabWidget *)widget())->insertTab( ((QWidget *)(ob->object())),QIconSet(*pix),szLabel,uIndex);
+ #else
+ ((QTabWidget *)widget())->insertTab(((QWidget *)(ob->object())),QIconSet(*pix,QIconSet::Small),szLabel,uIndex);
+ #endif
+ }
+ else ((QTabWidget *)widget())->insertTab(((QWidget *)(ob->object())),szLabel,uIndex);
+ return true;
+}
+
+bool KviKvsObject_tabwidget::functionsetCurrentPage(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QTabWidget *)widget())->setCurrentPage(uIndex);
+ return true;
+}
+bool KviKvsObject_tabwidget::functionsetTabToolTip(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ 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)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Not a widget object"));
+ return true;
+ }
+ int ctrl = ((QTabWidget *)widget())->indexOf (((QWidget *)(ob->object())));
+ if (ctrl == -1)
+ {
+ c->warning(__tr2qs("Can't find the tab "));
+ return true;
+ }
+ ((QTabWidget *)widget())->setTabToolTip(((QWidget *)(ob->object())),szTooltip);
+ return true;
+}
+bool KviKvsObject_tabwidget::functionremoveTabToolTip(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!widget()) return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Not a widget object"));
+ return true;
+ }
+ if (((QTabWidget *)widget())->indexOf (((QWidget *)(ob->object()))) == -1)
+ {
+ c->warning(__tr2qs("Can't find the tab "));
+ return true;
+ }
+ ((QTabWidget *)widget())->removeTabToolTip(((QWidget *)(ob->object())));
+ return true;
+}
+
+bool KviKvsObject_tabwidget::functionsetTabLabel(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ 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)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Not a widget object"));
+ return true;
+ }
+ int ctrl = ((QTabWidget *)widget())->indexOf (((QWidget *)(ob->object())));
+ if (ctrl == -1)
+ {
+ c->warning(__tr2qs("Can't find the tab "));
+ return true;
+ }
+ ((QTabWidget *)widget())->setTabLabel(((QWidget *)(ob->object())),szLabel);
+ return true;
+}
+bool KviKvsObject_tabwidget::functioncurrentPageIndex(KviKvsObjectFunctionCall *c)
+{
+ int index=((QTabWidget *)widget())->currentPageIndex();
+ if (widget()) c->returnValue()->setInteger(index);
+ return true;
+}
+bool KviKvsObject_tabwidget::functiontabLabel(KviKvsObjectFunctionCall *c)
+{
+ kvs_uint_t uIndex;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("index",KVS_PT_INT,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ if (!widget()) return true;
+ QString label=((QTabWidget *)widget())->label(uIndex);
+ c->returnValue()->setString(label);
+ return true;
+}
+bool KviKvsObject_tabwidget::functionsetMargin(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iMargin;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("margin",KVS_PT_INT,0,iMargin)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((QTabWidget *)widget())->setMargin(iMargin);
+ return true;
+}
+bool KviKvsObject_tabwidget::functionmargin(KviKvsObjectFunctionCall *c)
+{
+
+ if (widget()) c->returnValue()->setInteger(((QTabWidget *)widget())->margin());
+ return true;
+}
+
+bool KviKvsObject_tabwidget::functioncount(KviKvsObjectFunctionCall *c)
+{
+ if (!widget()) return true;
+ int count = ((QTabWidget *)widget())->count();
+ c->returnValue()->setInteger(count);
+ return true;
+}
+
+bool KviKvsObject_tabwidget::functioncurrentTabLabel(KviKvsObjectFunctionCall *c)
+{
+ if (widget())
+ {
+ int i= ((QTabWidget *)widget())->currentPageIndex();
+ QString label=((QTabWidget *)widget())->label(i);
+ c->returnValue()->setString(label);
+ }
+ return true;
+}
+bool KviKvsObject_tabwidget::functionremovePage(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Not a widget object"));
+ return true;
+ }
+ int ctrl = ((QTabWidget *)widget())->indexOf (((QWidget *)(ob->object())));
+ if (ctrl == -1)
+ {
+ c->warning(__tr2qs("Can't find the tab "));
+ return true;
+ }
+ ((QTabWidget *)widget())->removePage(((QWidget *)(ob->object())));
+ return true;
+}
+
+bool KviKvsObject_tabwidget::functionchangeTab(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ 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)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Not a widget object"));
+ return true;
+ }
+ int ctrl = ((QTabWidget *)widget())->indexOf (((QWidget *)(ob->object())));
+ if (ctrl == -1)
+ {
+ c->warning(__tr2qs("Can't find the tab "));
+ return true;
+ }
+ QPixmap * pix = g_pIconManager->getImage(szIcon);
+ if(pix){
+ #ifdef COMPILE_USE_QT4
+ ((QTabWidget *)widget())->changeTab(((QWidget *)(ob->object())),QIconSet(*pix),szLabel);
+ #else
+ ((QTabWidget *)widget())->changeTab(((QWidget *)(ob->object())),QIconSet(*pix,QIconSet::Small),szLabel);
+ #endif
+ }
+ else ((QTabWidget *)widget())->changeTab(((QWidget *)(ob->object())),szLabel);
+ return true;
+}
+bool KviKvsObject_tabwidget::functionsetTabPosition(KviKvsObjectFunctionCall *c)
+{
+ QString szPos;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("tab_position",KVS_PT_STRING,0,szPos)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ if(KviQString::equalCI(szPos,"Top"))
+ ((QTabWidget *)widget())->setTabPosition(QTabWidget::Top);
+ else if(KviQString::equalCI(szPos,"Bottom"))
+ ((QTabWidget *)widget())->setTabPosition(QTabWidget::Bottom);
+ else c->warning( __tr2qs("Unknown position 'Q%'"),&szPos);
+ return true;
+}
+
+
+
+bool KviKvsObject_tabwidget::functionCurrentChangedEvent(KviKvsObjectFunctionCall *c)
+{
+
+ emitSignal("valueChanged",c,c->params());
+ return true;
+}
+
+void KviKvsObject_tabwidget::slotCurrentChanged(int value)
+{
+ KviKvsVariantList params(new KviKvsVariant((kvs_int_t)value));
+ callFunction(this,"currentChangedEvent",&params);
+}
+
+#include "m_class_tabwidget.moc"
diff --git a/src/modules/objects/class_tabwidget.h b/src/modules/objects/class_tabwidget.h
new file mode 100644
index 00000000..acc76d36
--- /dev/null
+++ b/src/modules/objects/class_tabwidget.h
@@ -0,0 +1,61 @@
+#ifndef _CLASS_TABWIDGET_H_
+#define _CLASS_TABWIDGET_H_
+//mdm:
+// File : class_tabwidget.h
+// Creation date : Fri Feb 11 10:21:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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 <qtabwidget.h>
+#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);
+
+ bool functionaddTab(KviKvsObjectFunctionCall *c);
+ bool functioninsertTab(KviKvsObjectFunctionCall *c);
+ bool functionsetTabToolTip(KviKvsObjectFunctionCall *c);
+ bool functionremoveTabToolTip(KviKvsObjectFunctionCall *c);
+ bool functionsetTabLabel(KviKvsObjectFunctionCall *c);
+ bool functionsetCurrentPage(KviKvsObjectFunctionCall *c);
+ bool functioncurrentPageIndex(KviKvsObjectFunctionCall *c);
+ bool functiontabLabel(KviKvsObjectFunctionCall *c);
+ bool functioncurrentTabLabel(KviKvsObjectFunctionCall *c);
+ bool functionsetMargin(KviKvsObjectFunctionCall *c);
+ bool functionmargin(KviKvsObjectFunctionCall *c);
+ bool functioncount(KviKvsObjectFunctionCall *c);
+ bool functionchangeTab(KviKvsObjectFunctionCall *c);
+ bool functionCurrentChangedEvent(KviKvsObjectFunctionCall *c);
+ bool functionremovePage(KviKvsObjectFunctionCall *c);
+ bool functionsetTabPosition(KviKvsObjectFunctionCall *c);
+
+protected slots:
+ void slotCurrentChanged(int);
+};
+
+#endif //!_CLASS_TABWIDGET_H_
diff --git a/src/modules/objects/class_tbrowser.cpp b/src/modules/objects/class_tbrowser.cpp
new file mode 100644
index 00000000..67dce8cb
--- /dev/null
+++ b/src/modules/objects/class_tbrowser.cpp
@@ -0,0 +1,143 @@
+//mdm:
+// File : class_tbrowser.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) 1999-2005 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 <qtextbrowser.h>
+#include "class_tbrowser.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+/*
+ @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(<file_name:string>)
+ 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(<link_href:string>)
+ Triggered when a link is clicked by the user. The default implementation of this function
+ emits the "linkClicked" signal.
+ @signals:
+ !sg: $linkClicked(<link_href:string>)
+ This signal is emitted by the default implementation of the [classfnc]$linkClickedEvent[/classfnc]() function.
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_textbrowser,"textbrowser","multilineedit")
+ KVSO_REGISTER_HANDLER(KviKvsObject_textbrowser,"setSource",function_setSource)
+ KVSO_REGISTER_HANDLER(KviKvsObject_textbrowser,"forward",function_forward)
+ KVSO_REGISTER_HANDLER(KviKvsObject_textbrowser,"backward",function_backward)
+ KVSO_REGISTER_HANDLER(KviKvsObject_textbrowser,"home",function_home)
+ KVSO_REGISTER_HANDLER(KviKvsObject_textbrowser,"reload",function_reload)
+ KVSO_REGISTER_HANDLER(KviKvsObject_textbrowser,"linkClickedEvent",function_linkClickedEvent)
+KVSO_END_REGISTERCLASS(KviKvsObject_textbrowser)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_textbrowser,KviKvsObject_mledit)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_textbrowser)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_textbrowser)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_textbrowser)
+
+bool KviKvsObject_textbrowser::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ QTextBrowser * tb = new QTextBrowser(parentScriptWidget(), name());
+ setObject(tb, true);
+ connect(tb,SIGNAL(anchorClicked(const QString &,const QString &)),this,SLOT(anchorClicked(const QString &,const QString &)));
+ return true;
+}
+
+bool KviKvsObject_textbrowser::function_setSource(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("I can't find the specified file '%Q'."),&szFile);
+ return true;
+ }
+
+ if (widget()) ((QTextBrowser *)widget())->setSource(szFile);
+ return true;
+}
+
+bool KviKvsObject_textbrowser::function_forward(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) ((QTextBrowser *)widget())->forward();
+ return true;
+}
+
+bool KviKvsObject_textbrowser::function_backward(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) ((QTextBrowser *)widget())->backward();
+ return true;
+}
+
+bool KviKvsObject_textbrowser::function_home(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) ((QTextBrowser *)widget())->home();
+ return true;
+}
+
+bool KviKvsObject_textbrowser::function_reload(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) ((QTextBrowser *)widget())->reload();
+ return true;
+}
+
+void KviKvsObject_textbrowser::anchorClicked(const QString &szName,const QString &szLink)
+{
+ KviKvsVariantList parms(new KviKvsVariant(szLink));
+ callFunction(this,"linkClickedEvent",0,&parms);
+}
+
+bool KviKvsObject_textbrowser::function_linkClickedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("linkClicked",c,c->params());
+ return true;
+}
+
+#include "m_class_tbrowser.moc"
diff --git a/src/modules/objects/class_tbrowser.h b/src/modules/objects/class_tbrowser.h
new file mode 100644
index 00000000..980bdc28
--- /dev/null
+++ b/src/modules/objects/class_tbrowser.h
@@ -0,0 +1,52 @@
+#ifndef _CLASS_TBROWSER_H_
+#define _CLASS_TBROWSER_H_
+//mdm:
+// File : class_tbrowser.h
+// Creation date : Fri 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) 1999-2005 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 <qtextbrowser.h>
+#include "class_widget.h"
+#include <qfile.h>
+#include "class_multilineedit.h"
+#include "object_macros.h"
+
+class KviKvsObject_textbrowser : public KviKvsObject_mledit
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_textbrowser)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool function_setSource(KviKvsObjectFunctionCall *c);
+ bool function_forward(KviKvsObjectFunctionCall *c);
+ bool function_backward(KviKvsObjectFunctionCall *c);
+ bool function_home(KviKvsObjectFunctionCall *c);
+ bool function_reload(KviKvsObjectFunctionCall *c);
+ bool function_linkClickedEvent(KviKvsObjectFunctionCall *c);
+protected slots:
+ void anchorClicked(const QString &szName,const QString &szLink);
+};
+
+#endif //!_CLASS_TBROWSER_H_
diff --git a/src/modules/objects/class_toolbar.cpp b/src/modules/objects/class_toolbar.cpp
new file mode 100644
index 00000000..ed280bd0
--- /dev/null
+++ b/src/modules/objects/class_toolbar.cpp
@@ -0,0 +1,156 @@
+//mdm:
+// File : class_toolbar.cpp
+// Creation date : Tue Feb 22 22:12:55 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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_toolbar.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+#include "kvi_tal_toolbar.h"
+#include "kvi_tal_mainwindow.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.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(<text:string>)
+ Sets the toolbar's label.
+ !fn: <string> $label()
+ Returns the toolbar's label.
+ !fn: $setStretchableWidget(<widget:object>)
+ Sets the <widget> to be expanded.
+ !fn: $clear()
+ Deletes all the toolbar's child widgets.
+
+*/
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_toolbar,"toolbar","object")
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbar,"addSeparator", functionaddSeparator)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbar,"setLabel", functionsetLabel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbar,"label", functionlabel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbar,"setStretchableWidget", functionsetStretchableWidget)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbar,"clear", functionclear)
+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 *pParams)
+{
+ if (!parentObject())
+ {
+ pContext->warning(__tr2qs("the toolbar cannot be a parent-widget!"));
+ return true;
+ }
+ if(parentObject()->inherits("KviKvsObject_mainwindow"))
+ {
+ setObject(new KviTalToolBar(name(), ((KviTalMainWindow *)parentScriptWidget())), true);
+ }
+ else
+ {
+ pContext->warning(__tr2qs("The parent-widget isn't a MainWindow."));
+ }
+
+ return true;
+}
+
+bool KviKvsObject_toolbar::functionaddSeparator(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) ((KviTalToolBar *)widget())->addSeparator();
+ return true;
+}
+bool KviKvsObject_toolbar::functionsetLabel(KviKvsObjectFunctionCall *c)
+{
+ QString szLabel;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalToolBar *)widget())->setLabel(szLabel);
+ return true;
+}
+bool KviKvsObject_toolbar::functionlabel(KviKvsObjectFunctionCall *c)
+{
+ if (widget()) c->returnValue()->setString(((KviTalToolBar *)widget())->label());
+ return true;
+}
+bool KviKvsObject_toolbar::functionsetStretchableWidget(KviKvsObjectFunctionCall *c)
+{
+ 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 (!widget()) return true;
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!ob->object()->inherits("KviKvsObject_widget"))
+ {
+ c->warning(__tr2qs("Widget object required"));
+ return TRUE;
+ }
+#ifndef COMPILE_USE_QT4
+ // FIXME: no support for this in Qt4 ?
+ if(widget()) ((KviTalToolBar *)widget())->setStretchableWidget(((QWidget *)(ob->object())));
+#endif //!COMPILE_USE_QT4
+ return true;
+}
+bool KviKvsObject_toolbar::functionclear(KviKvsObjectFunctionCall *c)
+{
+ if (widget())
+ ((KviTalToolBar *)object())->clear();
+ return true;
+}
+
+#include "m_class_toolbar.moc"
+
diff --git a/src/modules/objects/class_toolbar.h b/src/modules/objects/class_toolbar.h
new file mode 100644
index 00000000..1912e639
--- /dev/null
+++ b/src/modules/objects/class_toolbar.h
@@ -0,0 +1,50 @@
+#ifndef _CLASS_TOOLBAR_H_
+#define _CLASS_TOOLBAR_H_
+//mdm:
+// File : class_toolbar.h
+// Creation date : Tue Feb 22 22:12:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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"
+
+class KviKvsObject_toolbar : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_toolbar)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionaddSeparator(KviKvsObjectFunctionCall *c);
+ bool functionsetLabel(KviKvsObjectFunctionCall *c);
+ bool functionlabel(KviKvsObjectFunctionCall *c);
+ bool functionsetStretchableWidget(KviKvsObjectFunctionCall *c);
+ bool functionclear(KviKvsObjectFunctionCall *c);
+};
+
+
+#endif //!_CLASS_TOOLBAR_H_
diff --git a/src/modules/objects/class_toolbutton.cpp b/src/modules/objects/class_toolbutton.cpp
new file mode 100644
index 00000000..032b0c60
--- /dev/null
+++ b/src/modules/objects/class_toolbutton.cpp
@@ -0,0 +1,341 @@
+//mdm:
+// File : class_toolbutton.cpp
+// Creation date : Wed Feb 23 16:39:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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_toolbutton.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_tal_popupmenu.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(<icon_id:string>)
+ Sets the image for this button.
+ !fn:$setUsesBigPixmap(<bEnabled:boolean>)
+ Sets whether this toolbutton uses big pixmaps to enable.
+ !fn:$usesBigPixmap(<bEnabled:boolean>)
+ This property holds whether this toolbutton uses big pixmaps.
+ !fn:setUsesTextLabel(<bEnabled:boolean>)
+ 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(<text:String>,[tooltip:string])
+ Sets the label of this button to <text> and automatically sets it as a tool tip if <tip> is TRUE.
+ !fn:<string> $textLabel()
+ Returns the label of tthe button.
+ !fn:$setAutoRaise(<bAutoraise:boolean>)
+ Sets whether auto-raising is enabled.
+ !fn:<boolean> $autoRaise()
+ Returns 1 if autoRaise is enabled, otherwise returns 0.
+ !fn:$setToggleButton(<bToggle:boolean>)
+ Sets whether the tool button is a toggle button 1 enable, 0 disable.
+ !fn:<boolean> $toggle()
+ Toggles the state of the tool button.
+ !fn:$setOn(<bEnabled:boolean>)
+ Sets whether the tool button is on to the bool value: 1 enable, 0 disable.
+ // findme
+ !fn:$setPopup (<toolbutton:object>)
+ !fn:$setPopupDelay (<int delay>)
+ Sets the time delay between pressing the button and the appearance of the associated popup menu in milliseconds to delay.[br]
+ A good value is 100.
+ !fn:<integer> $pupupDelay()
+ Returns the time delay between pressing the button and the appearance of the associated popup menu in milliseconds.
+ !fn:$openPopup()
+ Opens the associated popup menu. If there is no such menu, this function does nothing.
+ !fn:setTextPosition(<text_position:string>)
+ 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:<string> $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(KviKvsObject_toolbutton,"setImage", functionsetImage)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"setUsesBigPixmap", functionsetUsesBigPixmap)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"usesBigPixmap", functionusesBigPixmap)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"setUsesTextLabel", functionsetUsesTextLabel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"usesTextLabel", functionusesTextLabel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"setAutoRaise", function_setAutoRaise)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"autoRaise", function_autoRaise)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"setTextLabel", functionsetTextLabel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"textLabel", functiontextLabel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"setPopup", functionsetPopup)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"openPopup", functionopenPopup)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"setToggleButton", functionsetToggleButton)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"toggle", functiontoggle)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"setOn", functionsetOn)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"setPopupDelay", functionsetPopupDelay)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"popupDelay", functionpopupDelay)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"setTextPosition", functionsetTextPosition)
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"textPosition", functiontextPosition)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_toolbutton,"clickEvent",function_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 * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QToolButton(parentScriptWidget(), name()), true);
+ connect(widget(),SIGNAL(clicked()),this,SLOT(slotClicked()));
+ return true;
+}
+
+bool KviKvsObject_toolbutton::functionsetImage(KviKvsObjectFunctionCall *c)
+{
+ QString icon;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("icon_id",KVS_PT_STRING,0,icon)
+ KVSO_PARAMETERS_END(c)
+ if (!widget()) return true;
+ QPixmap * pix = g_pIconManager->getImage(icon);
+ if(pix){
+ #ifdef COMPILE_USE_QT4
+ ((QToolButton *)widget())->setIconSet(QIconSet(*pix));
+ #else
+ ((QToolButton *)widget())->setIconSet(QIconSet(*pix,QIconSet::Small));
+ #endif
+ }
+ else
+ ((QToolButton *)widget())->setIconSet(QIconSet());
+ return true;
+}
+bool KviKvsObject_toolbutton::functionsetUsesBigPixmap(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QToolButton *)widget())->setUsesBigPixmap(bEnabled);
+ return true;
+}
+bool KviKvsObject_toolbutton::functionusesBigPixmap(KviKvsObjectFunctionCall *c)
+{
+ if (widget())
+ c->returnValue()->setBoolean(((QToolButton *)widget())->usesBigPixmap());
+ return true;
+}
+bool KviKvsObject_toolbutton::functionsetUsesTextLabel(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QToolButton *)widget())->setUsesTextLabel(bEnabled);
+ return true;
+}
+bool KviKvsObject_toolbutton::functionusesTextLabel(KviKvsObjectFunctionCall *c)
+{
+ if (widget())
+ c->returnValue()->setBoolean(((QToolButton *)widget())->usesTextLabel());
+ return true;
+}
+bool KviKvsObject_toolbutton::function_setAutoRaise(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QToolButton *)widget())->setAutoRaise(bEnabled);
+ return true;
+}
+bool KviKvsObject_toolbutton::function_autoRaise(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((QToolButton *)widget())->autoRaise());
+ return true;
+}
+bool KviKvsObject_toolbutton::functionsetOn(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QToolButton *)widget())->setOn(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_toolbutton::functionsetToggleButton(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QToolButton *)widget())->setToggleButton(bEnabled);
+ return true;
+}
+bool KviKvsObject_toolbutton::functiontoggle(KviKvsObjectFunctionCall *c)
+{
+ if (widget())
+ ((QToolButton *)widget())->toggle();
+ return true;
+}
+
+bool KviKvsObject_toolbutton::functionsetTextLabel(KviKvsObjectFunctionCall *c)
+{
+ 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)
+ if(!widget()) return true;
+
+ #ifdef COMPILE_USE_QT4
+ ((QToolButton *)widget())->setText(szLabel);
+ if (!szTip.isEmpty()) ((QToolButton *)widget())->setToolTip(szTip);
+ #else
+ if (szTip.isEmpty()) ((QToolButton *)widget())->setTextLabel(szLabel);
+ else ((QToolButton *)widget())->setTextLabel(szLabel,szTip);
+ #endif
+ return true;
+}
+bool KviKvsObject_toolbutton::functiontextLabel(KviKvsObjectFunctionCall *c)
+{
+ if (widget())
+ c->returnValue()->setString(((QToolButton *)widget())->textLabel());
+ return true;
+}
+bool KviKvsObject_toolbutton::functionsetPopup(KviKvsObjectFunctionCall *c)
+{
+ 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("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!ob->object()->inherits("KviKvsObject_popupmenu"))
+ {
+ c->warning(__tr2qs("Can't add a non - popupmenu object"));
+ return TRUE;
+ }
+ if(widget())
+ ((QToolButton *)widget())->setPopup(((KviTalPopupMenu *)(ob->object())));
+ return true;
+}
+bool KviKvsObject_toolbutton::functionopenPopup(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QToolButton *)widget())->openPopup();
+ return true;
+}
+bool KviKvsObject_toolbutton::functionsetPopupDelay(KviKvsObjectFunctionCall *c)
+{
+ 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;
+}
+bool KviKvsObject_toolbutton::functionpopupDelay(KviKvsObjectFunctionCall *c)
+{
+ if (widget())
+ c->returnValue()->setInteger(((QToolButton *)widget())->popupDelay());
+ return true;
+}
+bool KviKvsObject_toolbutton::functionsetTextPosition(KviKvsObjectFunctionCall *c)
+{
+ QString szPos;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("position",KVS_PT_STRING,0,szPos)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ if(KviQString::equalCI(szPos,"BesideIcon"))
+ ((QToolButton *)widget())->setTextPosition(QToolButton::BesideIcon);
+ else if(KviQString::equalCI(szPos,"BelowIcon"))
+ ((QToolButton *)widget())->setTextPosition(QToolButton::BelowIcon);
+ else c->warning(__tr2qs("Unknown text position '%Q'"),&szPos);
+ return true;
+}
+bool KviKvsObject_toolbutton::functiontextPosition(KviKvsObjectFunctionCall *c)
+{
+ if(!widget()) return true;
+ QString szPos="BelowIcon";
+ if ((((QToolButton *)widget())->textPosition())==(QToolButton::BesideIcon))
+ szPos="BesideIcon";
+ c->returnValue()->setString(szPos);
+ return true;
+}
+bool KviKvsObject_toolbutton::function_clickEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("clicked",c);
+ return true;
+}
+
+void KviKvsObject_toolbutton::slotClicked()
+{
+ KviKvsVariantList *params=0;
+ callFunction(this,"clickEvent",params);
+}
+
+#include "m_class_toolbutton.moc"
+
diff --git a/src/modules/objects/class_toolbutton.h b/src/modules/objects/class_toolbutton.h
new file mode 100644
index 00000000..2cd4dfec
--- /dev/null
+++ b/src/modules/objects/class_toolbutton.h
@@ -0,0 +1,69 @@
+#ifndef _CLASS_TOOLBUTTON_H_
+#define _CLASS_TOOLBUTTON_H_
+
+//mdm:
+// File : class_toolbutton.h
+// Creation date : Wed Feb 23 16:39:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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 <qtoolbutton.h>
+#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 functionsetImage(KviKvsObjectFunctionCall *c);
+ bool functionsetUsesBigPixmap(KviKvsObjectFunctionCall *c);
+ bool functionusesBigPixmap(KviKvsObjectFunctionCall *c);
+ bool functionsetUsesTextLabel(KviKvsObjectFunctionCall *c);
+ bool functionusesTextLabel(KviKvsObjectFunctionCall *c);
+ bool functionsetTextLabel(KviKvsObjectFunctionCall *c);
+ bool functiontextLabel(KviKvsObjectFunctionCall *c);
+ bool functionsetPopup(KviKvsObjectFunctionCall *c);
+ bool functionopenPopup(KviKvsObjectFunctionCall *c);
+ bool functionsetOn(KviKvsObjectFunctionCall *c);
+ bool functionsetToggleButton(KviKvsObjectFunctionCall *c);
+ bool functiontoggle(KviKvsObjectFunctionCall *c);
+ bool functionsetPopupDelay(KviKvsObjectFunctionCall *c);
+ bool functionpopupDelay(KviKvsObjectFunctionCall *c);
+ bool functionsetTextPosition(KviKvsObjectFunctionCall *c);
+ bool functiontextPosition(KviKvsObjectFunctionCall *c);
+
+ bool function_setAutoRaise(KviKvsObjectFunctionCall *c);
+ bool function_autoRaise(KviKvsObjectFunctionCall *c);
+ bool function_clickEvent(KviKvsObjectFunctionCall *c);
+signals:
+ void clicked();
+protected slots:
+ void slotClicked();
+};
+
+
+#endif //!_CLASS_TOOLBUTTON_H_
diff --git a/src/modules/objects/class_urllabel.cpp b/src/modules/objects/class_urllabel.cpp
new file mode 100644
index 00000000..544153c2
--- /dev/null
+++ b/src/modules/objects/class_urllabel.cpp
@@ -0,0 +1,330 @@
+//vim: ts=8
+// File : class_urllabel.cpp
+// Creation date : Thu Feb 18 1:27:44 CEST 2001 by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Krzysztof Godlewski
+// Copyright (C) 1999-2000 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_urllabel.h"
+
+#include "kvi_debug.h"
+#include "kvi_locale.h"
+#include "kvi_error.h"
+
+#include "kvi_app.h"
+
+#include "kvi_window.h"
+#include "kvi_kvs_script.h"
+#ifdef COMPILE_USE_QT4
+#include <QMouseEvent>
+#define QT_LEFT_BUTTON Qt::LeftButton
+#else
+#define QT_LEFT_BUTTON QEvent::LeftButton
+#endif
+//#warning "Functions to change colors for different states"
+//#warning "$setUnderline(), $underline()"
+
+//extern KviApp * g_pApp;
+/*static KviScriptObjectClass * g_pUrlLabelClass = 0;
+
+static KviScriptObject * urlLabelClassCreateInstance(KviScriptObjectClass * c,
+ KviScriptObject * p, const char * n)
+{
+ return new KviScriptUrlLabelObject(c, p, n);
+}
+
+KviScriptUrlLabelObject::KviScriptUrlLabelObject(KviScriptObjectClass * c, \
+KviScriptObject * p, const char *n) : KviScriptLabelObject(c, p, n)
+{
+ m_normalClr = QColor("black");
+ m_enterClr = QColor("blue");
+ m_activeClr = QColor("red");
+ m_useSingleClick = true;
+// ((QLabel *)widget())->setAutoResize(true);
+ //widget()->setCursor(Qt::pointingHandCursor);
+ //((KviScriptWidgetObject: * )p)->widget()->setCursor(Qt::pointingHandCursor);
+}
+
+KviScriptUrlLabelObject::~KviScriptUrlLabelObject()
+{
+}
+
+bool KviScriptUrlLabelObject::eventFilter(QObject * o, QEvent * e)
+{
+ QPalette pal = ((QLabel *)widget())->palette();
+
+ switch(e->type())
+ {
+ case QEvent::Enter:
+ pal.setColor(QColorGroup::Foreground, m_enterClr);
+ break;
+ case QEvent::Leave:
+ // this doesn't work...
+ if(((QMouseEvent *)e)->state() & QEvent::LeftButton)
+ pal.setColor(QColorGroup::Foreground, \
+ m_activeClr);
+ else
+ pal.setColor(QColorGroup::Foreground, \
+ m_normalClr);
+ break;
+ case QEvent::MouseButtonRelease:
+ pal.setColor(QColorGroup::Foreground, m_enterClr);
+ // perform actions here
+ if(!m_lastClickWasDbl && !m_useSingleClick)
+ break;
+ if(!m_action.isEmpty())
+ {
+
+ }
+ break;
+ case QEvent::MouseButtonPress:
+ m_lastClickWasDbl = false;
+ if(!((QMouseEvent * )e)->button() & \
+ QEvent::LeftButton || !m_useSingleClick)
+ break;
+ pal.setColor(QColorGroup::Foreground, m_activeClr);
+ break;
+ case QEvent::MouseButtonDblClick:
+ m_lastClickWasDbl = true;
+ if(m_useSingleClick)
+ break;
+ pal.setColor(QColorGroup::Foreground, m_activeClr);
+ break;
+ default: // make gcc happy
+ break;
+ }
+
+ ((QLabel *)widget())->setPalette(pal);
+
+ return false;
+}
+*/
+//#warning "Docs for urllabel"
+
+/*
+ @doc: urllabel
+ @keyterms:
+ display url, link
+ @title:
+ urllabel class
+ @type:
+ class
+ @short:
+ Displays an URI allowing to perform actions on click
+ @inherits:
+ [class]object[/class]
+ [class]widget[/class]
+ [class]label[/class]
+ @description:
+ This widget allows you to bind specific action on click. It can
+ open an url, or execute any KVI++ code. The text color reacts on
+ cursor movements and clicks.
+ @functions:
+ !fn: $setUrl(<text:string>)
+ Sets the url to be opened when the links is activated. The way
+ the label opens the url is defined in KVirc config dialog.
+ !fn: <string> $url()
+ Returns the currently set url.
+ !fn: $setAction(<text:string>)
+ Sets the action to be performed when the link is triggered. It
+ can be any valid KVI++ code. Note that all KVirc commands must
+ be prefixed with a '/', just as if you typed them in the input
+ widget.
+ !fn: <string> $action()
+ Returns currently set action string.
+ !fn: $setText(<text>)
+ Sets the label's text. Reimplemented from internal reasons.
+ !fn: $setCursorChange(<bEnabled:boolean>)
+ Tells the label wheather to change or not the shape of cursor,
+ when it is above the widget. Default is false.
+ !fn: <boolean> $cursorChange()
+ Returns true if the cursor changes over the label, false if not.
+ !fn: $setUseSingleClick(<bEnabled:boolean>)
+ If <bEnabled> is true, the label will react on single clicks,
+ otherwise only double clicks will trigger the link.
+ !fn: <boolean> $useSingleClick()
+ Returns true if the label reacts on single clicks, false if it
+ reacts only on double clicks.
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_urlabel,"urllabel","label")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_urlabel,"setUrl",functionsetUrl)
+ KVSO_REGISTER_HANDLER(KviKvsObject_urlabel,"url",functionurl)
+ KVSO_REGISTER_HANDLER(KviKvsObject_urlabel,"setAction",functionsetAction)
+ KVSO_REGISTER_HANDLER(KviKvsObject_urlabel,"action",functionaction)
+ KVSO_REGISTER_HANDLER(KviKvsObject_urlabel,"setText",functionsetText)
+ KVSO_REGISTER_HANDLER(KviKvsObject_urlabel,"setCursorChange",functionsetCursorChange)
+ KVSO_REGISTER_HANDLER(KviKvsObject_urlabel,"cursorChange",functioncursorChange)
+ KVSO_REGISTER_HANDLER(KviKvsObject_urlabel,"setUseSingleClick",functionsetUseSingleClick)
+ KVSO_REGISTER_HANDLER(KviKvsObject_urlabel,"useSingleClick",functionuseSingleClick)
+
+KVSO_END_REGISTERCLASS(KviKvsObject_urlabel)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_urlabel,KviKvsObject_label)
+
+ m_normalClr = QColor("black");
+ m_enterClr = QColor("blue");
+ m_activeClr = QColor("red");
+ m_useSingleClick = true;
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_urlabel)
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_urlabel)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_urlabel)
+
+bool KviKvsObject_urlabel::eventFilter(QObject * o, QEvent * e)
+{
+ QPalette pal = ((QLabel *)widget())->palette();
+
+ switch(e->type())
+ {
+ case QEvent::Enter:
+ pal.setColor(QColorGroup::Foreground, m_enterClr);
+ break;
+ case QEvent::Leave:
+ // this doesn't work...
+ if(((QMouseEvent *)e)->state() & QT_LEFT_BUTTON)
+ pal.setColor(QColorGroup::Foreground, \
+ m_activeClr);
+ else
+ pal.setColor(QColorGroup::Foreground, \
+ m_normalClr);
+ break;
+ case QEvent::MouseButtonRelease:
+ pal.setColor(QColorGroup::Foreground, m_enterClr);
+ // perform actions here
+ if(!m_lastClickWasDbl && !m_useSingleClick)
+ break;
+ if(!m_action.isEmpty())
+ {
+ KviKvsScript kvs("commandline",m_action);
+ kvs.run(g_pActiveWindow,0,0/*,KviKvsScript::AssumeLocals*/);
+
+ } else if(!m_url.isEmpty()) {
+ KviKvsScript kvs("commandline","openurl "+m_url);
+ kvs.run(g_pActiveWindow,0,0/*,KviKvsScript::AssumeLocals*/);
+ }
+ break;
+ case QEvent::MouseButtonPress:
+ m_lastClickWasDbl = false;
+ if(!((QMouseEvent * )e)->button() & \
+ QT_LEFT_BUTTON || !m_useSingleClick)
+ break;
+ pal.setColor(QColorGroup::Foreground, m_activeClr);
+ break;
+ case QEvent::MouseButtonDblClick:
+ m_lastClickWasDbl = true;
+ if(m_useSingleClick)
+ break;
+ pal.setColor(QColorGroup::Foreground, m_activeClr);
+ break;
+ default: // make gcc happy
+ break;
+ }
+
+ ((QLabel *)widget())->setPalette(pal);
+
+ return false;
+}
+bool KviKvsObject_urlabel::functionsetUrl(KviKvsObjectFunctionCall *c)
+{
+ QString szUrl;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("url",KVS_PT_STRING,0,szUrl)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ if(szUrl.isEmpty()){
+ c->error(__tr2qs("Not Enough Parameters"));
+ return false;
+ }
+ m_url = szUrl;
+ return true;
+}
+bool KviKvsObject_urlabel::functionurl(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setString(m_url);
+ return true;
+}
+bool KviKvsObject_urlabel::functionsetAction(KviKvsObjectFunctionCall *c)
+{
+ QString szAction;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("action",KVS_PT_STRING,0,szAction)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ if(szAction.isEmpty()){
+ c->error(__tr2qs("Not Enough Parameters"));
+ return false;
+ }
+ m_action = szAction;
+ return true;
+}
+bool KviKvsObject_urlabel::functionsetText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ ((QLabel *)widget())->setText(szText);
+ ((QLabel *)widget())->setFixedSize(((QLabel *)widget())->sizeHint());
+ return true;
+}
+bool KviKvsObject_urlabel::functionaction(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setString(m_action);
+ return true;
+}
+bool KviKvsObject_urlabel::functionsetCursorChange(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOLEAN,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())
+ return true;
+ if(m_changeCursor = bFlag)
+ widget()->setCursor(Qt::pointingHandCursor);
+ else
+ widget()->setCursor(Qt::arrowCursor);
+ return true;
+}
+bool KviKvsObject_urlabel::functionsetUseSingleClick(KviKvsObjectFunctionCall *c)
+{
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOLEAN,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ m_useSingleClick = bFlag;
+ return true;
+}
+bool KviKvsObject_urlabel::functionuseSingleClick(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setBoolean(m_useSingleClick);
+ return true;
+}
+bool KviKvsObject_urlabel::functioncursorChange(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setBoolean(m_changeCursor);
+ return true;
+}
diff --git a/src/modules/objects/class_urllabel.h b/src/modules/objects/class_urllabel.h
new file mode 100644
index 00000000..b9ee35d6
--- /dev/null
+++ b/src/modules/objects/class_urllabel.h
@@ -0,0 +1,64 @@
+#ifndef _CLASS_URLLABEL_H_
+#define _CLASS_URLLABEL_H_
+//vim: ts=8
+// File : class_urllabel.h
+// Creation date : Thu Feb 18 1:28:23 CEST 2001 by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Krzysztof Godlewski
+// Copyright (C) 1999-2000 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_label.h"
+#include "object_macros.h"
+
+class KviKvsObject_urlabel : public KviKvsObject_label
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_urlabel)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool eventFilter(QObject *, QEvent *);
+
+ bool functionsetUrl(KviKvsObjectFunctionCall *c);
+ bool functionsetAction(KviKvsObjectFunctionCall *c);
+ bool functionurl(KviKvsObjectFunctionCall *c);
+ bool functionaction(KviKvsObjectFunctionCall *c);
+ bool functionsetText(KviKvsObjectFunctionCall *c);
+ bool functionsetCursorChange(KviKvsObjectFunctionCall *c);
+ bool functioncursorChange(KviKvsObjectFunctionCall *c);
+ bool functionsetUseSingleClick(KviKvsObjectFunctionCall *c);
+ bool functionuseSingleClick(KviKvsObjectFunctionCall *c);
+
+ QString m_url;
+ QString m_action;
+
+ QColor m_normalClr;
+ QColor m_enterClr;
+ QColor m_activeClr;
+
+ bool m_changeCursor;
+ bool m_useSingleClick;
+
+ bool m_lastClickWasDbl;
+
+};
+
+#endif // !_CLASS_URLLABEL_H_
diff --git a/src/modules/objects/class_vbox.cpp b/src/modules/objects/class_vbox.cpp
new file mode 100644
index 00000000..477a5b69
--- /dev/null
+++ b/src/modules/objects/class_vbox.cpp
@@ -0,0 +1,128 @@
+//
+// File : class_vbox.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) 2002-2006 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 "kvi_locale.h"
+
+#include "class_vbox.h"
+
+/*
+ @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(<spacing:int>)
+ Sets the default spacing of the widgets in pixels
+ !fn: $setMargin(<margin:int>)
+ Sets the dimension of the layout margin : the distance from the border to the outermost child widget edges.
+ !fn: $setStretchFactor(<widget:hobject>,<stretch:uint>)
+ Sets the stretch factor of widget to stretch.
+*/
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_vbox,"vbox","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_vbox,"setMargin", functionsetMargin)
+ KVSO_REGISTER_HANDLER(KviKvsObject_vbox,"setSpacing", functionsetSpacing)
+ KVSO_REGISTER_HANDLER(KviKvsObject_vbox,"setStretchFactor", functionsetStretchFactor )
+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)
+{
+ setObject(new KviTalVBox(parentScriptWidget()), true);
+ return true;
+}
+
+bool KviKvsObject_vbox::functionsetMargin(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iMargin;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("margin",KVS_PT_INT,0,iMargin)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalVBox *)widget())->setMargin(iMargin);
+ return true;
+}
+
+bool KviKvsObject_vbox::functionsetSpacing(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iSpacing;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("spacing",KVS_PT_INT,0,iSpacing)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) ((KviTalVBox *)widget())->setSpacing(iSpacing);
+ return true;
+}
+
+bool KviKvsObject_vbox::functionsetStretchFactor(KviKvsObjectFunctionCall *c)
+{
+ 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);
+ if(!widget())return true;
+ if (!pObject)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!pObject->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ if(!pObject->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+
+ if(((KviKvsObject_widget *)pObject)->widget()->parentWidget() != widget())
+ {
+ c->warning(__tr2qs("The widget must be a child of this vbox"));
+ return true;
+ }
+ ((KviTalVBox *)widget())->setStretchFactor(((QWidget *)(pObject->object())),uStretch);
+ return true;
+} \ No newline at end of file
diff --git a/src/modules/objects/class_vbox.h b/src/modules/objects/class_vbox.h
new file mode 100644
index 00000000..d6b9d1cf
--- /dev/null
+++ b/src/modules/objects/class_vbox.h
@@ -0,0 +1,45 @@
+#ifndef _CLASS_VBOX_H_
+#define _CLASS_VBOX_H_
+//
+// File : class_vbox.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) 2002-2006 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_string.h"
+
+#include "class_widget.h"
+#include "kvi_tal_vbox.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 functionsetMargin(KviKvsObjectFunctionCall *c);
+ bool functionsetSpacing(KviKvsObjectFunctionCall *c);
+ bool functionsetStretchFactor(KviKvsObjectFunctionCall *c);
+
+};
+
+
+#endif //_CLASS_HBOX_H_
diff --git a/src/modules/objects/class_widget.cpp b/src/modules/objects/class_widget.cpp
new file mode 100644
index 00000000..d248c98b
--- /dev/null
+++ b/src/modules/objects/class_widget.cpp
@@ -0,0 +1,1745 @@
+//=============================================================================
+//
+// 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) 1999-2005 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_malloc.h"
+#include "kvi_debug.h"
+
+#include "kvi_error.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_window.h"
+#include "kvi_out.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_app.h"
+#include "kvi_string.h"
+#include <qcursor.h>
+#include <qiconset.h>
+#include <qcolor.h>
+#include <qlayout.h>
+#include <qbitmap.h>
+#include <qmetaobject.h>
+#include "class_widget.h"
+#include "class_pixmap.h"
+
+#ifdef COMPILE_USE_QT4
+ #include <QKeyEvent>
+ #include <QDesktopWidget>
+#else
+ #include <qwidgetlist.h>
+#endif
+
+#include <qwidget.h>
+#include <qtooltip.h>
+#include <qfont.h>
+#include <qvariant.h>
+
+// FIX ME: WFLAGS
+const char * const widgettypes_tbl[] = {
+ "TopLevel",
+ "Dialog",
+ "Popup",
+ "Desktop",
+ "Customize",
+ "Title",
+ "StaysOnTop",
+ "SysMenu",
+ "Minimize",
+ "Maximize",
+ "NoAutoErase"
+ };
+#ifdef COMPILE_USE_QT4
+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 Qt::WindowType widgettypes_cod[] = {
+#else
+const int widgettypes_cod[] = {
+#endif
+ Qt::WType_TopLevel,
+ Qt::WType_Dialog,
+ Qt::WType_Popup,
+ Qt::WType_Desktop,
+ Qt::WStyle_Customize,
+ Qt::WStyle_Title,
+ Qt::WStyle_StaysOnTop,
+ Qt::WStyle_SysMenu,
+ Qt::WStyle_Minimize,
+ Qt::WStyle_Maximize,
+ Qt::WNoAutoErase
+};
+
+
+#ifdef COMPILE_USE_QT4
+
+ #define QT_WIDGET_TABFOCUS Qt::TabFocus
+ #define QT_WIDGET_CLICKFOCUS Qt::ClickFocus
+ #define QT_WIDGET_STRONGFOCUS Qt::StrongFocus
+ #define QT_WIDGET_NOFOCUS Qt::NoFocus
+
+#else
+ #define QT_WIDGET_TABFOCUS QWidget::TabFocus
+ #define QT_WIDGET_CLICKFOCUS QWidget::ClickFocus
+ #define QT_WIDGET_STRONGFOCUS QWidget::StrongFocus
+ #define QT_WIDGET_NOFOCUS QWidget::NoFocus
+#endif
+
+
+#define widgettypes_num (sizeof(widgettypes_tbl) / sizeof(widgettypes_tbl[0]))
+
+/*
+ @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(<bool erase>)
+ Repaints the widget directly by calling [classfnc]$paintEvent[/classfnc]() immediately.[br]
+ If erase is TRUE, erases the widget before the $paintEvent() call.
+ !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(<x_or_array>,[<y>,<width>,<heigth>])
+ Sets the geometry of this widget. <x> and <y> 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(<value>)
+ Sets the minimum width of this widget to <value>.
+ 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(<value>)
+ Sets the minimum height of this widget to <value>.
+ 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(<value>)
+ Sets the maximum width of this widget to <value>.
+ 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(<value>)
+ Sets the maximum height of this widget to <value>.
+ 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(<x_or_array>[,<y>])
+ Moves this widget to the coordinate <x> and <y> relative to its
+ parent widget (or the desktop if this widget is a toplevel one).
+ This is equivalent to [classfnc]$setGeometry[/classfnc](<x>,<y>,
+ [classfnc]$width[/classfnc](),[classfnc]$height[/classfnc]()).
+ !fn: $resize(<w_or_array>,[height])
+ Changes the widget's width to <width> and height to <height>.
+ See also [classfnc]$setGeometry[/classfnc]().
+ !fn: $isEnabled()
+ Returns '1' if the widget is enabled , '0' otherwise.
+ See also [classfnc:widget]$setEnabled[/classfnc]().
+ !fn: $setEnabled(<bool>)
+ Sets the widget state to enabled or disabled if <bool> is 1 or 0 respectively.
+ A disabled widget does not receive keyboard nor mouse input.
+ !fn: $setCaption(<text>)
+ Sets the caption of this widget to <text>.
+ This is meaningful for toplevel widgets only.
+ !fn: $setToolTip(<tooltip_text>)
+ Set the tooltip of this widget; the text can contain HTML formatting.
+ !fn: $window.caption()
+ Returns the caption 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(<rgb(hex string)_array(red:integer,green:integer,blue_integer)_or_red>,[geen:integer],[blue:integer])
+ Sets the background color of this widget to <rgb_value>: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(<rgb(hex string)_array(red:integer,green:integer,blue_integer)_or_red>,[geen:integer],[blue:integer])
+ Sets the foreground color of this widget to <rgb_value>: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(<bool>)
+ Enables or disables the mouse tracking if <bool> 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(<button>,<x>,<y>)
+ This function is called when a mouse button is pressed while
+ the cursor is in this widget. <button> is 0 if the pressed button
+ is the left one, 1 if the button is the right one and 2 if it is the middle one.
+ The <x> and <y> coordinates are relative to this widget upper-left corner
+ and are expressed in pixels.
+ If you call "[cmd]setreturn[/cmd] 1" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $mouseReleaseEvent(<button>,<x>,<y>)
+ This function is called when a mouse button is released while
+ the cursor is in this widget. <button> is 0 if the released button
+ is the left one, 1 if the button is the right one and 2 if it is the middle one.
+ The <x> and <y> coordinates are relative to this widget upper-left corner
+ and are expressed in pixels.
+ If you call "[cmd]setreturn[/cmd] 1" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $mouseDoubleClickEvent(<button>,<x>,<y>)
+ This function is called when a mouse button is double clicked while
+ the cursor is in this widget. <button> is 0 if the double clicked button
+ is the left one, 1 if the button is the right one and 2 if it is the middle one.
+ The <x> and <y> coordinates are relative to this widget upper-left corner
+ and are expressed in pixels.
+ If you call "[cmd]setreturn[/cmd] 1" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $mouseMoveEvent(<button>,<x>,<y>)
+ This function is called when the mouse cursor moves inside this widget.
+ <button> is 0 if the pressed button
+ is the left one, 1 if the button is the right one and 2 if it is the middle one.
+ The special value of -1 indicates that no button is being pressed.
+ The <x> and <y> coordinates are relative to this widget upper-left corner
+ and are expressed in pixels.
+ Normally you will receive this event only if a mouse button is being pressed
+ while moving. If you want to receive it also when the mouse buttons are not
+ pressed, call [classfnc]$setMouseTracking[/classfnc]().
+ If you call "[cmd]return[/cmd]$true" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $focusInEvent()
+ This function is called when this widget gains keyboard focus.
+ If you call "[cmd]return[/cmd] $true" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $focusOutEvent()
+ This function is called when this widget looses keyboard focus.
+ If you call "[cmd]return[/cmd] $true" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $mouseLeaveEvent()
+ This function is called when the mouse leaves this widget.
+ If you call "[cmd]return[/cmd] $true" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $mouseEnterEvent()
+ This function is called when the mouse enters this widget.
+ If you call "[cmd]return[/cmd] $true" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $showEvent()
+ This function is called when this widget is being shown.
+ If you call "[cmd]return[/cmd] $true" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $hideEvent()
+ This function is called when this widget is being hidden.
+ If you call "[cmd]return[/cmd] $true" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $closeEvent()
+ This function is called when this widget is going to be closed.
+ If you call "[cmd]return[/cmd] $true" you will ignore the close event.
+ The default implementation does nothing.
+ !fn: $resizeEvent()
+ This function is called immediately after this widget has been resized.
+ If you call "[cmd]return[/cmd] $true" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: $moveEvent()
+ This function is called immediately after this widget has been moved.
+ If you call "[cmd]return[/cmd] $true" you will stop the internal processing
+ of this event. The default implementation does nothing.
+ !fn: <tip:string> $maybeTipEvent(<x_tip_pos:integer>,<y_tip_pos:integer>)[QT4 only]
+ This event handler is called when a eventualy tip is going to be show.
+ You can be reimplement this event and set a dynamic tool tip by using "[cmd]return[/cmd] <tooltip_string>".
+ If a tooltip has setted with [classfnc]$setTooltip[/classfnc] the dynamic tooltip will be ignored.
+ The default implementation does nothing.
+ !fn: $paintEvent()
+ This event handler can be reimplemented to repaint all or part of the widget.
+ It's needed by the Painter class.
+ It's very useful for drawing flicker free animations or low level special graphic effects.
+ If you call "[cmd]return[/cmd] $true" you will stop the internal processing
+ of this event.
+ The default implementation does nothing.
+ !fn: $setIcon(<image_id>)
+ Sets the icon for this widget. This is meaningful only for toplevel widgets.
+ See the [doc:image_id]image identifier[/doc] documentation for the explaination
+ of the <image_id> parameter.
+ !fn: $setBackgroundImage(<image_id>)
+ Sets the background image for this widget.
+ See the [doc:image_id]image identifier[/doc] documentation for the explaination
+ of the <image_id> parameter.
+ For some kind of widgets, setting a background pixmap may have no effect or
+ have strange results. Experiment with it.
+ To unset the background image call [classfnc]$setBackgroundColor[/classfnc]
+ !fn: $setFont(<size>,<family>,<style>)[br]
+ Set the font's size, family and stile, valid flag for style are:[br]
+ [pre]
+ italic [br]
+ bold [br]
+ underline [br]
+ overline [br]
+ strikeout [br]
+ fixedpitch [br]
+ [/pre]
+ !fn: $setWFlags(<flag1>, <flag2>, ...)
+ This function sets widget flags, given as parameters.
+ Valid flags are:
+ [pre]
+ TopLevel - indicates that this widget is a top-level widget[br]
+ Dialog - indicates that this widget is a top-level window that should be decorated as a dialog[br]
+ Desktop - indicates that this widget is the desktop[br]
+ Popup - indicates that this widget is a popup top-level window[br]
+ NoAutoErase - indicates that this widget paints all its pixels. Updating, resizing, scrolling and focus changes should therefore not erase the widget.
+ Customize - let's the user to customize the style of the widget.[br]
+ [br]
+ Valid parameter for a customized widget are:[br]
+ Title - gives the window a title bar[br]
+ StaysOnTop - window stays on top [br]
+ SysMenu - add a windows system menu[br]
+ Minimize - add a minimize button for the sysmenu style[br]
+ Maximize - add a maximixe button for the sysmenu style[br]
+ [/pre]
+ !fn: $centerToScreen()
+ Centers the window on the screen (useful only for toplevel widgets).[br]
+ The best place to call this function is in $showEvent()
+ !fn: $setFocusPolicy(<key focus>)
+ Sets the way the widget accepts keyboard focus.[br]
+ Valid parameters are:
+ [pre]
+ - TabFocus; (widget accepts keyboard focus by tabbing)[br]
+ - ClickFocus; (widget accepts keyboard focus by clicking)[br]
+ - StrongFocus; (widget accepts both tabbing/clicking)[br]
+ - No Focus; (widget does not accept focus at all; this is the default value)[br]
+ [/pre]
+ !fn: $keyPressEvent(<key>)
+ If widget accepts keyboard focus (see [classfnc]$setFocusPolicy[/classfnc] ) this function handles for keys;
+ In its argument the key pressed.[br]
+ Special keys are:
+ [pre]
+ - Return [br]
+ - Enter [br]
+ - Down (cursor arrow down) [br]
+ - Up (cursor arrow up) [br]
+ - Left (cursor arrow left) [br]
+ - Right (cursor arrow right) [br]
+ - Shift [br]
+ - Ctrl [br]
+ - Alt [br]
+ - CapsLock [br]
+ - Backspace [br]
+ - Del [br]
+ - Esc [br]
+ - 0 [br]
+ - 1 [br]
+ - 2 [br]
+ - 3 [br]
+ - 4 [br]
+ - 5 [br]
+ - 6 [br]
+ - 7 [br]
+ - 8 [br]
+ - 9 [br]
+ - + [br]
+ - - [br]
+ - * [br]
+ - / [br]
+ - ( [br]
+ - ) [br]
+ - = [br]
+ - . [br]
+ - ^ [br]
+
+ [/pre]
+ !fn: $mapFromGlobal(<x>,<y>)
+ Translates the global screen coordinate pos to widget coordinates.
+ !fn: $mapToGlobal(<x>,<y>)
+ Translates widget coordinates into the global screen coordinate pos.
+ !fn: integer $globalCursorX()
+ Return the x coordinate of mouse pointer global position.
+ !fn: integer $globalCursorY()
+ Return the y coordinate of the mo>use pointer global position.
+ @examples:
+ [example]
+ %Widget = $new(widget)
+ # This is the main container for other elements.
+
+ %Widget->$setCaption("This is the widget title")
+
+ %Widget->$setGeometry(100,200,170,290)
+ # 100 and 200 are distance (pixel) from the left and the top of father widget (in this case the KVIrc window)
+ # 300 and 400 are the weight and the height of the widget
+
+ %Widget->%label = $new(label,%Widget)
+ %Widget->%label->$setText("This is a text label")
+ %Widget->%label->$setGeometry(10,10,150,20)
+
+ %Widget->%lineedit = $new(lineedit,%Widget)
+ %Widget->%lineedit->$setText("This is a lineedit")
+ %Widget->%lineedit->$setGeometry(10,40,150,20)
+
+ %Widget->%multilineedit = $new(multilineedit,%Widget)
+ %Widget->%multilineedit->$setText("This is a multilineedit")
+ %Widget->%multilineedit->$setGeometry(10,70,150,40)
+
+ %Widget->%checkbox = $new(checkbox,%Widget)
+ %Widget->%checkbox->$setText("This is a checkbox")
+ %Widget->%checkbox->$setGeometry(10,120,150,20)
+
+ %Widget->%combobox = $new(combobox,%Widget)
+ %Widget->%combobox->$setGeometry(10,150,150,20)
+ %Widget->%combobox->$insertItem("This is a combobox")
+ %Widget->%combobox->$insertItem("This is a combobox's item")
+
+ %Widget->%listbox = $new(listbox,%Widget)
+ %Widget->%listbox->$setGeometry(10,180,150,40)
+ %Widget->%listbox->$insertItem("This is another item")
+ %Widget->%listbox->$insertItem("This is a listbox's item")
+ %Widget->%listbox->$insertItem("This is a listbox")
+
+ %Widget->%radiobutton = $new(radiobutton,%Widget)
+ %Widget->%radiobutton->$setGeometry(10,230,150,20)
+ %Widget->%radiobutton->$setText("This is a radiobutton")
+
+ %Widget->%button = $new(button, %Widget)
+ %Widget->%button->$setText("Close me")
+ %Widget->%button->$setGeometry(10,260,150,20)
+
+ %Widget->$show()
+ # This shows the widget
+
+ privateimpl(%Widget->%button, mousePressEvent) {
+ delete %Widget
+ # This closes the widget automatically
+ }
+ # privateimpl is triggered when user press the button.
+ # To do that, widget must be a global variable.
+ [/example]
+
+*/
+
+
+
+
+//
+// If you never call c->error() , c->warning() (your function never fails)
+// and never call a function that can call c->error() or c->warning()
+// you can avoid ENTER_STACK_FRAME and c->leaveStackFrame()
+// Just return true.
+// c->error() should be called only in really critical situations
+// (we have to define better "critical situation")
+// if possible , leave the things go after just a c->warning()
+//
+
+ // widget() will be never 0 in THIS class
+ // but in derived classes WILL be
+ // ... now that I think about it , it
+ // may happen that widget() will be zero here too:
+ // If the Qt "physical" widget gets destroyed
+ // by some external factor (for example when children
+ // of a wrapper widget destroyed by KVIrc).
+ //
+ // as a convention:
+ // if widget() can be 0 in a class
+ // the user must have a function to check it
+ // (sth as object::$hasObject() could do the trick)
+ // obviously this will happen only in well defined cases
+ // as in a qtwrapper not yet wrapped or failed to wrap (so
+ // qtwrapper::$wrap() returned '0' for example)
+ // or after the widget has been destroyed...
+ // if widget() is 0 , the functions perform no actions
+ // return no errors and results that have to be assumed
+ // as invalid (this allows the minimum overhead: if widget()
+
+//=============================================================================================================
+
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_widget,"widget","object")
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"reparent",function_reparent)
+ // apparence
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"show",function_show)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"hide",function_hide)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"repaint",function_repaint)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"isTopLevel",function_isTopLevel)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"isVisible",function_isVisible)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"raise",function_raise)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"lower",function_lower)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setEnabled",function_setEnabled)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"isEnabled",function_isEnabled)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setMouseTracking",function_setMouseTracking)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setCaption",function_setCaption)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"caption",function_caption)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"hasFocus",function_hasFocus)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setFocus",function_setFocus)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setToolTip",function_setToolTip)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setWFlags",function_setWFlags)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setIcon",function_setIcon)
+ // fonts
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"fontDescent",function_fontDescent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"fontAscent",function_fontAscent)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"fontMetricsWidth",function_fontMetricsWidth)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"fontMetricsHeight",function_fontMetricsHeight)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setFont",function_setFont)
+ // geometry
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"screenResolution",function_screenResolution)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"centerToScreen",function_centerToScreen)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"geometry",function_geometry)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setGeometry",function_setGeometry)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"mapToGlobal",function_mapToGlobal)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"mapFromGlobal",function_mapFromGlobal)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"y",function_y)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"x",function_x)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"globalCursorX",function_globalCursorX)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"globalCursorY",function_globalCursorY)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"width",function_width)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"height",function_height)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setMinimumWidth",function_setMinimumWidth)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setMinimumHeight",function_setMinimumHeight)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setMaximumWidth",function_setMaximumWidth)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setMaximumHeight",function_setMaximumHeight)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"move",function_move)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"sizeHint",function_sizeHint)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"resize",function_resize)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setFocusPolicy",function_setFocusPolicy)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"addWidgetToWrappedLayout",function_addWidgetToWrappedLayout)
+
+ // colors and image
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setForegroundColor",function_setPaletteForeground)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setBackgroundColor",function_setBackgroundColor)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setBackgroundImage",function_setBackgroundImage)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"backgroundColor",function_backgroundColor)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"foregroundColor",function_foregroundColor)
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setMask",function_setMask)
+
+ // QT4 only
+#ifdef COMPILE_USE_QT4
+ KVSO_REGISTER_HANDLER(KviKvsObject_widget,"setAttribute",function_setAttribute)
+#endif
+
+ // events
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"mousePressEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"mouseReleaseEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"mouseDoubleClickEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"mouseMoveEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"focusInEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"focusOutEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"mouseLeaveEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"mouseEnterEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"showEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"hideEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"closeEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"resizeEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"moveEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"paintEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"keyPressEvent")
+#ifdef COMPILE_USE_QT4
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_widget,"maybeTipEvent")
+#endif
+
+
+KVSO_END_REGISTERCLASS(KviKvsObject_widget)
+
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_widget,KviKvsObject)
+KVSO_END_CONSTRUCTOR(KviKvsObject_widget)
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_widget)
+ emit aboutToDie();
+KVSO_END_CONSTRUCTOR(KviKvsObject_widget)
+
+bool KviKvsObject_widget::init(KviKvsRunTimeContext * pContext,KviKvsVariantList * pParams)
+{
+ setObject(new QWidget(parentScriptWidget(),getName()),true);
+ return true;
+}
+
+bool KviKvsObject_widget::eventFilter(QObject *o,QEvent *e)
+{
+ if(o == object())
+ {
+ bool ret=false;
+ int aparam;
+ bool brokenhandler=false;
+ KviKvsVariant *retv=new KviKvsVariant(ret);
+
+ switch(e->type())
+ {
+ #ifdef COMPILE_USE_QT4
+ case QEvent::ToolTip:
+ {
+ QHelpEvent *helpEvent = static_cast<QHelpEvent *>(e);
+ QPoint point=helpEvent->pos();
+ QString szTooltip;
+ KviKvsVariant *tipret=new KviKvsVariant(szTooltip);
+ KviKvsVariantList params(new KviKvsVariant((kvs_int_t)point.x()),new KviKvsVariant((kvs_int_t)point.y()));
+ callFunction(this,"maybeTipEvent",tipret,&params);
+ tipret->asString(szTooltip);
+ QToolTip::showText(helpEvent->globalPos(),szTooltip);
+ break;
+ }
+ #endif
+ case QEvent::Paint:
+ {
+ QRect rect=((QPaintEvent *)e)->rect();
+ KviKvsVariantList params(new KviKvsVariant((kvs_int_t)rect.x()),new KviKvsVariant((kvs_int_t)rect.y()),new KviKvsVariant((kvs_int_t)rect.width()),new KviKvsVariant((kvs_int_t)rect.height()));
+ callFunction(this,"paintEvent",retv,&params);
+ break;
+ }
+
+ case QEvent::KeyPress:
+ {
+ QString tmp="";
+ switch(((QKeyEvent *)e)->key())
+ {
+ case Qt::Key_Return:
+ tmp="Return";
+ break;
+ case Qt::Key_Down:
+ tmp="Down";
+ break;
+ case Qt::Key_Up:
+ tmp="Up";
+ break;
+ case Qt::Key_Left:
+ tmp="Left";
+ break;
+ case Qt::Key_Right:
+ tmp="Right";
+ break;
+ case Qt::Key_Shift:
+ tmp="Shift";
+ break;
+ case Qt::Key_Control:
+ tmp="Ctrl";
+ break;
+ case Qt::Key_Alt:
+ tmp="Alt";
+ break;
+ case Qt::Key_CapsLock:
+ tmp="CapsLock";
+ break;
+ case Qt::Key_Backspace:
+ tmp="Backspace";
+ break;
+ case Qt::Key_Delete:
+ tmp="Del";
+ break;
+
+ case Qt::Key_Enter:
+ tmp="Enter";
+ break;
+ case Qt::Key_Escape:
+ tmp="Esc";
+ break;
+ case Qt::Key_0:
+ tmp="0";
+ case Qt::Key_1:
+ tmp="1";
+ break;
+ case Qt::Key_2:
+ tmp="2";
+ break;
+ case Qt::Key_3:
+ tmp="3";
+ break;
+ case Qt::Key_4:
+ tmp="4";
+ break;
+ case Qt::Key_5:
+ tmp="5";
+ break;
+ case Qt::Key_6:
+ tmp="6";
+ break;
+ case Qt::Key_7:
+ tmp="7";
+ break;
+ case Qt::Key_8:
+ tmp="8";
+ break;
+ case Qt::Key_9:
+ tmp="9";
+ break;
+ case Qt::Key_Plus:
+ tmp="+";
+ break;
+ case Qt::Key_Minus:
+ tmp="-";
+ break;
+ case Qt::Key_Slash:
+ tmp="/";
+ break;
+ case Qt::Key_Asterisk:
+ tmp="*";
+ break;
+ case Qt::Key_Period:
+ tmp=".";
+ break;
+ case Qt::Key_ParenLeft:
+ tmp="(";
+ break;
+ case Qt::Key_ParenRight:
+ tmp=")";
+ break;
+ case Qt::Key_Equal:
+ tmp="=";
+ break;
+ case Qt::Key_AsciiCircum:
+ tmp="^";
+ break;
+ default:
+ if (!((QKeyEvent *)e)->text().isEmpty()) tmp = ((QKeyEvent *)e)->text();
+ }
+
+ KviKvsVariantList params(new KviKvsVariant(tmp));
+ callFunction(this,"keyPressEvent",0,&params);
+ }
+ break;
+ case QEvent::MouseButtonPress:
+ if(((QMouseEvent *)e)->button() & Qt::LeftButton)aparam = 0;
+ else {
+ if(((QMouseEvent *)e)->button() & Qt::RightButton)aparam = 1;
+ else aparam = 2;
+ }
+ if(!callFunction(this,"mousePressEvent",retv,new KviKvsVariantList(new KviKvsVariant((kvs_int_t)aparam),new KviKvsVariant((kvs_int_t)((QMouseEvent *)e)->pos().x()),new KviKvsVariant((kvs_int_t)((QMouseEvent *)e)->pos().y())
+ ))) brokenhandler = true; // ignore results of a broken event handler
+ break;
+ case QEvent::MouseButtonRelease:
+ if(((QMouseEvent *)e)->button() & Qt::LeftButton)aparam = 0;
+ else {
+ if(((QMouseEvent *)e)->button() & Qt::RightButton)aparam = 1;
+ else aparam = 2;
+ }
+ if(!callFunction(this,"mouseReleaseEvent",retv,new KviKvsVariantList(new KviKvsVariant((kvs_int_t)aparam),new KviKvsVariant((kvs_int_t)((QMouseEvent *)e)->pos().x()),new KviKvsVariant((kvs_int_t)((QMouseEvent *)e)->pos().y())
+ ))) brokenhandler = true; // ignore results of a broken event handler
+ break;
+ case QEvent::MouseButtonDblClick:
+ if(( (QMouseEvent *)e)->button() & Qt::LeftButton)aparam = 0;
+ else {
+ if(((QMouseEvent *)e)->button() & Qt::RightButton)aparam = 1;
+ else aparam = 2;
+ }
+ if(!callFunction(this,"mouseDoubleClickEvent",retv,new KviKvsVariantList(new KviKvsVariant((kvs_int_t)aparam),new KviKvsVariant((kvs_int_t)((QMouseEvent *)e)->pos().x()),new KviKvsVariant((kvs_int_t)((QMouseEvent *)e)->pos().y())
+ ))) brokenhandler = true; // ignore results of a broken event handler
+
+ break;
+ case QEvent::MouseMove:
+ if( (((QMouseEvent *)e)->state()) & Qt::LeftButton) aparam = 0;
+ else
+ {
+ if(((QMouseEvent *)e)->state() & Qt::RightButton)aparam = 1;
+ else
+ {
+ if(((QMouseEvent *)e)->state() & Qt::MidButton)aparam = 2;
+ else aparam = -1;
+ }
+ }
+ if(!callFunction(this,"mouseMoveEvent",retv,new KviKvsVariantList(new KviKvsVariant((kvs_int_t)aparam),new KviKvsVariant((kvs_int_t)((QMouseEvent *)e)->pos().x()),new KviKvsVariant((kvs_int_t)((QMouseEvent *)e)->pos().y())
+ ))) brokenhandler = true; // ignore results of a broken event handler
+ break;
+ case QEvent::FocusIn:
+ if(!callFunction(this,"focusInEvent",retv,0))brokenhandler = true;
+ break;
+ case QEvent::FocusOut:
+ if(!callFunction(this,"focusOutEvent",retv,0))brokenhandler = true;
+ break;
+ case QEvent::Resize:
+ if(!callFunction(this,"resizeEvent",retv,0))brokenhandler = true;
+ break;
+ case QEvent::Move:
+ if(!callFunction(this,"moveEvent",retv,0))brokenhandler = true;
+ break;
+ case QEvent::Close:
+ if(!callFunction(this,"closeEvent",retv,0))brokenhandler = true;
+ break;
+ case QEvent::Enter:
+ if(!callFunction(this,"mouseEnterEvent",retv,0))brokenhandler = true;
+ break;
+ case QEvent::Leave:
+ if(!callFunction(this,"mouseLeaveEvent",retv,0))brokenhandler = true;
+ break;
+ case QEvent::Show:
+ if(!callFunction(this,"showEvent",retv,0))brokenhandler = true;
+ break;
+ case QEvent::Hide:
+ if(!callFunction(this,"hideEvent",retv,0))ret =false;
+ break;
+ default:
+ return KviKvsObject::eventFilter(o,e);
+ break;
+
+ }
+ if (!brokenhandler) ret=retv->asBoolean();
+ delete retv;
+ return ret;
+ /*
+ if(ret.length() == 1)
+ {
+ if(KviQString::equalCI("1",ret))return true;
+ }
+ */
+ }
+
+ return KviKvsObject::eventFilter(o,e);
+}
+
+
+bool KviKvsObject_widget::function_show(KviKvsObjectFunctionCall *c)
+{
+ if(!widget())return true; // should we warn here ?
+ widget()->show();
+ return true;
+}
+
+bool KviKvsObject_widget::function_setEnabled(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ widget()->setEnabled(bEnabled);
+ return true;
+}
+bool KviKvsObject_widget::function_isEnabled(KviKvsObjectFunctionCall *c)
+{
+ if(!widget()) return true;
+ c->returnValue()->setBoolean(widget()->isEnabled());
+ return true;
+}
+bool KviKvsObject_widget::function_fontDescent(KviKvsObjectFunctionCall * c)
+{
+ if(!widget()) return true;
+ QFontMetrics fm = widget()->fontMetrics();
+ int d = fm.descent();
+ c->returnValue()->setInteger(d);
+ return true;
+}
+
+bool KviKvsObject_widget::function_fontAscent(KviKvsObjectFunctionCall * c)
+{
+ if(!widget()) return true;
+ QFontMetrics fm = widget()->fontMetrics();
+ int d = fm.ascent();
+ c->returnValue()->setInteger(d);
+ return true;
+
+}
+
+bool KviKvsObject_widget::function_repaint(KviKvsObjectFunctionCall * c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+ widget()->repaint(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_widget::function_fontMetricsWidth(KviKvsObjectFunctionCall * c)
+{
+ QString m_szStr;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("string",KVS_PT_STRING,0,m_szStr)
+ KVSO_PARAMETERS_END(c)
+ if(!widget()) return true;
+// int fm = widget()->fontMetrics().width(m_szStr);
+ c->returnValue()->setInteger(widget()->fontMetrics().width(m_szStr));
+ return true;
+}
+
+bool KviKvsObject_widget::function_fontMetricsHeight(KviKvsObjectFunctionCall * c)
+{
+ if(!widget())return true;
+ int fm = widget()->fontMetrics().height();
+ c->returnValue()->setInteger(fm);
+ return true;
+}
+bool KviKvsObject_widget::function_screenResolution(KviKvsObjectFunctionCall * c)
+{
+ KviKvsArray * a = new KviKvsArray();
+ a->set(0,new KviKvsVariant((kvs_int_t)g_pApp->desktop()->width()));
+ a->set(1,new KviKvsVariant((kvs_int_t)g_pApp->desktop()->height()));
+ c->returnValue()->setArray(a);
+ return true;
+}
+
+bool KviKvsObject_widget::function_geometry(KviKvsObjectFunctionCall *c)
+{
+ QRect r = widget() ? widget()->geometry() : QRect(0,0,0,0);
+ KviKvsArray * a = new KviKvsArray();
+ a->set(0,new KviKvsVariant((kvs_int_t)r.x()));
+ a->set(1,new KviKvsVariant((kvs_int_t)r.y()));
+ a->set(2,new KviKvsVariant((kvs_int_t)r.width()));
+ a->set(3,new KviKvsVariant((kvs_int_t)r.height()));
+ c->returnValue()->setArray(a);
+ return true;
+}
+
+bool KviKvsObject_widget::function_setGeometry(KviKvsObjectFunctionCall *c)
+{
+ 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)
+
+ // this is a little bit tricky: we accept two syntax versions
+ // (this is something like a C++ overload)
+ // $setGeometry(x,y,w,h) OR $setGeometry($array(x,y,w,h))
+
+ // For this purpose we ask the parameter processing engine
+ // to return the first parameter as variant and we manually check its data typoe
+ // We also set the following three parameters as optional
+ // so the user can either pass one or four parameters.
+
+ // Because of this trick, we must check the parameter consistency
+ // manually.
+
+ if(pXOrArray->isArray())
+ {
+ // the user has passed a complete geometry array as first parameter
+ // make sure it has at least 4 elements
+ if(pXOrArray->array()->size() < 4)
+ {
+ c->error(__tr2qs("The array passed as parameter must contain at least 4 elements"));
+ return false;
+ }
+ // we must also manually extract the data from the array
+ KviKvsVariant * pX = pXOrArray->array()->at(0);
+ KviKvsVariant * pY = pXOrArray->array()->at(1);
+ KviKvsVariant * pW = pXOrArray->array()->at(2);
+ KviKvsVariant * pH = pXOrArray->array()->at(3);
+ // note that some of the array elements may be empty in fact
+ // a null value returned by KviKvsArray::at() means that
+ // no parameter was set in that place
+ if(!(pX && pY && pW && pH))
+ {
+ c->error(__tr2qs("One of the geometry array parameters is empty"));
+ return false;
+ }
+ if(!(pX->asInteger(iX) && pY->asInteger(iY) && pW->asInteger(iW) && pH->asInteger(iH)))
+ {
+ c->error(__tr2qs("One of the geometry array parameters didn't evaluate to an integer"));
+ return false;
+ }
+ // ok: the params are correct
+ } else {
+ // The user passed something else as first parameter
+ // make sure that it is an integer.
+ // Also make sure that we really have 4 parameters
+ if(c->params()->count() < 4)
+ {
+ c->error(__tr2qs("$setGeometry() requires either an array as first parameter or four integers"));
+ return false;
+ }
+ if(!pXOrArray->asInteger(iX))
+ {
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));
+ return false;
+ }
+ // ok: the params are correct
+ }
+
+ if(widget())
+ widget()->setGeometry(iX,iY,iW,iH);
+
+ return true;
+}
+bool KviKvsObject_widget::function_mapToGlobal(KviKvsObjectFunctionCall *c)
+
+{
+ if(!widget())return true;
+ kvs_int_t iX,iY;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("x",KVS_PT_INT,0,iX)
+ KVSO_PARAMETER("y",KVS_PT_INT,0,iY)
+ KVSO_PARAMETERS_END(c)
+ QPoint point=widget()->mapToGlobal(QPoint(iX,iY));
+ KviKvsArray * a = new KviKvsArray();
+ a->set(0,new KviKvsVariant((kvs_int_t)point.x()));
+ a->set(1,new KviKvsVariant((kvs_int_t)point.y()));
+ c->returnValue()->setArray(a);
+ return true;
+}
+
+bool KviKvsObject_widget::function_mapFromGlobal(KviKvsObjectFunctionCall *c)
+
+{
+ if(!widget())return true;
+ kvs_int_t iX,iY;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("x",KVS_PT_INT,0,iX)
+ KVSO_PARAMETER("y",KVS_PT_INT,0,iY)
+ KVSO_PARAMETERS_END(c)
+ QPoint point=widget()->mapFromGlobal(QPoint(iX,iY));
+ KviKvsArray * a = new KviKvsArray();
+ a->set(0,new KviKvsVariant((kvs_int_t)point.x()));
+ a->set(1,new KviKvsVariant((kvs_int_t)point.y()));
+ c->returnValue()->setArray(a);
+ return true;
+}
+bool KviKvsObject_widget::function_centerToScreen(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) widget()->move((g_pApp->desktop()->width() - widget()->width())/2,(g_pApp->desktop()->height() - widget()->height())/2);
+ return true;
+}
+
+bool KviKvsObject_widget::function_setPaletteForeground(KviKvsObjectFunctionCall *c)
+{
+ KviKvsVariant * pColArray;
+ kvs_int_t iColR,iColG,iColB;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("hex_rgb_array_or_red",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("The array passed as parameter must contain at least 3 elements"));
+ 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("One of the colors array parameters is empty"));
+ return false;
+ }
+ if(!(pColR->asInteger(iColR) && pColG->asInteger(iColG) && pColB->asInteger(iColB)))
+ {
+ c->error(__tr2qs("One of the colors array parameters didn't evaluate to an integer"));
+ return false;
+ }
+
+ } else {
+ if (c->params()->count()==1)
+ {
+ bool bOk,bOk1,bOk2;
+ QString value;
+ pColArray->asString(value);
+ int i=0;
+ if (value.length()!=6)
+ {
+ c->warning(__tr2qs("A string of 6 digits hex is required"));
+ 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("Not an hex digits"));
+ return true;
+ }
+ if (widget()) widget()->setPaletteForegroundColor(QColor(iColR,iColG,iColB));
+ return true;
+ }
+
+ if(c->params()->count() < 3)
+ {
+
+ c->error(__tr2qs("$setForegroundColor requires either an array as first parameter, one hex string or three integers"));
+ return false;
+ }
+ if(!pColArray->asInteger(iColR))
+ {
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));
+ return false;
+ }
+ }
+ if (widget()) widget()->setPaletteForegroundColor(QColor(iColR,iColG,iColB));
+ return true;
+}
+
+bool KviKvsObject_widget::function_setBackgroundColor(KviKvsObjectFunctionCall *c)
+{
+ KviKvsVariant * pColArray;
+ kvs_int_t iColR,iColG,iColB;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("hex_rgb_array_or_red",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("The array passed as parameter must contain at least 3 elements"));
+ 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("One of the colors array parameters is empty"));
+ return false;
+ }
+ if(!(pColR->asInteger(iColR) && pColG->asInteger(iColG) && pColB->asInteger(iColB)))
+ {
+ c->error(__tr2qs("One of the colors array parameters didn't evaluate to an integer"));
+ return false;
+ }
+
+ } else {
+ if (c->params()->count()==1)
+ {
+ bool bOk,bOk1,bOk2;
+ QString value;
+ pColArray->asString(value);
+ int i=0;
+ if (value.length()!=6)
+ {
+ c->warning(__tr2qs("A string of 6 digits hex is required"));
+ 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("Not an hex digits"));
+ return true;
+ }
+ if (widget()) widget()->setBackgroundColor(QColor(iColR,iColG,iColB));
+ return true;
+ }
+
+ if(c->params()->count() < 3)
+ {
+
+ c->error(__tr2qs("$setBackgroundColor requires either an array as first parameter, one hex string or three integers"));
+ return false;
+ }
+ if(!pColArray->asInteger(iColR))
+ {
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));
+ return false;
+ }
+ }
+ if (widget()) widget()->setBackgroundColor(QColor(iColR,iColG,iColB));
+ return true;
+}
+
+bool KviKvsObject_widget::function_backgroundColor(KviKvsObjectFunctionCall *c)
+{
+ if(!widget())return true;
+ QColor col = widget()->backgroundColor();
+ KviKvsArray * a = new KviKvsArray();
+ a->set(0,new KviKvsVariant((kvs_int_t)col.red()));
+ a->set(1,new KviKvsVariant((kvs_int_t)col.green()));
+ a->set(2,new KviKvsVariant((kvs_int_t)col.blue()));
+ c->returnValue()->setArray(a);
+ return true;
+}
+
+bool KviKvsObject_widget::function_foregroundColor(KviKvsObjectFunctionCall *c)
+{
+ if(!widget())return true;
+ QColor col = widget()->foregroundColor();
+ KviKvsArray * a = new KviKvsArray();
+ a->set(0,new KviKvsVariant((kvs_int_t)col.red()));
+ a->set(1,new KviKvsVariant((kvs_int_t)col.green()));
+ a->set(2,new KviKvsVariant((kvs_int_t)col.blue()));
+ c->returnValue()->setArray(a);
+ return true;
+}
+
+bool KviKvsObject_widget::function_parentWidget(KviKvsObjectFunctionCall *c)
+{
+ if(!widget())return true;
+ if(parentScriptWidget()) c->returnValue()->setHObject(parentObject()->handle());
+ else
+ c->returnValue()->setHObject((kvs_hobject_t)0);
+ return true;
+
+}
+bool KviKvsObject_widget::function_setMouseTracking(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) widget()->setMouseTracking(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_widget::function_setCaption(KviKvsObjectFunctionCall *c)
+{
+ QString szCaption;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) widget()->setCaption(szCaption);
+ return true;
+}
+
+bool KviKvsObject_widget::function_caption(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) c->returnValue()->setString(widget()->caption().utf8().data());
+ return true;
+}
+
+bool KviKvsObject_widget::function_isTopLevel(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) c->returnValue()->setBoolean(widget()->isTopLevel());
+ return true;
+}
+
+bool KviKvsObject_widget::function_isVisible(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) c->returnValue()->setBoolean(widget()->isVisible());
+ return true;
+}
+
+bool KviKvsObject_widget::function_raise(KviKvsObjectFunctionCall *)
+{
+ if(widget()) widget()->raise();
+ return true;
+}
+
+bool KviKvsObject_widget::function_lower(KviKvsObjectFunctionCall *)
+{
+ if(widget())widget()->lower();
+ return true;
+}
+
+bool KviKvsObject_widget::function_hasFocus(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) c->returnValue()->setBoolean(widget()->hasFocus());
+ return true;
+}
+
+bool KviKvsObject_widget::function_setFocus(KviKvsObjectFunctionCall *c)
+{
+ if (widget())widget()->setFocus();
+ return true;
+}
+bool KviKvsObject_widget::function_hide(KviKvsObjectFunctionCall *)
+{
+ if(widget())widget()->hide();
+ return true;
+}
+
+bool KviKvsObject_widget::function_setToolTip(KviKvsObjectFunctionCall *c)
+{
+ QString szTooltip;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("tooltip",KVS_PT_STRING,0,szTooltip)
+ KVSO_PARAMETERS_END(c)
+ if(widget())QToolTip::add( widget(), szTooltip );
+ return true;
+}
+
+bool KviKvsObject_widget::function_x(KviKvsObjectFunctionCall *c)
+{
+ if(widget()) c->returnValue()->setInteger(widget()->x());
+ return true;
+}
+
+bool KviKvsObject_widget::function_y(KviKvsObjectFunctionCall *c)
+{
+ if(widget())c->returnValue()->setInteger(widget()->y());
+ return true;
+}
+
+bool KviKvsObject_widget::function_width(KviKvsObjectFunctionCall *c)
+{
+ if(widget())c->returnValue()->setInteger(widget()->width());
+ return true;
+}
+
+bool KviKvsObject_widget::function_height(KviKvsObjectFunctionCall *c)
+{
+ if(widget())c->returnValue()->setInteger(widget()->height());
+ return true;
+}
+
+bool KviKvsObject_widget::function_setMinimumWidth(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iW;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("w",KVS_PT_INT,0,iW)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) widget()->setMinimumWidth(iW);
+ return true;
+}
+
+bool KviKvsObject_widget::function_setMinimumHeight(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iH;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("h",KVS_PT_INT,0,iH)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) widget()->setMinimumHeight(iH);
+ return true;
+}
+
+bool KviKvsObject_widget::function_setMaximumWidth(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iW;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("w",KVS_PT_INT,0,iW)
+ KVSO_PARAMETERS_END(c)
+ if (widget()) widget()->setMaximumWidth(iW);
+ return true;
+}
+
+bool KviKvsObject_widget::function_setMaximumHeight(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iH;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("h",KVS_PT_INT,0,iH)
+ KVSO_PARAMETERS_END(c)
+ if(widget()) widget()->setMaximumHeight(iH);
+ return true;
+}
+
+bool KviKvsObject_widget::function_move(KviKvsObjectFunctionCall *c)
+{
+ kvs_int_t iX,iY;
+
+ KviKvsVariant * pXOrArray;
+ 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)
+ if(pXOrArray->isArray())
+ {
+ if(pXOrArray->array()->size() < 2)
+ {
+ c->error(__tr2qs("The array passed as parameter must contain at least 2 elements"));
+ return false;
+ }
+ KviKvsVariant * pX = pXOrArray->array()->at(0);
+ KviKvsVariant * pY = pXOrArray->array()->at(1);
+ if(!(pX && pY))
+ {
+ c->error(__tr2qs("One of the move array parameters is empty"));
+ return false;
+ }
+ if(!(pX->asInteger(iX) && pY->asInteger(iY)))
+ {
+ c->error(__tr2qs("One of the move array parameters didn't evaluate to an integer"));
+ return false;
+ }
+ // ok: the params are correct
+ } else {
+ if(c->params()->count() < 2)
+ {
+ c->error(__tr2qs("$move() requires either an array as first parameter or two integers"));
+ return false;
+ }
+ if(!pXOrArray->asInteger(iX))
+ {
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));
+ return false;
+ }
+ // ok: the params are correct
+ }
+
+ if(!widget())return true;
+ widget()->move(QPoint(iX,iY));
+ return true;
+}
+bool KviKvsObject_widget::function_sizeHint(KviKvsObjectFunctionCall *c)
+{
+ if(!widget())return true;
+ QSize sizehint = widget()->sizeHint();
+ KviKvsArray * a = new KviKvsArray();
+ a->set(0,new KviKvsVariant((kvs_int_t)sizehint.width()));
+ a->set(1,new KviKvsVariant((kvs_int_t)sizehint.height()));
+ c->returnValue()->setArray(a);
+ return true;
+}
+
+bool KviKvsObject_widget::function_resize(KviKvsObjectFunctionCall *c)
+{
+ KviKvsVariant * pWOrArray;
+ kvs_int_t iW,iH;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("width_or_array",KVS_PT_VARIANT,0,pWOrArray)
+ KVSO_PARAMETER("height",KVS_PT_INT,KVS_PF_OPTIONAL,iH)
+ KVSO_PARAMETERS_END(c)
+ if(pWOrArray->isArray())
+ {
+ if(pWOrArray->array()->size() < 2)
+ {
+ c->error(__tr2qs("The array passed as parameter must contain at least 2 elements"));
+ return false;
+ }
+ KviKvsVariant * pW = pWOrArray->array()->at(0);
+ KviKvsVariant * pH = pWOrArray->array()->at(1);
+ if(!(pW && pH))
+ {
+ c->error(__tr2qs("One of the resize array parameters is empty"));
+ return false;
+ }
+ if(!(pW->asInteger(iW) && pH->asInteger(iH)))
+ {
+ c->error(__tr2qs("One of the resize array parameters didn't evaluate to an integer"));
+ return false;
+ }
+ // ok: the params are correct
+ } else {
+ if(c->params()->count() < 2)
+ {
+ c->error(__tr2qs("$resize() requires either an array as first parameter or two integers"));
+ return false;
+ }
+ if(!pWOrArray->asInteger(iW))
+ {
+ c->error(__tr2qs("The first parameter didn't evaluate to an array nor an integer"));
+ return false;
+ }
+ // ok: the params are correct
+ }
+
+ if(!widget())return true;
+ widget()->resize(QSize(iW,iH));
+ return true;
+}
+bool KviKvsObject_widget::function_setFocusPolicy(KviKvsObjectFunctionCall *c)
+{
+ QString szMode;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("focus",KVS_PT_STRING,0,szMode)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ if(KviQString::equalCI(szMode, "TabFocus"))
+ widget()->setFocusPolicy(QT_WIDGET_TABFOCUS);
+ else
+ if(KviQString::equalCI(szMode, "ClickFocus"))
+ widget()->setFocusPolicy(QT_WIDGET_CLICKFOCUS);
+ else
+ if(KviQString::equalCI(szMode, "StrongFocus"))
+ widget()->setFocusPolicy(QT_WIDGET_STRONGFOCUS);
+ else
+ if(KviQString::equalCI(szMode, "NoFocus"))
+ widget()->setFocusPolicy(QT_WIDGET_NOFOCUS);
+ else c->warning(__tr2qs("Invalid parameters"));
+ return true;
+}
+
+bool KviKvsObject_widget::function_setWFlags(KviKvsObjectFunctionCall *c)
+{
+ QStringList wflags;
+ //Qt::WindowType sum;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("widget_flags",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,wflags)
+ KVSO_PARAMETERS_END(c)
+ if (!widget()) return true;
+ #ifdef COMPILE_USE_QT4
+ Qt::WindowFlags flag,sum=0;
+ #else
+ int flag,sum=0;
+ #endif
+ for ( QStringList::Iterator it = wflags.begin(); it != wflags.end(); ++it )
+ {
+
+ flag=0;
+ for(unsigned int j = 0; j < widgettypes_num; j++)
+ {
+ if(KviQString::equalCI((*it), widgettypes_tbl[j]))
+ {
+ flag=widgettypes_cod[j];
+ break;
+ }
+ }
+ if(flag)
+ sum = sum | flag;
+ else
+ c->warning(__tr2qs("Unknown widget flag '%Q'"),&(*it));
+
+ }
+
+#ifdef COMPILE_USE_QT4
+ widget()->setWindowFlags(sum);
+#else
+ widget()->reparent(widget()->parentWidget(),sum,QPoint(widget()->x(),widget()->y()));
+#endif
+ return true;
+}
+
+bool KviKvsObject_widget::function_setFont(KviKvsObjectFunctionCall *c)
+{
+
+ QString szFamily,szStyle;
+ kvs_int_t uSize;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("size",KVS_PT_UNSIGNEDINTEGER,0,uSize)
+ KVSO_PARAMETER("family",KVS_PT_STRING,0,szFamily)
+ KVSO_PARAMETER("style",KVS_PT_STRING,0,szStyle)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ QFont font=widget()->font();
+ font.setFamily(szFamily);
+ font.setPointSize(uSize);
+ if(KviQString::equalCI(szStyle,"italic")) font.setItalic(TRUE);
+ else if(KviQString::equalCI(szStyle,"bold")) font.setBold(TRUE);
+ else if(KviQString::equalCI(szStyle,"underline"))font.setUnderline(TRUE);
+ else if(KviQString::equalCI(szStyle,"overline")) font.setOverline(TRUE);
+ else if(KviQString::equalCI(szStyle,"strikeout"))font.setStrikeOut(TRUE);
+ else if(KviQString::equalCI(szStyle,"fixedpitch")) font.setFixedPitch(TRUE);
+ else c->warning(__tr2qs("Unknown style '%Q'"),&szStyle);
+ widget()->setFont(font);
+ return true;
+}
+
+bool KviKvsObject_widget::function_addWidgetToWrappedLayout(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ kvs_int_t uCol,uRow;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol)
+ KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if (!ob)
+ {
+ c->warning(__tr2qs("Widget parameter is not an object"));
+ return true;
+ }
+ if (!ob->object())
+ {
+ c->warning(__tr2qs("Widget parameter is not a valid object"));
+ return true;
+ }
+ QLayout *lay=widget()->layout();
+ if (!lay)
+ {
+ c->warning(__tr2qs("No Layout associated to the widget "));
+ return true;
+ }
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ lay->add(((QWidget *)(ob->object())));
+ return true;
+}
+bool KviKvsObject_widget::function_reparent(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("widget",KVS_PT_HOBJECT,KVS_PF_OPTIONAL,hObject)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget()) return true;
+ if(!ob)
+ {
+ widget()->reparent(0,QPoint(widget()->x(),widget()->y()));
+ return true;
+ }
+ else
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr("Parent must be a widget object"));
+ return true;
+ }
+ widget()->reparent(((QWidget *)(ob->object())),QPoint(((QWidget *)(ob->object()))->x(),((QWidget *)(ob->object()))->y()));
+ return true;
+}
+bool KviKvsObject_widget::function_setIcon(KviKvsObjectFunctionCall *c)
+{
+
+ QString icon;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("icon",KVS_PT_STRING,0,icon)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ QPixmap * pix = g_pIconManager->getImage(icon);
+ if(pix)widget()->setIcon(*pix);
+ return true;
+}
+
+bool KviKvsObject_widget::function_setBackgroundImage(KviKvsObjectFunctionCall *c)
+{
+ QString image;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("image",KVS_PT_STRING,0,image)
+ KVSO_PARAMETERS_END(c)
+ if(!widget())return true;
+ QPixmap * pix = g_pIconManager->getImage(image);
+ if(pix)widget()->setPaletteBackgroundPixmap(*pix);
+ return true;
+}
+bool KviKvsObject_widget::function_globalCursorX(KviKvsObjectFunctionCall *c)
+{
+ if(widget())c->returnValue()->setInteger(QCursor::pos().x());
+ return true;
+}
+bool KviKvsObject_widget::function_globalCursorY(KviKvsObjectFunctionCall *c)
+{
+ if(widget())c->returnValue()->setInteger(QCursor::pos().y());
+ return true;
+}
+bool KviKvsObject_widget::function_setMask(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *obj;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("pixmap",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETERS_END(c)
+ obj=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if (!obj)
+ {
+ c->warning(__tr2qs("Pixmap parameter is not an object"));
+ return true;
+ }
+ if (!obj->inherits("KviKvsObject_pixmap"))
+ {
+ c->warning(__tr2qs("Pixmap object required"));
+ return true;
+ }
+ QPixmap * pm=((KviKvsObject_pixmap *)obj)->getPixmap();
+#ifdef COMPILE_USE_QT4
+ QBitmap mask(pm->mask());
+#else
+ QBitmap mask(*pm->mask());
+#endif
+ if (mask.isNull()) c->warning(__tr2qs("Null mask"));
+ widget()->setMask(mask);
+ return true;
+}
+#ifdef COMPILE_USE_QT4
+bool KviKvsObject_widget::function_setAttribute(KviKvsObjectFunctionCall *c)
+{
+ QString attribute;
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("widget_atribute",KVS_PT_STRING,0,attribute)
+ KVSO_PARAMETER("bool_flag",KVS_PT_BOOLEAN,0,bFlag)
+ KVSO_PARAMETERS_END(c)
+ if (!widget()) return true;
+ bool found=false;
+ unsigned int j = 0;
+ for(; j < widgetattributes_num; j++)
+ {
+ if(KviQString::equalCI(attribute, widgetattributes_tbl[j]))
+ {
+ found=true;
+ break;
+ }
+ }
+ if(found)widget()->setAttribute(widgetattributes_cod[j],bFlag);
+ else c->warning(__tr2qs("Unknown widget attribute '%Q'"),&attribute);
+ return true;
+}
+#endif
+
+#include "m_class_widget.moc"
diff --git a/src/modules/objects/class_widget.h b/src/modules/objects/class_widget.h
new file mode 100644
index 00000000..ecd87bba
--- /dev/null
+++ b/src/modules/objects/class_widget.h
@@ -0,0 +1,113 @@
+#ifndef _CLASS_WIDGET_H_
+#define _CLASS_WIDGET_H_
+//vim: ts=8
+// File : class_widget.h
+// Creation date : Mon 11 Sep 16:34:36 CET 2000 by Krzysztof Godlewski
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_tal_tooltip.h>
+#include "kvi_string.h"
+#include "qtooltip.h"
+#include "object_macros.h"
+
+
+class KviKvsObject_widget : public KviKvsObject
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_widget)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ virtual bool eventFilter(QObject *o,QEvent *e);
+
+ // ok, it is clear that we're messing with the naming conventions for the
+ // object classes :D
+ // let's try to use this one:
+ // function_isEnabled
+ // function_setEnabled..
+ // ... etc
+ // so the name of the C++ function matches exactly the name of the KVS function at this point
+
+ // let's also try to keep alphabetic order for the functions here.. so one can find them quickly
+
+ bool function_addWidgetToWrappedLayout(KviKvsObjectFunctionCall *c);
+ bool function_backgroundColor(KviKvsObjectFunctionCall *c);
+ bool function_caption(KviKvsObjectFunctionCall *c);
+ bool function_centerToScreen(KviKvsObjectFunctionCall *c);
+ bool function_fontAscent(KviKvsObjectFunctionCall * c);
+ bool function_fontDescent(KviKvsObjectFunctionCall * c);
+ bool function_fontMetricsHeight(KviKvsObjectFunctionCall * c);
+ bool function_fontMetricsWidth(KviKvsObjectFunctionCall * c);
+ bool function_foregroundColor(KviKvsObjectFunctionCall *c);
+ bool function_geometry(KviKvsObjectFunctionCall *c);
+ bool function_globalCursorX(KviKvsObjectFunctionCall *c);
+ bool function_globalCursorY(KviKvsObjectFunctionCall *c);
+ bool function_hasFocus(KviKvsObjectFunctionCall *c);
+ bool function_height(KviKvsObjectFunctionCall *);
+ bool function_hide(KviKvsObjectFunctionCall *);
+ bool function_isEnabled(KviKvsObjectFunctionCall *c);
+ bool function_isTopLevel(KviKvsObjectFunctionCall *c);
+ bool function_isVisible(KviKvsObjectFunctionCall *c);
+ bool function_lower(KviKvsObjectFunctionCall *);
+ bool function_mapFromGlobal(KviKvsObjectFunctionCall *c);
+ bool function_mapToGlobal(KviKvsObjectFunctionCall *c);
+ bool function_move(KviKvsObjectFunctionCall *c);
+ bool function_parentWidget(KviKvsObjectFunctionCall *c);
+ bool function_raise(KviKvsObjectFunctionCall *);
+ bool function_repaint(KviKvsObjectFunctionCall *c);
+ bool function_reparent(KviKvsObjectFunctionCall *c);
+ bool function_resize(KviKvsObjectFunctionCall *c);
+ bool function_screenResolution(KviKvsObjectFunctionCall * c);
+ bool function_setBackgroundColor(KviKvsObjectFunctionCall *c);
+ bool function_setBackgroundImage(KviKvsObjectFunctionCall *c);
+ bool function_setCaption(KviKvsObjectFunctionCall *c);
+ bool function_setEnabled(KviKvsObjectFunctionCall *c);
+ bool function_setFocus(KviKvsObjectFunctionCall *c);
+ bool function_setFocusPolicy(KviKvsObjectFunctionCall *c);
+ bool function_setFont(KviKvsObjectFunctionCall *c);
+ bool function_setIcon(KviKvsObjectFunctionCall *c);
+ bool function_setMaximumWidth(KviKvsObjectFunctionCall *c);
+ bool function_setMaximumHeight(KviKvsObjectFunctionCall *c);
+ bool function_setMinimumWidth(KviKvsObjectFunctionCall *c);
+ bool function_setMinimumHeight(KviKvsObjectFunctionCall *c);
+ bool function_setMouseTracking(KviKvsObjectFunctionCall *c);
+ bool function_setPaletteForeground(KviKvsObjectFunctionCall *c);
+ bool function_setToolTip(KviKvsObjectFunctionCall *);
+ bool function_setGeometry(KviKvsObjectFunctionCall *c);
+ bool function_setWFlags(KviKvsObjectFunctionCall *c);
+ bool function_show(KviKvsObjectFunctionCall *c);
+ bool function_sizeHint(KviKvsObjectFunctionCall *c);
+ bool function_width(KviKvsObjectFunctionCall *);
+ bool function_x(KviKvsObjectFunctionCall *);
+ bool function_y(KviKvsObjectFunctionCall *);
+ bool function_setMask(KviKvsObjectFunctionCall *c);
+
+
+#ifdef COMPILE_USE_QT4
+bool function_setAttribute(KviKvsObjectFunctionCall *c);
+#endif
+
+signals:
+ void aboutToDie();
+};
+
+#endif // !_CLASS_WIDGET_H_
diff --git a/src/modules/objects/class_window.cpp b/src/modules/objects/class_window.cpp
new file mode 100644
index 00000000..9218cb8f
--- /dev/null
+++ b/src/modules/objects/class_window.cpp
@@ -0,0 +1,158 @@
+//
+// File : class_window.cpp
+// Creation date : Tue Now 26 21:39:59 CEST 2002 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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_window.h"
+
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+
+
+
+KviKvsScriptWindowWindow::KviKvsScriptWindowWindow(KviFrame * pParent,const QString &szName)
+: KviWindow(KVI_WINDOW_TYPE_SCRIPTOBJECT,pParent,szName)
+{
+ m_pCentralWidget = 0;
+ #ifdef COMPILE_USE_QT4
+ setBackgroundMode(Qt::NoBackground);
+ #else
+ setBackgroundMode(QWidget::NoBackground);
+ #endif
+}
+
+KviKvsScriptWindowWindow::~KviKvsScriptWindowWindow()
+{
+}
+
+void KviKvsScriptWindowWindow::setCentralWidget(KviKvsObject_widget *o,QWidget * w)
+{
+ m_pCentralWidgetObject = o;
+ m_pCentralWidget = w;
+}
+
+void KviKvsScriptWindowWindow::resizeEvent(QResizeEvent *e)
+{
+ if(m_pCentralWidget)
+ m_pCentralWidget->setGeometry(0,0,width(),height());
+}
+
+void KviKvsScriptWindowWindow::centralWidgetObjectDestroyed()
+{
+ m_pCentralWidget = 0;
+ m_pCentralWidgetObject = 0;
+}
+
+void KviKvsScriptWindowWindow::centralWidgetDestroyed()
+{
+ m_pCentralWidget = 0;
+ m_pCentralWidgetObject = 0;
+}
+
+
+
+
+/*
+ @doc: window
+ @title:
+ window class
+ @type:
+ class
+ @short:
+ A MDI window object
+ @inherits:
+ [class]object[/class]
+ [class]widget[/class]
+ @description:
+ This class rappresents a MDI window in a KVIrc frame.
+ Regardless of the parent object passed, the window will be always
+ a "physical" child of the frame window: you can't embed a window object
+ inside a widget or another window. The parent object will just "own" this
+ window object and eventually destroy it when it dies.
+ This class can manage only a single central child widget that must
+ be set with $setCentralWidget().
+ The central widget MUST be set before you initially call show()
+ @functions:
+*/
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_window,"window","widget")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_window,"setCaption", functionsetCaption)
+ KVSO_REGISTER_HANDLER(KviKvsObject_window,"setCentralWidget", functionsetCentralWidget)
+// KVSO_REGISTER_HANDLER(KviKvsObject_window,"setIcon", functionsetIcon)
+KVSO_END_REGISTERCLASS(KviKvsObject_window)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_window,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_window)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_window)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_window)
+
+bool KviKvsObject_window::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ KviWindow * w = new KviKvsScriptWindowWindow(pContext->window()->frame(),name());
+ setObject(w);
+ pContext->window()->frame()->addWindow(w,false);
+ w->minimize(); // must be minimized before children are added, otherwise the focus handling goes nuts...
+
+ return true;
+}
+bool KviKvsObject_window::functionsetCaption(KviKvsObjectFunctionCall *c)
+{
+ QString szCaption;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((KviKvsScriptWindowWindow *)widget())->setCaptionString(szCaption);
+ return true;
+}
+bool KviKvsObject_window::functionsetCentralWidget(KviKvsObjectFunctionCall *c)
+{
+ 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(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ if(!ob->inherits("KviKvsObject_widget"))
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ ((KviKvsScriptWindowWindow *)widget())->setCentralWidget((KviKvsObject_widget *)ob,((KviKvsObject_widget *)ob)->widget());
+ return true;
+}
+#include "m_class_window.moc"
diff --git a/src/modules/objects/class_window.h b/src/modules/objects/class_window.h
new file mode 100644
index 00000000..1f2ae482
--- /dev/null
+++ b/src/modules/objects/class_window.h
@@ -0,0 +1,64 @@
+#ifndef _CLASS_WINDOW_H_
+#define _CLASS_WINDOW_H_
+//
+// File : class_window.h
+// Creation date : Tue Nov 26 21:37:48 CEST 2002 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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 "kvi_window.h"
+
+#include "object_macros.h"
+
+class KviKvsObject_window : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_window)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionsetCaption(KviKvsObjectFunctionCall *c);
+ bool functionsetCentralWidget(KviKvsObjectFunctionCall *c);
+
+};
+
+
+class KviKvsScriptWindowWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviKvsScriptWindowWindow(KviFrame * pParent,const QString &szName);
+ ~KviKvsScriptWindowWindow();
+protected:
+ KviKvsObject_widget * m_pCentralWidgetObject;
+ QWidget * m_pCentralWidget;
+public:
+ void setCentralWidget(KviKvsObject_widget *o,QWidget * w);
+ void setCaptionString(const QString &s){ setFixedCaption(s); };
+ virtual void resizeEvent(QResizeEvent *e);
+protected slots:
+ void centralWidgetObjectDestroyed();
+ void centralWidgetDestroyed();
+};
+
+#endif // !_CLASS_WINDOW_H_
diff --git a/src/modules/objects/class_wizard.cpp b/src/modules/objects/class_wizard.cpp
new file mode 100644
index 00000000..091b3065
--- /dev/null
+++ b/src/modules/objects/class_wizard.cpp
@@ -0,0 +1,371 @@
+//mdm:
+// File : class_wizard.cpp
+// Creation date : Mon Apr 10 19:21:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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_tal_wizard.h>
+#include <qpushbutton.h>
+#include "class_wizard.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+
+
+
+/*
+ @doc: wizard
+ @keyterms:
+ wizard object class,
+ @title:
+ wizard class
+ @type:
+ class
+ @short:
+ The wizard class provides a framework for wizard dialogs.
+ @inherits:
+ [class]object[/class]
+ [class]widget[/class]
+ @description:
+ A wizard is an input dialog that consists of a sequence of dialog pages.It walks the user through a process step by step.[br]
+ @functions:
+ !fn: $addPage(<page_widget:object>,<title:string>)
+ Add a page with title.<page_widget> must be a widget's object.
+ !fn: $insertPage(<page_widget>,<title:string>,<index:integer>)
+ Inserts a page at the position <index>. If index is -1, page will appended to the end of the wizard's page sequenze.
+ !fn: $setTitle(<page>,<title:string>)
+ Sets the title for page page to title text.
+ !fn: $setBackEnabled(<page_widget>,<bEnabled:boolean>)
+ If enable is set to 1, page page has a Back button; otherwise page has no Back button.[br]
+ By default all pages have this button.
+ !fn: $setNextEnabled(<page_widget>,<bEnabled:boolean>)
+ If enable is set to 1, page page has a Next button; otherwise the Next button on page is disabled.[br]
+ By default all pages have this button.
+ !fn: $setFinishEnabled(<page_widget>,<bEnabled:boolean>)
+ If enable is set to 1, page page has a Finish button; otherwise the Finish button on page is disabled.[br]
+ By default NO pages have this button.
+ !fn: $setHelpEnabled(<page_widget>,<bEnabled:boolean>)
+ If enable is set to 1, page page has a Help button; otherwise the Help button on page is disabled.[br]
+ By default all pages have this button.
+ !fn: $setNextBtnText(<text:string>)
+ Set the text for button Next.
+ !fn: $setBackBtnText(<text:string>)
+ Set the text for button Back.
+ !fn: $setFinishBtnText(<text:string>)
+ Set the text for button Finish.
+ !fn: $setHelpBtnText(<text:string>)
+ Set the text for button Help.
+ !fn: $acceptEvent()
+ This function is called when the user click on the Finish button.
+ !fn: $rejectEvent()
+ This function is called when thie user click on the Reject button.
+ !fn: $nextClickedEvent()
+ This function is called when the user click on the Next button.
+ !fn: $backClickedEvent()
+ This function is called when thie user click on the Back button.
+ @signals:
+ !sg: $nextClicked()
+ This signal is emitted by the default implementation of [classfnc]$nextClickedEvent[/classfnc]().
+ !sg: $backClicked()
+ This signal is emitted by the default implementation of [classfnc]$backClickedEvent[/classfnc]().
+
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_wizard,"wizard","widget")
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"addPage", functionaddPage)
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"insertPage", functioninsertPage)
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"setTitle", functionsetTitle)
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"setBackEnabled", functionsetBackEnabled);
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"setNextEnabled", functionsetNextEnabled);
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"setFinishEnabled", functionsetFinishEnabled);
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"setHelpEnabled", functionsetHelpEnabled);
+
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"setBackBtnText", functionsetBackBtnText);
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"setNextBtnText", functionsetNextBtnText);
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"setFinishBtnText", functionsetFinishBtnText);
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"setHelpBtnText", functionsetHelpBtnText);
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"nextClickedEvent", functionnextClickedEvent);
+ KVSO_REGISTER_HANDLER(KviKvsObject_wizard,"backClickedEvent", functionbackClickedEvent);
+
+
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_wizard,"acceptEvent")
+ KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_wizard,"rejectEvent")
+
+KVSO_END_REGISTERCLASS(KviKvsObject_wizard)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_wizard,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_wizard)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_wizard)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_wizard)
+
+bool KviKvsObject_wizard::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new KviKvsMdmWizard(parentScriptWidget(), name(),this), true);
+
+ return true;
+}
+bool KviKvsObject_wizard::functionaddPage(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ QString szLabel;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("page_widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ ((KviTalWizard *)widget())->addPage(((QWidget *)(ob->object())),szLabel);
+ return true;
+}
+bool KviKvsObject_wizard::functioninsertPage(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ QString szLabel;
+ kvs_int_t uIndex;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("page_widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel)
+ KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Can't add a non-widget object"));
+ return true;
+ }
+ ((KviTalWizard *)widget())->insertPage(((QWidget *)(ob->object())),szLabel,uIndex);
+ return true;
+}
+
+
+bool KviKvsObject_wizard::functionsetTitle(KviKvsObjectFunctionCall *c)
+{
+ KviKvsObject *ob;
+ QString szTitle;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("page_widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETER("title",KVS_PT_STRING,0,szTitle)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Widget object required"));
+ return true;
+ }
+ ((KviTalWizard *)widget())->setPageTitle(((QWidget *)(ob->object())),szTitle);
+ return true;
+}
+bool KviKvsObject_wizard::functionsetBackEnabled(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KviKvsObject *ob;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("page_widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Widget object required"));
+ return true;
+ }
+ ((KviTalWizard *)widget())->setBackEnabled(((QWidget *)(ob->object())),bEnabled);
+ return true;
+}
+
+bool KviKvsObject_wizard::functionsetNextEnabled(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KviKvsObject *ob;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("page_widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Widget object required"));
+ return true;
+ }
+ ((KviTalWizard *)widget())->setNextEnabled(((QWidget *)(ob->object())),bEnabled);
+ return true;
+}
+bool KviKvsObject_wizard::functionsetFinishEnabled(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KviKvsObject *ob;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("page_widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Widget object required"));
+ return true;
+ }
+ ((KviTalWizard *)widget())->setFinishEnabled(((QWidget *)(ob->object())),bEnabled);
+ return true;
+}
+bool KviKvsObject_wizard::functionsetHelpEnabled(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KviKvsObject *ob;
+ kvs_hobject_t hObject;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("page_widget",KVS_PT_HOBJECT,0,hObject)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
+ if(!widget())return true;
+ if(!ob->object()->isWidgetType())
+ {
+ c->warning(__tr2qs("Widget object required"));
+ return true;
+ }
+ ((KviTalWizard *)widget())->setHelpEnabled(((QWidget *)(ob->object())),bEnabled);
+ return true;
+}
+bool KviKvsObject_wizard::functionsetBackBtnText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalWizard *)widget())->KviTalWizard::backButton()->setText(szText);
+ return true;
+}
+bool KviKvsObject_wizard::functionsetNextBtnText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalWizard *)widget())->KviTalWizard::nextButton()->setText(szText);
+ return true;
+}
+bool KviKvsObject_wizard::functionsetHelpBtnText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalWizard *)widget())->KviTalWizard::helpButton()->setText(szText);
+ return true;
+}
+bool KviKvsObject_wizard::functionsetFinishBtnText(KviKvsObjectFunctionCall *c)
+{
+ QString szText;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("text",KVS_PT_STRING,0,szText)
+ KVSO_PARAMETERS_END(c)
+ if (widget())
+ ((KviTalWizard *)widget())->KviTalWizard::finishButton()->setText(szText);
+ return true;
+}
+bool KviKvsObject_wizard::accept()
+{
+ KviKvsVariantList * pParams = 0;
+ callFunction(this,"acceptEvent",0,pParams);
+ return true;
+}
+bool KviKvsObject_wizard::reject()
+{
+ KviKvsVariantList * pParams = 0;
+ callFunction(this,"rejectEvent",0,pParams);
+ return true;
+}
+bool KviKvsObject_wizard::functionnextClickedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("nextClicked",c);
+ return true;
+}
+
+void KviKvsObject_wizard::nextClicked()
+{
+ KviKvsVariantList *params=0;
+ callFunction(this,"nextClickedEvent",params);
+}
+bool KviKvsObject_wizard::functionbackClickedEvent(KviKvsObjectFunctionCall *c)
+{
+ emitSignal("backClicked",c);
+ return true;
+}
+
+void KviKvsObject_wizard::backClicked()
+{
+ KviKvsVariantList *params=0;
+ callFunction(this,"backClickedEvent",params);
+}
+KviKvsMdmWizard::KviKvsMdmWizard(QWidget * par,const char * name,KviKvsObject_wizard * parent)
+:KviTalWizard(par)
+{
+ m_pParentScript=parent;
+ connect (this->backButton(),SIGNAL(clicked()),this,SLOT(slotBackClicked()));
+ connect (this->nextButton(),SIGNAL(clicked()),this,SLOT(slotNextClicked()));
+}
+void KviKvsMdmWizard::accept()
+{
+ if(m_pParentScript->accept())KviTalWizard::accept();
+
+}
+void KviKvsMdmWizard::reject()
+{
+ if(m_pParentScript->reject())KviTalWizard::reject();
+
+}
+void KviKvsMdmWizard::slotNextClicked()
+{
+ m_pParentScript->nextClicked();
+}
+void KviKvsMdmWizard::slotBackClicked()
+{
+ m_pParentScript->backClicked();
+}
+KviKvsMdmWizard::~KviKvsMdmWizard()
+{
+}
+#include "m_class_wizard.moc"
diff --git a/src/modules/objects/class_wizard.h b/src/modules/objects/class_wizard.h
new file mode 100644
index 00000000..0c605efe
--- /dev/null
+++ b/src/modules/objects/class_wizard.h
@@ -0,0 +1,79 @@
+#ifndef _CLASS_WIZARD_H_
+#define _CLASS_WIZARD_H_
+//
+// File : class_wizard.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) 1999-2005 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_tal_wizard.h>
+#include "class_widget.h"
+
+
+#include "object_macros.h"
+
+class KviKvsObject_wizard : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_wizard)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+ bool accept();
+ bool reject();
+ void nextClicked();
+ void backClicked();
+
+
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionaddPage(KviKvsObjectFunctionCall *c);
+ bool functioninsertPage(KviKvsObjectFunctionCall *c);
+ bool functionremovePage(KviKvsObjectFunctionCall *c);
+ bool functionsetTitle(KviKvsObjectFunctionCall *c);
+ bool functionsetBackEnabled(KviKvsObjectFunctionCall *c);
+ bool functionsetNextEnabled(KviKvsObjectFunctionCall *c);
+ bool functionsetFinishEnabled(KviKvsObjectFunctionCall *c);
+ bool functionsetHelpEnabled(KviKvsObjectFunctionCall *c);
+
+ bool functionsetBackBtnText(KviKvsObjectFunctionCall *c);
+ bool functionsetNextBtnText(KviKvsObjectFunctionCall *c);
+ bool functionsetFinishBtnText(KviKvsObjectFunctionCall *c);
+ bool functionsetHelpBtnText(KviKvsObjectFunctionCall *c);
+
+ bool functionnextClickedEvent(KviKvsObjectFunctionCall *c);
+ bool functionbackClickedEvent(KviKvsObjectFunctionCall *c);
+
+};
+class KviKvsMdmWizard : public KviTalWizard
+
+{
+ Q_OBJECT
+public:
+ KviKvsMdmWizard(QWidget * par,const char * name,KviKvsObject_wizard *);
+ void accept();
+ void reject();
+ virtual ~KviKvsMdmWizard();
+protected:
+ KviKvsObject_wizard *m_pParentScript;
+protected slots:
+ void slotNextClicked();
+ void slotBackClicked();
+};
+#endif //!_CLASS_WIZARD_H_
diff --git a/src/modules/objects/class_workspace.cpp b/src/modules/objects/class_workspace.cpp
new file mode 100644
index 00000000..1f6d8a3e
--- /dev/null
+++ b/src/modules/objects/class_workspace.cpp
@@ -0,0 +1,262 @@
+//mdm:
+// File : class_workspace.cpp
+// Creation date : Sat Feb 12 23:01:48 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor).
+// Thanks to Lucia Papini (^ashura^) for English help.
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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 <qworkspace.h>
+#include "class_workspace.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+/*
+ @doc: workspace
+ @keyterms:
+ workspace object class,
+ @title:
+ workspace class
+ @type:
+ class
+ @short:
+ Provides a MDI workspace object
+ @inherits:
+ [class]object[/class]
+ [class]widget[/class]
+ @description:
+ This widget provides a workspace window that can contain decorated window.
+ @functions:
+ !fn: <object> $activeWindow()
+ Returns the active window, or 0 if no window is active.
+ !fn: <boolean> $scrollBarsEnabled()
+ Returns TRUE if the workspace provides scrollbars; otherwise returns FALSE.
+ !fn: $setscrollBarsEnabled(<bEnabled:boolean>)
+ Sets whether the workspace provides scrollbars to enable. (bEnabled 1 or 0)
+ !fn: $cascade()
+ Arranges all the child windows in a cascade pattern.
+ !fn: $tile()
+ Arranges all child windows in a tile pattern.
+ !fn: $closeActiveWindow()
+ Closes the child window that is currently active.
+ !fn: $closeAllWindows()
+ Closes all child windows.
+ !fn: $activateNextWindow()
+ Activates the next window in the child window chain.
+ !fn: $activatePrevWindow()
+ Activates the prev window in the child window chain.[br]
+
+ |----CLASS EXAMPLE----|[br]
+ |-Start:[br]
+ #Let's start.[br]
+ #We start the main class creation, in the constructor we do the[br]
+ #widget's showing, to give a particular pop-up[br]
+ #creation appearance.[br]
+ class (ws,widget)[br]
+ {[br]
+ constructor[br]
+ {[br]
+ $$->$setGeometry(%X,%Y,100,100)[br]
+ $$->%label=$new(label,$$)[br]
+ $$->%label->$settext("Another class by N\&G")[br]
+ $$->%label->$setautoresize(1)[br]
+ $$->$show()[br]
+ }[br]
+ }[br]
+ #We create the new workspace, and we set a 640x480 size with widget $resize[br]
+ #command.[br]
+ %Workspace=$new(workspace)[br]
+ %Workspace->$resize(640,480)[br]
+ #Now we make a cycling costruction of the widgets(look at the class),[br]
+ #and give to the widgets a random X and Y coordinates.[br]
+ #It takes few seconds to show the effects, be patient.[br]
+ %I=0[br]
+ while (%I<100)[br]
+ {[br]
+ %X=$rand(500)[br]
+ %Y=$rand(480)[br]
+ %Widget=$new(ws,%Workspace)[br]
+ %I++[br]
+ }[br]
+ #Let's show the fireworks! EnJoY![br]
+ %Workspace->$show()[br]
+ |-Start:[br]
+ |-|EXAMPLE n2:[br]
+ #This is like the first example but it has a particular animation effect.[br]
+ %Hex[]=$array(0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)[br]
+ class (ws,widget)[br]
+ {[br]
+ constructor[br]
+ {[br]
+ $$->$setGeometry(%X,%Y,100,100)[br]
+ $$->%lay=$new(layout,$$)[br]
+ %i=0[br]
+ while (%i<10)[br]
+ {[br]
+ $$->%label=$new(label,$$)[br]
+ $$->%label->$settext("Another class by N\&G")[br]
+ %color=%Hex[$rand(15)]%Hex[$rand(15)]%Hex[$rand(15)]%Hex[$rand(15)]%Hex[$rand(15)]%Hex[$rand(15)][br]
+ $$->%label->$setforegroundcolor(%color)[br]
+ $$->%label->$setautoresize(1)[br]
+ $$->%lay->$addwidget($$->%label,%i,0)[br]
+ %i++;[br]
+ }[br]
+ $$->$show()[br]
+ }[br]
+ mousepressevent[br]
+ {[br]
+ if ($istimer(cycle) == 1) killtimer cycle[br]
+ }[br]
+ }[br]
+ %Workspace=$new(workspace)[br]
+ %Workspace->$resize(640,480)[br]
+ %Workspace->$setCaption("Hit the mouse to stop cycling windows....")[br]
+ %I=0[br]
+ %Cicle=1[br]
+ while (%I<20)[br]
+ {[br]
+ %X=$rand(500)[br]
+ %Y=$rand(480)[br]
+ %Widget=$new(ws,%Workspace)[br]
+ %I++[br]
+ }[br]
+ %Workspace->$show[br]
+ timer (cycle,3000)[br]
+ {[br]
+ if (%Cicle==1) %Workspace->$tile()[br]
+ if (%Cicle==2)[br]
+ {[br]
+ %Workspace->$cascade()[br]
+ %Cicle=1[br]
+ return[br]
+ }[br]
+ %Cicle++[br]
+ }[br]
+ privateimpl(%Workspace,mousepressevent)[br]
+ {[br]
+ if ($istimer(cycle) == 1) killtimer cycle[br]
+ }[br]
+ #-|End.[br]
+
+*/
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_workspace,"workspace","widget")
+ KVSO_REGISTER_HANDLER(KviKvsObject_workspace,"activeWindow", functionactiveWindow);
+ KVSO_REGISTER_HANDLER(KviKvsObject_workspace,"scrollBarsEnabled", functionscrollBarsEnabled);
+ KVSO_REGISTER_HANDLER(KviKvsObject_workspace,"setscrollBarsEnabled", functionsetscrollBarsEnabled);
+ KVSO_REGISTER_HANDLER(KviKvsObject_workspace,"cascade", functioncascade);
+ KVSO_REGISTER_HANDLER(KviKvsObject_workspace,"tile", functiontile);
+ KVSO_REGISTER_HANDLER(KviKvsObject_workspace,"closeActiveWindow", functioncloseActiveWindow);
+ KVSO_REGISTER_HANDLER(KviKvsObject_workspace,"closeAllWindows", functioncloseAllWindows);
+ KVSO_REGISTER_HANDLER(KviKvsObject_workspace,"activateNextWindow", functionactivateNextWindow);
+ KVSO_REGISTER_HANDLER(KviKvsObject_workspace,"activatePrevWindow", functionactivatePrevWindow);
+KVSO_END_REGISTERCLASS(KviKvsObject_workspace)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_workspace,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_workspace)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_workspace)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_workspace)
+
+bool KviKvsObject_workspace::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ setObject(new QWorkspace(parentScriptWidget(), name()), true);
+ return true;
+}
+
+bool KviKvsObject_workspace::functionactiveWindow(KviKvsObjectFunctionCall *c)
+{
+ //if(widget()) c->returnValue()->setHObject((unsigned long)(((QWorkspace *)widget())->activeWindow()));
+ // FIXME!
+ c->returnValue()->setHObject(0);
+ return true; //?pFIX ME?
+}
+
+bool KviKvsObject_workspace::functionscrollBarsEnabled(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ c->returnValue()->setBoolean(((QWorkspace *)widget())->scrollBarsEnabled());
+ return true;
+}
+
+bool KviKvsObject_workspace::functionsetscrollBarsEnabled(KviKvsObjectFunctionCall *c)
+{
+ bool bEnabled;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSO_PARAMETERS_END(c)
+ if(widget())
+ ((QWorkspace *)widget())->setScrollBarsEnabled(bEnabled);
+ return true;
+}
+
+bool KviKvsObject_workspace::functioncascade(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QWorkspace *)widget())->cascade();
+ return true;
+}
+
+bool KviKvsObject_workspace::functiontile(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QWorkspace *)widget())->tile();
+ return true;
+}
+
+bool KviKvsObject_workspace::functioncloseActiveWindow(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QWorkspace *)widget())->closeActiveWindow();
+ return true;
+}
+
+bool KviKvsObject_workspace::functioncloseAllWindows(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QWorkspace *)widget())->closeAllWindows();
+ return true;
+}
+
+bool KviKvsObject_workspace::functionactivateNextWindow(KviKvsObjectFunctionCall *c)
+{
+ if(widget())
+ ((QWorkspace *)widget())->activateNextWindow();
+ return true;
+}
+
+bool KviKvsObject_workspace::functionactivatePrevWindow(KviKvsObjectFunctionCall *c)
+{
+ if(widget()){
+ #ifdef COMPILE_USE_QT4
+ ((QWorkspace *)widget())->activatePreviousWindow();
+ #else
+ ((QWorkspace *)widget())->activatePrevWindow();
+ #endif
+ }
+ return true;
+}
diff --git a/src/modules/objects/class_workspace.h b/src/modules/objects/class_workspace.h
new file mode 100644
index 00000000..c18264df
--- /dev/null
+++ b/src/modules/objects/class_workspace.h
@@ -0,0 +1,53 @@
+#ifndef _CLASS_WORKSPACE_H_
+#define _CLASS_WORKSPACE_H_
+//mdm:
+// File : class_workspace.h
+// Creation date : Sat Feb 12 23:05:58 CEST 2005
+// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 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 <qworkspace.h>
+#include "class_widget.h"
+
+class KviKvsObject_workspace : public KviKvsObject_widget
+{
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_workspace)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+
+ bool functionactiveWindow(KviKvsObjectFunctionCall *c);
+ bool functionscrollBarsEnabled(KviKvsObjectFunctionCall *c);
+ bool functionsetscrollBarsEnabled(KviKvsObjectFunctionCall *c);
+ bool functioncascade(KviKvsObjectFunctionCall *c);
+ bool functiontile(KviKvsObjectFunctionCall *c);
+ bool functioncloseActiveWindow(KviKvsObjectFunctionCall *c);
+ bool functioncloseAllWindows(KviKvsObjectFunctionCall *c);
+ bool functionactivateNextWindow(KviKvsObjectFunctionCall *c);
+ bool functionactivatePrevWindow(KviKvsObjectFunctionCall *c);
+};
+
+#endif //!_CLASS_WORKSPACE_H_
diff --git a/src/modules/objects/class_wrapper.cpp b/src/modules/objects/class_wrapper.cpp
new file mode 100644
index 00000000..02ff632c
--- /dev/null
+++ b/src/modules/objects/class_wrapper.cpp
@@ -0,0 +1,269 @@
+//mdm:
+// File : class_wrapper.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) 1999-2005 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_wrapper.h"
+#include "kvi_error.h"
+#include "kvi_debug.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+#include "class_widget.h"
+#include <qwidget.h>
+#ifndef COMPILE_USE_QT4
+ #include <qobjectlist.h>
+ #include <qwidgetlist.h>
+#endif
+#include "kvi_app.h"
+#include "kvi_frame.h"
+
+
+/*
+ @doc: wrapper
+ @keyterms:
+ wrapper object class,
+ @title:
+ wrapper class
+ @type:
+ class
+ @short:
+ Provides a wrapper class that hooks to an existing Qt graphic object modifying it.
+ @inherits:
+ [class]object[/class]
+ [class]widget[/class]
+ @description:
+ This is a class for advanced KVIrc scripting.[br]
+ It can wrap any existing KVIrc widget.[br]
+ This class allows some unbelievable changes to the whole graphic environment of the kvirc,[br]
+ in fact, could hook every widget, you can modify the property or you can be inserted other widget as child of this...[br]
+ in short you have absolute liberty. [br]
+ The power of this class is fantastic, because it allows the change at "run time" of almost all the elements of the Kvirc.[br]
+ But to use this class in optimal way and to exploit its power, you have to know the Qt.... so you won't have limits [br]
+ The KVIrc Qt widgets are arranged in trees (just as the objects).[br]
+ The difference is that there are more toplevel widgets (and so more than one tree).[br]
+ You can use [fnc]$objects.dump()[/fnc] to take a look at the KVIrc Qt objects tree.[br]
+ Here is a part of the tree:[br][br]
+ Ptr 14332520: top level object: kvirc_frame, class KviFrame, visible, rect = -4, -4, 1024, 708
+ Ptr 17296024: object: qt_top_dock, class QDockArea
+ Ptr 14882136: object: qt_custom_toolbar, class KviCustomToolBar
+ Ptr 18143368: object: qt_dockwidget_internal, class QDockWindowTitleBar
+ [br][br]
+ Every listed widget has a "name", a "class" and a set of properties.[br]
+ The first entry in this example is a KVIrc server window, class "KviFrame" and name "kvirc_frame":
+ it is a toplevel widget.[br]
+ The "qt_top_dock", "qt_custom_toolbar" and the "qt_dockwidget_internal" are
+ direct children of that widget.[br]
+ To indicate a specific widget we will use the "class::name" form.[br]
+ So to indicate the main KVIrc frame you will use "KviFrame::kvirc_main_frame".
+ Look at this example:[br]
+ %A=$new(wrapper,0,test,KviFrame::kvirc_frame,KviStatusBar::unnamed)[br]
+ %A->$setBackGroundColor(FFFFFF)[br]
+ For first thing we create an object type wrapper,then we flow the tree that there from the command /object.dump and we will have:[br]
+ . [br]
+ . [br]
+ Ptr 14196288: top level object: kvirc_frame, class KviFrame, visible, rect = -4, -4, 1024, 712 [br]
+. [br]
+ Ptr 17197360: object: unnamed, class KviStatusBar [br]
+ . [br]
+ . [br]
+ in this way we can follow the order, father->child from the top-level widget(KviFrame::kvirc_frame)[br]
+ to reach the child that interests us (KviStatusBar::unnamed)[br]
+ Then, following the syntax we will have:
+ %A=$new(wrapper,0,test,KviFrame::kvirc_frame,KviStatusBar::unnamed)
+ Now %A. will be point to the wrapped object, therefore we could modify its property or to consider it as if it were an object created by us in scripting. [br]
+ Obviously, deleting the created object (for example %A) you don't will delete the object of Kvirc (in this case the statusbar). [br]
+ Another example could be this:[br]
+ %A=$new(wrapper,0,test,KviFrame::kvirc_frame,QToolButton::kvirc.identityoptions)[br]
+ %A->$setProperty(usesBigPixmap,0)[br]
+ In this fool example with the function $setProperty, we has setted the property usesBigPixmap to False, making to become the small icons of the ToolBar.[br]
+ [br]
+ The wrapping object search can optionally start with a window
+ identifier with the following syntax: WinId::<window_id>.
+
+*/
+
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_wrapper,"wrapper","widget")
+
+KVSO_END_REGISTERCLASS(KviKvsObject_wrapper)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_wrapper,KviKvsObject_widget)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_wrapper)
+
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_wrapper)
+
+KVSO_END_CONSTRUCTOR(KviKvsObject_wrapper)
+
+bool KviKvsObject_wrapper::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams)
+{
+ if( !pParams ) return false;
+
+ debug ("ci sono i parametri");
+ QWidget *pWidget = 0;
+ int i=0;
+ while(i!=pParams->count())
+ {
+ QString szClass;
+ QString szName;
+ QString s=0;
+ pParams->at(i)->asString(s);
+ if (!s.isEmpty())
+ {
+ int idx = s.find("::");
+ if( idx != -1 ) {
+ szClass = s.left(idx);
+ szName = s.right(s.length() - idx - 2);
+ } else {
+ szClass = s;
+ szName = "";
+ }
+ debug ("szClass %s",szClass.latin1());
+ debug ("szName %s",szName.latin1());
+ debug ("s %s",s.latin1());
+
+ if(KviQString::equalCI(szClass,"WinId"))
+ {
+ if(pWidget)
+ {
+ pContext->warning(__tr2qs("The window identifier preceeded by WinId must be the first object in the search path"));
+ return false;
+ } else {
+ pWidget = g_pApp->findWindow(szName);
+ }
+ } else {
+ if(pWidget) {
+ pWidget = findWidgetToWrap(
+ !szClass.isEmpty() ? szClass : KviQString::empty, !szName.isEmpty() ? szName : KviQString::empty, pWidget
+ );
+ } else {
+ pWidget = findTopLevelWidgetToWrap(szClass.isEmpty() ? szClass : KviQString::empty, !szName.isEmpty() ? szName : KviQString::empty);
+ }
+ }
+ if( !pWidget )
+ {
+ pContext->warning(__tr2qs("Failed to find one of the wrap path widgets (%Q::%Q)"),&szClass,&szName);
+ return false;
+ }
+ }
+ i++;
+
+ }
+ if( !pWidget )
+ {
+ pContext->warning(__tr2qs("Failed to find the widget to wrap"));
+ return false;
+ }
+ setObject(pWidget,false);
+
+ return true;
+}
+QWidget *KviKvsObject_wrapper::findTopLevelWidgetToWrap(const QString szClass, const QString szName)
+{
+#ifdef COMPILE_USE_QT4
+ QWidgetList list = g_pApp->topLevelWidgets();
+ if( !list.count() ) return 0;
+ for(int idx=0;idx<list.count();idx++)
+ {
+ bool bNameMatch = false;
+ bool bClassMatch = false;
+ if( !szName.isEmpty() )
+ bNameMatch = KviQString::equalCI(list.at(idx)->name(), szName);
+ else
+ bNameMatch = true;
+ if( !szClass.isEmpty())
+ bClassMatch = KviQString::equalCI(list.at(idx)->className(), szClass);
+ else
+ bClassMatch = true;
+ if( bNameMatch && bClassMatch ) {
+ QWidget *w = list.at(idx);
+ return w;
+ }
+ }
+ return 0;
+#else
+
+ QWidgetList *list = g_pApp->topLevelWidgets();
+ if( !list ) return 0;
+
+ QWidgetListIt it(*list);
+ while( it.current() ) {
+ bool bNameMatch = false;
+ bool bClassMatch = false;
+ if( szName )
+ bNameMatch = KviQString::equalCI(it.current()->name(), szName);
+ else
+ bNameMatch = true;
+ if( szClass )
+ bClassMatch = KviQString::equalCI(it.current()->className(), szClass);
+ else
+ bClassMatch = true;
+ if( bNameMatch && bClassMatch ) {
+ QWidget *w = it.current();
+ delete list;
+ return w;
+ }
+ ++it;
+ }
+ delete list;
+
+ return 0;
+#endif
+}
+
+QWidget *KviKvsObject_wrapper::findWidgetToWrap(const char *szClass, const char *szName, QWidget *childOf)
+{
+#ifdef COMPILE_USE_QT4
+ QObjectList list = childOf->queryList(szClass ? szClass : 0, szName ? szName : 0, false, true);
+ if( !list.count() ) return 0;
+ for(int idx=0;idx<list.count();idx++)
+ {
+ if( list.at(idx)->isWidgetType() ) {
+ QWidget *w = (QWidget *)list.at(idx);
+ return w;
+ }
+
+ }
+ return 0;
+#else
+
+ QObjectList *list = childOf->queryList(szClass ? szClass : 0, szName ? szName : 0, false, true);
+ if( !list ) return 0;
+
+ QObjectListIt it(*list);
+ while( it.current() ) {
+ if( it.current()->isWidgetType() ) {
+ QWidget *w = (QWidget *) it.current();
+ delete list;
+ return w;
+ }
+ ++it;
+ }
+ delete list;
+ return 0;
+#endif
+}
+
+#include "m_class_wrapper.moc"
diff --git a/src/modules/objects/class_wrapper.h b/src/modules/objects/class_wrapper.h
new file mode 100644
index 00000000..900b0672
--- /dev/null
+++ b/src/modules/objects/class_wrapper.h
@@ -0,0 +1,53 @@
+#ifndef _CLASS_WRAPPER_H_
+#define _CLASS_WRAPPER_H_
+//
+// File : class_wrapper.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) 1999-2005 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 "qlistview.h"
+
+
+
+
+#include "object_macros.h"
+
+class KviKvsObject_wrapper : public KviKvsObject_widget
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_wrapper)
+public:
+ QWidget * widget() { return (QWidget *)object(); };
+protected:
+ virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams);
+ QWidget * findTopLevelWidgetToWrap(const QString szClass, const QString szName);
+ QWidget * findWidgetToWrap(const char *szClass, const char *szName, QWidget *childOf);
+
+};
+
+
+
+#endif //!_CLASS_WRAPPER_H_
diff --git a/src/modules/objects/class_xmlreader.cpp b/src/modules/objects/class_xmlreader.cpp
new file mode 100644
index 00000000..f4bccc8f
--- /dev/null
+++ b/src/modules/objects/class_xmlreader.cpp
@@ -0,0 +1,343 @@
+//=============================================================================
+//
+// File : class_xmlreader.cpp
+// Created on Tue 27 Dec 2005 00:14:09 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2005 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_xmlreader.h"
+
+#include "kvi_locale.h"
+
+#include "kvi_kvs_variantlist.h"
+#include "kvi_kvs_hash.h"
+
+#include "kvi_qstring.h"
+
+
+/*
+ @doc: xmlreader
+ @keyterms:
+ xml
+ @title:
+ xmlreader class
+ @type:
+ class
+ @short:
+ A simple xml document parser
+ @inherits:
+ [class]object[/class]
+ @description:
+ This class implements a really simple xml document parser.
+ You will usually derive your own class from this one and reimplement
+ some of the events that it triggers.
+ You will typically reimplement [classfnc:xmlparser]onElementStart[/classfnc]()
+ and [classfnc:xmlparser]onElementEnd[/classfnc]() that will be called
+ during the execution of [classfnc:xmlparser]$parse[/classfnc]() in an order
+ reflecting the order of elements in the parsed document.
+ @functions:
+ !fn: <boolean> $parse(<xml_data:string>)
+ Call this function to parse a string that contains an XML document.
+ A typical call for this method will look like:
+ [example]
+ %x = [fnc]$new[/fnc](xmlparser)
+ %x->$parse([fnc]$file.read[/fnc]("/home/somefile.xml"))
+ [/example]
+ During the call the <xml_data> string will be parsed and the
+ relevant on* events (see below) will be triggered.
+ $parse will return $true when the parsing terminates succesfully
+ or $false if it aborts for some reason (unrecoverable error
+ in the document, user abort etc...).
+ If this function return $false then you can call $lastError() to
+ obtain a descriptive error message.
+
+ !fn: <string> $lastError()
+ Returns the last error occured inside the parser.
+ You will typically call this function when $parse() above returns $false.
+
+ !fn: <boolean> $onDocumentStart()
+ This function is called when the document parsing starts.
+ You can reimplement it in order to handle this notification.
+ You should return $true if you want document parsing to continue
+ and $false if you want it to be aborted.
+ The default implementation does nothing besides returning $true.
+
+ !fn: <boolean> $onDocumentEnd()
+ This function is called when the document parsing terminates succesfully.
+ You can reimplement it in order to handle this notification.
+ You should return $true if you want document parsing to continue
+ and $false if you want it to be aborted.
+ The default implementation does nothing besides returning $true.
+
+ !fn: <boolean> $onElementStart(<qualified_name:string>,<attributes:hash>,<namespace:string>,<local_name:string>)
+ This function is called when an element opening tag is encountered.
+ The <qualified_name> of the tag is passed as the first parameter.
+ The <attributes> are passed in the form of a hash with attribute
+ values indexed by their names.
+ When the <qualified_name> contains a namespace then it is also reported
+ in the splitted <namespace> <local_name> pair.
+ You should return $true if you want document parsing to continue
+ and $false if you want it to be aborted.
+ The default implementation does nothing besides returning $true.
+
+ !fn: <boolean> $onElementEnd(<qualified_name:string>,<namespace:string>,<local_name:string>)
+ This function is called when an element closing tag is encountered.
+ The <qualified_name> of the tag is passed as the first parameter.
+ When the <qualified_name> contains a namespace then it is also reported
+ in the splitted <namespace> <local_name> pair.
+ You should return $true if you want document parsing to continue
+ and $false if you want it to be aborted.
+ The default implementation does nothing besides returning $true.
+
+ !fn: <boolean> $onText($0 = <text:string>)
+ This function is called when a chunk of text is encountered inside the document.
+ The parsed <text> chunk is passed as the first parameter.
+ You should return $true if you want document parsing to continue
+ and $false if you want it to be aborted.
+ The default implementation does nothing besides returning $true.
+
+ !fn: <boolean> $onWarning(<message:string>)
+ This function is called when the parser generates a recoverable error.
+ The error <message> is passed as the first parameter.
+ You should return $true if you want document parsing to continue
+ and $false if you want it to be aborted.
+ The default implementation does nothing besides returning $true.
+
+ !fn: <boolean> $onError(<message:string>)
+ This function is called when the parser generates an unrecoverable error.
+ The error <message> is passed as the first parameter.
+ The document parsing can't continue.
+ The default implementation does nothing besides returning $true.
+*/
+
+
+#ifndef QT_NO_XML
+
+#include <qxml.h>
+
+class KviXmlHandler : public QXmlDefaultHandler
+{
+protected:
+ KviKvsObject_xmlreader * m_pReader;
+ QString m_szErrorString;
+public:
+ KviXmlHandler(KviKvsObject_xmlreader * pReader)
+ {
+ m_pReader = pReader;
+ }
+ ~KviXmlHandler()
+ {
+ }
+private:
+ bool kvsCodeFailure()
+ {
+ m_szErrorString = __tr2qs("Error in KVS class implementation: processing aborted");
+ return false;
+ }
+ bool kvsCodeAbort()
+ {
+ m_szErrorString = __tr2qs("Processing aborted");
+ return false;
+ }
+ void decodeException(QString &szMsg,bool bError,const QXmlParseException &exception)
+ {
+ if(bError)
+ KviQString::sprintf(szMsg,__tr2qs("Error near line %d, column %d"),exception.lineNumber(),exception.columnNumber());
+ else
+ KviQString::sprintf(szMsg,__tr2qs("Warning near line %d, column %d"),exception.lineNumber(),exception.columnNumber());
+ szMsg += ": ";
+ szMsg += exception.message();
+ }
+ bool handleKvsCallReturnValue(KviKvsVariant * pRetVal)
+ {
+ if(!pRetVal->asBoolean())return kvsCodeAbort();
+ return true;
+ }
+public:
+ virtual bool startDocument()
+ {
+ KviKvsVariant ret;
+ if(!m_pReader->callFunction(m_pReader,"onDocumentStart",&ret))
+ return kvsCodeFailure();
+ return handleKvsCallReturnValue(&ret);
+ }
+
+ virtual bool endDocument()
+ {
+ KviKvsVariant ret;
+ if(!m_pReader->callFunction(m_pReader,"onDocumentEnd",&ret))
+ return kvsCodeFailure();
+ return handleKvsCallReturnValue(&ret);
+ }
+
+ virtual bool startElement(const QString &szNamespaceUri,const QString &szLocalName,const QString &szQualifiedName,const QXmlAttributes &attrs)
+ {
+ KviKvsVariant ret;
+ KviKvsVariantList par;
+ par.setAutoDelete(true);
+ par.append(new KviKvsVariant(szQualifiedName));
+ KviKvsHash * pHash = new KviKvsHash();
+ par.append(new KviKvsVariant(pHash));
+ par.append(new KviKvsVariant(szNamespaceUri));
+ par.append(new KviKvsVariant(szLocalName));
+ int c = attrs.count();
+ for(int i=0;i<c;i++)
+ pHash->set(attrs.qName(i),new KviKvsVariant(attrs.value(i)));
+ if(!m_pReader->callFunction(m_pReader,"onElementStart",&ret,&par))
+ return kvsCodeFailure();
+ return handleKvsCallReturnValue(&ret);
+ }
+
+ virtual bool endElement(const QString &szNamespaceUri,const QString &szLocalName,const QString &szQualifiedName)
+ {
+ KviKvsVariant ret;
+ KviKvsVariantList par;
+ par.setAutoDelete(true);
+ par.append(new KviKvsVariant(szQualifiedName));
+ par.append(new KviKvsVariant(szNamespaceUri));
+ par.append(new KviKvsVariant(szLocalName));
+ if(!m_pReader->callFunction(m_pReader,"onElementEnd",&ret,&par))
+ return kvsCodeFailure();
+ return handleKvsCallReturnValue(&ret);
+ }
+
+ virtual bool characters(const QString &szChars)
+ {
+ KviKvsVariant ret;
+ KviKvsVariantList par;
+ par.setAutoDelete(true);
+ par.append(new KviKvsVariant(szChars));
+ if(!m_pReader->callFunction(m_pReader,"onText",&ret,&par))
+ return kvsCodeFailure();
+ return handleKvsCallReturnValue(&ret);
+ }
+
+ virtual bool warning(const QXmlParseException &exception)
+ {
+ // recoverable
+ QString szMsg;
+ decodeException(szMsg,false,exception);
+
+ KviKvsVariant ret;
+ KviKvsVariantList par;
+ par.setAutoDelete(true);
+ par.append(new KviKvsVariant(szMsg));
+ if(!m_pReader->callFunction(m_pReader,"onWarning",&ret,&par))
+ return kvsCodeFailure();
+ return handleKvsCallReturnValue(&ret);
+ }
+
+ virtual bool error(const QXmlParseException &exception)
+ {
+ // recoverable
+ QString szMsg;
+ decodeException(szMsg,false,exception);
+
+ KviKvsVariant ret;
+ KviKvsVariantList par;
+ par.setAutoDelete(true);
+ par.append(new KviKvsVariant(szMsg));
+ if(!m_pReader->callFunction(m_pReader,"onWarning",&ret,&par))
+ return kvsCodeFailure();
+ return handleKvsCallReturnValue(&ret);
+ }
+
+ virtual bool fatalError(const QXmlParseException &exception)
+ {
+ QString szMsg;
+ decodeException(szMsg,true,exception);
+ m_pReader->fatalError(szMsg);
+ return true;
+ }
+
+ virtual QString errorString()
+ {
+ return m_szErrorString;
+ }
+};
+
+#endif // !QT_NO_XML
+
+
+KVSO_BEGIN_REGISTERCLASS(KviKvsObject_xmlreader,"xmlreader","object")
+ KVSO_REGISTER_HANDLER(KviKvsObject_xmlreader,"lastError",function_lastError)
+ KVSO_REGISTER_HANDLER(KviKvsObject_xmlreader,"parse",function_parse)
+
+ KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(KviKvsObject_xmlreader,"onDocumentStart")
+ KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(KviKvsObject_xmlreader,"onDocumentEnd")
+ KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(KviKvsObject_xmlreader,"onElementStart")
+ KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(KviKvsObject_xmlreader,"onElementEnd")
+ KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(KviKvsObject_xmlreader,"onText")
+ KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(KviKvsObject_xmlreader,"onWarning")
+ KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(KviKvsObject_xmlreader,"onError")
+KVSO_END_REGISTERCLASS(KviKvsObject_xmlreader)
+
+KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_xmlreader,KviKvsObject)
+KVSO_END_CONSTRUCTOR(KviKvsObject_xmlreader)
+
+KVSO_BEGIN_DESTRUCTOR(KviKvsObject_xmlreader)
+KVSO_END_DESTRUCTOR(KviKvsObject_xmlreader)
+
+void KviKvsObject_xmlreader::fatalError(const QString &szError)
+{
+ m_szLastError = szError;
+
+ KviKvsVariantList vArgs;
+ vArgs.append(new KviKvsVariant(m_szLastError));
+ callFunction(this,"onError",&vArgs);
+}
+
+bool KviKvsObject_xmlreader::function_parse(KviKvsObjectFunctionCall *c)
+{
+ QString szString;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSO_PARAMETERS_END(c)
+
+#ifdef QT_NO_XML
+ fatalError(__tr2qs("XML support not available in the Qt library"));
+ c->returnValue()->setBoolean(false);
+#else
+ m_szLastError = "";
+ KviXmlHandler handler(this);
+ QXmlInputSource source;
+ // We have a problem here.. most kvirc functions already interpret the data
+ // read from files. We should have binary data handling features to get this to work correctly.
+ // The following snippet of code tries to provide a best-effort workaround.
+ KviQCString utf8data = KviQString::toUtf8(szString);
+ QByteArray data = utf8data;
+ data.truncate(utf8data.length()); // don't include the null terminator in data
+ source.setData(data);
+ //debug("PARSING(%s) LEN(%d)",szString.utf8().data(),szString.utf8().length());
+ QXmlSimpleReader reader;
+ reader.setContentHandler(&handler);
+ reader.setErrorHandler(&handler);
+ c->returnValue()->setBoolean(reader.parse(source));
+#endif
+ return true;
+}
+
+bool KviKvsObject_xmlreader::function_lastError(KviKvsObjectFunctionCall *c)
+{
+ c->returnValue()->setString(m_szLastError);
+ return true;
+}
+
+#include "m_class_xmlreader.moc"
diff --git a/src/modules/objects/class_xmlreader.h b/src/modules/objects/class_xmlreader.h
new file mode 100644
index 00000000..dca69333
--- /dev/null
+++ b/src/modules/objects/class_xmlreader.h
@@ -0,0 +1,46 @@
+#ifndef _CLASS_XMLREADER_H_
+#define _CLASS_XMLREADER_H_
+//=============================================================================
+//
+// File : class_xmlreader.h
+// Created on Tue 27 Dec 2005 00:14:09 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2005 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 "kvi_qstring.h"
+
+#include "object_macros.h"
+
+class KviKvsObject_xmlreader : public KviKvsObject
+{
+ Q_OBJECT
+public:
+ KVSO_DECLARE_OBJECT(KviKvsObject_xmlreader)
+public:
+ bool function_parse(KviKvsObjectFunctionCall *c);
+ bool function_lastError(KviKvsObjectFunctionCall *c);
+
+ void fatalError(const QString &szError);
+protected:
+ QString m_szLastError;
+};
+
+#endif //!_CLASS_XMLREADER_H_
diff --git a/src/modules/objects/libkviobjects.cpp b/src/modules/objects/libkviobjects.cpp
new file mode 100644
index 00000000..73eacace
--- /dev/null
+++ b/src/modules/objects/libkviobjects.cpp
@@ -0,0 +1,1066 @@
+//=============================================================================
+//
+// File : libkviobjects.cpp
+// Creation date : Wed Sep 09 2000 20:59:01 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2006 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_tal_listview.h"
+#include <qimage.h>
+#include "kvi_iconmanager.h"
+#include "kvi_window.h"
+#include "kvi_out.h"
+#include "kvi_mirccntrl.h"
+
+#include "kvi_app.h"
+
+#include "kvi_module.h"
+
+#include "kvi_locale.h"
+#include "kvi_error.h"
+#include "kvi_cmdformatter.h"
+#include "kvi_out.h"
+#include "kvi_app.h"
+#include "kvi_fileutils.h"
+#ifndef COMPILE_USE_QT4
+ #include <qwidgetlist.h>
+ #include <qobjectlist.h>
+#endif
+
+#include <qdir.h>
+
+#include "class_button.h"
+#include "class_checkbox.h"
+#include "class_urllabel.h"
+#include "class_lineedit.h"
+#include "class_multilineedit.h"
+#include "class_combobox.h"
+#include "class_widget.h"
+#include "class_list.h"
+#include "class_file.h"
+#include "class_socket.h"
+#include "class_layout.h"
+#include "class_menubar.h"
+#include "class_window.h"
+#include "class_listbox.h"
+#include "class_progressbar.h"
+#include "class_slider.h"
+#include "class_spinbox.h"
+#include "class_lcd.h"
+#include "class_radiobutton.h"
+#include "class_process.h"
+#include "class_groupbox.h"
+#include "class_buttongroup.h"
+#include "class_tabwidget.h"
+#include "class_workspace.h"
+#include "class_popupmenu.h"
+#include "class_listview.h"
+#include "class_listviewitem.h"
+#include "class_toolbar.h"
+#include "class_mainwindow.h"
+#include "class_toolbutton.h"
+#include "class_wizard.h"
+#include "class_tbrowser.h"
+#include "class_painter.h"
+#include "class_pixmap.h"
+#include "class_wrapper.h"
+#include "class_dialog.h"
+#include "class_xmlreader.h"
+#include "class_dockwindow.h"
+#include "class_vbox.h"
+#include "class_hbox.h"
+static void dumpChildObjects(KviWindow *pWnd, QObject *parent, const char *spacing, bool bWidgetsOnly, KviKvsArray *n, int &idx);
+
+static bool objects_module_cleanup(KviModule *m)
+{
+ KviKvsObject_process::unregisterSelf();
+ KviKvsObject_socket::unregisterSelf();
+ KviKvsObject_xmlreader::unregisterSelf();
+ KviKvsObject_wrapper::unregisterSelf();
+ KviKvsObject_file::unregisterSelf();
+ KviKvsObject_progressbar::unregisterSelf();
+ KviKvsObject_dockwindow::unregisterSelf();
+ KviKvsObject_wizard::unregisterSelf();
+ KviKvsObject_window::unregisterSelf();
+ KviKvsObject_urlabel::unregisterSelf();
+ KviKvsObject_toolbutton::unregisterSelf();
+ KviKvsObject_toolbar::unregisterSelf();
+ KviKvsObject_tabwidget::unregisterSelf();
+ KviKvsObject_spinbox::unregisterSelf();
+ KviKvsObject_slider::unregisterSelf();
+ KviKvsObject_radiobutton::unregisterSelf();
+ KviKvsObject_popupmenu::unregisterSelf();
+ KviKvsObject_pixmap::unregisterSelf();
+ KviKvsObject_painter::unregisterSelf();
+ KviKvsObject_mainwindow::unregisterSelf();
+ KviKvsObject_listviewitem::unregisterSelf();
+ KviKvsObject_listview::unregisterSelf();
+ KviKvsObject_listbox::unregisterSelf();
+ KviKvsObject_combobox::unregisterSelf();
+ KviKvsObject_workspace::unregisterSelf();
+ KviKvsObject_menubar::unregisterSelf();
+ KviKvsObject_lineedit::unregisterSelf();
+ KviKvsObject_lcd::unregisterSelf();
+ KviKvsObject_layout::unregisterSelf();
+ KviKvsObject_hbox::unregisterSelf();
+ KviKvsObject_vbox::unregisterSelf();
+ KviKvsObject_label::unregisterSelf();
+ KviKvsObject_buttongroup::unregisterSelf();
+ KviKvsObject_groupbox::unregisterSelf();
+ KviKvsObject_dialog::unregisterSelf();
+ KviKvsObject_checkbox::unregisterSelf();
+ KviKvsObject_textbrowser::unregisterSelf();
+ KviKvsObject_mledit::unregisterSelf();
+ KviKvsObject_button::unregisterSelf();
+ KviKvsObject_widget::unregisterSelf();
+ KviKvsObject_list::unregisterSelf();
+
+ return true;
+}
+
+
+static bool objects_kvs_cmd_killClass(KviKvsModuleCommandCall * c)
+{
+ /*
+ @doc: objects.killclass
+ @title:
+ objects.killclass
+ @type:
+ command
+ @short:
+ Removes a class definition
+ @syntax:
+ objects.killclass [-q] <classname:string>
+ @switches:
+ !sw: -q | --quiet
+ Suppresses any warning message
+ @description:
+ Removes the definition of the class <class_name>.[br]
+ All the instances of the class are killed (thus children objects are killed too).[br]
+ All the derived class definitions are removed as well.[br]
+ Builtin class definitions cannot be removed and this commands
+ kills only all the instances of that class (derived class definitions
+ and instances in this case are NOT killed).[br]
+ @seealso:
+ [cmd]class[/cmd], [cmd]objects.clear[/cmd], [fnc]$classDefined[/fnc](),
+ [doc:objects]Objects documentation[/doc]
+ */
+
+
+ QString szClass;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("class",KVS_PT_NONEMPTYSTRING,0,szClass)
+ KVSM_PARAMETERS_END(c)
+ KviKvsObjectClass * pClass=KviKvsKernel::instance()->objectController()->lookupClass(szClass);
+ if(pClass)
+ {
+ if(pClass->isBuiltin())
+ {
+ KviKvsKernel::instance()->objectController()->killAllObjectsWithClass(pClass);
+ } else {
+ KviKvsKernel::instance()->objectController()->deleteClass(pClass); //Yahoo!!
+ }
+ }
+ else if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("Class '%Q' is not definited"),&szClass);
+ return true;
+}
+
+
+static bool objects_kvs_cmd_clearObjects(KviKvsModuleCommandCall * c)
+{
+ /*
+ @doc: objects.clear
+ @title:
+ objects.clear
+ @type:
+ command
+ @short:
+ Removes all the user class definitions
+ @syntax:
+ objects.clear [-i]
+ @description:
+ Removes the definition of all the user classes and kill all the object
+ instances (also instances of the builtin classes).[br]
+ If the -i switch is used, only the object instances are cleared
+ but the class definitions are left unchanged.[br]
+ This command should be used only for debugging & testing purposes
+ and in particular should be NEVER used from inside an object
+ function handler (leads to SIGSEGV :).[br]
+ @seealso:
+ [cmd]class[/cmd], [cmd]objects.killclass[/cmd],
+ [doc:objects]Objects documentation[/doc]
+ */
+
+ KviKvsKernel::instance()->objectController()->clearInstances();
+ if(!c->switches()->find('i',"ii")) KviKvsKernel::instance()->objectController()->clearUserClasses();
+ return true;
+}
+
+
+static bool objects_kvs_cmd_connect(KviKvsModuleCommandCall * c)
+{
+
+ /*
+ @doc: objects.connect
+ @title:
+ objects.connect
+ @type:
+ command
+ @short:
+ Connects a signal to a slot
+ @syntax:
+ objects.connect <source_object:hobject> <signal_name:string> <target_object:hobject> <slot_name:string>
+ @description:
+ Connects the <source_object>'s signal <signal_name> to the
+ <target_object>'s slot <slot_name>.
+ When one of the two objects is destroyed, the signal/slot
+ connection is automatically removed.[br]
+ WARNING: This command name collides with the [doc:rfc2812]RFC2812[/doc]
+ CONNECT IRC Op command: this IRC command is available to operators only
+ and is rather rarely used: you can use it by the means of [doc:raw]raw[/doc].
+ @seealso:
+ [cmd]class[/cmd], [cmd]object.disconnect[/cmd], [doc:objects]objects documentation[/doc]
+ */
+
+
+ KviKvsObject *obSrc;
+ KviKvsObject *obTrg;
+ QString szSignal,szSlot;
+ kvs_hobject_t hSrc,hTrg;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("object source",KVS_PT_HOBJECT,0,hSrc)
+ KVSM_PARAMETER("signal name",KVS_PT_NONEMPTYSTRING,0,szSignal)
+ KVSO_PARAMETER("object target",KVS_PT_HOBJECT,0,hTrg)
+ KVSM_PARAMETER("slot",KVS_PT_NONEMPTYSTRING,0,szSlot)
+ KVSM_PARAMETERS_END(c)
+ obTrg=KviKvsKernel::instance()->objectController()->lookupObject(hTrg);
+ obSrc=KviKvsKernel::instance()->objectController()->lookupObject(hSrc);
+ if(!obTrg)
+ {
+ c->warning(__tr2qs("Inexisting target object for objects.connect"));
+ return true;
+ }
+ if(!obSrc)
+ {
+ c->warning(__tr2qs("Inexisting source object for objects.connect"));
+ return true;
+ }
+ obSrc->connectSignal(szSignal,obTrg,szSlot);
+ return true;
+}
+
+
+static bool objects_kvs_fnc_exists(KviKvsModuleFunctionCall * c)
+{
+ /*
+ @doc: objects.exists
+ @title:
+ objects.exists
+ @type:
+ command
+ @short:
+ Check if an object exists.
+ @syntax:
+ <boolean> $object.exists(<obejct id:hobject>)
+ @description:
+ Check if an objects exists and return a boolean value.
+ @seealso:
+ [doc:objects]objects documentation[/doc]
+ */
+
+
+ kvs_hobject_t hObj;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("object",KVS_PT_HOBJECT,0,hObj)
+ KVSM_PARAMETERS_END(c)
+ KviKvsObject *ob=KviKvsKernel::instance()->objectController()->lookupObject(hObj);
+ c->returnValue()->setBoolean(ob ? true : false);
+ return true;
+}
+
+static bool objects_kvs_fnc_instances(KviKvsModuleFunctionCall * c)
+{
+ /*
+ @doc: objects.instances
+ @title:
+ objects.instances
+ @type:
+ command
+ @short:
+ List object instances
+ @syntax:
+ <array> $object.instances(<class name:string>[,<flags:string>])
+ @description:
+ Returns an array with the instance handles of
+ of objects of the specified class. <flags> is a
+ string containing modifiers for the function behaviour.[br]
+ If <flags> contains the letter "s" then
+ only unsubclassed instances of the specified
+ class are returned. This means that if B is
+ a subclass of A then when asked for instances
+ of A without the flag "s" this function will return
+ both instances of A and B, and with the flag "s"
+ this function will return only instances of A (and not B).
+ If the class name does not define a valid class
+ then an empty array is returned and a warning is
+ printed unless the "q" flag is used.
+ @examples:
+ [example]
+ foreach(%x,$objects.instances(object))
+ {
+ echo "OBJECT WITH CLASS" %x->$className() "AND NAME \""%x->$name()"\""
+ }
+ [/example]
+ @seealso:
+ [doc:objects]objects documentation[/doc]
+ */
+
+ QString szClassName;
+ QString szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("class name",KVS_PT_NONEMPTYSTRING,0,szClassName)
+ KVSO_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray * pArry = new KviKvsArray();
+ c->returnValue()->setArray(pArry);
+
+ KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName);
+ if(!pClass)
+ {
+ if(!szFlags.contains(QChar('q')))
+ c->warning(__tr2qs("The class '%Q' does not exist"),&szClassName);
+ return true;
+ }
+ KviPointerHashTable<void *,KviKvsObject> * od = KviKvsKernel::instance()->objectController()->objectDict();
+
+ KviPointerHashTableIterator<void *,KviKvsObject> it(*od);
+ kvs_uint_t uIdx = 0;
+ if(szFlags.contains(QChar('s')))
+ {
+ while(KviKvsObject * ob = it.current())
+ {
+ if(ob->getExactClass() == pClass)
+ {
+ pArry->set(uIdx,new KviKvsVariant(ob->handle()));
+ uIdx++;
+ }
+ ++it;
+ }
+ } else {
+ while(KviKvsObject * ob = it.current())
+ {
+ if(ob->inheritsClass(pClass))
+ {
+ pArry->set(uIdx,new KviKvsVariant(ob->handle()));
+ uIdx++;
+ }
+ ++it;
+ }
+ }
+ return true;
+}
+/*
+ @doc: objects.variables
+ @title:
+ objects.variables
+ @type:
+ command
+ @short:
+ List object's variables.
+ @syntax:
+ <hash> objects.variables(<hobject>)
+ @description:
+ Returns an hash with the object's variables(useful only for debugging).
+ @seealso:
+ [doc:objects]objects documentation[/doc]
+ */
+static bool objects_kvs_fnc_variables(KviKvsModuleFunctionCall * c)
+{
+ kvs_hobject_t hObj;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("object",KVS_PT_HOBJECT,0,hObj)
+ KVSM_PARAMETERS_END(c)
+ KviKvsObject *ob=KviKvsKernel::instance()->objectController()->lookupObject(hObj);
+ if (!ob)
+ {
+ c->warning(__tr2qs("Object does not exists"));
+ return true;
+ }
+ KviPointerHashTableIterator<QString,KviKvsVariant> it(* ob->dataContainer()->dict());
+ KviKvsHash* pHash = new KviKvsHash();
+ c->returnValue()->setHash(pHash);
+ while(KviKvsVariant * t = it.current())
+ {
+ pHash->set(it.currentKey(),new KviKvsVariant(*t));
+ ++it;
+ }
+ return true;
+
+
+
+}
+/*
+ @doc: objects.classAllHandlers
+ @title:
+ objects.classAllHandlers
+ @type:
+ function
+ @short:
+ List all the functions .
+ @syntax:
+ <hash> objects.classAllHandlers(<class name:string>)
+ @description:
+ Returns an hash with the class's functions(useful only for debugging).
+ @seealso:
+ [doc:objects]objects documentation[/doc]
+ */
+static bool objects_kvs_fnc_classAllHandlers(KviKvsModuleFunctionCall * c)
+{
+ QString szClassName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("class name",KVS_PT_NONEMPTYSTRING,0,szClassName)
+ KVSM_PARAMETERS_END(c)
+ KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName);
+ if(!pClass)
+ {
+ c->warning(__tr2qs("The class '%Q' does not exist"),&szClassName);
+ return true;
+ }
+
+ KviPointerHashTableIterator<QString,KviKvsObjectFunctionHandler> it(* pClass->getHandlers());
+ KviKvsHash* pHash = new KviKvsHash();
+ c->returnValue()->setHash(pHash);
+ while(KviKvsObjectFunctionHandler * t = it.current())
+ {
+ QString szCode;
+ KviKvsObjectFunctionHandler *handler=pClass->lookupFunctionHandler(it.currentKey());
+ pClass->getFunctionCode(szCode,*handler);
+ pHash->set(it.currentKey(),new KviKvsVariant(szCode));
+ ++it;
+ }
+
+ return true;
+}
+static bool objects_kvs_fnc_classes(KviKvsModuleFunctionCall * c)
+{
+
+ /*
+ @doc: objects.classes
+ @title:
+ objects.classes
+ @type:
+ command
+ @short:
+ List user defined classes
+ @syntax:
+ <array> $object.classes()
+ @description:
+ Returns an array with the user defined classes.
+ @seealso:
+ [doc:objects]objects documentation[/doc]
+ */
+
+ KviKvsArray * pArry = new KviKvsArray();
+ c->returnValue()->setArray(pArry);
+ int uIdx=0;
+ KviPointerHashTableIterator<QString,KviKvsObjectClass> it(*KviKvsKernel::instance()->objectController()->classDict());
+ KviPointerHashTable<QString,bool> *classdict=new KviPointerHashTable<QString,bool>;
+ classdict->setAutoDelete(false);
+ bool bFake=true;
+ while(KviKvsObjectClass * pClass=it.current())
+ {
+ if (!pClass->isBuiltin())classdict->insert(it.currentKey(),&bFake);
+ ++it;
+ }
+ QString szPath;
+ g_pApp->getLocalKvircDirectory(szPath,KviApp::Classes);
+ QDir d(szPath);
+ QStringList sl;
+ sl = d.entryList(QDir::Files);
+ for(QStringList::Iterator it2 = sl.begin();it2 != sl.end();++it2)
+ {
+ QString szName=*it2;
+ szName.replace("--","::");
+ if (szName!=".." && szName!=".") classdict->insert(szName.left(szName.length()-4),&bFake);
+ }
+ KviKvsArray* pArray = new KviKvsArray();
+ c->returnValue()->setArray(pArray);
+ int idx=0;
+ KviPointerHashTableIterator<QString,bool> strIt(*classdict);
+ while(strIt.current())
+ {
+ pArray->set(idx,new KviKvsVariant(strIt.currentKey()));
+ idx++;
+ ++strIt;
+ }
+ delete classdict;
+ return true;
+
+}
+
+static bool objects_kvs_cmd_disconnect(KviKvsModuleCommandCall * c)
+{
+ /*
+ @doc: objects.disconnect
+ @title:
+ objects.disconnect
+ @type:
+ command
+ @short:
+ Disconnects a signal from a slot
+ @syntax:
+ disconnect <source_object:hobject> <signal_name:string> <target_object:hobject> <slot_name:string>
+ @description:
+ Disconnects the <source_object>'s signal <signal_name> from the
+ <target_object>'s slot <slot_name>.
+ When one of the two objects is destroyed, the signal/slot
+ connection is automatically removed.
+ @seealso:
+ [cmd]class[/cmd], [cmd]objects.connect[/cmd], [doc:objects]objects documentation[/doc]
+ */
+
+
+
+
+ KviKvsObject *obSrc;
+ KviKvsObject *obTrg;
+ QString szSignal,szSlot;
+ kvs_hobject_t hSrc,hTrg;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("object source",KVS_PT_HOBJECT,0,hSrc)
+ KVSM_PARAMETER("signal name",KVS_PT_NONEMPTYSTRING,0,szSignal)
+ KVSO_PARAMETER("object target",KVS_PT_HOBJECT,0,hTrg)
+ KVSM_PARAMETER("slot",KVS_PT_NONEMPTYSTRING,0,szSlot)
+ KVSM_PARAMETERS_END(c)
+ obTrg=KviKvsKernel::instance()->objectController()->lookupObject(hTrg);
+ obSrc=KviKvsKernel::instance()->objectController()->lookupObject(hSrc);
+ if(!obTrg)
+ {
+ c->warning(__tr2qs("Inexisting target object for objects.disconnect"));
+ return true;
+ }
+ if(!obSrc)
+ {
+ c->warning(__tr2qs("Inexisting source object for objects.disconnect"));
+ return true;
+ }
+ obSrc->disconnectSignal(szSignal,obTrg,szSlot);
+ return true;
+}
+
+
+
+static bool objects_kvs_cmd_bitBlt(KviKvsModuleCommandCall * c)
+{
+ /*
+ @doc: objects.bitblt
+ @type:
+ command
+ @title:
+ objects.bitblt
+ @keyterms:
+ widget pixmap painter
+ @short:
+ Copies a block of pixels from a source to a destination.
+ @syntax:
+ objects.bitblt <source> <x> <y> <destination>
+ @description:
+ Copies a block of pixels from <source> to <destination> at the coordinates <x>,<y> .[br]
+ Source and destination must be a widget or pixmap.[br]
+
+ */
+
+ KviKvsObject *obSrc;
+ KviKvsObject *obDst;
+ kvs_int_t iXdst,iYdst,iXsrc,iYsrc,uW,uH;
+ kvs_hobject_t hDst,hSrc;
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("destination",KVS_PT_HOBJECT,0,hDst)
+ KVSO_PARAMETER("x offset dest",KVS_PT_INT,0,iXdst)
+ KVSO_PARAMETER("y offset dest",KVS_PT_INT,0,iYdst)
+ KVSO_PARAMETER("source",KVS_PT_HOBJECT,0,hSrc)
+ KVSO_PARAMETER("x offset source",KVS_PT_INT,0,iXsrc)
+ KVSO_PARAMETER("y offset source",KVS_PT_INT,0,iYsrc)
+ KVSO_PARAMETER("width",KVS_PT_UNSIGNEDINTEGER,0,uW)
+ KVSO_PARAMETER("height",KVS_PT_UNSIGNEDINTEGER,0,uH)
+ KVSO_PARAMETERS_END(c)
+ obSrc=KviKvsKernel::instance()->objectController()->lookupObject(hSrc);
+ if (!obSrc)
+ {
+ c->warning(__tr2qs("Source is not an object"));
+ return true;
+ }
+ obDst=KviKvsKernel::instance()->objectController()->lookupObject(hDst);
+ if (!obDst)
+ {
+ c->warning(__tr2qs("Destination is not an object"));
+ return true;
+ }
+
+ QImage * imgSource=0;
+ QPaintDevice * pdSource = 0;
+
+ if(obSrc->inherits("KviKvsObject_pixmap")) pdSource =((KviKvsObject_pixmap *)obSrc)->getPixmap();
+ else if (obSrc->inherits("KviKvsObject_widget")) pdSource=((KviKvsObject_widget *)obSrc)->widget();
+ if (!pdSource)
+ {
+ c->warning(__tr2qs("Widget, Image or Pixmap required "));
+ return true;
+ }
+ QPaintDevice * pdDest = 0;
+ if(obDst->inherits("KviKvsObject_pixmap")){
+ pdDest= ((KviKvsObject_pixmap *)obDst)->getPixmap();
+ }
+ else if (obDst->inherits("KviKvsObject_widget")) pdDest=((KviKvsObject_widget *)obDst)->widget();
+ if (!pdDest)
+ {
+ c->warning(__tr2qs("Widget or Pixmap required"));
+ return true;
+ }
+ if(obDst->inherits("KviKvsObject_pixmap")){
+ ((KviKvsObject_pixmap *)obDst)->pixmapChanged();
+ }
+#ifdef COMPILE_USE_QT4
+ /*QPainter p(pdDest);
+ QRect rectdest(iXdst,iYdst,uW,uH);
+ QRect rectsrc(iXsrc,iYsrc,uW,uH);
+
+ p.drawPixmap(rectdest,pdSource,rectsrc);
+*/
+ #else
+ bitBlt(pdDest,iXdst,iYdst,pdSource,iXsrc,iYsrc,uW,uH);
+#endif
+ return true;
+}
+ /*
+ @doc: objects.blend
+ @type:
+ command
+ @title:
+ objects.blend
+ @keyterms:
+ widget pixmap image
+ @short:
+ Blends two images to a destination.
+ @syntax:
+ objects.blend <background: image hobject> <x_offset_bkg:unsigned integer> <y_offset_bkg:unsigned integer>
+ <foreground: image hobject> <x_offset_fgr:unsigned integer> <y_offset_fgr:unsigned integer>
+ <destination: image, pixmap. widget hobject> <x_offset_dest:unsigned integer> <y_offset_dest:unsigned integer> <width:unsigned integer> <height:unsigned integer> <blend_factor>
+ @description:
+ Blends two images <background> and <foreground> and copy the result to <destination> at the coordinates <x_offset>,<y_offset> with a <blend_factor> value .[br]
+ Destination must be a widget or pixmap.[br]
+
+ */
+
+static bool objects_kvs_cmd_blend(KviKvsModuleCommandCall * c)
+{
+
+ KviKvsObject *obFor;
+ KviKvsObject *obBck;
+ KviKvsObject *obDest;
+
+ kvs_int_t iBkX,iBkY;
+ kvs_int_t iFoX,iFoY;
+ kvs_int_t iDesX,iDesY,uW,uH;
+ kvs_real_t dBlend;
+
+ kvs_hobject_t hBk,hFo,hDest;
+
+ KVSO_PARAMETERS_BEGIN(c)
+ KVSO_PARAMETER("destination",KVS_PT_HOBJECT,0,hDest)
+ KVSO_PARAMETER("x_offset_dest",KVS_PT_INT,0,iDesX)
+ KVSO_PARAMETER("y_offset_dest",KVS_PT_INT,0,iDesY)
+
+ KVSO_PARAMETER("image_background",KVS_PT_HOBJECT,0,hBk)
+ KVSO_PARAMETER("x_offset_background",KVS_PT_UNSIGNEDINTEGER,0,iBkX)
+ KVSO_PARAMETER("y_offset_background",KVS_PT_UNSIGNEDINTEGER,0,iBkY)
+ KVSO_PARAMETER("image_foreground",KVS_PT_HOBJECT,0,hFo)
+ KVSO_PARAMETER("x_offset_foreground",KVS_PT_UNSIGNEDINTEGER,0,iFoX)
+ KVSO_PARAMETER("y_offset_foreground",KVS_PT_UNSIGNEDINTEGER,0,iFoY)
+ KVSO_PARAMETER("width",KVS_PT_UNSIGNEDINTEGER,0,uW)
+ KVSO_PARAMETER("height",KVS_PT_UNSIGNEDINTEGER,0,uH)
+
+ KVSO_PARAMETER("blend_value",KVS_PT_REAL,0,dBlend)
+
+
+
+ KVSO_PARAMETERS_END(c)
+
+ obFor=KviKvsKernel::instance()->objectController()->lookupObject(hFo);
+
+
+ obBck=KviKvsKernel::instance()->objectController()->lookupObject(hBk);
+ obDest=KviKvsKernel::instance()->objectController()->lookupObject(hDest);
+ if (!obFor || !obBck || !obDest)
+ {
+ c->warning(__tr2qs("One o more of background, foreground or destination aren't objects"));
+ return true;
+ }
+
+ if (!obBck->inherits("KviKvsObject_pixmap") || !obFor->inherits("KviKvsObject_pixmap"))
+ {
+ c->warning(__tr2qs("Pixmap objects required"));
+ return true;
+ }
+
+ QPaintDevice * pdDest = 0;
+ if(obDest->inherits("KviKvsObject_pixmap")) pdDest = ((KviKvsObject_pixmap *)obDest)->getPixmap();
+ else if (obDest->inherits("KviKvsObject_widget")) pdDest=((KviKvsObject_widget *)obDest)->widget();
+
+ if (!pdDest)
+ {
+ c->warning(__tr2qs("Widget or Pixmap required "));
+ return true;
+ }
+
+ if(obDest->inherits("KviKvsObject_pixmap")) ((KviKvsObject_pixmap *)obDest)->pixmapChanged();
+
+
+ QImage *img_back=((KviKvsObject_pixmap *)obBck)->getImage();
+ QImage *img_fore=((KviKvsObject_pixmap *)obFor)->getImage();
+
+ // check size
+ if ((iBkX+uW>img_back->width())||(iBkY+uH>img_back->height()))
+ {
+ c->warning(__tr2qs("Values for background are out of image size "));
+ return true;
+ }
+ if ((iFoX+uW>img_fore->width())||(iFoY+uH>img_fore->height()))
+ {
+ c->warning(__tr2qs("Values for foreground are out of image size "));
+ return true;
+ }
+ QImage buffer;
+ buffer.create(uW,uH,32);
+ buffer.setAlphaBuffer(true);
+ for(int y = 0;y < buffer.height();y++)
+ {
+ QRgb * dst = (QRgb *)buffer.scanLine(y);
+ QRgb * end = dst + buffer.width();
+ QRgb * bkg = (QRgb *)img_back->scanLine(y+iBkY);
+ bkg += iBkX;
+ QRgb * fgn = (QRgb *)img_fore->scanLine(y+iFoY);
+ fgn += iFoX;
+ double dRemaining = 1.0 - dBlend;
+ int a=0;
+ while(dst < end)
+ {
+
+
+ *dst = qRgba(
+ (int)((qRed(*bkg) * dRemaining) + (qRed(*fgn) * dBlend)),
+ (int)((qGreen(*bkg) * dRemaining) + (qGreen(*fgn) * dBlend)),
+ (int)((qBlue(*bkg) * dRemaining) + (qBlue(*fgn) * dBlend)),
+ (int)((qAlpha(*bkg) * dRemaining) + (qAlpha(*fgn) * dBlend))
+ );
+
+ dst++;
+ bkg++;
+ fgn++;
+ }
+
+
+ }
+#ifdef COMPILE_USE_QT4
+ QPainter p(pdDest);
+ QRect rect(iDesX,iDesY,buffer.width(),buffer.height());
+ p.drawImage(rect,buffer);
+#else
+ bitBlt(pdDest,iDesX,iDesY,&buffer,0,0,buffer.width(),buffer.height());
+#endif
+ return true;
+
+}
+
+// ASSASSINI! LA DOVETE INDENTARE PER BENE :D
+
+
+static bool objects_kvs_fnc_listObjects(KviKvsModuleFunctionCall * cmd)
+{
+/*
+ @doc: objects.dump
+ @type:
+ function
+ @title:
+ $objects.dump
+ @keyterms:
+ dump objects
+ @short:
+ Dump the kvirc widgets.
+ @syntax:
+ $objects.dump(<flag b>)
+ @description:
+ This function returns the tree of the widgets of the kvirc, if the flag <b> is planned to 1,[br]
+ will return it on the currente window, if it' is planned to 0 instead it will return it as a string.[br]
+ ES:
+ %A[]=$str.split("\|",$objects.dump(0))
+ %i=0
+ while (%i != %A[]#)
+ {
+ echo %A[%i]
+ %i++
+ }
+*/
+
+
+ bool bFlag;
+ KVSO_PARAMETERS_BEGIN(cmd)
+ KVSO_PARAMETER("flag on video",KVS_PT_BOOL,0,bFlag)
+ KVSO_PARAMETERS_END(cmd)
+ if (bFlag) cmd->window()->output(80, "Objects dump:");
+ #ifdef COMPILE_USE_QT4
+ QWidgetList list = g_pApp->topLevelWidgets();
+
+ KviStr spacing = ">";
+ QString szTemp;
+ KviKvsArray * n = new KviKvsArray();
+ int idx=0;
+ for(int i=0;i<list.count();i++)
+ {
+ if( list.at(i)->isWidgetType())
+ {
+ if (bFlag)
+ {
+ cmd->window()->output(80, "Ptr %u: top level object: %c%s%c, class %s, %s, rect = %d, %d, %d, %d",
+ list.at(i),
+ KVI_TEXT_BOLD, list.at(i)->name(), KVI_TEXT_BOLD,
+ list.at(i)->className(),
+ list.at(i)->isVisible() ? "visible" : "hidden",
+ list.at(i)->x(), list.at(i)->y(), list.at(i)->width(), list.at(i)->height());
+ }
+ QString szClass=list.at(i)->className();
+ QString szObj=list.at(i)->name();
+ QString szTemp;
+ szTemp = szClass + "::" + szObj;
+ KviKvsVariant v;
+ v.setString(szTemp);
+ n->set(idx,new KviKvsVariant(v));
+ debug ("string %s",szTemp.latin1());
+ debug ("class %s",szClass.latin1());
+ debug ("Obj %s",szObj.latin1());
+
+ idx++;
+
+ dumpChildObjects(cmd->window(), list.at(i), spacing.ptr(), bFlag,n,idx);
+ }
+ //++it;
+ }
+
+#else
+ QWidgetList *l = g_pApp->topLevelWidgets();
+ l->setAutoDelete(false);
+ QWidgetListIt it(*l);
+ KviStr spacing = ">";
+ QString szTemp;
+ KviKvsArray * n = new KviKvsArray();
+ int idx=0;
+ while( it.current() )
+ {
+ if( it.current()->isWidgetType())
+ {
+ if (bFlag)
+ {
+ cmd->window()->output(80, "Ptr %u: top level object: %c%s%c, class %s, %s, rect = %d, %d, %d, %d",
+ it.current(),
+ KVI_TEXT_BOLD, it.current()->name(), KVI_TEXT_BOLD,
+ it.current()->className(),
+ it.current()->isVisible() ? "visible" : "hidden",
+ it.current()->x(), it.current()->y(), it.current()->width(), it.current()->height());
+ }
+ QString szClass=it.current()->className();
+ QString szObj=it.current()->name();
+ QString szTemp;
+ szTemp = szClass + "::" + szObj;
+ KviKvsVariant v;
+ v.setString(szTemp);
+ n->set(idx,new KviKvsVariant(v));
+ debug ("string %s",szTemp.latin1());
+ debug ("class %s",szClass.latin1());
+ debug ("Obj %s",szObj.latin1());
+
+ idx++;
+
+ dumpChildObjects(cmd->window(), it.current(), spacing.ptr(), bFlag,n,idx);
+
+
+ }
+ ++it;
+ }
+
+#endif
+ cmd->returnValue()->setArray(n);
+ return true;
+}
+
+static void dumpChildObjects(KviWindow *pWnd, QObject *parent, const char *spacing, bool bFlag, KviKvsArray *n, int &idx)
+{
+#ifdef COMPILE_USE_QT4
+ const QObjectList list = parent->children();
+ if( !list.count() ) return;
+ QString sp(spacing);
+ sp.append(">");
+ for(int i=0;i<list.count();i++)
+ {
+ if( list.at(i)->isWidgetType() )
+ {
+ if (bFlag)
+ {
+ pWnd->output(80, "%sPtr %u: object: %c%s%c, class %s",
+ spacing, list.at(i), KVI_TEXT_BOLD,
+ list.at(i)->name(), KVI_TEXT_BOLD, list.at(i)->className()
+ );
+ }
+ QString szClass=list.at(i)->className();
+ QString szObj=list.at(i)->name();
+ QString szTemp;
+ szTemp=spacing+szClass+"::"+szObj;
+ KviKvsVariant v;
+ v.setString(szTemp);
+ n->set(idx,new KviKvsVariant(v));
+ debug ("string %s",szTemp.latin1());
+ idx++;
+ dumpChildObjects(pWnd, list.at(i), sp, bFlag, n, idx );
+ }
+ }
+
+#else
+ const QObjectList *l = parent->children();
+ if( !l ) return;
+ if( l->isEmpty() ) return;
+ QObjectListIt it(*l);
+ QString sp(spacing);
+ sp.append(">");
+ while( it.current() )
+ {
+ if( it.current()->isWidgetType() )
+ {
+ if (bFlag)
+ {
+ pWnd->output(80, "%sPtr %u: object: %c%s%c, class %s",
+ spacing, it.current(), KVI_TEXT_BOLD,
+ it.current()->name(), KVI_TEXT_BOLD, it.current()->className()
+ );
+ }
+ QString szClass=it.current()->className();
+ QString szObj=it.current()->name();
+ QString szTemp;
+ szTemp=spacing+szClass+"::"+szObj;
+ KviKvsVariant v;
+ v.setString(szTemp);
+ n->set(idx,new KviKvsVariant(v));
+ debug ("string %s",szTemp.latin1());
+ idx++;
+ dumpChildObjects(pWnd, it.current(), sp, bFlag, n, idx );
+ }
+ ++it;
+ }
+#endif
+}
+
+static bool objects_module_can_unload(KviModule *m)
+{
+ // Actually this object remains locked in memory
+ // FIXME: unlock when no more instances & derived classes!
+ return false;
+}
+static bool objects_module_init(KviModule * m)
+{
+ // functions
+ KVSM_REGISTER_FUNCTION(m,"exists",objects_kvs_fnc_exists);
+ KVSM_REGISTER_FUNCTION(m,"instances",objects_kvs_fnc_instances);
+ KVSM_REGISTER_FUNCTION(m,"classes",objects_kvs_fnc_classes);
+ KVSM_REGISTER_FUNCTION(m,"dump",objects_kvs_fnc_listObjects);
+ KVSM_REGISTER_FUNCTION(m,"variables",objects_kvs_fnc_variables);
+ KVSM_REGISTER_FUNCTION(m,"classAllHandlers",objects_kvs_fnc_classAllHandlers);
+
+ // commands
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"connect",objects_kvs_cmd_connect);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"disconnect",objects_kvs_cmd_disconnect);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"killClass",objects_kvs_cmd_killClass);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"bitblt",objects_kvs_cmd_bitBlt);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"blend",objects_kvs_cmd_blend);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"clearObjects",objects_kvs_cmd_clearObjects);
+
+ KviKvsObject_list::registerSelf();
+
+ KviKvsObject_widget::registerSelf();
+ KviKvsObject_button::registerSelf();
+ KviKvsObject_mledit::registerSelf();
+
+ KviKvsObject_textbrowser::registerSelf();
+ KviKvsObject_checkbox::registerSelf();
+ KviKvsObject_dialog::registerSelf();
+ KviKvsObject_groupbox::registerSelf();
+ KviKvsObject_buttongroup::registerSelf();
+ KviKvsObject_label::registerSelf();
+ KviKvsObject_vbox::registerSelf();
+ KviKvsObject_hbox::registerSelf();
+ KviKvsObject_layout::registerSelf();
+ KviKvsObject_lcd::registerSelf();
+ KviKvsObject_lineedit::registerSelf();
+ KviKvsObject_menubar::registerSelf();
+ KviKvsObject_workspace::registerSelf();
+
+
+
+ KviKvsObject_combobox::registerSelf();
+ KviKvsObject_listbox::registerSelf();
+ KviKvsObject_listview::registerSelf();
+ KviKvsObject_listviewitem::registerSelf();
+ KviKvsObject_mainwindow::registerSelf();
+ KviKvsObject_painter::registerSelf();
+ KviKvsObject_pixmap::registerSelf();
+ KviKvsObject_popupmenu::registerSelf();
+ KviKvsObject_radiobutton::registerSelf();
+ KviKvsObject_slider::registerSelf();
+ KviKvsObject_spinbox::registerSelf();
+ KviKvsObject_tabwidget::registerSelf();
+ KviKvsObject_toolbar::registerSelf();
+ KviKvsObject_toolbutton::registerSelf();
+ KviKvsObject_urlabel::registerSelf();
+ KviKvsObject_window::registerSelf();
+ KviKvsObject_wizard::registerSelf();
+ KviKvsObject_dockwindow::registerSelf();
+ KviKvsObject_progressbar::registerSelf();
+ KviKvsObject_file::registerSelf();
+ KviKvsObject_wrapper::registerSelf();
+ KviKvsObject_xmlreader::registerSelf();
+ KviKvsObject_socket::registerSelf();
+ KviKvsObject_process::registerSelf();
+
+
+ return true;
+}
+
+KVIRC_MODULE(
+ "Objects",
+ "2.0.0",
+ "Copyright (C) 2000-2006:\n" \
+ " Szymon Stefanek (pragma at kvirc dot net)\n" \
+ " Krzysztof Godlewski (kristoff at poczta dot wprost dot pl)\n" \
+ " Tonino Imbesi (grifisx at barmes dot org)\n" \
+ " Alessandro Carbone (noldor at barmes dot org)",
+ "Object classes for KVIrc scripting language\n",
+ objects_module_init,
+ objects_module_can_unload,
+ 0,
+ objects_module_cleanup
+)
diff --git a/src/modules/objects/object_macros.h b/src/modules/objects/object_macros.h
new file mode 100644
index 00000000..9c0360b2
--- /dev/null
+++ b/src/modules/objects/object_macros.h
@@ -0,0 +1,90 @@
+#ifndef _OBJECT_MACROS_H_
+#define _OBJECT_MACROS_H_
+//=========================================================================================
+//
+// File : object_macros.h
+// Creation date : Sat Jun 18 2005 15:32:01 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2005 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_kvs_object.h"
+#include "kvi_kvs_object_class.h"
+#include "kvi_kvs_kernel.h"
+#include "kvi_kvs_object_controller.h"
+#include "kvi_kvs_object_functioncall.h"
+
+#define KVSO_DECLARE_OBJECT(__className) \
+ __className(KviKvsObjectClass * pClass,KviKvsObject * pParent,const QString &szName); \
+ ~__className(); \
+ static void registerSelf(); \
+ static void unregisterSelf();
+
+
+#define KVSO_REGISTER_HANDLER(__className,__szName,__proc) \
+ g_pKvs##__className##Class->registerFunctionHandler(__szName,(KviKvsObjectFunctionHandlerProc)(KVI_PTR2MEMBER(__className::__proc)));
+
+#define KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(__className,__szName) \
+ g_pKvs##__className##Class->registerStandardNothingReturnFunctionHandler(__szName);
+
+#define KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(__className,__szName) \
+ g_pKvs##__className##Class->registerStandardTrueReturnFunctionHandler(__szName);
+
+#define KVSO_REGISTER_STANDARD_FALSERETURN_HANDLER(__className,__szName) \
+ g_pKvs##__className##Class->registerStandardFalseReturnFunctionHandler(__szName);
+
+#define KVSO_BEGIN_REGISTERCLASS(__className,__stringName,__baseClass) \
+ static KviKvsObjectClass * g_pKvs##__className##Class = 0; \
+ static KviKvsObject * kvs_##__className##_createInstance(KviKvsObjectClass * pClass,KviKvsObject * pParent,const QString &szName) \
+ { \
+ return new __className(pClass,pParent,szName); \
+ } \
+ void __className::unregisterSelf() \
+ { \
+ delete g_pKvs##__className##Class; \
+ g_pKvs##__className##Class = 0; \
+ } \
+ void __className::registerSelf() \
+ { \
+ KviKvsObjectClass * base = KviKvsKernel::instance()->objectController()->lookupClass(__baseClass); \
+ g_pKvs##__className##Class = new KviKvsObjectClass(base,__stringName,kvs_##__className##_createInstance,true);
+
+
+
+#define KVSO_END_REGISTERCLASS(__className) \
+ }
+
+
+#define KVSO_BEGIN_CONSTRUCTOR(__className,__baseClass) \
+ __className::__className(KviKvsObjectClass * pClass,KviKvsObject * pParent,const QString &szName) \
+ : __baseClass(pClass,pParent,szName) \
+ {
+
+#define KVSO_END_CONSTRUCTOR(__className) \
+ }
+
+#define KVSO_BEGIN_DESTRUCTOR(__className) \
+ __className::~__className() \
+ {
+
+#define KVSO_END_DESTRUCTOR(__className) \
+ }
+
+
+#endif
diff --git a/src/modules/options/Makefile.am b/src/modules/options/Makefile.am
new file mode 100644
index 00000000..53c0988c
--- /dev/null
+++ b/src/modules/options/Makefile.am
@@ -0,0 +1,157 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+EXTRA_DIST = mkcreateinstanceproc.sh
+
+pluglib_LTLIBRARIES = libkvioptions.la
+
+libkvioptions_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvioptions_la_SOURCES = libkvioptions.cpp \
+ container.cpp \
+ dialog.cpp \
+ instances.cpp \
+ optw_antispam.cpp \
+ optw_avatar.cpp \
+ optw_connection.cpp \
+ optw_ctcp.cpp \
+ optw_ctcpfloodprotection.cpp \
+ optw_dcc.cpp \
+ optw_generalopt.cpp \
+ optw_highlighting.cpp \
+ optw_ident.cpp \
+ optw_identity.cpp \
+ optw_ignore.cpp \
+ optw_input.cpp \
+ optw_interfacefeatures.cpp \
+ optw_interfacelookglobal.cpp \
+ optw_irc.cpp \
+ optw_ircoutput.cpp \
+ optw_ircview.cpp \
+ optw_lag.cpp \
+ optw_logging.cpp \
+ optw_mediatypes.cpp \
+ optw_messages.cpp \
+ optw_nickserv.cpp \
+ optw_notify.cpp \
+ optw_protection.cpp \
+ optw_proxy.cpp \
+ optw_query.cpp \
+ optw_servers.cpp \
+ optw_sound.cpp \
+ optw_ssl.cpp \
+ optw_taskbar.cpp \
+ optw_textencoding.cpp \
+ optw_texticons.cpp \
+ optw_theme.cpp \
+ optw_tools.cpp \
+ optw_transport.cpp \
+ optw_topiclabel.cpp \
+ optw_away.cpp \
+ optw_uparser.cpp \
+ optw_urlhandlers.cpp \
+ optw_userlist.cpp \
+ optw_tray.cpp
+
+libkvioptions_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= container.h \
+ dialog.h \
+ instances.h \
+ optw_antispam.h \
+ optw_avatar.h \
+ optw_connection.h \
+ optw_ctcp.h \
+ optw_ctcpfloodprotection.h \
+ optw_dcc.h \
+ optw_generalopt.h \
+ optw_highlighting.h \
+ optw_ident.h \
+ optw_identity.h \
+ optw_ignore.h \
+ optw_input.h \
+ optw_interfacefeatures.h \
+ optw_interfacelookglobal.h \
+ optw_irc.h \
+ optw_ircoutput.h \
+ optw_ircview.h \
+ optw_lag.h \
+ optw_logging.h \
+ optw_mediatypes.h \
+ optw_messages.h \
+ optw_nickserv.h \
+ optw_notify.h \
+ optw_protection.h \
+ optw_proxy.h \
+ optw_query.h \
+ optw_servers.h \
+ optw_sound.h \
+ optw_ssl.h \
+ optw_taskbar.h \
+ optw_textencoding.h \
+ optw_texticons.h \
+ optw_theme.h \
+ optw_tools.h \
+ optw_transport.h \
+ optw_topiclabel.h \
+ optw_away.h \
+ optw_uparser.h \
+ optw_urlhandlers.h \
+ optw_userlist.h \
+ optw_tray.h
+
+instances.h: optw_*.h mkcreateinstanceproc.sh
+ ./mkcreateinstanceproc.sh
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+container.cpp: m_container.moc
+dialog.cpp: m_dialog.moc
+instances.cpp: m_instances.moc
+optw_antispam.cpp: m_optw_antispam.moc
+optw_avatar.cpp: m_optw_avatar.moc
+optw_away.cpp: m_optw_away.moc
+optw_connection.cpp: m_optw_connection.moc
+optw_ctcp.cpp: m_optw_ctcp.moc
+optw_ctcpfloodprotection.cpp: m_optw_ctcpfloodprotection.moc
+optw_dcc.cpp: m_optw_dcc.moc
+optw_generalopt.cpp: m_optw_generalopt.moc
+optw_highlighting.cpp: m_optw_highlighting.moc
+optw_ident.cpp: m_optw_ident.moc
+optw_identity.cpp: m_optw_identity.moc
+optw_ignore.cpp: m_optw_ignore.moc
+optw_input.cpp: m_optw_input.moc
+optw_interfacefeatures.cpp: m_optw_interfacefeatures.moc
+optw_interfacelookglobal.cpp: m_optw_interfacelookglobal.moc
+optw_irc.cpp: m_optw_irc.moc
+optw_ircoutput.cpp: m_optw_ircoutput.moc
+optw_ircview.cpp: m_optw_ircview.moc
+optw_lag.cpp: m_optw_lag.moc
+optw_logging.cpp: m_optw_logging.moc
+optw_look.cpp: m_optw_look.moc
+optw_mediatypes.cpp: m_optw_mediatypes.moc
+optw_messages.cpp: m_optw_messages.moc
+optw_nickserv.cpp: m_optw_nickserv.moc
+optw_notify.cpp: m_optw_notify.moc
+optw_protection.cpp: m_optw_protection.moc
+optw_proxy.cpp: m_optw_proxy.moc
+optw_query.cpp: m_optw_query.moc
+optw_servers.cpp: m_optw_servers.moc
+optw_sound.cpp: m_optw_sound.moc
+optw_ssl.cpp: m_optw_ssl.moc
+optw_taskbar.cpp: m_optw_taskbar.moc
+optw_textencoding.cpp: m_optw_textencoding.moc
+optw_texticons.cpp: m_optw_texticons.moc
+optw_transport.cpp: m_optw_transport.moc
+optw_theme.cpp: m_optw_theme.moc
+optw_topiclabel.cpp: m_optw_topiclabel.moc
+optw_tools.cpp: m_optw_tools.moc
+optw_uparser.cpp: m_optw_uparser.moc
+optw_urlhandlers.cpp: m_optw_urlhandlers.moc
+optw_userlist.cpp: m_optw_userlist.moc
+optw_tray.cpp : m_optw_tray.moc
diff --git a/src/modules/options/container.cpp b/src/modules/options/container.cpp
new file mode 100644
index 00000000..7e2272c1
--- /dev/null
+++ b/src/modules/options/container.cpp
@@ -0,0 +1,123 @@
+//
+// File : container.cpp
+// Creation date : Wed Nov 21 17:09:49 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 "container.h"
+#include "instances.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_app.h"
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include "kvi_tal_tooltip.h"
+#include <qevent.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <qdesktopwidget.h>
+#endif
+
+extern KviOptionsInstanceManager * g_pOptionsInstanceManager;
+
+KviOptionsWidgetContainer::KviOptionsWidgetContainer(QWidget * par,bool bModal)
+: QDialog(par,"container","options")
+{
+ m_pOptionsWidget = 0;
+ setModal(bModal);
+}
+
+KviOptionsWidgetContainer::~KviOptionsWidgetContainer()
+{
+ if(m_pOptionsWidget)delete m_pOptionsWidget;
+}
+
+void KviOptionsWidgetContainer::setup(KviOptionsWidget * w)
+{
+ QGridLayout * g = new QGridLayout(this,2,3,4,8);
+
+ g->addMultiCellWidget(w,0,0,0,2);
+
+
+ QPushButton * b = new QPushButton(__tr2qs_ctx("&OK","options"),this);
+ KviTalToolTip::add(b,__tr2qs_ctx("Close this dialog, accepting all changes.","options"));
+ //b->setMinimumWidth(m_pCancel->sizeHint().width());
+ g->addWidget(b,1,1);
+ b->setDefault(true);
+ connect(b,SIGNAL(clicked()),this,SLOT(okClicked()));
+ b->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+
+ m_pCancel = new QPushButton(__tr2qs_ctx("Cancel","options"),this);
+ KviTalToolTip::add(m_pCancel,__tr2qs_ctx("Close this dialog, discarding all changes.","options"));
+ g->addWidget(m_pCancel,1,2);
+ connect(m_pCancel,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ m_pCancel->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+
+
+ g->setRowStretch(0,1);
+ g->setColStretch(0,1);
+
+ KviOptionsWidgetInstanceEntry * e = g_pOptionsInstanceManager->findInstanceEntry(w->className());
+ if(e)
+ {
+ //KviStr caption(KviStr::Format,"%s - KVIrc",e->szName);
+ setIcon(*(g_pIconManager->getSmallIcon(e->iIcon)));
+ setCaption(e->szName);
+ }
+ m_pOptionsWidget = w;
+
+}
+
+void KviOptionsWidgetContainer::closeEvent(QCloseEvent *e)
+{
+ e->ignore();
+ cancelClicked();
+}
+
+void KviOptionsWidgetContainer::showEvent(QShowEvent *e)
+{
+ if(parent() == 0)
+ {
+ move((g_pApp->desktop()->width() - width()) / 2,
+ (g_pApp->desktop()->height() - height()) / 2);
+ }
+ QWidget::showEvent(e);
+ m_pCancel->setFocus();
+}
+
+void KviOptionsWidgetContainer::reject()
+{
+ cancelClicked();
+}
+
+void KviOptionsWidgetContainer::okClicked()
+{
+ if(m_pOptionsWidget)m_pOptionsWidget->commit();
+ g_pApp->saveOptions();
+ delete this;
+}
+
+void KviOptionsWidgetContainer::cancelClicked()
+{
+ deleteLater();
+}
+
+#include "m_container.moc"
diff --git a/src/modules/options/container.h b/src/modules/options/container.h
new file mode 100644
index 00000000..10ae69de
--- /dev/null
+++ b/src/modules/options/container.h
@@ -0,0 +1,53 @@
+#ifndef _CONTAINER_H_
+#define _CONTAINER_H_
+//
+// File : container.h
+// Creation date : Wed Nov 21 17:09:50 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_optionswidget.h"
+#include <qdialog.h>
+
+class QPushButton;
+
+class KviOptionsWidgetContainer : public QDialog
+{
+ Q_OBJECT
+public:
+ KviOptionsWidgetContainer(QWidget * par,bool bModal = false);
+ ~KviOptionsWidgetContainer();
+protected:
+ KviOptionsWidget * m_pOptionsWidget;
+ QPushButton * m_pCancel;
+public:
+ void setup(KviOptionsWidget * w);
+protected:
+ virtual void closeEvent(QCloseEvent *e);
+ virtual void showEvent(QShowEvent *e);
+ virtual void reject();
+protected slots:
+ void okClicked();
+ void cancelClicked();
+};
+
+
+
+#endif //_CONTAINER_H_
diff --git a/src/modules/options/dialog.cpp b/src/modules/options/dialog.cpp
new file mode 100644
index 00000000..bebcae3e
--- /dev/null
+++ b/src/modules/options/dialog.cpp
@@ -0,0 +1,675 @@
+//=============================================================================
+//
+// File : dialog.cpp
+// Created on Fri 10 Feb 2006 18:52:18 by Szymon Stefanek
+// Based on dlg_options.cpp: Tue Jun 11 2000 02:39:12 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2000-2006 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 "dialog.h"
+
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_module.h"
+#include "kvi_styled_controls.h"
+#include "kvi_pointerhashtable.h"
+#include <qlayout.h>
+#include "kvi_accel.h"
+#include <qlabel.h>
+#include "kvi_tal_vbox.h"
+#include <qsplitter.h>
+#include "kvi_tal_widgetstack.h"
+#include <qpushbutton.h>
+#include "kvi_tal_tooltip.h"
+
+#ifdef COMPILE_USE_QT4
+ #include <q3header.h>
+#else
+ #include <qheader.h>
+ #include <qobjectlist.h>
+#endif
+#include "kvi_tal_popupmenu.h"
+#include <qtoolbutton.h>
+#include <qcheckbox.h>
+#include <kvi_tal_groupbox.h>
+#include <qpainter.h>
+#include <qfont.h>
+#include <qevent.h>
+
+//extern KviModule * g_pOptionsModule;
+extern KviPointerHashTable<QString,KviOptionsDialog> * g_pOptionsDialogDict;
+
+extern KVIRC_API KviApp * g_pApp;
+extern KviOptionsInstanceManager * g_pOptionsInstanceManager;
+
+KviGeneralOptionsFrontWidget::KviGeneralOptionsFrontWidget(QWidget *parent,const QString &szText)
+:KviOptionsWidget(parent,"general_options_front_widget")
+{
+ createLayout(1,1);
+ QLabel * l = new QLabel(szText,this);
+#ifdef COMPILE_USE_QT4
+ l->setWordWrap(true);
+#endif
+ l->setAlignment(Qt::AlignTop);
+ layout()->addWidget(l,0,0);
+}
+
+KviGeneralOptionsFrontWidget::~KviGeneralOptionsFrontWidget()
+{
+}
+
+
+
+
+KviOptionsListViewItem::KviOptionsListViewItem(KviTalListView *parent,KviOptionsWidgetInstanceEntry * e)
+:KviTalListViewItem(parent,e->szName)
+{
+ m_pInstanceEntry = e;
+ m_pOptionsWidget = 0;
+ m_bHighlighted = false;
+ setPixmap(0,*(g_pIconManager->getSmallIcon(e->iIcon)));
+}
+
+KviOptionsListViewItem::KviOptionsListViewItem(KviTalListViewItem *parent,KviOptionsWidgetInstanceEntry * e)
+:KviTalListViewItem(parent,e->szName)
+{
+ m_pInstanceEntry = e;
+ m_pOptionsWidget = 0;
+ m_bHighlighted = false;
+ setPixmap(0,*(g_pIconManager->getSmallIcon(e->iIcon)));
+}
+
+KviOptionsListViewItem::~KviOptionsListViewItem()
+{
+}
+
+void KviOptionsListViewItem::paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align)
+{
+ if(m_bHighlighted)
+ {
+ QColorGroup tmp(cg);
+ tmp.setColor(QColorGroup::Base,Qt::red);
+ tmp.setColor(QColorGroup::Background,Qt::red);
+ tmp.setColor(QColorGroup::Text,Qt::yellow);
+ KviTalListViewItem::paintCell(p,tmp,column,width,align);
+ } else {
+ KviTalListViewItem::paintCell(p,cg,column,width,align);
+ }
+}
+
+
+KviOptionsDialog::KviOptionsDialog(QWidget * par,const QString &szGroup)
+: QDialog(par,"general_options_dialog")
+{
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)));
+
+ m_szGroup = szGroup;
+
+ QString szDialogTitle;
+
+ if(szGroup.isEmpty() || KviQString::equalCI(szGroup,"general"))
+ {
+ szDialogTitle = __tr2qs_ctx("General Preferences","options");
+ } else if(KviQString::equalCI(szGroup,"theme"))
+ {
+ szDialogTitle = __tr2qs_ctx("Theme Preferences","options");
+ } else {
+ szDialogTitle = __tr2qs_ctx("KVIrc Preferences","options");
+ }
+
+ QString szDialog = __tr2qs_ctx("This dialog contains a set of KVIrc settings.<br> Use the icons " \
+ "on the left to navigate through the option pages. The text box in the " \
+ "bottom left corner is a small search engine. It will highlight the " \
+ "pages that contain options related to the search term you have entered.","options");
+
+
+ QString szInfoTips;
+#ifdef COMPILE_INFO_TIPS
+ szInfoTips = __tr2qs_ctx("Many settings have tooltips that can be shown by holding " \
+ "the cursor over their label for a few seconds.","options");
+#else
+ szInfoTips = "";
+#endif
+ QString szOkCancelButtons = __tr2qs_ctx("When you have finished, click \"<b>OK</b>\" to accept your changes " \
+ "or \"<b>Cancel</b>\" to discard them. Clicking \"<b>Apply</b>\" will commit your " \
+ "changes without closing the window.","options");
+
+
+ QString szFrontText = QString(
+ "<table width=\"100%\" height=\"100%\" valign=\"top\" align=\"center\" cellpadding=\"4\">" \
+ "<tr>" \
+ "<td bgcolor=\"#303030\" valign=\"top\">" \
+ "<center><h1><font color=\"#FFFFFF\">%1</font></h1></center>" \
+ "</td>" \
+ "</tr>" \
+ "<tr>" \
+ "<td valign=\"bottom\">" \
+ "<br>" \
+ "<br>" \
+ "<p>" \
+ "%2" \
+ "</p>" \
+ "<br>" \
+ "<p>" \
+ "%3" \
+ "</p>" \
+ "<br>" \
+ "<p>" \
+ "%4" \
+ "</p>" \
+ "</td>" \
+ "</tr>" \
+ "</table>"
+ ).arg(szDialogTitle).arg(szDialog).arg(szInfoTips).arg(szOkCancelButtons);
+
+ QString szCaption = szDialogTitle + " - KVIrc";
+ setCaption(szCaption);
+
+ QGridLayout * g1 = new QGridLayout(this,2,5,8,8);
+ QSplitter * spl = new QSplitter(Qt::Horizontal,this);
+
+ g1->addMultiCellWidget(spl,0,0,0,4);
+
+ KviTalVBox * vbox = new KviTalVBox(spl);
+ vbox->setSpacing(2);
+ vbox->setMargin(0);
+
+ // Controlling list view
+ m_pListView = new KviTalListView(vbox);
+ m_pListView->addColumn("");
+ m_pListView->header()->hide();
+ m_pListView->setRootIsDecorated(true);
+ m_pListView->setSorting(-1);
+ connect(m_pListView,SIGNAL(selectionChanged(KviTalListViewItem *)),this,SLOT(listViewItemSelectionChanged(KviTalListViewItem *)));
+
+ KviTalHBox * hbox = new KviTalHBox(vbox);
+ vbox->setSpacing(2);
+ vbox->setMargin(0);
+
+ m_pSearchLineEdit = new QLineEdit(hbox);
+ connect(m_pSearchLineEdit,SIGNAL(returnPressed()),this,SLOT(searchClicked()));
+ m_pSearchButton = new KviStyledToolButton(hbox);
+ m_pSearchButton->setUsesBigPixmap(false);
+ m_pSearchButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SEARCH)));
+ connect(m_pSearchButton,SIGNAL(clicked()),this,SLOT(searchClicked()));
+ connect(m_pSearchLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(searchLineEditTextChanged(const QString &)));
+
+#ifdef COMPILE_INFO_TIPS
+ QString szTip = __tr2qs_ctx("<p>This is the search tool for this options dialog.</p>" \
+ "<p>You can enter a search term either in your native " \
+ "language or in english and press the button on the right. " \
+ "The pages that contain some options related to the " \
+ "search term will be highlighted and you will be able " \
+ "to quickly find them.</p><p>Try \"nickname\" for example.</p>","options");
+ KviTalToolTip::add(m_pSearchLineEdit,szTip);
+ KviTalToolTip::add(m_pSearchButton,szTip);
+#endif
+
+ vbox = new KviTalVBox(spl);
+ vbox->setSpacing(2);
+ vbox->setMargin(0);
+
+ m_pCategoryLabel = new QLabel("<b>&nbsp;</b>",vbox,"labgeneraloptions");
+ //m_pCategoryLabel->setMargin(3);
+
+ QFrame * f = new QFrame(vbox);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+
+ // Widget stack
+ m_pWidgetStack = new KviTalWidgetStack(vbox);
+ vbox->setStretchFactor(m_pWidgetStack,1);
+
+ // First widget visible
+ m_pFrontWidget = new KviGeneralOptionsFrontWidget(m_pWidgetStack,szFrontText);
+ m_pWidgetStack->addWidget(m_pFrontWidget,0);
+ m_pWidgetStack->raiseWidget(m_pFrontWidget);
+
+// Ok,Cancel,Help
+
+ QPushButton * b = new QPushButton(__tr2qs_ctx("&OK","options"),this,"btnok");
+ KviTalToolTip::add(b,__tr2qs_ctx("Close this dialog, accepting all changes.","options"));
+ connect(b,SIGNAL(clicked()),this,SLOT(okClicked()));
+ //b->setMinimumWidth(whatIsThisWidth);
+ b->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g1->addWidget(b,1,2);
+
+ b = new QPushButton(__tr2qs_ctx("&Apply","options"),this,"btnapply");
+ KviTalToolTip::add(b,__tr2qs_ctx("Commit all changes immediately.","options"));
+ connect(b,SIGNAL(clicked()),this,SLOT(applyClicked()));
+ b->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g1->addWidget(b,1,3);
+
+ b = new QPushButton(__tr2qs_ctx("Cancel","options"),this,"btncancel");
+ KviTalToolTip::add(b,__tr2qs_ctx("Close this dialog, discarding all changes.","options"));
+ b->setDefault(true);
+ //b->setMinimumWidth(whatIsThisWidth);
+ connect(b,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ b->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ g1->addWidget(b,1,4);
+
+ g1->setRowStretch(0,1);
+ g1->setColStretch(1,1);
+
+
+ fillListView(0,g_pOptionsInstanceManager->instanceEntryTree(),szGroup);
+
+ if(!parent())
+ {
+
+ if(KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).y() < 5)
+ {
+ KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).setY(5);
+ }
+ //setGeometry(KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry));
+ resize(KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).width(),
+ KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).height());
+ move(KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).x(),
+ KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).y());
+ }
+
+ KviAccel *a = new KviAccel( this );
+ a->connectItem( a->insertItem(Qt::Key_Escape), this,SLOT(close()) );
+
+}
+
+KviOptionsDialog::~KviOptionsDialog()
+{
+ if(!parent())KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry) = QRect(pos().x(),pos().y(),
+ size().width(),size().height());
+ if(g_pOptionsDialogDict)
+ g_pOptionsDialogDict->remove(m_szGroup);
+}
+
+
+void KviOptionsDialog::searchLineEditTextChanged(const QString &)
+{
+ QString txt = m_pSearchLineEdit->text().stripWhiteSpace();
+ m_pSearchButton->setEnabled(txt.length() > 0);
+}
+
+bool KviOptionsDialog::recursiveSearch(KviOptionsListViewItem * pItem,const QStringList &lKeywords)
+{
+ //debug("recursive search:");
+ if(!pItem)return false;
+
+ if(!pItem->m_pOptionsWidget)
+ {
+ pItem->m_pOptionsWidget = g_pOptionsInstanceManager->getInstance(pItem->m_pInstanceEntry,m_pWidgetStack);
+ m_pWidgetStack->addWidget(pItem->m_pOptionsWidget,0);
+ }
+
+ bool bFoundSomethingHere = false;
+ KviPointerHashTable<void *,bool> lOptionWidgetsToMark;
+ lOptionWidgetsToMark.setAutoDelete(true);
+ QTabWidget * pTabWidgetToMark = 0;
+
+ QObject * o;
+#ifdef COMPILE_USE_QT4
+ QObjectList ol = pItem->m_pOptionsWidget->queryList();
+ if(ol.count() > 0)
+ {
+ for(QObjectList::Iterator it = ol.begin();it != ol.end();++it)
+ {
+ o = *it;
+#else
+ QObjectList * ol = pItem->m_pOptionsWidget->queryList();
+ if(ol)
+ {
+ QObjectListIt it(*ol);
+ while((o = it.current())/* && (!bFoundSomethingHere)*/)
+ {
+#endif
+ QString szText;
+ if(o->inherits("QLabel"))szText = ((QLabel *)o)->text();
+ else if(o->inherits("QCheckBox"))szText = ((QCheckBox *)o)->text();
+ else if(o->inherits("KviTalGroupBox"))szText = ((KviTalGroupBox *)o)->title();
+#ifdef COMPILE_INFO_TIPS
+ if(o->inherits("QWidget"))
+#ifdef COMPILE_USE_QT4
+ szText.append(((QWidget *)o)->toolTip());
+#else
+ szText.append(QToolTip::textFor((QWidget*)o));
+#endif
+#endif
+ if(!szText.isEmpty())
+ {
+ bool bOk = true;
+ for(int j=0;j<lKeywords.count();j++)
+ {
+#ifdef COMPILE_USE_QT4
+ if(szText.find(lKeywords.at(j),0,false) == -1)
+#else
+ if(szText.find(*(lKeywords.at(j)),0,false) == -1)
+#endif
+ {
+ bOk = false;
+ break;
+ }
+ }
+ if(bOk)
+ {
+ bFoundSomethingHere = true;
+ }
+
+ if(o->inherits("QWidget"))
+ {
+ QWidget* pWidget=(QWidget*)o;
+ QFont font = pWidget->font();
+ font.setBold(bOk);
+ font.setUnderline(bOk);
+ pWidget->setFont(font);
+
+ // if there is a QTabWidget in the parent chain, signal it in the tab text
+ QObject * pParent = pWidget->parent();
+ while(pParent)
+ {
+ if(pParent->inherits("QTabWidget"))
+ {
+ pTabWidgetToMark = (QTabWidget *)pParent;
+ break;
+ }
+ pParent = pParent->parent();
+ }
+
+ if(pTabWidgetToMark)
+ {
+ // lookup the KviOptionsWidget parent
+ pParent = pWidget->parent();
+ while(pParent)
+ {
+ if(pParent->inherits("KviOptionsWidget"))
+ {
+ bool * pExistingBool = lOptionWidgetsToMark.find(pParent);
+ if(pExistingBool)
+ {
+ if(bOk)
+ *pExistingBool = true;
+ } else {
+ lOptionWidgetsToMark.insert(pParent,new bool(bOk));
+ }
+ break;
+ }
+ pParent = pParent->parent();
+ }
+ }
+ }
+ }
+
+#ifndef COMPILE_USE_QT4
+ ++it;
+#endif
+ }
+#ifndef COMPILE_USE_QT4
+ delete ol;
+#endif
+ }
+
+ if(pTabWidgetToMark)
+ {
+ KviPointerHashTableIterator<void *,bool> it(lOptionWidgetsToMark);
+ while(bool * pBool = it.current())
+ {
+ KviOptionsWidget * pOptionsWidget = (KviOptionsWidget *)it.currentKey();
+ QString szTxt = pTabWidgetToMark->tabLabel(pOptionsWidget);
+ if(KviQString::equalCIN(szTxt,">>> ",4))
+ {
+ szTxt.replace(">>> ","");
+ szTxt.replace(" <<<","");
+ }
+ if(*pBool)
+ {
+ szTxt.insert(0,">>> ");
+ szTxt += QString(" <<<");
+ }
+ pTabWidgetToMark->setTabLabel(pOptionsWidget,szTxt);
+ ++it;
+ }
+ }
+
+ pItem->setHighlighted(bFoundSomethingHere);
+
+ KviOptionsListViewItem * pChild = (KviOptionsListViewItem *)pItem->firstChild();
+ bool bFoundSomethingInside = false;
+ while(pChild)
+ {
+ bool bRet = recursiveSearch(pChild,lKeywords);
+ if(bRet)bFoundSomethingInside = true;
+ pChild = (KviOptionsListViewItem *)(pChild->nextSibling());
+ }
+ pItem->setSelected(false);
+ m_pListView->setOpen(pItem,bFoundSomethingInside);
+ return (bFoundSomethingInside || bFoundSomethingHere);
+}
+
+void KviOptionsDialog::search(const QStringList &lKeywords)
+{
+ m_pListView->setUpdatesEnabled(false);
+
+ KviOptionsListViewItem * pChild = (KviOptionsListViewItem *)(m_pListView->firstChild());
+ bool bFoundSomethingInside = false;
+ while(pChild)
+ {
+ bFoundSomethingInside = recursiveSearch(pChild,lKeywords);
+ pChild = (KviOptionsListViewItem *)(pChild->nextSibling());
+ }
+ m_pListView->setUpdatesEnabled(true);
+ m_pListView->triggerUpdate();
+}
+
+void KviOptionsDialog::search(const QString &szKeywords)
+{
+ QStringList lKeywords = QStringList::split(" ",szKeywords,false);
+ search(lKeywords);
+}
+
+void KviOptionsDialog::searchClicked()
+{
+ QString szTxt = m_pSearchLineEdit->text().stripWhiteSpace();
+ if(!szTxt.isEmpty())
+ search(szTxt);
+}
+
+void KviOptionsDialog::fillListView(KviTalListViewItem * p,KviPointerList<KviOptionsWidgetInstanceEntry> * l,const QString &szGroup,bool bNotContainedOnly)
+{
+ if(!l)return;
+
+ KviOptionsListViewItem * it;
+ KviOptionsWidgetInstanceEntry * e;
+
+ KviPointerList<KviOptionsWidgetInstanceEntry> tmp;
+ tmp.setAutoDelete(false);
+
+
+ for(e = l->first();e;e = l->next())
+ {
+ // must be in the correct group
+ // if we want only containers then well.. must be one
+ e->bDoInsert = KviQString::equalCI(szGroup,e->szGroup) && ((!bNotContainedOnly) || e->bIsContainer || e->bIsNotContained);
+ KviOptionsWidgetInstanceEntry * ee = tmp.first();
+ int idx = 0;
+ while(ee)
+ {
+ if(ee->iPriority >= e->iPriority)break;
+ idx++;
+ ee = tmp.next();
+ }
+ tmp.insert(idx,e);
+ }
+
+ for(e = tmp.first();e;e = tmp.next())
+ {
+ if(e->bDoInsert)
+ {
+ if(p)it = new KviOptionsListViewItem(p,e);
+ else it = new KviOptionsListViewItem(m_pListView,e);
+ if(!it->m_pOptionsWidget)
+ {
+ it->m_pOptionsWidget = g_pOptionsInstanceManager->getInstance(it->m_pInstanceEntry,m_pWidgetStack);
+ m_pWidgetStack->addWidget(it->m_pOptionsWidget,0);
+ }
+ } else {
+ it = (KviOptionsListViewItem *)p;
+ }
+
+ if(e->pChildList)
+ {
+ if(e->bIsContainer)
+ {
+ // it's a container: add only eventual not contained children (containers or explicitly marked as not contained)
+ fillListView(it,e->pChildList,szGroup,true);
+ } else {
+ // it's not a container, add any children
+ fillListView(it,e->pChildList,szGroup,false);
+ }
+ }
+ }
+}
+
+void KviOptionsDialog::listViewItemSelectionChanged(KviTalListViewItem *it)
+{
+ if(it)
+ {
+ QString str = it->text(0);
+ KviTalListViewItem * par = it->parent();
+
+ while(par)
+ {
+ str.prepend(" :: ");
+ str.prepend(par->text(0));
+ par = par->parent();
+ }
+ str.prepend("<b>");
+ str += "</b>";
+
+ KviOptionsListViewItem *i = (KviOptionsListViewItem *)it;
+ if(!i->m_pOptionsWidget)
+ {
+ i->m_pOptionsWidget = g_pOptionsInstanceManager->getInstance(i->m_pInstanceEntry,m_pWidgetStack);
+ m_pWidgetStack->addWidget(i->m_pOptionsWidget,0);
+ }
+
+ m_pWidgetStack->raiseWidget(i->m_pOptionsWidget);
+ m_pCategoryLabel->setText(str);
+ }
+}
+
+KviOptionsListViewItem * KviOptionsDialog::findItemByPage(KviOptionsListViewItem *it,KviOptionsWidget * pPage)
+{
+ if(!it)return 0;
+ if(it->m_pOptionsWidget == pPage)return it;
+
+ KviOptionsListViewItem *i;
+ // run through the children
+ i = (KviOptionsListViewItem *)(it->firstChild());
+ if(i)
+ {
+ i = findItemByPage(i,pPage);
+ if(i)return i;
+ }
+
+ // not found in the children tree.. look in the next sibling
+ i = (KviOptionsListViewItem *)(it->nextSibling());
+ if(i)
+ {
+ i = findItemByPage(i,pPage);
+ if(i)return i;
+ }
+ return 0;
+}
+
+
+void KviOptionsDialog::pageWantsToSwitchToAdvancedPage(KviOptionsWidget * pPage)
+{
+ // unused
+}
+
+void KviOptionsDialog::applyClicked()
+{
+ apply(false);
+}
+
+void KviOptionsDialog::apply(bool bDialogAboutToClose)
+{
+
+ KviOptionsListViewItem *it = (KviOptionsListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ recursiveCommit(it);
+ it = (KviOptionsListViewItem *)it->nextSibling();
+ }
+
+ if(!bDialogAboutToClose)
+ {
+ // bring up the current widget again!
+ it = (KviOptionsListViewItem *)m_pListView->currentItem();
+ if(it)listViewItemSelectionChanged(it);
+ }
+
+ g_pApp->saveConfiguration();
+
+}
+
+void KviOptionsDialog::okClicked()
+{
+ apply(true);
+ delete this;
+}
+
+void KviOptionsDialog::cancelClicked()
+{
+ delete this;
+}
+
+void KviOptionsDialog::closeEvent(QCloseEvent *e)
+{
+ e->ignore();
+ delete this;
+}
+
+void KviOptionsDialog::recursiveCommit(KviOptionsListViewItem *it)
+{
+ // First commit the children
+ if(!it) return;
+ KviOptionsListViewItem *it2 = (KviOptionsListViewItem *)it->firstChild();
+ while(it2)
+ {
+ recursiveCommit(it2);
+ it2 = (KviOptionsListViewItem *)it2->nextSibling();
+ }
+ // then the parents
+ if(it->m_pOptionsWidget)
+ {
+ it->m_pOptionsWidget->commit();
+ delete it->m_pOptionsWidget;
+ it->m_pOptionsWidget = 0;
+ }
+ //refreshListView(); // <-- this tends to jump into infinite recursion
+}
+void KviOptionsDialog::keyPressEvent( QKeyEvent * e )
+{
+ if(e->key()==Qt::Key_Return)
+ e->accept();
+ else
+ e->ignore();
+}
+
+#include "m_dialog.moc"
diff --git a/src/modules/options/dialog.h b/src/modules/options/dialog.h
new file mode 100644
index 00000000..b342ca51
--- /dev/null
+++ b/src/modules/options/dialog.h
@@ -0,0 +1,104 @@
+#ifndef _DIALOG_H_
+#define _DIALOG_H_
+//=============================================================================
+//
+// File : dialog.h
+// Created on Fri 10 Feb 2006 18:52:18 by Szymon Stefanek
+// Based on dlg_options.h: Tue Jun 11 2000 02:39:12 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2000-2006 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 <qdialog.h>
+#include "kvi_tal_listview.h"
+#include <qstringlist.h>
+#include "kvi_optionswidget.h"
+
+#include "instances.h"
+
+class QLabel;
+class KviTalWidgetStack;
+class QPushButton;
+class QLineEdit;
+class QToolButton;
+
+class KviGeneralOptionsFrontWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviGeneralOptionsFrontWidget(QWidget *parent,const QString &szText);
+ ~KviGeneralOptionsFrontWidget();
+};
+
+class KviOptionsListViewItem : public KviTalListViewItem
+{
+public:
+ KviOptionsListViewItem(KviTalListView *parent,KviOptionsWidgetInstanceEntry * e);
+ KviOptionsListViewItem(KviTalListViewItem *parent,KviOptionsWidgetInstanceEntry * e);
+ ~KviOptionsListViewItem();
+public:
+ KviOptionsWidgetInstanceEntry * m_pInstanceEntry;
+ KviOptionsWidget * m_pOptionsWidget;
+ bool m_bHighlighted;
+public:
+ void setHighlighted(bool b){ m_bHighlighted = b; };
+protected:
+ virtual void paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align);
+};
+
+class KviOptionsDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviOptionsDialog(QWidget * par,const QString &szGroup);
+ ~KviOptionsDialog();
+private:
+ KviTalListView * m_pListView;
+ QLabel * m_pCategoryLabel;
+ KviTalWidgetStack * m_pWidgetStack;
+ KviGeneralOptionsFrontWidget* m_pFrontWidget;
+ QString m_szGroup;
+ QLineEdit * m_pSearchLineEdit;
+ QToolButton * m_pSearchButton;
+private:
+ void recursiveCommit(KviOptionsListViewItem *it);
+ void fillListView(KviTalListViewItem * p,KviPointerList<KviOptionsWidgetInstanceEntry> * l,const QString &szGroup,bool bNotContainedOnly = false);
+ //KviOptionsListViewItem * showHiddenChildren(KviTalListViewItem * p,KviPointerList<KviOptionsWidgetInstanceEntry> * l);
+ KviOptionsListViewItem * findItemByPage(KviOptionsListViewItem *it,KviOptionsWidget * pPage);
+private slots:
+ void listViewItemSelectionChanged(KviTalListViewItem *it);
+ void applyClicked();
+ void okClicked();
+ void cancelClicked();
+ void pageWantsToSwitchToAdvancedPage(KviOptionsWidget * pPage);
+ void searchClicked();
+ void searchLineEditTextChanged(const QString &);
+protected:
+ void apply(bool bDialogAboutToClose);
+ virtual void closeEvent(QCloseEvent *e);
+ virtual void keyPressEvent( QKeyEvent * e );
+ bool recursiveSearch(KviOptionsListViewItem * pItem,const QStringList &lKeywords);
+public:
+ void search(const QString &szKeywords);
+ void search(const QStringList &lKeywords);
+};
+
+
+#endif //!_DIALOG_H_
diff --git a/src/modules/options/instances.cpp b/src/modules/options/instances.cpp
new file mode 100644
index 00000000..aa23e7be
--- /dev/null
+++ b/src/modules/options/instances.cpp
@@ -0,0 +1,3590 @@
+
+
+//
+// File : instances.cpp
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001 Szymon Stefanek (stefanek@tin.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.
+//
+
+//
+// Instance creation routines for the KVIrc options module
+// DO NOT EDIT THIS FILE!! ALL CHANGES WILL BE LOST!!
+// This file is automatically generated by mkcreateinstanceproc.sh
+// so any change should go in that script
+//
+
+#include "optw_antispam.h"
+#include "optw_avatar.h"
+#include "optw_away.h"
+#include "optw_connection.h"
+#include "optw_ctcp.h"
+#include "optw_ctcpfloodprotection.h"
+#include "optw_dcc.h"
+#include "optw_generalopt.h"
+#include "optw_highlighting.h"
+#include "optw_ident.h"
+#include "optw_identity.h"
+#include "optw_ignore.h"
+#include "optw_input.h"
+#include "optw_interfacefeatures.h"
+#include "optw_interfacelookglobal.h"
+#include "optw_irc.h"
+#include "optw_ircoutput.h"
+#include "optw_ircview.h"
+#include "optw_lag.h"
+#include "optw_logging.h"
+#include "optw_mediatypes.h"
+#include "optw_messages.h"
+#include "optw_nickserv.h"
+#include "optw_notify.h"
+#include "optw_protection.h"
+#include "optw_proxy.h"
+#include "optw_query.h"
+#include "optw_servers.h"
+#include "optw_sound.h"
+#include "optw_ssl.h"
+#include "optw_taskbar.h"
+#include "optw_textencoding.h"
+#include "optw_texticons.h"
+#include "optw_theme.h"
+#include "optw_tools.h"
+#include "optw_topiclabel.h"
+#include "optw_transport.h"
+#include "optw_tray.h"
+#include "optw_uparser.h"
+#include "optw_urlhandlers.h"
+#include "optw_userlist.h"
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "instances.h"
+
+int g_iOptionWidgetInstances = 0;
+
+KviOptionsWidget * classKviAntispamOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviAntispamOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviAvatarAdvancedOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviAvatarAdvancedOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviAwayOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviAwayOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviConnectionOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviConnectionOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviConnectionAdvancedOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviConnectionAdvancedOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviSSLOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviSSLOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTransportOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTransportOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIdentOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIdentOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviCtcpOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviCtcpOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviCtcpFloodProtectionOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviCtcpFloodProtectionOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviDccOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviDccOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviDccGeneralOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviDccGeneralOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviDccAdvancedOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviDccAdvancedOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviDccSendOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviDccSendOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviDccSendGeneralOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviDccSendGeneralOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviDccSendAdvancedOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviDccSendAdvancedOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviDccChatOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviDccChatOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviDccVoiceOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviDccVoiceOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviGeneralOptOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviGeneralOptOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviAlertHighlightingOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviAlertHighlightingOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviHighlightingOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviHighlightingOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviAlertOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviAlertOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIdentityOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIdentityOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIdentityGeneralOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIdentityGeneralOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIdentityAvatarOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIdentityAvatarOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIdentityAdvancedOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIdentityAdvancedOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIgnoreOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIgnoreOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviInputLookOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviInputLookOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviInputFeaturesOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviInputFeaturesOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviInterfaceFeaturesOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviInterfaceFeaturesOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviThemeGeneralOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviThemeGeneralOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviThemeTransparencyOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviThemeTransparencyOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviThemeMdiCaptionsOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviThemeMdiCaptionsOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviThemeMdiAreaOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviThemeMdiAreaOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviThemeToolBarAppletsOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviThemeToolBarAppletsOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIrcOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIrcOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIrcGeneralOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIrcGeneralOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIrcAdvancedOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIrcAdvancedOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviChannelOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviChannelOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviChannelGeneralOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviChannelGeneralOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviChannelAdvancedOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviChannelAdvancedOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIrcOutputOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIrcOutputOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIrcViewThemeOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIrcViewThemeOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIrcViewLookOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIrcViewLookOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviIrcViewFeaturesOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviIrcViewFeaturesOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviLagOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviLagOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviLoggingOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviLoggingOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviMediaTypesOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviMediaTypesOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviMessageOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviMessageOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviPrivmsgOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviPrivmsgOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTimestampOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTimestampOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviMessageColorsOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviMessageColorsOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviStandardColorsOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviStandardColorsOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviNickServOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviNickServOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviNotifyOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviNotifyOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviNotifierOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviNotifierOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviProtectionOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviProtectionOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviProxyOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviProxyOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviQueryOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviQueryOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviServerOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviServerOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviSoundOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviSoundOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviSoundGeneralOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviSoundGeneralOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviSoundsOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviSoundsOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTaskBarOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTaskBarOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTreeTaskBarOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTreeTaskBarOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTreeTaskBarForegroundOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTreeTaskBarForegroundOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTreeTaskBarBackgroundOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTreeTaskBarBackgroundOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTreeTaskBarFeaturesOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTreeTaskBarFeaturesOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviClassicTaskBarOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviClassicTaskBarOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTextEncodingOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTextEncodingOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTextIconsOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTextIconsOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviToolsOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviToolsOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTopicLabelLookOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTopicLabelLookOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviTrayOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviTrayOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviUParserOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviUParserOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviUrlHandlersOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviUrlHandlersOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviUserListLookOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviUserListLookOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviUserListLookBackgroundOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviUserListLookBackgroundOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviUserListLookForegroundOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviUserListLookForegroundOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviUserListGridOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviUserListGridOptionsWidget(parent);
+}
+
+KviOptionsWidget * classKviUserListFeaturesOptionsWidget_createInstanceProc(QWidget * parent)
+{
+ return new KviUserListFeaturesOptionsWidget(parent);
+}
+
+
+
+static const char * g_szName_KviAntispamOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviAntispamOptionsWidget;
+static const char * g_szClassName_KviAntispamOptionsWidget = "KviAntispamOptionsWidget";
+static const char * g_szName_KviAvatarAdvancedOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviAvatarAdvancedOptionsWidget;
+static const char * g_szClassName_KviAvatarAdvancedOptionsWidget = "KviAvatarAdvancedOptionsWidget";
+static const char * g_szName_KviAwayOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviAwayOptionsWidget;
+static const char * g_szClassName_KviAwayOptionsWidget = "KviAwayOptionsWidget";
+static const char * g_szName_KviConnectionOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviConnectionOptionsWidget;
+static const char * g_szClassName_KviConnectionOptionsWidget = "KviConnectionOptionsWidget";
+static const char * g_szName_KviConnectionAdvancedOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviConnectionAdvancedOptionsWidget;
+static const char * g_szClassName_KviConnectionAdvancedOptionsWidget = "KviConnectionAdvancedOptionsWidget";
+static const char * g_szName_KviSSLOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviSSLOptionsWidget;
+static const char * g_szClassName_KviSSLOptionsWidget = "KviSSLOptionsWidget";
+static const char * g_szName_KviTransportOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTransportOptionsWidget;
+static const char * g_szClassName_KviTransportOptionsWidget = "KviTransportOptionsWidget";
+static const char * g_szName_KviIdentOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIdentOptionsWidget;
+static const char * g_szClassName_KviIdentOptionsWidget = "KviIdentOptionsWidget";
+static const char * g_szName_KviCtcpOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviCtcpOptionsWidget;
+static const char * g_szClassName_KviCtcpOptionsWidget = "KviCtcpOptionsWidget";
+static const char * g_szName_KviCtcpFloodProtectionOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviCtcpFloodProtectionOptionsWidget;
+static const char * g_szClassName_KviCtcpFloodProtectionOptionsWidget = "KviCtcpFloodProtectionOptionsWidget";
+static const char * g_szName_KviDccOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviDccOptionsWidget;
+static const char * g_szClassName_KviDccOptionsWidget = "KviDccOptionsWidget";
+static const char * g_szName_KviDccGeneralOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviDccGeneralOptionsWidget;
+static const char * g_szClassName_KviDccGeneralOptionsWidget = "KviDccGeneralOptionsWidget";
+static const char * g_szName_KviDccAdvancedOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviDccAdvancedOptionsWidget;
+static const char * g_szClassName_KviDccAdvancedOptionsWidget = "KviDccAdvancedOptionsWidget";
+static const char * g_szName_KviDccSendOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviDccSendOptionsWidget;
+static const char * g_szClassName_KviDccSendOptionsWidget = "KviDccSendOptionsWidget";
+static const char * g_szName_KviDccSendGeneralOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviDccSendGeneralOptionsWidget;
+static const char * g_szClassName_KviDccSendGeneralOptionsWidget = "KviDccSendGeneralOptionsWidget";
+static const char * g_szName_KviDccSendAdvancedOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviDccSendAdvancedOptionsWidget;
+static const char * g_szClassName_KviDccSendAdvancedOptionsWidget = "KviDccSendAdvancedOptionsWidget";
+static const char * g_szName_KviDccChatOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviDccChatOptionsWidget;
+static const char * g_szClassName_KviDccChatOptionsWidget = "KviDccChatOptionsWidget";
+static const char * g_szName_KviDccVoiceOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviDccVoiceOptionsWidget;
+static const char * g_szClassName_KviDccVoiceOptionsWidget = "KviDccVoiceOptionsWidget";
+static const char * g_szName_KviGeneralOptOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviGeneralOptOptionsWidget;
+static const char * g_szClassName_KviGeneralOptOptionsWidget = "KviGeneralOptOptionsWidget";
+static const char * g_szName_KviAlertHighlightingOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviAlertHighlightingOptionsWidget;
+static const char * g_szClassName_KviAlertHighlightingOptionsWidget = "KviAlertHighlightingOptionsWidget";
+static const char * g_szName_KviHighlightingOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviHighlightingOptionsWidget;
+static const char * g_szClassName_KviHighlightingOptionsWidget = "KviHighlightingOptionsWidget";
+static const char * g_szName_KviAlertOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviAlertOptionsWidget;
+static const char * g_szClassName_KviAlertOptionsWidget = "KviAlertOptionsWidget";
+static const char * g_szName_KviIdentityOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIdentityOptionsWidget;
+static const char * g_szClassName_KviIdentityOptionsWidget = "KviIdentityOptionsWidget";
+static const char * g_szName_KviIdentityGeneralOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIdentityGeneralOptionsWidget;
+static const char * g_szClassName_KviIdentityGeneralOptionsWidget = "KviIdentityGeneralOptionsWidget";
+static const char * g_szName_KviIdentityAvatarOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIdentityAvatarOptionsWidget;
+static const char * g_szClassName_KviIdentityAvatarOptionsWidget = "KviIdentityAvatarOptionsWidget";
+static const char * g_szName_KviIdentityAdvancedOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIdentityAdvancedOptionsWidget;
+static const char * g_szClassName_KviIdentityAdvancedOptionsWidget = "KviIdentityAdvancedOptionsWidget";
+static const char * g_szName_KviIgnoreOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIgnoreOptionsWidget;
+static const char * g_szClassName_KviIgnoreOptionsWidget = "KviIgnoreOptionsWidget";
+static const char * g_szName_KviInputLookOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviInputLookOptionsWidget;
+static const char * g_szClassName_KviInputLookOptionsWidget = "KviInputLookOptionsWidget";
+static const char * g_szName_KviInputFeaturesOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviInputFeaturesOptionsWidget;
+static const char * g_szClassName_KviInputFeaturesOptionsWidget = "KviInputFeaturesOptionsWidget";
+static const char * g_szName_KviInterfaceFeaturesOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviInterfaceFeaturesOptionsWidget;
+static const char * g_szClassName_KviInterfaceFeaturesOptionsWidget = "KviInterfaceFeaturesOptionsWidget";
+static const char * g_szName_KviThemeGeneralOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviThemeGeneralOptionsWidget;
+static const char * g_szClassName_KviThemeGeneralOptionsWidget = "KviThemeGeneralOptionsWidget";
+static const char * g_szName_KviThemeTransparencyOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviThemeTransparencyOptionsWidget;
+static const char * g_szClassName_KviThemeTransparencyOptionsWidget = "KviThemeTransparencyOptionsWidget";
+static const char * g_szName_KviThemeMdiCaptionsOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviThemeMdiCaptionsOptionsWidget;
+static const char * g_szClassName_KviThemeMdiCaptionsOptionsWidget = "KviThemeMdiCaptionsOptionsWidget";
+static const char * g_szName_KviThemeMdiAreaOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviThemeMdiAreaOptionsWidget;
+static const char * g_szClassName_KviThemeMdiAreaOptionsWidget = "KviThemeMdiAreaOptionsWidget";
+static const char * g_szName_KviThemeToolBarAppletsOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviThemeToolBarAppletsOptionsWidget;
+static const char * g_szClassName_KviThemeToolBarAppletsOptionsWidget = "KviThemeToolBarAppletsOptionsWidget";
+static const char * g_szName_KviIrcOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIrcOptionsWidget;
+static const char * g_szClassName_KviIrcOptionsWidget = "KviIrcOptionsWidget";
+static const char * g_szName_KviIrcGeneralOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIrcGeneralOptionsWidget;
+static const char * g_szClassName_KviIrcGeneralOptionsWidget = "KviIrcGeneralOptionsWidget";
+static const char * g_szName_KviIrcAdvancedOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIrcAdvancedOptionsWidget;
+static const char * g_szClassName_KviIrcAdvancedOptionsWidget = "KviIrcAdvancedOptionsWidget";
+static const char * g_szName_KviChannelOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviChannelOptionsWidget;
+static const char * g_szClassName_KviChannelOptionsWidget = "KviChannelOptionsWidget";
+static const char * g_szName_KviChannelGeneralOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviChannelGeneralOptionsWidget;
+static const char * g_szClassName_KviChannelGeneralOptionsWidget = "KviChannelGeneralOptionsWidget";
+static const char * g_szName_KviChannelAdvancedOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviChannelAdvancedOptionsWidget;
+static const char * g_szClassName_KviChannelAdvancedOptionsWidget = "KviChannelAdvancedOptionsWidget";
+static const char * g_szName_KviIrcOutputOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIrcOutputOptionsWidget;
+static const char * g_szClassName_KviIrcOutputOptionsWidget = "KviIrcOutputOptionsWidget";
+static const char * g_szName_KviIrcViewThemeOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIrcViewThemeOptionsWidget;
+static const char * g_szClassName_KviIrcViewThemeOptionsWidget = "KviIrcViewThemeOptionsWidget";
+static const char * g_szName_KviIrcViewLookOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIrcViewLookOptionsWidget;
+static const char * g_szClassName_KviIrcViewLookOptionsWidget = "KviIrcViewLookOptionsWidget";
+static const char * g_szName_KviIrcViewFeaturesOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviIrcViewFeaturesOptionsWidget;
+static const char * g_szClassName_KviIrcViewFeaturesOptionsWidget = "KviIrcViewFeaturesOptionsWidget";
+static const char * g_szName_KviLagOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviLagOptionsWidget;
+static const char * g_szClassName_KviLagOptionsWidget = "KviLagOptionsWidget";
+static const char * g_szName_KviLoggingOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviLoggingOptionsWidget;
+static const char * g_szClassName_KviLoggingOptionsWidget = "KviLoggingOptionsWidget";
+static const char * g_szName_KviMediaTypesOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviMediaTypesOptionsWidget;
+static const char * g_szClassName_KviMediaTypesOptionsWidget = "KviMediaTypesOptionsWidget";
+static const char * g_szName_KviMessageOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviMessageOptionsWidget;
+static const char * g_szClassName_KviMessageOptionsWidget = "KviMessageOptionsWidget";
+static const char * g_szName_KviPrivmsgOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviPrivmsgOptionsWidget;
+static const char * g_szClassName_KviPrivmsgOptionsWidget = "KviPrivmsgOptionsWidget";
+static const char * g_szName_KviTimestampOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTimestampOptionsWidget;
+static const char * g_szClassName_KviTimestampOptionsWidget = "KviTimestampOptionsWidget";
+static const char * g_szName_KviMessageColorsOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviMessageColorsOptionsWidget;
+static const char * g_szClassName_KviMessageColorsOptionsWidget = "KviMessageColorsOptionsWidget";
+static const char * g_szName_KviStandardColorsOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviStandardColorsOptionsWidget;
+static const char * g_szClassName_KviStandardColorsOptionsWidget = "KviStandardColorsOptionsWidget";
+static const char * g_szName_KviNickServOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviNickServOptionsWidget;
+static const char * g_szClassName_KviNickServOptionsWidget = "KviNickServOptionsWidget";
+static const char * g_szName_KviNotifyOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviNotifyOptionsWidget;
+static const char * g_szClassName_KviNotifyOptionsWidget = "KviNotifyOptionsWidget";
+static const char * g_szName_KviNotifierOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviNotifierOptionsWidget;
+static const char * g_szClassName_KviNotifierOptionsWidget = "KviNotifierOptionsWidget";
+static const char * g_szName_KviProtectionOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviProtectionOptionsWidget;
+static const char * g_szClassName_KviProtectionOptionsWidget = "KviProtectionOptionsWidget";
+static const char * g_szName_KviProxyOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviProxyOptionsWidget;
+static const char * g_szClassName_KviProxyOptionsWidget = "KviProxyOptionsWidget";
+static const char * g_szName_KviQueryOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviQueryOptionsWidget;
+static const char * g_szClassName_KviQueryOptionsWidget = "KviQueryOptionsWidget";
+static const char * g_szName_KviServerOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviServerOptionsWidget;
+static const char * g_szClassName_KviServerOptionsWidget = "KviServerOptionsWidget";
+static const char * g_szName_KviSoundOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviSoundOptionsWidget;
+static const char * g_szClassName_KviSoundOptionsWidget = "KviSoundOptionsWidget";
+static const char * g_szName_KviSoundGeneralOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviSoundGeneralOptionsWidget;
+static const char * g_szClassName_KviSoundGeneralOptionsWidget = "KviSoundGeneralOptionsWidget";
+static const char * g_szName_KviSoundsOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviSoundsOptionsWidget;
+static const char * g_szClassName_KviSoundsOptionsWidget = "KviSoundsOptionsWidget";
+static const char * g_szName_KviTaskBarOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTaskBarOptionsWidget;
+static const char * g_szClassName_KviTaskBarOptionsWidget = "KviTaskBarOptionsWidget";
+static const char * g_szName_KviTreeTaskBarOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTreeTaskBarOptionsWidget;
+static const char * g_szClassName_KviTreeTaskBarOptionsWidget = "KviTreeTaskBarOptionsWidget";
+static const char * g_szName_KviTreeTaskBarForegroundOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTreeTaskBarForegroundOptionsWidget;
+static const char * g_szClassName_KviTreeTaskBarForegroundOptionsWidget = "KviTreeTaskBarForegroundOptionsWidget";
+static const char * g_szName_KviTreeTaskBarBackgroundOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTreeTaskBarBackgroundOptionsWidget;
+static const char * g_szClassName_KviTreeTaskBarBackgroundOptionsWidget = "KviTreeTaskBarBackgroundOptionsWidget";
+static const char * g_szName_KviTreeTaskBarFeaturesOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTreeTaskBarFeaturesOptionsWidget;
+static const char * g_szClassName_KviTreeTaskBarFeaturesOptionsWidget = "KviTreeTaskBarFeaturesOptionsWidget";
+static const char * g_szName_KviClassicTaskBarOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviClassicTaskBarOptionsWidget;
+static const char * g_szClassName_KviClassicTaskBarOptionsWidget = "KviClassicTaskBarOptionsWidget";
+static const char * g_szName_KviTextEncodingOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTextEncodingOptionsWidget;
+static const char * g_szClassName_KviTextEncodingOptionsWidget = "KviTextEncodingOptionsWidget";
+static const char * g_szName_KviTextIconsOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTextIconsOptionsWidget;
+static const char * g_szClassName_KviTextIconsOptionsWidget = "KviTextIconsOptionsWidget";
+static const char * g_szName_KviToolsOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviToolsOptionsWidget;
+static const char * g_szClassName_KviToolsOptionsWidget = "KviToolsOptionsWidget";
+static const char * g_szName_KviTopicLabelLookOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTopicLabelLookOptionsWidget;
+static const char * g_szClassName_KviTopicLabelLookOptionsWidget = "KviTopicLabelLookOptionsWidget";
+static const char * g_szName_KviTrayOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTrayOptionsWidget;
+static const char * g_szClassName_KviTrayOptionsWidget = "KviTrayOptionsWidget";
+static const char * g_szName_KviUParserOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviUParserOptionsWidget;
+static const char * g_szClassName_KviUParserOptionsWidget = "KviUParserOptionsWidget";
+static const char * g_szName_KviUrlHandlersOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviUrlHandlersOptionsWidget;
+static const char * g_szClassName_KviUrlHandlersOptionsWidget = "KviUrlHandlersOptionsWidget";
+static const char * g_szName_KviUserListLookOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviUserListLookOptionsWidget;
+static const char * g_szClassName_KviUserListLookOptionsWidget = "KviUserListLookOptionsWidget";
+static const char * g_szName_KviUserListLookBackgroundOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviUserListLookBackgroundOptionsWidget;
+static const char * g_szClassName_KviUserListLookBackgroundOptionsWidget = "KviUserListLookBackgroundOptionsWidget";
+static const char * g_szName_KviUserListLookForegroundOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviUserListLookForegroundOptionsWidget;
+static const char * g_szClassName_KviUserListLookForegroundOptionsWidget = "KviUserListLookForegroundOptionsWidget";
+static const char * g_szName_KviUserListGridOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviUserListGridOptionsWidget;
+static const char * g_szClassName_KviUserListGridOptionsWidget = "KviUserListGridOptionsWidget";
+static const char * g_szName_KviUserListFeaturesOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviUserListFeaturesOptionsWidget;
+static const char * g_szClassName_KviUserListFeaturesOptionsWidget = "KviUserListFeaturesOptionsWidget";
+
+KviOptionsInstanceManager::KviOptionsInstanceManager()
+: QObject(0)
+{
+
+ //debug("Instantiating");
+ // Create the global widget dict : case sensitive , do not copy keys
+ m_pInstanceTree = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ m_pInstanceTree->setAutoDelete(true);
+
+
+ KviOptionsWidgetInstanceEntry * e0;
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviConnectionOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviConnectionOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviConnectionOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviConnectionOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviConnectionOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviConnectionOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviConnectionOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviConnectionOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviConnectionOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviConnectionOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviConnectionOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviConnectionOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviConnectionOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviConnectionOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviConnectionOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ KviOptionsWidgetInstanceEntry * e1;
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviConnectionAdvancedOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviConnectionAdvancedOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviConnectionAdvancedOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviConnectionAdvancedOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviConnectionAdvancedOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviConnectionAdvancedOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviConnectionAdvancedOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviConnectionAdvancedOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviConnectionAdvancedOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviConnectionAdvancedOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviConnectionAdvancedOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviConnectionAdvancedOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviConnectionAdvancedOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviConnectionAdvancedOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviConnectionAdvancedOptionsWidget,"options");
+ e0->pChildList->append(e1);
+
+ e1->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e1->pChildList->setAutoDelete(true);
+
+ KviOptionsWidgetInstanceEntry * e2;
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviSSLOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviSSLOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviSSLOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviSSLOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviSSLOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviSSLOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviSSLOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviSSLOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviSSLOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviSSLOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviSSLOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviSSLOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviSSLOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviSSLOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviSSLOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviTransportOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviTransportOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTransportOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTransportOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTransportOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTransportOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTransportOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTransportOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTransportOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTransportOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTransportOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTransportOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTransportOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviTransportOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTransportOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviIdentOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviIdentOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIdentOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIdentOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIdentOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIdentOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIdentOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIdentOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIdentOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviIdentOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIdentOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviProxyOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviProxyOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviProxyOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviProxyOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviProxyOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviProxyOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviProxyOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviProxyOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviProxyOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviProxyOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviProxyOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviProxyOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviProxyOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviProxyOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviProxyOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviDccOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviDccOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviDccOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviDccOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviDccOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviDccOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviDccOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviDccOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviDccOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviDccOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviDccOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviDccOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviDccOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviDccGeneralOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviDccGeneralOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviDccGeneralOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviDccGeneralOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviDccGeneralOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviDccGeneralOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviDccGeneralOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviDccGeneralOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviDccGeneralOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviDccGeneralOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviDccGeneralOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccGeneralOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccGeneralOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviDccGeneralOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviDccGeneralOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviDccAdvancedOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviDccAdvancedOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviDccAdvancedOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviDccAdvancedOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviDccAdvancedOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviDccAdvancedOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviDccAdvancedOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviDccAdvancedOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviDccAdvancedOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviDccAdvancedOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviDccAdvancedOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccAdvancedOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccAdvancedOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviDccAdvancedOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviDccAdvancedOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviDccSendOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviDccSendOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviDccSendOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviDccSendOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviDccSendOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviDccSendOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviDccSendOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviDccSendOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviDccSendOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviDccSendOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviDccSendOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccSendOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccSendOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviDccSendOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviDccSendOptionsWidget,"options");
+ e0->pChildList->append(e1);
+
+ e1->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e1->pChildList->setAutoDelete(true);
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviDccSendGeneralOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviDccSendGeneralOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviDccSendGeneralOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviDccSendGeneralOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviDccSendGeneralOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviDccSendGeneralOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviDccSendGeneralOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviDccSendGeneralOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviDccSendGeneralOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviDccSendGeneralOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviDccSendGeneralOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccSendGeneralOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccSendGeneralOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviDccSendGeneralOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviDccSendGeneralOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviDccSendAdvancedOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviDccSendAdvancedOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviDccSendAdvancedOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviDccSendAdvancedOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviDccSendAdvancedOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviDccSendAdvancedOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviDccSendAdvancedOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviDccSendAdvancedOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviDccSendAdvancedOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviDccSendAdvancedOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviDccSendAdvancedOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccSendAdvancedOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccSendAdvancedOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviDccSendAdvancedOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviDccSendAdvancedOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviDccChatOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviDccChatOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviDccChatOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviDccChatOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviDccChatOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviDccChatOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviDccChatOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviDccChatOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviDccChatOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviDccChatOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviDccChatOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccChatOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccChatOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviDccChatOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviDccChatOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviDccVoiceOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviDccVoiceOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviDccVoiceOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviDccVoiceOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviDccVoiceOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviDccVoiceOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviDccVoiceOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviDccVoiceOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviDccVoiceOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviDccVoiceOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviDccVoiceOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccVoiceOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccVoiceOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviDccVoiceOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviDccVoiceOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviGeneralOptOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviGeneralOptOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviGeneralOptOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviGeneralOptOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviGeneralOptOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviGeneralOptOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviGeneralOptOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviGeneralOptOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviGeneralOptOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviGeneralOptOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviGeneralOptOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviGeneralOptOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviGeneralOptOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviGeneralOptOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviGeneralOptOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviMediaTypesOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviMediaTypesOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviMediaTypesOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviMediaTypesOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviMediaTypesOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviMediaTypesOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviMediaTypesOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviMediaTypesOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviMediaTypesOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviMediaTypesOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviMediaTypesOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviMediaTypesOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviMediaTypesOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviMediaTypesOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviMediaTypesOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviSoundOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviSoundOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviSoundOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviSoundOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviSoundOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviSoundOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviSoundOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviSoundOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviSoundOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviSoundOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviSoundOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviSoundOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviSoundOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviSoundOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviSoundOptionsWidget,"options");
+ e0->pChildList->append(e1);
+
+ e1->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e1->pChildList->setAutoDelete(true);
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviSoundGeneralOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviSoundGeneralOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviSoundGeneralOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviSoundGeneralOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviSoundGeneralOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviSoundGeneralOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviSoundGeneralOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviSoundGeneralOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviSoundGeneralOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviSoundGeneralOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviSoundGeneralOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviSoundGeneralOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviSoundGeneralOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviSoundGeneralOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviSoundGeneralOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviSoundsOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviSoundsOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviSoundsOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviSoundsOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviSoundsOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviSoundsOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviSoundsOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviSoundsOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviSoundsOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviSoundsOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviSoundsOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviSoundsOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviSoundsOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviSoundsOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviSoundsOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviTextEncodingOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviTextEncodingOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTextEncodingOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTextEncodingOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTextEncodingOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTextEncodingOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTextEncodingOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTextEncodingOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTextEncodingOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTextEncodingOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTextEncodingOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTextEncodingOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTextEncodingOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviTextEncodingOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTextEncodingOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviUParserOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviUParserOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviUParserOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviUParserOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviUParserOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviUParserOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviUParserOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviUParserOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviUParserOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviUParserOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviUParserOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUParserOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUParserOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviUParserOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviUParserOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviUrlHandlersOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviUrlHandlersOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviUrlHandlersOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviUrlHandlersOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviUrlHandlersOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviUrlHandlersOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviUrlHandlersOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviUrlHandlersOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviUrlHandlersOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviUrlHandlersOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviUrlHandlersOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUrlHandlersOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUrlHandlersOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviUrlHandlersOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviUrlHandlersOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviIdentityOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviIdentityOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIdentityOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentityOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentityOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIdentityOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIdentityOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIdentityOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIdentityOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentityOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentityOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviIdentityOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIdentityOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviIdentityGeneralOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviIdentityGeneralOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIdentityGeneralOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityGeneralOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityGeneralOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentityGeneralOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentityGeneralOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIdentityGeneralOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIdentityGeneralOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIdentityGeneralOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIdentityGeneralOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentityGeneralOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentityGeneralOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviIdentityGeneralOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIdentityGeneralOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviIdentityAvatarOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviIdentityAvatarOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIdentityAvatarOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityAvatarOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityAvatarOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentityAvatarOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentityAvatarOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIdentityAvatarOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIdentityAvatarOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIdentityAvatarOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIdentityAvatarOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentityAvatarOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentityAvatarOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviIdentityAvatarOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIdentityAvatarOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviIdentityAdvancedOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviIdentityAdvancedOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIdentityAdvancedOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityAdvancedOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityAdvancedOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentityAdvancedOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIdentityAdvancedOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIdentityAdvancedOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIdentityAdvancedOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIdentityAdvancedOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIdentityAdvancedOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentityAdvancedOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIdentityAdvancedOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviIdentityAdvancedOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIdentityAdvancedOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviInputLookOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviInputLookOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviInputLookOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviInputLookOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviInputLookOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviInputLookOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviInputLookOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviInputLookOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviInputLookOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviInputLookOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviInputLookOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviInputLookOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviInputLookOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviInputLookOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviInputLookOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+ e0->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviInterfaceFeaturesOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviInterfaceFeaturesOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviInterfaceFeaturesOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviInterfaceFeaturesOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviInterfaceFeaturesOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviInterfaceFeaturesOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviInterfaceFeaturesOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviInterfaceFeaturesOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviInterfaceFeaturesOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviInterfaceFeaturesOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviInterfaceFeaturesOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviInterfaceFeaturesOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviInterfaceFeaturesOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviInterfaceFeaturesOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviInterfaceFeaturesOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviInputFeaturesOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviInputFeaturesOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviInputFeaturesOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviInputFeaturesOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviInputFeaturesOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviInputFeaturesOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviInputFeaturesOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviInputFeaturesOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviInputFeaturesOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviInputFeaturesOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviInputFeaturesOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviInputFeaturesOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviInputFeaturesOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviInputFeaturesOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviInputFeaturesOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviNotifierOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviNotifierOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviNotifierOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviNotifierOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviNotifierOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviNotifierOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviNotifierOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviNotifierOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviNotifierOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviNotifierOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviNotifierOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviNotifierOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviNotifierOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviNotifierOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviNotifierOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviTrayOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviTrayOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTrayOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTrayOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTrayOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTrayOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTrayOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTrayOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTrayOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTrayOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTrayOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTrayOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTrayOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviTrayOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTrayOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviThemeGeneralOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviThemeGeneralOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviThemeGeneralOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviThemeGeneralOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviThemeGeneralOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeGeneralOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeGeneralOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviThemeGeneralOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviThemeGeneralOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviThemeGeneralOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviThemeGeneralOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeGeneralOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeGeneralOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviThemeGeneralOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviThemeGeneralOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+ e0->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviThemeTransparencyOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviThemeTransparencyOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviThemeTransparencyOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviThemeTransparencyOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviThemeTransparencyOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeTransparencyOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeTransparencyOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviThemeTransparencyOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviThemeTransparencyOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviThemeTransparencyOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviThemeTransparencyOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeTransparencyOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeTransparencyOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviThemeTransparencyOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviThemeTransparencyOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+ e0->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviThemeMdiCaptionsOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviThemeMdiCaptionsOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviThemeMdiCaptionsOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviThemeMdiCaptionsOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviThemeMdiCaptionsOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeMdiCaptionsOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeMdiCaptionsOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviThemeMdiCaptionsOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviThemeMdiCaptionsOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviThemeMdiCaptionsOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviThemeMdiCaptionsOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeMdiCaptionsOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeMdiCaptionsOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviThemeMdiCaptionsOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviThemeMdiCaptionsOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+ e0->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviThemeMdiAreaOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviThemeMdiAreaOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviThemeMdiAreaOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviThemeMdiAreaOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviThemeMdiAreaOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeMdiAreaOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeMdiAreaOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviThemeMdiAreaOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviThemeMdiAreaOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviThemeMdiAreaOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviThemeMdiAreaOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeMdiAreaOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeMdiAreaOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviThemeMdiAreaOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviThemeMdiAreaOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+ e0->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviThemeToolBarAppletsOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviThemeToolBarAppletsOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviThemeToolBarAppletsOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviThemeToolBarAppletsOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviThemeToolBarAppletsOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeToolBarAppletsOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeToolBarAppletsOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviThemeToolBarAppletsOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviThemeToolBarAppletsOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviThemeToolBarAppletsOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviThemeToolBarAppletsOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeToolBarAppletsOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeToolBarAppletsOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviThemeToolBarAppletsOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviThemeToolBarAppletsOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+ e0->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviIrcOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviIrcOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIrcOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIrcOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIrcOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIrcOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIrcOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIrcOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIrcOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviIrcOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIrcOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviIrcGeneralOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviIrcGeneralOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIrcGeneralOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIrcGeneralOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIrcGeneralOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcGeneralOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcGeneralOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIrcGeneralOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIrcGeneralOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIrcGeneralOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIrcGeneralOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcGeneralOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcGeneralOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviIrcGeneralOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIrcGeneralOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviIrcAdvancedOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviIrcAdvancedOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIrcAdvancedOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIrcAdvancedOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIrcAdvancedOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcAdvancedOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcAdvancedOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIrcAdvancedOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIrcAdvancedOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIrcAdvancedOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIrcAdvancedOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcAdvancedOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcAdvancedOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviIrcAdvancedOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIrcAdvancedOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviChannelOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviChannelOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviChannelOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviChannelOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviChannelOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviChannelOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviChannelOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviChannelOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviChannelOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviChannelOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviChannelOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviChannelOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviChannelOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviChannelOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviChannelOptionsWidget,"options");
+ e0->pChildList->append(e1);
+
+ e1->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e1->pChildList->setAutoDelete(true);
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviChannelGeneralOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviChannelGeneralOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviChannelGeneralOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviChannelGeneralOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviChannelGeneralOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviChannelGeneralOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviChannelGeneralOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviChannelGeneralOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviChannelGeneralOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviChannelGeneralOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviChannelGeneralOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviChannelGeneralOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviChannelGeneralOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviChannelGeneralOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviChannelGeneralOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviChannelAdvancedOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviChannelAdvancedOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviChannelAdvancedOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviChannelAdvancedOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviChannelAdvancedOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviChannelAdvancedOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviChannelAdvancedOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviChannelAdvancedOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviChannelAdvancedOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviChannelAdvancedOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviChannelAdvancedOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviChannelAdvancedOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviChannelAdvancedOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviChannelAdvancedOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviChannelAdvancedOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviIrcOutputOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviIrcOutputOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIrcOutputOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIrcOutputOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIrcOutputOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcOutputOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcOutputOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIrcOutputOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIrcOutputOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIrcOutputOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIrcOutputOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcOutputOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcOutputOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviIrcOutputOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIrcOutputOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviProtectionOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviProtectionOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviProtectionOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviProtectionOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviProtectionOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviProtectionOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviProtectionOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviProtectionOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviProtectionOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviProtectionOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviProtectionOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviProtectionOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviProtectionOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviProtectionOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviProtectionOptionsWidget,"options");
+ e0->pChildList->append(e1);
+
+ e1->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e1->pChildList->setAutoDelete(true);
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviAntispamOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviAntispamOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviAntispamOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviAntispamOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviAntispamOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviAntispamOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviAntispamOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviAntispamOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviAntispamOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviAntispamOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviAntispamOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAntispamOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAntispamOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviAntispamOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviAntispamOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviCtcpFloodProtectionOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviCtcpFloodProtectionOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviCtcpFloodProtectionOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviCtcpFloodProtectionOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviCtcpFloodProtectionOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviCtcpFloodProtectionOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviCtcpFloodProtectionOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviCtcpFloodProtectionOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviCtcpFloodProtectionOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviCtcpFloodProtectionOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviCtcpFloodProtectionOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviCtcpFloodProtectionOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviCtcpFloodProtectionOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviCtcpFloodProtectionOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviCtcpFloodProtectionOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviIgnoreOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviIgnoreOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIgnoreOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIgnoreOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIgnoreOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIgnoreOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIgnoreOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIgnoreOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIgnoreOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIgnoreOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIgnoreOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIgnoreOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIgnoreOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviIgnoreOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIgnoreOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviQueryOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviQueryOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviQueryOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviQueryOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviQueryOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviQueryOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviQueryOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviQueryOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviQueryOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviQueryOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviQueryOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviQueryOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviQueryOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviQueryOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviQueryOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviToolsOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviToolsOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviToolsOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviToolsOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviToolsOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviToolsOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviToolsOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviToolsOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviToolsOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviToolsOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviToolsOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviToolsOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviToolsOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviToolsOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviToolsOptionsWidget,"options");
+ e0->pChildList->append(e1);
+
+ e1->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e1->pChildList->setAutoDelete(true);
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviAvatarAdvancedOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviAvatarAdvancedOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviAvatarAdvancedOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviAvatarAdvancedOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviAvatarAdvancedOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviAvatarAdvancedOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviAvatarAdvancedOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviAvatarAdvancedOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviAvatarAdvancedOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviAvatarAdvancedOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviAvatarAdvancedOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAvatarAdvancedOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAvatarAdvancedOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviAvatarAdvancedOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviAvatarAdvancedOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviAwayOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviAwayOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviAwayOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviAwayOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviAwayOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviAwayOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviAwayOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviAwayOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviAwayOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviAwayOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviAwayOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAwayOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAwayOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviAwayOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviAwayOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviCtcpOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviCtcpOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviCtcpOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviCtcpOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviCtcpOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviCtcpOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviCtcpOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviCtcpOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviCtcpOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviCtcpOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviCtcpOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviCtcpOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviCtcpOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviCtcpOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviCtcpOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviAlertHighlightingOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviAlertHighlightingOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviAlertHighlightingOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviAlertHighlightingOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviAlertHighlightingOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviAlertHighlightingOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviAlertHighlightingOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviAlertHighlightingOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviAlertHighlightingOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviAlertHighlightingOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviAlertHighlightingOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAlertHighlightingOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAlertHighlightingOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviAlertHighlightingOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviAlertHighlightingOptionsWidget,"options");
+ e1->pChildList->append(e2);
+
+ e2->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e2->pChildList->setAutoDelete(true);
+
+ KviOptionsWidgetInstanceEntry * e3;
+ e3 = new KviOptionsWidgetInstanceEntry;
+ e3->createProc = &classKviHighlightingOptionsWidget_createInstanceProc;
+ e3->pWidget = 0;
+ e3->szClassName = g_szClassName_KviHighlightingOptionsWidget;
+ e3->iIcon = KVI_OPTIONS_WIDGET_ICON_KviHighlightingOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviHighlightingOptionsWidget
+ e3->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviHighlightingOptionsWidget;
+ #else
+ e3->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviHighlightingOptionsWidget
+ e3->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviHighlightingOptionsWidget;
+ e3->szKeywords = __tr2qs_ctx_no_xgettext(e3->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviHighlightingOptionsWidget
+ e3->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviHighlightingOptionsWidget;
+ #else
+ e3->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviHighlightingOptionsWidget
+ e3->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviHighlightingOptionsWidget;
+ #else
+ e3->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviHighlightingOptionsWidget
+ e3->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviHighlightingOptionsWidget;
+ #else
+ e3->bIsNotContained = false;
+ #endif
+ e3->szNameNoLocale = g_szName_KviHighlightingOptionsWidget;
+ e3->szName = __tr2qs_ctx_no_xgettext(g_szName_KviHighlightingOptionsWidget,"options");
+ e2->pChildList->append(e3);
+ e3->pChildList = 0;
+
+ e3 = new KviOptionsWidgetInstanceEntry;
+ e3->createProc = &classKviAlertOptionsWidget_createInstanceProc;
+ e3->pWidget = 0;
+ e3->szClassName = g_szClassName_KviAlertOptionsWidget;
+ e3->iIcon = KVI_OPTIONS_WIDGET_ICON_KviAlertOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviAlertOptionsWidget
+ e3->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviAlertOptionsWidget;
+ #else
+ e3->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviAlertOptionsWidget
+ e3->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviAlertOptionsWidget;
+ e3->szKeywords = __tr2qs_ctx_no_xgettext(e3->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviAlertOptionsWidget
+ e3->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviAlertOptionsWidget;
+ #else
+ e3->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviAlertOptionsWidget
+ e3->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviAlertOptionsWidget;
+ #else
+ e3->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAlertOptionsWidget
+ e3->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviAlertOptionsWidget;
+ #else
+ e3->bIsNotContained = false;
+ #endif
+ e3->szNameNoLocale = g_szName_KviAlertOptionsWidget;
+ e3->szName = __tr2qs_ctx_no_xgettext(g_szName_KviAlertOptionsWidget,"options");
+ e2->pChildList->append(e3);
+ e3->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviLagOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviLagOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviLagOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviLagOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviLagOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviLagOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviLagOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviLagOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviLagOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviLagOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviLagOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviLagOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviLagOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviLagOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviLagOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviLoggingOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviLoggingOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviLoggingOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviLoggingOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviLoggingOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviLoggingOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviLoggingOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviLoggingOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviLoggingOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviLoggingOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviLoggingOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviLoggingOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviLoggingOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviLoggingOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviLoggingOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviNickServOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviNickServOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviNickServOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviNickServOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviNickServOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviNickServOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviNickServOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviNickServOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviNickServOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviNickServOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviNickServOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviNickServOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviNickServOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviNickServOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviNickServOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviNotifyOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviNotifyOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviNotifyOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviNotifyOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviNotifyOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviNotifyOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviNotifyOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviNotifyOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviNotifyOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviNotifyOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviNotifyOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviNotifyOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviNotifyOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviNotifyOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviNotifyOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviTextIconsOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviTextIconsOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTextIconsOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTextIconsOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTextIconsOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTextIconsOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTextIconsOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTextIconsOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTextIconsOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTextIconsOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTextIconsOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTextIconsOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTextIconsOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviTextIconsOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTextIconsOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviIrcViewThemeOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviIrcViewThemeOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIrcViewThemeOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIrcViewThemeOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIrcViewThemeOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcViewThemeOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcViewThemeOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIrcViewThemeOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIrcViewThemeOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIrcViewThemeOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIrcViewThemeOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcViewThemeOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcViewThemeOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviIrcViewThemeOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIrcViewThemeOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviIrcViewLookOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviIrcViewLookOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIrcViewLookOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIrcViewLookOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIrcViewLookOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcViewLookOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcViewLookOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIrcViewLookOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIrcViewLookOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIrcViewLookOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIrcViewLookOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcViewLookOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcViewLookOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviIrcViewLookOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIrcViewLookOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviIrcViewFeaturesOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviIrcViewFeaturesOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviIrcViewFeaturesOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviIrcViewFeaturesOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviIrcViewFeaturesOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcViewFeaturesOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcViewFeaturesOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviIrcViewFeaturesOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviIrcViewFeaturesOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviIrcViewFeaturesOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviIrcViewFeaturesOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcViewFeaturesOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviIrcViewFeaturesOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviIrcViewFeaturesOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviIrcViewFeaturesOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviMessageOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviMessageOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviMessageOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviMessageOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviMessageOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviMessageOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviMessageOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviMessageOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviMessageOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviMessageOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviMessageOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviMessageOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviMessageOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviMessageOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviMessageOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviPrivmsgOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviPrivmsgOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviPrivmsgOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviPrivmsgOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviPrivmsgOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviPrivmsgOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviPrivmsgOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviPrivmsgOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviPrivmsgOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviPrivmsgOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviPrivmsgOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviPrivmsgOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviPrivmsgOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviPrivmsgOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviPrivmsgOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviTimestampOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviTimestampOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTimestampOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTimestampOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTimestampOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTimestampOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTimestampOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTimestampOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTimestampOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTimestampOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTimestampOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTimestampOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTimestampOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviTimestampOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTimestampOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviMessageColorsOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviMessageColorsOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviMessageColorsOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviMessageColorsOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviMessageColorsOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviMessageColorsOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviMessageColorsOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviMessageColorsOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviMessageColorsOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviMessageColorsOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviMessageColorsOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviMessageColorsOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviMessageColorsOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviMessageColorsOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviMessageColorsOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviStandardColorsOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviStandardColorsOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviStandardColorsOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviStandardColorsOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviStandardColorsOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviStandardColorsOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviStandardColorsOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviStandardColorsOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviStandardColorsOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviStandardColorsOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviStandardColorsOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviStandardColorsOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviStandardColorsOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviStandardColorsOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviStandardColorsOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviServerOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviServerOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviServerOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviServerOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviServerOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviServerOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviServerOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviServerOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviServerOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviServerOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviServerOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviServerOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviServerOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviServerOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviServerOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+ e0->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviTaskBarOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviTaskBarOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTaskBarOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTaskBarOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTaskBarOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTaskBarOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTaskBarOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTaskBarOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTaskBarOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTaskBarOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTaskBarOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTaskBarOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTaskBarOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviTaskBarOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTaskBarOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviTreeTaskBarOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviTreeTaskBarOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTreeTaskBarOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTreeTaskBarOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTreeTaskBarOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBarOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBarOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTreeTaskBarOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTreeTaskBarOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTreeTaskBarOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTreeTaskBarOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviTreeTaskBarOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTreeTaskBarOptionsWidget,"options");
+ e0->pChildList->append(e1);
+
+ e1->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e1->pChildList->setAutoDelete(true);
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviTreeTaskBarForegroundOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviTreeTaskBarForegroundOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTreeTaskBarForegroundOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTreeTaskBarForegroundOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTreeTaskBarForegroundOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBarForegroundOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBarForegroundOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarForegroundOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarForegroundOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTreeTaskBarForegroundOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTreeTaskBarForegroundOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTreeTaskBarForegroundOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTreeTaskBarForegroundOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviTreeTaskBarForegroundOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTreeTaskBarForegroundOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviTreeTaskBarBackgroundOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviTreeTaskBarBackgroundOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTreeTaskBarBackgroundOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTreeTaskBarBackgroundOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTreeTaskBarBackgroundOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBarBackgroundOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBarBackgroundOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarBackgroundOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarBackgroundOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTreeTaskBarBackgroundOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTreeTaskBarBackgroundOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTreeTaskBarBackgroundOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTreeTaskBarBackgroundOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviTreeTaskBarBackgroundOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTreeTaskBarBackgroundOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e2 = new KviOptionsWidgetInstanceEntry;
+ e2->createProc = &classKviTreeTaskBarFeaturesOptionsWidget_createInstanceProc;
+ e2->pWidget = 0;
+ e2->szClassName = g_szClassName_KviTreeTaskBarFeaturesOptionsWidget;
+ e2->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTreeTaskBarFeaturesOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTreeTaskBarFeaturesOptionsWidget
+ e2->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTreeTaskBarFeaturesOptionsWidget;
+ #else
+ e2->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBarFeaturesOptionsWidget
+ e2->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBarFeaturesOptionsWidget;
+ e2->szKeywords = __tr2qs_ctx_no_xgettext(e2->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarFeaturesOptionsWidget
+ e2->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarFeaturesOptionsWidget;
+ #else
+ e2->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTreeTaskBarFeaturesOptionsWidget
+ e2->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTreeTaskBarFeaturesOptionsWidget;
+ #else
+ e2->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTreeTaskBarFeaturesOptionsWidget
+ e2->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTreeTaskBarFeaturesOptionsWidget;
+ #else
+ e2->bIsNotContained = false;
+ #endif
+ e2->szNameNoLocale = g_szName_KviTreeTaskBarFeaturesOptionsWidget;
+ e2->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTreeTaskBarFeaturesOptionsWidget,"options");
+ e1->pChildList->append(e2);
+ e2->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviClassicTaskBarOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviClassicTaskBarOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviClassicTaskBarOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviClassicTaskBarOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviClassicTaskBarOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviClassicTaskBarOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviClassicTaskBarOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviClassicTaskBarOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviClassicTaskBarOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviClassicTaskBarOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviClassicTaskBarOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviClassicTaskBarOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviClassicTaskBarOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviClassicTaskBarOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviClassicTaskBarOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviTopicLabelLookOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviTopicLabelLookOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviTopicLabelLookOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviTopicLabelLookOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviTopicLabelLookOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviTopicLabelLookOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviTopicLabelLookOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviTopicLabelLookOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviTopicLabelLookOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviTopicLabelLookOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviTopicLabelLookOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTopicLabelLookOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviTopicLabelLookOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviTopicLabelLookOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviTopicLabelLookOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+ e0->pChildList = 0;
+
+ e0 = new KviOptionsWidgetInstanceEntry;
+ e0->createProc = &classKviUserListLookOptionsWidget_createInstanceProc;
+ e0->pWidget = 0;
+ e0->szClassName = g_szClassName_KviUserListLookOptionsWidget;
+ e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviUserListLookOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviUserListLookOptionsWidget
+ e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviUserListLookOptionsWidget;
+ #else
+ e0->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListLookOptionsWidget
+ e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListLookOptionsWidget;
+ e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviUserListLookOptionsWidget
+ e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviUserListLookOptionsWidget;
+ #else
+ e0->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviUserListLookOptionsWidget
+ e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviUserListLookOptionsWidget;
+ #else
+ e0->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListLookOptionsWidget
+ e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListLookOptionsWidget;
+ #else
+ e0->bIsNotContained = false;
+ #endif
+ e0->szNameNoLocale = g_szName_KviUserListLookOptionsWidget;
+ e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviUserListLookOptionsWidget,"options");
+ m_pInstanceTree->append(e0);
+
+ e0->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ e0->pChildList->setAutoDelete(true);
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviUserListLookBackgroundOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviUserListLookBackgroundOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviUserListLookBackgroundOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviUserListLookBackgroundOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviUserListLookBackgroundOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListLookBackgroundOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListLookBackgroundOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviUserListLookBackgroundOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviUserListLookBackgroundOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviUserListLookBackgroundOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviUserListLookBackgroundOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListLookBackgroundOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListLookBackgroundOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviUserListLookBackgroundOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviUserListLookBackgroundOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviUserListLookForegroundOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviUserListLookForegroundOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviUserListLookForegroundOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviUserListLookForegroundOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviUserListLookForegroundOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListLookForegroundOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListLookForegroundOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviUserListLookForegroundOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviUserListLookForegroundOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviUserListLookForegroundOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviUserListLookForegroundOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListLookForegroundOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListLookForegroundOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviUserListLookForegroundOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviUserListLookForegroundOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviUserListGridOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviUserListGridOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviUserListGridOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviUserListGridOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviUserListGridOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListGridOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListGridOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviUserListGridOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviUserListGridOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviUserListGridOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviUserListGridOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListGridOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListGridOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviUserListGridOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviUserListGridOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+ e1 = new KviOptionsWidgetInstanceEntry;
+ e1->createProc = &classKviUserListFeaturesOptionsWidget_createInstanceProc;
+ e1->pWidget = 0;
+ e1->szClassName = g_szClassName_KviUserListFeaturesOptionsWidget;
+ e1->iIcon = KVI_OPTIONS_WIDGET_ICON_KviUserListFeaturesOptionsWidget;
+ #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviUserListFeaturesOptionsWidget
+ e1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviUserListFeaturesOptionsWidget;
+ #else
+ e1->iPriority = 0;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListFeaturesOptionsWidget
+ e1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListFeaturesOptionsWidget;
+ e1->szKeywords = __tr2qs_ctx_no_xgettext(e1->szKeywordsNoLocale,"options");;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_GROUP_KviUserListFeaturesOptionsWidget
+ e1->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviUserListFeaturesOptionsWidget;
+ #else
+ e1->szGroup = "general";
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviUserListFeaturesOptionsWidget
+ e1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviUserListFeaturesOptionsWidget;
+ #else
+ e1->bIsContainer = false;
+ #endif
+ #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListFeaturesOptionsWidget
+ e1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviUserListFeaturesOptionsWidget;
+ #else
+ e1->bIsNotContained = false;
+ #endif
+ e1->szNameNoLocale = g_szName_KviUserListFeaturesOptionsWidget;
+ e1->szName = __tr2qs_ctx_no_xgettext(g_szName_KviUserListFeaturesOptionsWidget,"options");
+ e0->pChildList->append(e1);
+ e1->pChildList = 0;
+
+}
+
+void KviOptionsInstanceManager::deleteInstanceTree(KviPointerList<KviOptionsWidgetInstanceEntry> * l)
+{
+ if(l)
+ {
+ for(KviOptionsWidgetInstanceEntry * e = l->first();e;e = l->next())
+ {
+ if(e->pWidget)
+ {
+ if(e->pWidget->parent()->inherits("KviOptionsWidgetContainer"))
+ {
+ disconnect(e->pWidget,SIGNAL(destroyed()),this,SLOT(widgetDestroyed()));
+ delete e->pWidget->parent();
+ e->pWidget = 0;
+ } else {
+ debug("Ops...i have deleted the options dialog ?");
+ }
+ } //else debug("Clas %s has no widget",e->szName);
+ if(e->pChildList)deleteInstanceTree(e->pChildList);
+ }
+ delete l;
+ }
+}
+
+
+KviOptionsInstanceManager::~KviOptionsInstanceManager()
+{
+ if(m_pInstanceTree)debug("Ops...KviOptionsInstanceManager::cleanup() not called ?");
+}
+
+void KviOptionsInstanceManager::cleanup(KviModule * m)
+{
+ deleteInstanceTree(m_pInstanceTree);
+ m_pInstanceTree = 0;
+}
+
+void KviOptionsInstanceManager::widgetDestroyed()
+{
+ KviOptionsWidgetInstanceEntry * e = findInstanceEntry(sender(),m_pInstanceTree);
+ if(e)e->pWidget = 0;
+ if(g_iOptionWidgetInstances > 0)g_iOptionWidgetInstances--;
+
+}
+
+KviOptionsWidget * KviOptionsInstanceManager::getInstance(KviOptionsWidgetInstanceEntry * e,QWidget * par)
+{
+ if(!e)return 0;
+ if(!(e->pWidget))
+ {
+ e->pWidget = e->createProc(par);
+ g_iOptionWidgetInstances++;
+ connect(e->pWidget,SIGNAL(destroyed()),this,SLOT(widgetDestroyed()));
+ }
+ if(e->pWidget->parent() != par)
+ {
+ QWidget * oldPar = (QWidget *)e->pWidget->parent();
+ e->pWidget->reparent(par,QPoint(0,0));
+ delete oldPar;
+ }
+ if(e->bIsContainer)
+ {
+ // need to create the container structure!
+ e->pWidget->createTabbedPage();
+ if(e->pChildList)
+ {
+ KviPointerList<KviOptionsWidgetInstanceEntry> tmp;
+ tmp.setAutoDelete(false);
+
+ for(KviOptionsWidgetInstanceEntry * e2 = e->pChildList->first();e2;e2 = e->pChildList->next())
+ {
+ // add only non containers and widgets not explicitly marked as noncontained
+ if((!e2->bIsContainer) && (!e2->bIsNotContained))
+ {
+ KviOptionsWidgetInstanceEntry * ee = tmp.first();
+ int idx = 0;
+ while(ee)
+ {
+ if(ee->iPriority >= e2->iPriority)break;
+ idx++;
+ ee = tmp.next();
+ }
+ tmp.insert(idx,e2);
+ }
+ }
+
+ for(KviOptionsWidgetInstanceEntry * e3 = tmp.last();e3;e3 = tmp.prev())
+ {
+ KviOptionsWidget * ow = getInstance(e3,e->pWidget->tabWidget());
+ e->pWidget->addOptionsWidget(e3->szName,*(g_pIconManager->getSmallIcon(e3->iIcon)),ow);
+ }
+ }
+ }
+ return e->pWidget;
+}
+
+KviOptionsWidgetInstanceEntry * KviOptionsInstanceManager::findInstanceEntry(const QObject * ptr,KviPointerList<KviOptionsWidgetInstanceEntry> * l)
+{
+ if(l)
+ {
+ for(KviOptionsWidgetInstanceEntry * e = l->first();e;e = l->next())
+ {
+ if(ptr == e->pWidget)return e;
+ if(e->pChildList)
+ {
+ KviOptionsWidgetInstanceEntry * e2 = findInstanceEntry(ptr,e->pChildList);
+ if(e2)return e2;
+ }
+ }
+ }
+ return 0;
+}
+
+KviOptionsWidgetInstanceEntry * KviOptionsInstanceManager::findInstanceEntry(const char * clName,KviPointerList<KviOptionsWidgetInstanceEntry> * l)
+{
+ if(l)
+ {
+ for(KviOptionsWidgetInstanceEntry * e = l->first();e;e = l->next())
+ {
+ if(kvi_strEqualCI(e->szClassName,clName))return e;
+ if(e->pChildList)
+ {
+ KviOptionsWidgetInstanceEntry * e2 = findInstanceEntry(clName,e->pChildList);
+ if(e2)return e2;
+ }
+ }
+ }
+ return 0;
+}
+
+KviOptionsWidgetInstanceEntry * KviOptionsInstanceManager::findInstanceEntry(const char * clName)
+{
+ return findInstanceEntry(clName,m_pInstanceTree);
+}
+
+
+#include "m_instances.moc"
+
diff --git a/src/modules/options/instances.h b/src/modules/options/instances.h
new file mode 100644
index 00000000..fc8674cc
--- /dev/null
+++ b/src/modules/options/instances.h
@@ -0,0 +1,83 @@
+
+
+#ifndef __OPTIONS_INSTANCES_H__
+#define __OPTIONS_INSTANCES_H__
+
+//
+// File : instances.h
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2006 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.
+//
+
+//
+// Instance creation routines for the KVIrc options module
+// DO NOT EDIT THIS FILE!! ALL CHANGES WILL BE LOST!!
+// This file is automatically generated by mkcreateinstanceproc.sh
+// so any change should go in that script
+//
+
+#include "kvi_optionswidget.h"
+#include "kvi_module.h"
+#include "kvi_pointerlist.h"
+#include "kvi_qstring.h"
+
+typedef struct _KviOptionsWidgetInstanceEntry KviOptionsWidgetInstanceEntry;
+
+
+typedef struct _KviOptionsWidgetInstanceEntry
+{
+ KviOptionsWidget * (*createProc)(QWidget *);
+ KviOptionsWidget * pWidget; // singleton
+ int iIcon;
+ QString szName;
+ QString szNameNoLocale;
+ const char * szClassName;
+ int iPriority;
+ QString szKeywords;
+ QString szKeywordsNoLocale;
+ QString szGroup;
+ bool bIsContainer;
+ bool bIsNotContained;
+ KviPointerList<KviOptionsWidgetInstanceEntry> * pChildList;
+ bool bDoInsert; // a helper for KviOptionsDialog::fillListView()
+} KviOptionsWidgetInstanceEntry;
+
+
+class KviOptionsInstanceManager : public QObject
+{
+ Q_OBJECT
+public:
+ KviOptionsInstanceManager();
+ virtual ~KviOptionsInstanceManager();
+protected:
+ KviPointerList<KviOptionsWidgetInstanceEntry> * m_pInstanceTree;
+public:
+ KviPointerList<KviOptionsWidgetInstanceEntry> * instanceEntryTree(){ return m_pInstanceTree; };
+ KviOptionsWidget * getInstance(KviOptionsWidgetInstanceEntry * e,QWidget * par);
+ KviOptionsWidgetInstanceEntry * findInstanceEntry(const char * clName);
+ void cleanup(KviModule * m);
+protected:
+ KviOptionsWidgetInstanceEntry * findInstanceEntry(const char * clName,KviPointerList<KviOptionsWidgetInstanceEntry> * l);
+ KviOptionsWidgetInstanceEntry * findInstanceEntry(const QObject * ptr,KviPointerList<KviOptionsWidgetInstanceEntry> * l);
+ void deleteInstanceTree(KviPointerList<KviOptionsWidgetInstanceEntry> * l);
+protected slots:
+ void widgetDestroyed();
+};
+
+#endif //__OPTIONS_INSTANCES_H__
+
diff --git a/src/modules/options/libkvioptions.cpp b/src/modules/options/libkvioptions.cpp
new file mode 100644
index 00000000..175b61ff
--- /dev/null
+++ b/src/modules/options/libkvioptions.cpp
@@ -0,0 +1,324 @@
+//============================================================================================
+//
+// File : libkvioptions.cpp
+// Creation date : Fri Aug 18 2000 15:04:09 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2006 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_module.h"
+#include "kvi_options.h"
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_window.h"
+#include "kvi_locale.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_out.h"
+#include "kvi_splash.h"
+
+#include "container.h"
+#include "instances.h"
+
+#include "dialog.h"
+
+#include <qsplitter.h>
+#include "kvi_pointerhashtable.h"
+
+
+KviPointerHashTable<QString,KviOptionsDialog> * g_pOptionsDialogDict = 0;
+
+KviOptionsInstanceManager * g_pOptionsInstanceManager = 0;
+
+extern int g_iOptionWidgetInstances;
+
+/*
+ @doc: options.save
+ @type:
+ command
+ @title:
+ options.save
+ @short:
+ Saves the options to disk
+ @syntax:
+ options.save
+ @description:
+ Saves the options to disk; this includes aliases , popups ,
+ events and user preferences.
+*/
+
+static bool options_kvs_cmd_save(KviKvsModuleCommandCall * c)
+{
+ g_pApp->saveOptions();
+ return true;
+}
+
+
+/*
+ @doc: options.dialog
+ @type:
+ command
+ @title:
+ options.dialog
+ @short:
+ Shows the "options dialog"
+ @syntax:
+ options.dialog [-t] [options_group]
+ @description:
+ Shows the KVIrc options dialog for the specified options group.
+ If the [-t] switch is used , the dialog is opened as toplevel window,
+ otherwise it is opened as part of the current frame window.[br]
+ Valid values for [options_group] are "general" and "theme".
+ If [options_group] is omitted, the option group "general" is assumed.
+ This command is exported by the "options" module.
+ @seealso:
+ [fnc]$options.isDialog[/fnc]
+*/
+
+
+static bool options_kvs_cmd_dialog(KviKvsModuleCommandCall * c)
+{
+ QString szGroup;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("options_group",KVS_PT_STRING,KVS_PF_OPTIONAL,szGroup)
+ KVSM_PARAMETERS_END(c)
+ if(szGroup.isEmpty())szGroup = "general";
+ KviOptionsDialog * d = g_pOptionsDialogDict->find(szGroup);
+ if(d)
+ {
+ if(c->hasSwitch('t',"toplevel"))
+ {
+ if(d->parent())
+ {
+ d->reparent(0,QPoint(0,0),true);
+ }
+ } else {
+ if(d->parent() != c->window()->frame()->splitter())
+ {
+ d->reparent(c->window()->frame()->splitter(),QPoint(0,0),true);
+ }
+ }
+ } else {
+ if(c->hasSwitch('t',"toplevel"))
+ {
+ d = new KviOptionsDialog(0,szGroup);
+ } else {
+ d = new KviOptionsDialog(c->window()->frame()->splitter(),szGroup);
+ }
+ g_pOptionsDialogDict->insert(szGroup,d);
+ }
+ d->raise();
+ d->show();
+ d->setFocus();
+ return true;
+}
+
+/*
+ @doc: options.pages
+ @type:
+ command
+ @title:
+ options.pages
+ @short:
+ Lists the option pages
+ @syntax:
+ options.pages
+ @description:
+ Lists the option pages available for editing by the means of [cmd]options.edit[/cmd].
+ @seealso:
+*/
+
+
+static void options_kvs_module_print_pages(KviKvsModuleCommandCall * c,KviOptionsWidgetInstanceEntry * e,const char * prefix)
+{
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,"%s%c%s%c (%Q)",prefix,KVI_TEXT_BOLD,e->szClassName,KVI_TEXT_BOLD,&(e->szName));
+ KviStr szPre = prefix;
+ szPre.append(" ");
+ if(e->pChildList)
+ {
+ for(KviOptionsWidgetInstanceEntry * ex = e->pChildList->first();ex;ex = e->pChildList->next())
+ {
+ options_kvs_module_print_pages(c,ex,szPre.ptr());
+ }
+ }
+}
+static bool options_kvs_cmd_pages(KviKvsModuleCommandCall * c)
+{
+ KviPointerList<KviOptionsWidgetInstanceEntry> * l = g_pOptionsInstanceManager->instanceEntryTree();
+
+ for(KviOptionsWidgetInstanceEntry * e = l->first();e;e = l->next())
+ {
+ options_kvs_module_print_pages(c,e,"");
+ }
+
+ return true;
+}
+
+/*
+ @doc: options.edit
+ @type:
+ command
+ @title:
+ options.edit [-m]
+ @short:
+ Shows a single options page
+ @syntax:
+ options.edit <"options page class name">
+ @description:
+ Shows an options page as toplevel dialog.
+ The available option pages can be listed by using [cmd]options.pages[/cmd].
+ If the -m switch is used, the dialog will appear as modal, blocking input
+ to the main frame until it's closed.
+ @seealso:
+*/
+
+static bool options_kvs_cmd_edit(KviKvsModuleCommandCall * c)
+{
+ QString szOption;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("option",KVS_PT_STRING,0,szOption)
+ KVSM_PARAMETERS_END(c)
+ KviOptionsWidgetInstanceEntry * e = g_pOptionsInstanceManager->findInstanceEntry(szOption);
+ if(!e)
+ {
+ c->warning(__tr2qs_ctx("No such options page class name %Q","options"),&szOption);
+ return true;
+ }
+
+ if(e->pWidget)
+ {
+ //c->warning(__tr("The editor page is already open","options"));
+ e->pWidget->raise();
+ e->pWidget->setActiveWindow();
+ e->pWidget->setFocus();
+ return true;
+ }
+
+ QWidget * w;
+
+ if(c->hasSwitch('m',"modal"))
+ {
+ w = g_pApp->activeModalWidget();
+ if(!w)w = g_pFrame;
+ } else {
+ w = g_pFrame;
+ }
+
+ KviOptionsWidgetContainer * wc = new KviOptionsWidgetContainer(w,c->hasSwitch('m',"modal"));
+
+ wc->setup(g_pOptionsInstanceManager->getInstance(e,wc));
+
+ // a trick for the dialog covering the splash screen before the time (this is prolly a WM or Qt bug)
+ if(g_pSplashScreen)
+ {
+ if(g_pSplashScreen->isVisible()) // another bug: this ALWAYS RETURNS TRUE, even if the splash was hidden by a mouse click...
+ {
+ QObject::connect(g_pSplashScreen,SIGNAL(destroyed()),wc,SLOT(show()));
+ return true;
+ }
+ }
+
+ wc->show();
+ wc->raise();
+ return true;
+}
+
+/*
+ @doc: options.isdialog
+ @type:
+ function
+ @title:
+ $options.isdialog
+ @short:
+ Returns the options dialog state
+ @syntax:
+ <boolean> $options.isdialog([options_group:string])
+ @description:
+ Returns '1' if the options dialog for the specified options_group is open, '0' otherwise.[br]
+ If [options_group] is omitted then the group "general" is assumed.
+ At the moment of writing the valid [options_group] values are "general" and "theme".
+ This command is exported by the "options" module.
+ @seealso:
+ [cmd]options.dialog[/cmd]
+*/
+
+static bool options_kvs_fnc_isdialog(KviKvsModuleFunctionCall * c)
+{
+ QString szGroup;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("options_group",KVS_PT_STRING,KVS_PF_OPTIONAL,szGroup)
+ KVSM_PARAMETERS_END(c)
+ if(szGroup.isEmpty())szGroup = "general";
+ c->returnValue()->setBoolean(g_pOptionsDialogDict->find(szGroup));
+ return true;
+}
+
+
+static bool options_module_init(KviModule * m)
+{
+ g_pOptionsInstanceManager = new KviOptionsInstanceManager();
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"dialog",options_kvs_cmd_dialog);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"save",options_kvs_cmd_save);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"pages",options_kvs_cmd_pages);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"edit",options_kvs_cmd_edit);
+ KVSM_REGISTER_FUNCTION(m,"isDialog",options_kvs_fnc_isdialog);
+
+ g_pOptionsDialogDict = new KviPointerHashTable<QString,KviOptionsDialog>;
+ g_pOptionsDialogDict->setAutoDelete(false);
+
+ return true;
+}
+
+static bool options_module_cleanup(KviModule *m)
+{
+ KviPointerHashTableIterator<QString,KviOptionsDialog> it(*g_pOptionsDialogDict);
+ KviPointerList<KviOptionsDialog> l;
+ l.setAutoDelete(false);
+ KviOptionsDialog * d;
+ while(d = it.current())
+ {
+ l.append(d);
+ ++it;
+ }
+ for(d = l.first();d;d = l.next())delete d;
+ delete g_pOptionsDialogDict;
+ g_pOptionsDialogDict = 0;
+
+ g_pOptionsInstanceManager->cleanup(m);
+ delete g_pOptionsInstanceManager;
+ g_pOptionsInstanceManager = 0;
+
+ return true;
+}
+
+static bool options_module_can_unload(KviModule *m)
+{
+ return ((g_pOptionsDialogDict->isEmpty()) && (g_iOptionWidgetInstances == 0));
+}
+
+KVIRC_MODULE(
+ "Options", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Options Dialog",
+ options_module_init,
+ options_module_can_unload,
+ 0,
+ options_module_cleanup
+)
diff --git a/src/modules/options/mkcreateinstanceproc.sh b/src/modules/options/mkcreateinstanceproc.sh
new file mode 100755
index 00000000..97be80b5
--- /dev/null
+++ b/src/modules/options/mkcreateinstanceproc.sh
@@ -0,0 +1,441 @@
+#!/bin/sh
+
+#####################################################################################################
+#
+# Generator for instances.h and instances.cpp
+#
+# This file is part of the KVirc irc client distribution
+# Copyright (C) 2001-2006 Szymon Stefanek (pragma at kvirc dot net)
+#
+#####################################################################################################
+
+
+echo "" > instances.h
+
+######################################################################################################
+cat >> instances.h <<EOF
+
+#ifndef __OPTIONS_INSTANCES_H__
+#define __OPTIONS_INSTANCES_H__
+
+//
+// File : instances.h
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2006 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.
+//
+
+//
+// Instance creation routines for the KVIrc options module
+// DO NOT EDIT THIS FILE!! ALL CHANGES WILL BE LOST!!
+// This file is automatically generated by mkcreateinstanceproc.sh
+// so any change should go in that script
+//
+
+#include "kvi_optionswidget.h"
+#include "kvi_module.h"
+#include "kvi_pointerlist.h"
+#include "kvi_qstring.h"
+
+typedef struct _KviOptionsWidgetInstanceEntry KviOptionsWidgetInstanceEntry;
+
+
+typedef struct _KviOptionsWidgetInstanceEntry
+{
+ KviOptionsWidget * (*createProc)(QWidget *);
+ KviOptionsWidget * pWidget; // singleton
+ int iIcon;
+ QString szName;
+ QString szNameNoLocale;
+ const char * szClassName;
+ int iPriority;
+ QString szKeywords;
+ QString szKeywordsNoLocale;
+ QString szGroup;
+ bool bIsContainer;
+ bool bIsNotContained;
+ KviPointerList<KviOptionsWidgetInstanceEntry> * pChildList;
+ bool bDoInsert; // a helper for KviOptionsDialog::fillListView()
+} KviOptionsWidgetInstanceEntry;
+
+
+class KviOptionsInstanceManager : public QObject
+{
+ Q_OBJECT
+public:
+ KviOptionsInstanceManager();
+ virtual ~KviOptionsInstanceManager();
+protected:
+ KviPointerList<KviOptionsWidgetInstanceEntry> * m_pInstanceTree;
+public:
+ KviPointerList<KviOptionsWidgetInstanceEntry> * instanceEntryTree(){ return m_pInstanceTree; };
+ KviOptionsWidget * getInstance(KviOptionsWidgetInstanceEntry * e,QWidget * par);
+ KviOptionsWidgetInstanceEntry * findInstanceEntry(const char * clName);
+ void cleanup(KviModule * m);
+protected:
+ KviOptionsWidgetInstanceEntry * findInstanceEntry(const char * clName,KviPointerList<KviOptionsWidgetInstanceEntry> * l);
+ KviOptionsWidgetInstanceEntry * findInstanceEntry(const QObject * ptr,KviPointerList<KviOptionsWidgetInstanceEntry> * l);
+ void deleteInstanceTree(KviPointerList<KviOptionsWidgetInstanceEntry> * l);
+protected slots:
+ void widgetDestroyed();
+};
+
+#endif //__OPTIONS_INSTANCES_H__
+
+EOF
+######################################################################################################
+
+CLASS_LIST=`grep -h "[ ]*\:[ ]*public[ ]*KviOptionsWidget" optw_*.h | sed -e 's/[ ]*\:[ ]*public[ ]*KviOptionsWidget'//g | sed -e 's/[ ]*class[ ]*//g'`
+
+
+TARGET="instances.cpp"
+
+echo "" > $TARGET
+
+######################################################################################################
+cat >> instances.cpp <<EOF
+
+//
+// File : instances.cpp
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001 Szymon Stefanek (stefanek@tin.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.
+//
+
+//
+// Instance creation routines for the KVIrc options module
+// DO NOT EDIT THIS FILE!! ALL CHANGES WILL BE LOST!!
+// This file is automatically generated by mkcreateinstanceproc.sh
+// so any change should go in that script
+//
+
+EOF
+######################################################################################################
+
+
+for afile in optw_*.h; do
+ echo "#include \"$afile\"" >> $TARGET
+done
+
+######################################################################################################
+cat >> instances.cpp <<EOF
+
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "instances.h"
+
+int g_iOptionWidgetInstances = 0;
+
+EOF
+######################################################################################################
+
+
+for aclass in $CLASS_LIST; do
+ echo -n "KviOptionsWidget * class$aclass" >> $TARGET
+ echo "_createInstanceProc(QWidget * parent)" >> $TARGET
+ echo "{" >> $TARGET
+ echo " return new $aclass(parent);" >> $TARGET
+ echo "}" >> $TARGET
+ echo "" >> $TARGET
+done
+
+######################################################################################################
+cat >> instances.cpp <<EOF
+
+
+EOF
+######################################################################################################
+
+for aclass in $CLASS_LIST; do
+ echo "static const char * g_szName_$aclass = KVI_OPTIONS_WIDGET_NAME_$aclass;" >> $TARGET
+ echo "static const char * g_szClassName_$aclass = \"$aclass\";" >> $TARGET
+done
+
+######################################################################################################
+cat >> instances.cpp <<EOF
+
+KviOptionsInstanceManager::KviOptionsInstanceManager()
+: QObject(0)
+{
+
+ //debug("Instantiating");
+ // Create the global widget dict : case sensitive , do not copy keys
+ m_pInstanceTree = new KviPointerList<KviOptionsWidgetInstanceEntry>;
+ m_pInstanceTree->setAutoDelete(true);
+
+EOF
+######################################################################################################
+
+CLASSDIR=".classtmp"
+
+mkdir -p $CLASSDIR
+
+rm -f $CLASSDIR/*
+
+for aclass in $CLASS_LIST; do
+ PARENT=`grep -h "KVI_OPTIONS_WIDGET_PARENT_$aclass" optw_*.h | sed -e 's/#define//g' | sed -e s/KVI_OPTIONS_WIDGET_PARENT_$aclass//g | sed -e 's/[ ]*//g'`
+ if [ -z "$PARENT" ]; then
+ PARENT="NOPARENT"
+ fi
+ echo $aclass >> $CLASSDIR/$PARENT
+done
+
+SPACES=""
+
+printclass()
+{
+ echo "" >> $TARGET
+ found=
+ for anum in $DECLARED; do
+ if [ "$anum" = "$1" ]; then
+ found="yes"
+ break
+ fi
+ done
+ if [ -z "$found" ]; then
+ echo "$3 KviOptionsWidgetInstanceEntry * e$1;" >> $TARGET
+ DECLARED="$DECLARED $1"
+ fi
+ echo "$3 e$1 = new KviOptionsWidgetInstanceEntry;" >> $TARGET
+ echo -n "$3 e$1->createProc = &class$2" >> $TARGET
+ echo "_createInstanceProc;" >> $TARGET
+ echo "$3 e$1->pWidget = 0;" >> $TARGET
+ echo "$3 e$1->szClassName = g_szClassName_$2;" >> $TARGET
+ echo "$3 e$1->iIcon = KVI_OPTIONS_WIDGET_ICON_$2;" >> $TARGET
+
+ echo "$3 #ifdef KVI_OPTIONS_WIDGET_PRIORITY_$2" >> $TARGET
+ echo "$3 e$1->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_$2;" >> $TARGET
+ echo "$3 #else" >> $TARGET
+ echo "$3 e$1->iPriority = 0;" >> $TARGET
+ echo "$3 #endif" >> $TARGET
+
+ echo "$3 #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_$2" >> $TARGET
+ echo "$3 e$1->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_$2;" >> $TARGET
+ echo "$3 e$1->szKeywords = __tr2qs_ctx_no_xgettext(e$1->szKeywordsNoLocale,\"options\");;" >> $TARGET
+ echo "$3 #endif" >> $TARGET
+
+ echo "$3 #ifdef KVI_OPTIONS_WIDGET_GROUP_$2" >> $TARGET
+ echo "$3 e$1->szGroup = KVI_OPTIONS_WIDGET_GROUP_$2;" >> $TARGET
+ echo "$3 #else" >> $TARGET
+ echo "$3 e$1->szGroup = \"general\";" >> $TARGET
+ echo "$3 #endif" >> $TARGET
+
+ echo "$3 #ifdef KVI_OPTIONS_WIDGET_CONTAINER_$2" >> $TARGET
+ echo "$3 e$1->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_$2;" >> $TARGET
+ echo "$3 #else" >> $TARGET
+ echo "$3 e$1->bIsContainer = false;" >> $TARGET
+ echo "$3 #endif" >> $TARGET
+
+ echo "$3 #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_$2" >> $TARGET
+ echo "$3 e$1->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_$2;" >> $TARGET
+ echo "$3 #else" >> $TARGET
+ echo "$3 e$1->bIsNotContained = false;" >> $TARGET
+ echo "$3 #endif" >> $TARGET
+
+ echo "$3 e$1->szNameNoLocale = g_szName_$2;" >> $TARGET
+ echo "$3 e$1->szName = __tr2qs_ctx_no_xgettext(g_szName_$2,\"options\");" >> $TARGET
+
+ if [ "$1" = "0" ]; then
+ echo "$3 m_pInstanceTree->append(e$1);" >> $TARGET
+ else
+ VAL=`expr $1 - 1`
+ echo "$3 e$VAL->pChildList->append(e$1);" >> $TARGET
+ fi
+}
+
+addchildren()
+{
+ if [ -f "$CLASSDIR/$2" ]; then
+ LEVEL=`cat $CLASSDIR/$2`
+ for achild in $LEVEL; do
+ printclass $1 $achild "$3"
+ if [ -f "$CLASSDIR/$achild" ]; then
+ echo "" >> $TARGET
+ echo "$3 e$1->pChildList = new KviPointerList<KviOptionsWidgetInstanceEntry>;" >> $TARGET
+ echo "$3 e$1->pChildList->setAutoDelete(true);" >> $TARGET
+ NEXTLEVEL=`expr $1 + 1`
+ addchildren $NEXTLEVEL $achild "$3 "
+ else
+ echo "$3 e$1->pChildList = 0;" >> $TARGET
+ fi
+ done
+ fi
+}
+
+addchildren 0 NOPARENT ""
+
+
+rm -fr $CLASSDIR
+
+######################################################################################################
+cat >> $TARGET <<EOF
+
+}
+
+void KviOptionsInstanceManager::deleteInstanceTree(KviPointerList<KviOptionsWidgetInstanceEntry> * l)
+{
+ if(l)
+ {
+ for(KviOptionsWidgetInstanceEntry * e = l->first();e;e = l->next())
+ {
+ if(e->pWidget)
+ {
+ if(e->pWidget->parent()->inherits("KviOptionsWidgetContainer"))
+ {
+ disconnect(e->pWidget,SIGNAL(destroyed()),this,SLOT(widgetDestroyed()));
+ delete e->pWidget->parent();
+ e->pWidget = 0;
+ } else {
+ debug("Ops...i have deleted the options dialog ?");
+ }
+ } //else debug("Clas %s has no widget",e->szName);
+ if(e->pChildList)deleteInstanceTree(e->pChildList);
+ }
+ delete l;
+ }
+}
+
+
+KviOptionsInstanceManager::~KviOptionsInstanceManager()
+{
+ if(m_pInstanceTree)debug("Ops...KviOptionsInstanceManager::cleanup() not called ?");
+}
+
+void KviOptionsInstanceManager::cleanup(KviModule * m)
+{
+ deleteInstanceTree(m_pInstanceTree);
+ m_pInstanceTree = 0;
+}
+
+void KviOptionsInstanceManager::widgetDestroyed()
+{
+ KviOptionsWidgetInstanceEntry * e = findInstanceEntry(sender(),m_pInstanceTree);
+ if(e)e->pWidget = 0;
+ if(g_iOptionWidgetInstances > 0)g_iOptionWidgetInstances--;
+
+}
+
+KviOptionsWidget * KviOptionsInstanceManager::getInstance(KviOptionsWidgetInstanceEntry * e,QWidget * par)
+{
+ if(!e)return 0;
+ if(!(e->pWidget))
+ {
+ e->pWidget = e->createProc(par);
+ g_iOptionWidgetInstances++;
+ connect(e->pWidget,SIGNAL(destroyed()),this,SLOT(widgetDestroyed()));
+ }
+ if(e->pWidget->parent() != par)
+ {
+ QWidget * oldPar = (QWidget *)e->pWidget->parent();
+ e->pWidget->reparent(par,QPoint(0,0));
+ delete oldPar;
+ }
+ if(e->bIsContainer)
+ {
+ // need to create the container structure!
+ e->pWidget->createTabbedPage();
+ if(e->pChildList)
+ {
+ KviPointerList<KviOptionsWidgetInstanceEntry> tmp;
+ tmp.setAutoDelete(false);
+
+ for(KviOptionsWidgetInstanceEntry * e2 = e->pChildList->first();e2;e2 = e->pChildList->next())
+ {
+ // add only non containers and widgets not explicitly marked as noncontained
+ if((!e2->bIsContainer) && (!e2->bIsNotContained))
+ {
+ KviOptionsWidgetInstanceEntry * ee = tmp.first();
+ int idx = 0;
+ while(ee)
+ {
+ if(ee->iPriority >= e2->iPriority)break;
+ idx++;
+ ee = tmp.next();
+ }
+ tmp.insert(idx,e2);
+ }
+ }
+
+ for(KviOptionsWidgetInstanceEntry * e3 = tmp.last();e3;e3 = tmp.prev())
+ {
+ KviOptionsWidget * ow = getInstance(e3,e->pWidget->tabWidget());
+ e->pWidget->addOptionsWidget(e3->szName,*(g_pIconManager->getSmallIcon(e3->iIcon)),ow);
+ }
+ }
+ }
+ return e->pWidget;
+}
+
+KviOptionsWidgetInstanceEntry * KviOptionsInstanceManager::findInstanceEntry(const QObject * ptr,KviPointerList<KviOptionsWidgetInstanceEntry> * l)
+{
+ if(l)
+ {
+ for(KviOptionsWidgetInstanceEntry * e = l->first();e;e = l->next())
+ {
+ if(ptr == e->pWidget)return e;
+ if(e->pChildList)
+ {
+ KviOptionsWidgetInstanceEntry * e2 = findInstanceEntry(ptr,e->pChildList);
+ if(e2)return e2;
+ }
+ }
+ }
+ return 0;
+}
+
+KviOptionsWidgetInstanceEntry * KviOptionsInstanceManager::findInstanceEntry(const char * clName,KviPointerList<KviOptionsWidgetInstanceEntry> * l)
+{
+ if(l)
+ {
+ for(KviOptionsWidgetInstanceEntry * e = l->first();e;e = l->next())
+ {
+ if(kvi_strEqualCI(e->szClassName,clName))return e;
+ if(e->pChildList)
+ {
+ KviOptionsWidgetInstanceEntry * e2 = findInstanceEntry(clName,e->pChildList);
+ if(e2)return e2;
+ }
+ }
+ }
+ return 0;
+}
+
+KviOptionsWidgetInstanceEntry * KviOptionsInstanceManager::findInstanceEntry(const char * clName)
+{
+ return findInstanceEntry(clName,m_pInstanceTree);
+}
+
+
+#include "m_instances.moc"
+
+EOF
+######################################################################################################
+
diff --git a/src/modules/options/optw_antispam.cpp b/src/modules/options/optw_antispam.cpp
new file mode 100644
index 00000000..ba8180e6
--- /dev/null
+++ b/src/modules/options/optw_antispam.cpp
@@ -0,0 +1,64 @@
+//
+// File : optw_antispam.cpp
+// Creation date : Tue Oct 16 15:47:02 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 "optw_antispam.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+#include <qlabel.h>
+
+
+
+KviAntispamOptionsWidget::KviAntispamOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"antispam_options_widget")
+{
+ createLayout(3,1);
+
+ KviTalGroupBox *g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Enable Anti-spam For","options"));
+ m_b1 = addBoolSelector(g,__tr2qs_ctx("Private messages","options"),KviOption_boolUseAntiSpamOnPrivmsg);
+ connect(m_b1,SIGNAL(toggled(bool)),this,SLOT(reenableStuff(bool)));
+ m_b2 = addBoolSelector(g,__tr2qs_ctx("Private notices","options"),KviOption_boolUseAntiSpamOnNotice);
+ connect(m_b2,SIGNAL(toggled(bool)),this,SLOT(reenableStuff(bool)));
+
+ m_b3 = addBoolSelector(0,1,0,1,__tr2qs_ctx("Silent anti-spam (no warnings)","options"),KviOption_boolSilentAntiSpam);
+ m_sl = addStringListSelector(0,2,0,2,__tr2qs_ctx("Words considered spam:","options"),KviOption_stringlistSpamWords);
+
+ reenableStuff(true);
+
+ layout()->setRowStretch(2,1);
+}
+
+KviAntispamOptionsWidget::~KviAntispamOptionsWidget()
+{
+}
+
+void KviAntispamOptionsWidget::reenableStuff(bool)
+{
+ m_b3->setEnabled(m_b1->isChecked() || m_b2->isChecked());
+ m_sl->setEnabled(m_b1->isChecked() || m_b2->isChecked());
+}
+
+
+#include "m_optw_antispam.moc"
diff --git a/src/modules/options/optw_antispam.h b/src/modules/options/optw_antispam.h
new file mode 100644
index 00000000..28e51b41
--- /dev/null
+++ b/src/modules/options/optw_antispam.h
@@ -0,0 +1,47 @@
+#ifndef _OPTW_ANTISPAM_H_
+#define _OPTW_ANTISPAM_H_
+//
+// File : optw_antispam.h
+// Creation date : Tue Oct 16 15:47:03 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviAntispamOptionsWidget KVI_SMALLICON_SPAM
+#define KVI_OPTIONS_WIDGET_NAME_KviAntispamOptionsWidget __tr2qs_no_lookup("Anti-spam")
+#define KVI_OPTIONS_WIDGET_PARENT_KviAntispamOptionsWidget KviProtectionOptionsWidget
+
+class KviAntispamOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviAntispamOptionsWidget(QWidget * parent);
+ ~KviAntispamOptionsWidget();
+protected:
+ KviBoolSelector * m_b1;
+ KviBoolSelector * m_b2;
+ KviBoolSelector * m_b3;
+ KviStringListSelector * m_sl;
+protected slots:
+ void reenableStuff(bool);
+};
+
+
+#endif //_OPTW_ANTISPAM_H_
diff --git a/src/modules/options/optw_avatar.cpp b/src/modules/options/optw_avatar.cpp
new file mode 100644
index 00000000..f93631fd
--- /dev/null
+++ b/src/modules/options/optw_avatar.cpp
@@ -0,0 +1,131 @@
+//=============================================================================
+//
+// File : optw_avatar.cpp
+// Creation date : Wed Nov 19 09:25:16 2005 GMT by Grifisx & Noldor
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2003-2006 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 "optw_avatar.h"
+
+#include "kvi_locale.h"
+#include "kvi_selectors.h"
+#include "kvi_options.h"
+
+#include "kvi_tal_tooltip.h"
+
+KviAvatarAdvancedOptionsWidget::KviAvatarAdvancedOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"avatar_advanced_options_widget")
+{
+ createLayout(4,1);
+ // AVATAR
+
+ // 1st Box
+ KviTalGroupBox *g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Scaling in userlist","options"));
+ KviBoolSelector *b = addBoolSelector(g,__tr2qs_ctx("Scale avatar images in userlist (recommended)","options"),KviOption_boolScaleAvatars);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(b,__tr2qs_ctx("<center>This option will force KVIrc to scale avatars" \
+ " shown in the userlist.<br>" \
+ "Avatars will be scaled to fit the " \
+ "constraints set below. Better keep this option on. :)</center>","options"));
+#endif
+ addBoolSelector(g,__tr2qs_ctx("Do not scale avatar if it is less than required size","options"),KviOption_boolDoNotStretchAvatars);
+
+ KviUIntSelector *u = addUIntSelector(g,__tr2qs_ctx("Image width:","options"),KviOption_uintAvatarScaleWidth,0,512,80,KVI_OPTION_BOOL(KviOption_boolScaleAvatars));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+ u = addUIntSelector(g,__tr2qs_ctx("Image height:","options"),KviOption_uintAvatarScaleHeight,0,512,80,KVI_OPTION_BOOL(KviOption_boolScaleAvatars));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ //2nd
+ g = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Scaling on load (and in user tooltips)","options"));
+ b = addBoolSelector(g,__tr2qs_ctx("Scale avatar images on image load","options"),KviOption_boolScaleAvatarsOnLoad);
+
+ u = addUIntSelector(g,__tr2qs_ctx("Image width:","options"),KviOption_uintScaleAvatarsOnLoadWidth,0,1280,80,KVI_OPTION_BOOL(KviOption_boolScaleAvatarsOnLoad));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+ u = addUIntSelector(g,__tr2qs_ctx("Image height:","options"),KviOption_uintScaleAvatarsOnLoadHeight,0,1280,80,KVI_OPTION_BOOL(KviOption_boolScaleAvatarsOnLoad));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ // 2st Box
+ KviTalGroupBox *gs = addGroupBox(0,2,0,2,1,Qt::Horizontal,__tr2qs_ctx("Request CTCP","options"));
+ KviBoolSelector * bs = addBoolSelector(g,__tr2qs_ctx("Request missing avatars","options"),KviOption_boolRequestMissingAvatars);
+ KviUIntSelector * us = addUIntSelector(g,__tr2qs_ctx("Maximum requested file size:","options"),KviOption_uintMaximumRequestedAvatarSize,0,1048576,102400,KVI_OPTION_BOOL(KviOption_boolRequestMissingAvatars));
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(bs,
+ __tr2qs_ctx("<center>This option will cause KVIrc to send a DCC GET request " \
+ "when someone sets an avatar and there is no cached copy available.</center>","options"));
+#endif
+ us->setSuffix(__tr2qs_ctx(" bytes","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(us,
+ __tr2qs_ctx("<center>This is the maximum size for avatar images that " \
+ "will be automatically requested.<br>" \
+ "A reasonable value might be 102400 bytes (100 K).</center>","options"));
+#endif
+ connect(bs,SIGNAL(toggled(bool)),us,SLOT(setEnabled(bool)));
+
+ bs = addBoolSelector(gs,__tr2qs_ctx("Automatically accept incoming avatars","options"),KviOption_boolAutoAcceptIncomingAvatars);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(
+ bs,
+ __tr2qs_ctx("<center>This option will cause KVIrc to auto-accept " \
+ "DCC SEND requests for incoming avatars.<br>" \
+ "If you're using the \"Request missing avatars\" option " \
+ "above, enabling this may by useful.<br>" \
+ "Avatars will be saved in the local KVIrc directory.</center>","options"));
+#endif
+
+ bs = addBoolSelector(gs,__tr2qs_ctx("Remember avatars for registered users","options"),KviOption_boolSetLastAvatarAsDefaultForRegisteredUsers);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(
+ bs,
+ __tr2qs_ctx("<center>Use a user's last known avatar by default " \
+ "(only for users that are registered).</center>","options"));
+#endif
+
+ us = addUIntSelector(gs,__tr2qs_ctx("Avatar offer timeout:","options"),KviOption_uintAvatarOfferTimeoutInSecs,1,99999,60);
+ us->setSuffix(__tr2qs_ctx(" sec","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(us,
+ __tr2qs_ctx("<center>This is the amount of time to make an avatar available for transfer when requested.<br>" \
+ "When someone sends a CTCP AVATAR request, " \
+ "KVIrc will reply with a CTCP AVATAR message containing the name and size " \
+ "of your avatar image.<br>" \
+ "A time-limited file offer is added for the image file " \
+ "to the requesting user.</center>","options"));
+#endif
+
+ bs = addBoolSelector(gs,__tr2qs_ctx("Ignore requests if no avatar is set","options"),KviOption_boolIgnoreChannelAvatarRequestsWhenNoAvatarSet);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(bs,
+ __tr2qs_ctx("This option will cause KVIrc to ignore channel CTCP AVATAR requests " \
+ "when you have no avatar set. This is usually a good practice since " \
+ "it helps in reducing traffic by not sending a reply that would be empty.","options"));
+#endif
+
+ addRowSpacer(0,3,0,3);
+}
+
+KviAvatarAdvancedOptionsWidget::~KviAvatarAdvancedOptionsWidget()
+{
+}
+
+
+#include "m_optw_avatar.moc"
diff --git a/src/modules/options/optw_avatar.h b/src/modules/options/optw_avatar.h
new file mode 100644
index 00000000..2235a659
--- /dev/null
+++ b/src/modules/options/optw_avatar.h
@@ -0,0 +1,45 @@
+#ifndef _OPTW_AVATAR_H_
+#define _OPTW_AVATAR_H_
+
+//=============================================================================
+//
+// File : optw_avatar.cpp
+// Creation date : Wed Nov 19 09:25:16 2005 GMT by Grifisx & Noldor
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2003 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_optionswidget.h"
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviAvatarAdvancedOptionsWidget KVI_SMALLICON_AVATAR
+#define KVI_OPTIONS_WIDGET_NAME_KviAvatarAdvancedOptionsWidget __tr2qs_no_lookup("Avatars")
+#define KVI_OPTIONS_WIDGET_PARENT_KviAvatarAdvancedOptionsWidget KviToolsOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviAvatarAdvancedOptionsWidget 9
+#define KVI_OPTIONS_WIDGET_MINIMAL_USER_EXPERIENCE_LEVEL_KviAvatarAdvancedOptionsWidget 2
+
+class KviAvatarAdvancedOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviAvatarAdvancedOptionsWidget(QWidget * parent);
+ ~KviAvatarAdvancedOptionsWidget();
+};
+
+#endif //!_OPTW_AVATAR_H_
diff --git a/src/modules/options/optw_away.cpp b/src/modules/options/optw_away.cpp
new file mode 100644
index 00000000..151b8446
--- /dev/null
+++ b/src/modules/options/optw_away.cpp
@@ -0,0 +1,71 @@
+//
+// File : optw_away.cpp
+// Creation date : Mon Oct 29 15:37:16 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 "optw_away.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+//#warning "Info tips"
+
+
+KviAwayOptionsWidget::KviAwayOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"away_options_widget")
+{
+ createLayout(4,1);
+
+ addStringSelector(0,0,0,0, __tr2qs_ctx("Default away message:","options"), KviOption_stringAwayMessage);
+
+ addBoolSelector(0,1,0,1, __tr2qs_ctx("User input exits away mode","options"), KviOption_boolExitAwayOnInput);
+
+ KviTalGroupBox *g = addGroupBox(0,2,0,2,1,Qt::Horizontal,__tr2qs_ctx("Away Nickname","options"));
+ m_pEnableAwayNick = addBoolSelector(g,__tr2qs_ctx("Change nickname on away","options"),KviOption_boolChangeNickAway);
+ connect(m_pEnableAwayNick,SIGNAL(toggled(bool)),this,SLOT(enableCustomAwayText(bool)));
+
+ m_pEnableCustomAwayNick = addBoolSelector(g,__tr2qs_ctx("Use automatic nickname ([5 letters]AWAY)","options"),KviOption_boolAutoGeneratedAwayNick,KVI_OPTION_BOOL(KviOption_boolChangeNickAway));
+ connect(m_pEnableAwayNick,SIGNAL(toggled(bool)),m_pEnableCustomAwayNick,SLOT(setEnabled(bool)));
+ connect(m_pEnableCustomAwayNick,SIGNAL(toggled(bool)),this,SLOT(enableCustomAwayText(bool)));
+
+ // m_p <-- stands for pointer
+ // m_sz <-- stands for a string :)
+// m_szCustomAwayNick = addStringSelector(0,4,0,4,__tr2qs_ctx("Custom away nick","options"),KviOption_stringCustomAwayNick,KVI_OPTION_BOOL(KviOption_boolChangeNickAway) && !(KVI_OPTION_BOOL(KviOption_boolAutoGeneratedAwayNick)));
+
+ m_pCustomAwayNick = addStringSelector(g,__tr2qs_ctx("Custom nickname (%%nick%% means a current nick):","options"),KviOption_stringCustomAwayNick,KVI_OPTION_BOOL(KviOption_boolChangeNickAway) && !(KVI_OPTION_BOOL(KviOption_boolAutoGeneratedAwayNick)));
+
+ addRowSpacer(0,3,0,3);
+}
+
+KviAwayOptionsWidget::~KviAwayOptionsWidget()
+{
+}
+
+void KviAwayOptionsWidget::enableCustomAwayText(bool)
+{
+ m_pCustomAwayNick->setEnabled(m_pEnableAwayNick->isChecked() && !(m_pEnableCustomAwayNick->isChecked()));
+
+}
+
+
+#include "m_optw_away.moc"
diff --git a/src/modules/options/optw_away.h b/src/modules/options/optw_away.h
new file mode 100644
index 00000000..e8892faa
--- /dev/null
+++ b/src/modules/options/optw_away.h
@@ -0,0 +1,46 @@
+#ifndef _OPTW_AWAY_H_
+#define _OPTW_AWAY_H_
+//
+// File : optw_away.h
+// Creation date : Mon Oct 29 15:37:18 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviAwayOptionsWidget KVI_SMALLICON_AWAY
+#define KVI_OPTIONS_WIDGET_NAME_KviAwayOptionsWidget __tr2qs_no_lookup("Away")
+#define KVI_OPTIONS_WIDGET_PARENT_KviAwayOptionsWidget KviToolsOptionsWidget
+
+class KviAwayOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviAwayOptionsWidget(QWidget * parent);
+ ~KviAwayOptionsWidget();
+protected:
+ KviBoolSelector * m_pEnableAwayNick;
+ KviBoolSelector * m_pEnableCustomAwayNick;
+ KviStringSelector * m_pCustomAwayNick;
+public slots:
+ void enableCustomAwayText(bool);
+
+};
+
+#endif //_OPTW_AWAY_H_
diff --git a/src/modules/options/optw_connection.cpp b/src/modules/options/optw_connection.cpp
new file mode 100644
index 00000000..608b47bd
--- /dev/null
+++ b/src/modules/options/optw_connection.cpp
@@ -0,0 +1,321 @@
+//=============================================================================
+//
+// File : optw_connection.cpp
+// Creation date : Sat Nov 24 04:25:16 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 "optw_connection.h"
+
+#include "kvi_settings.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_iconmanager.h"
+#include <qradiobutton.h>
+
+
+KviConnectionOptionsWidget::KviConnectionOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"connection_options_widget")
+{
+
+ createLayout(2,1);
+ KviTalGroupBox *gbox = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("On Disconnect","options"));
+
+
+ KviBoolSelector *b1 = addBoolSelector(gbox,__tr2qs_ctx("Keep channels open","options"),KviOption_boolKeepChannelsOpenOnDisconnect,true);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b1,__tr2qs_ctx("<center>This option will cause KVIrc to keep channels open after disconnect.</center>","options"));
+#endif
+
+ b1 = addBoolSelector(gbox,__tr2qs_ctx("Keep queries open","options"),KviOption_boolKeepQueriesOpenOnDisconnect,true);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b1,__tr2qs_ctx("<center>This option will cause KVIrc to keep queries open after disconnect.</center>","options"));
+#endif
+
+ gbox = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("On Unexpected Disconnect","options"));
+
+
+ b1 = addBoolSelector(gbox,__tr2qs_ctx("Keep channels open","options"),KviOption_boolKeepChannelsOpenOnUnexpectedDisconnect,true);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b1,__tr2qs_ctx("<center>This option will cause KVIrc to keep channels open after an unexpected disconnect.</center>","options"));
+#endif
+
+ b1 = addBoolSelector(gbox,__tr2qs_ctx("Keep queries open","options"),KviOption_boolKeepQueriesOpenOnUnexpectedDisconnect,true);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b1,__tr2qs_ctx("<center>This option will cause KVIrc to keep queries open after an unexpected disconnect.</center>","options"));
+#endif
+
+ b1 = addBoolSelector(gbox,__tr2qs_ctx("Rejoin channels after reconnect","options"),KviOption_boolRejoinChannelsAfterReconnect,KVI_OPTION_BOOL(KviOption_boolAutoReconnectOnUnexpectedDisconnect));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b1,__tr2qs_ctx("<center>This option will cause KVIrc to rejoin channels after a successful reconnect attempt.</center>","options"));
+#endif
+ b1 = addBoolSelector(gbox,__tr2qs_ctx("Reopen queries after reconnect","options"),KviOption_boolReopenQueriesAfterReconnect,KVI_OPTION_BOOL(KviOption_boolAutoReconnectOnUnexpectedDisconnect));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b1,__tr2qs_ctx("<center>This option will cause KVIrc to reopen query windows after a successful reconnect attempt.</center>","options"));
+#endif
+
+// gbox = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("On Unexpected Disconnect","options"));
+ KviBoolSelector * b = addBoolSelector(gbox,__tr2qs_ctx("Automatically reconnect","options"),KviOption_boolAutoReconnectOnUnexpectedDisconnect);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>This option will enable auto-reconnecting after an unexpected disconnect. " \
+ "An unexpected disconnect is the <b>termination</b> of a <b>fully connected IRC session</b> " \
+ "that was <b>not requested by the user</b> by the means of the QUIT message." \
+ "<p><b>Warning:</b> If you use /RAW to send a QUIT message to the server, " \
+ "this option will not behave correctly, since does not detect the outgoing " \
+ "QUIT message and will attempt to reconnect after the server has closed the connection. " \
+ "For this reason, always use the /QUIT command to close your connections. " \
+ "This option may also behave incorrectly with bouncers that support " \
+ "detaching, in this case a solution could be to prepare an alias that sends the " \
+ "bouncer \"detach\" command immediately before the \"quit\" command.<br>" \
+ "<tt>alias(bncdetach){ raw bouncer detach; quit; }</tt></p></center>","options"));
+#endif
+ KviUIntSelector * u = addUIntSelector(gbox,__tr2qs_ctx("Maximum attempts (0: unlimited):","options"),
+ KviOption_uintMaxAutoReconnectAttempts,0,100,5,
+ KVI_OPTION_BOOL(KviOption_boolAutoReconnectOnUnexpectedDisconnect));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ u = addUIntSelector(gbox,__tr2qs_ctx("Delay between attempts:","options"),
+ KviOption_uintAutoReconnectDelay,0,86400,5,
+ KVI_OPTION_BOOL(KviOption_boolAutoReconnectOnUnexpectedDisconnect));
+ u->setSuffix(__tr2qs_ctx(" sec","options"));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(u,__tr2qs_ctx("<center>Minimum value: <b>0 sec</b><br>Maximum value: <b>86400 sec</b></center>","options"));
+#endif
+
+
+
+
+ addRowSpacer(0,2,4,2);
+}
+
+
+KviConnectionOptionsWidget::~KviConnectionOptionsWidget()
+{
+}
+
+
+
+
+KviSSLOptionsWidget::KviSSLOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ssl_options_widget")
+{
+#ifdef COMPILE_SSL_SUPPORT
+ createLayout(3,1);
+
+ KviTalGroupBox * gbox = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Certificate","options"));
+
+ KviBoolSelector * b = addBoolSelector(gbox,__tr2qs_ctx("Use SSL certificate (PEM format only)","options"),
+ &(KVI_OPTION_BOOL(KviOption_boolUseSSLCertificate)),true);
+ KviFileSelector * f = addFileSelector(gbox,__tr2qs_ctx("Certificate location:","options"),
+ &(KVI_OPTION_STRING(KviOption_stringSSLCertificatePath)),KVI_OPTION_BOOL(KviOption_boolUseSSLCertificate));
+ connect(b,SIGNAL(toggled(bool)),f,SLOT(setEnabled(bool)));
+ KviPasswordSelector * p = new KviPasswordSelector(gbox,__tr2qs_ctx("Certificate password:","options"),
+ &(KVI_OPTION_STRING(KviOption_stringSSLCertificatePass)),KVI_OPTION_BOOL(KviOption_boolUseSSLCertificate));
+ connect(b,SIGNAL(toggled(bool)),p,SLOT(setEnabled(bool)));
+
+ gbox = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Private Key","options"));
+ b = addBoolSelector(gbox,__tr2qs_ctx("Use SSL private key","options"),
+ &(KVI_OPTION_BOOL(KviOption_boolUseSSLPrivateKey)),true);
+ f = addFileSelector(gbox,__tr2qs_ctx("Private key location:","options"),
+ &(KVI_OPTION_STRING(KviOption_stringSSLPrivateKeyPath)),KVI_OPTION_BOOL(KviOption_boolUseSSLPrivateKey));
+ connect(b,SIGNAL(toggled(bool)),f,SLOT(setEnabled(bool)));
+ p = addPasswordSelector(gbox,__tr2qs_ctx("Private key password:","options"),
+ &(KVI_OPTION_STRING(KviOption_stringSSLPrivateKeyPass)),KVI_OPTION_BOOL(KviOption_boolUseSSLPrivateKey));
+ connect(b,SIGNAL(toggled(bool)),p,SLOT(setEnabled(bool)));
+ addRowSpacer(0,2,0,2);
+#else
+ createLayout(1,1);
+ addLabel(0,0,0,0,__tr2qs_ctx("This executable has no SSL support.","options"));
+#endif
+}
+
+KviSSLOptionsWidget::~KviSSLOptionsWidget()
+{
+}
+
+
+
+
+
+
+KviTransportOptionsWidget::KviTransportOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"transport_options_widget")
+{
+ createLayout(5,1);
+ KviUIntSelector * u;
+
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Timeout Values","options"),this);
+ u = addUIntSelector(g,__tr2qs_ctx("Connect timeout:","options"),KviOption_uintIrcSocketTimeout,5,6000,60);
+ u->setSuffix(__tr2qs_ctx(" sec","options"));
+ u = addUIntSelector(g,__tr2qs_ctx("Outgoing data queue flush timeout:","options"),KviOption_uintSocketQueueFlushTimeout,100,2000,500);
+ u->setSuffix(__tr2qs_ctx(" msec","options"));
+ KviBoolSelector * b = addBoolSelector(0,1,0,1,__tr2qs_ctx("Limit outgoing traffic","options"),KviOption_boolLimitOutgoingTraffic);
+ u = addUIntSelector(0,2,0,2,__tr2qs_ctx("Limit to 1 message every:","options"),
+ KviOption_uintOutgoingTrafficLimitUSeconds,10000,2000000,10000000,KVI_OPTION_BOOL(KviOption_boolLimitOutgoingTraffic));
+ u->setSuffix(__tr2qs_ctx(" usec","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(u,__tr2qs_ctx("<center>Minimum value: <b>10000 usec</b><br>Maximum value: <b>10000000 usec</b></center>","options"));
+#endif
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ g = addGroupBox(0,3,0,3,2,Qt::Horizontal,__tr2qs_ctx("Network Interfaces","options"));
+
+ b = addBoolSelector(g,__tr2qs_ctx("Bind IPv4 connections to:","options"),KviOption_boolBindIrcIpV4ConnectionsToSpecifiedAddress);
+ KviStringSelector * s = addStringSelector(g,"",KviOption_stringIpV4ConnectionBindAddress,KVI_OPTION_BOOL(KviOption_boolBindIrcIpV4ConnectionsToSpecifiedAddress));
+ connect(b,SIGNAL(toggled(bool)),s,SLOT(setEnabled(bool)));
+#ifdef COMPILE_IPV6_SUPPORT
+ b = addBoolSelector(g,__tr2qs_ctx("Bind IPv6 connections to:","options"),KviOption_boolBindIrcIpV6ConnectionsToSpecifiedAddress);
+ s = addStringSelector(g,"",KviOption_stringIpV6ConnectionBindAddress,KVI_OPTION_BOOL(KviOption_boolBindIrcIpV6ConnectionsToSpecifiedAddress));
+ connect(b,SIGNAL(toggled(bool)),s,SLOT(setEnabled(bool)));
+#endif //!COMPILE_IPV6_SUPPORT
+
+ addRowSpacer(0,4,0,4);
+}
+
+KviTransportOptionsWidget::~KviTransportOptionsWidget()
+{
+}
+
+
+
+
+
+
+
+
+
+KviIdentOptionsWidget::KviIdentOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ident_options_widget")
+{
+ createLayout(6,1);
+
+ m_pEnableIdent = addBoolSelector(0,0,0,0,__tr2qs_ctx("Enable ident service (bad practice on UNIX!)","options"),KviOption_boolUseIdentService);
+ connect(m_pEnableIdent,SIGNAL(toggled(bool)),this,SLOT(enableIpv4InIpv6(bool)));
+
+ KviTalGroupBox * gbox = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Output verbosity","options"),KVI_OPTION_BOOL(KviOption_boolUseIdentService));
+ connect(m_pEnableIdent,SIGNAL(toggled(bool)),gbox,SLOT(setEnabled(bool)));
+
+ addLabel(gbox,__tr2qs_ctx("Output identd messages to:","options"));
+
+ m_pActiveRadio = new QRadioButton(__tr2qs_ctx("Active window","options"),gbox);
+ m_pConsoleRadio = new QRadioButton(__tr2qs_ctx("Console","options"),gbox);
+ m_pQuietRadio = new QRadioButton(__tr2qs_ctx("Do not show any identd messages","options"),gbox);
+
+ switch(KVI_OPTION_UINT(KviOption_uintIdentdOutputMode))
+ {
+ case KviIdentdOutputMode::Quiet :
+ m_pQuietRadio->setChecked(true);
+ break;
+ case KviIdentdOutputMode::ToConsole :
+ m_pConsoleRadio->setChecked(true);
+ break;
+ case KviIdentdOutputMode::ToActiveWindow :
+ m_pActiveRadio->setChecked(true);
+ break;
+ }
+
+ gbox = addGroupBox(0,2,0,2,1,Qt::Horizontal,__tr2qs_ctx("Configuration","options"),KVI_OPTION_BOOL(KviOption_boolUseIdentService));
+
+ KviBoolSelector *b = addBoolSelector(gbox,__tr2qs_ctx("Enable ident service only while connecting to server","options"),KviOption_boolUseIdentServiceOnlyOnConnect);
+ connect(m_pEnableIdent,SIGNAL(toggled(bool)),b,SLOT(setEnabled(bool)));
+
+ KviStringSelector * s = addStringSelector(gbox,__tr2qs_ctx("Ident username:","options"),
+ KviOption_stringIdentdUser,KVI_OPTION_BOOL(KviOption_boolUseIdentService));
+
+ KviUIntSelector * u = addUIntSelector(gbox,__tr2qs_ctx("Service port:","options"),
+ KviOption_uintIdentdPort,0,65535,113,KVI_OPTION_BOOL(KviOption_boolUseIdentService));
+ connect(m_pEnableIdent,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+ connect(m_pEnableIdent,SIGNAL(toggled(bool)),gbox,SLOT(setEnabled(bool)));
+
+ gbox = addGroupBox(0,3,0,3,1,Qt::Horizontal,__tr2qs_ctx("IPv6 Settings","options"),KVI_OPTION_BOOL(KviOption_boolUseIdentService));
+ m_pEnableIpv6 = addBoolSelector(gbox,__tr2qs_ctx("Enable service for IPv6","options"),
+ KviOption_boolIdentdEnableIpV6,
+ KVI_OPTION_BOOL(KviOption_boolUseIdentService));
+#ifdef COMPILE_IPV6_SUPPORT
+ connect(m_pEnableIdent,SIGNAL(toggled(bool)),m_pEnableIpv6,SLOT(setEnabled(bool)));
+ connect(m_pEnableIpv6,SIGNAL(toggled(bool)),this,SLOT(enableIpv4InIpv6(bool)));
+#else
+ m_pEnableIpv6->setEnabled(false);
+#endif
+ m_pIpv4InIpv6 = addBoolSelector(gbox,__tr2qs_ctx("IP stack treats IPv4 as part of IPv6 namespace","options"),
+ KviOption_boolIdentdIpV6ContainsIpV4,
+ KVI_OPTION_BOOL(KviOption_boolUseIdentService) && KVI_OPTION_BOOL(KviOption_boolIdentdEnableIpV6));
+ connect(m_pEnableIdent,SIGNAL(toggled(bool)),gbox,SLOT(setEnabled(bool)));
+
+ addLabel(0,4,0,4,
+#ifdef COMPILE_ON_WINDOWS
+ __tr2qs_ctx("<p><b>Warning:</b><br>" \
+ "This is a <b>non RFC 1413 compliant</b> ident daemon that implements " \
+ "only a limited subset of the Identification Protocol specifications. If it is possible, install a " \
+ "real ident daemon.</p>","options")
+#else
+ __tr2qs_ctx("<p><b>Warning:</b><br>" \
+ "This is a <b>non RFC 1413 compliant</b> ident daemon that implements " \
+ "only a limited subset of the Identification Protocol specifications.<br>" \
+ "On UNIX, you may also need root privileges to bind to the auth port (113).<br>" \
+ "It is <b>highly recommended</b> that a <b>real</b> system-wide ident daemon be used instead, "\
+ "or none at all if ident is not required.</p>","options")
+#endif
+ );
+
+ addRowSpacer(0,5,0,5);
+}
+
+KviIdentOptionsWidget::~KviIdentOptionsWidget()
+{
+}
+
+void KviIdentOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+ if(m_pConsoleRadio->isOn())
+ KVI_OPTION_UINT(KviOption_uintIdentdOutputMode)=KviIdentdOutputMode::ToConsole;
+ if(m_pActiveRadio->isOn())
+ KVI_OPTION_UINT(KviOption_uintIdentdOutputMode)=KviIdentdOutputMode::ToActiveWindow;
+ if(m_pQuietRadio->isOn())
+ KVI_OPTION_UINT(KviOption_uintIdentdOutputMode)=KviIdentdOutputMode::Quiet;
+}
+
+void KviIdentOptionsWidget::enableIpv4InIpv6(bool)
+{
+#ifdef COMPILE_IPV6_SUPPORT
+ m_pIpv4InIpv6->setEnabled(m_pEnableIdent->isChecked() && m_pEnableIpv6->isChecked());
+#endif
+}
+
+
+
+
+
+
+
+KviConnectionAdvancedOptionsWidget::KviConnectionAdvancedOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"connection_advanced_options_widget")
+{
+
+}
+
+KviConnectionAdvancedOptionsWidget::~KviConnectionAdvancedOptionsWidget()
+{
+
+}
+
+#include "m_optw_connection.moc"
diff --git a/src/modules/options/optw_connection.h b/src/modules/options/optw_connection.h
new file mode 100644
index 00000000..189ee4a0
--- /dev/null
+++ b/src/modules/options/optw_connection.h
@@ -0,0 +1,116 @@
+#ifndef _OPTW_CONNECTION_H_
+#define _OPTW_CONNECTION_H_
+//
+// File : optw_connection.h
+// Creation date : Sat Nov 24 04:25:12 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2006 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviConnectionOptionsWidget KVI_SMALLICON_WORLD
+#define KVI_OPTIONS_WIDGET_NAME_KviConnectionOptionsWidget __tr2qs_no_lookup("Connection")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviConnectionOptionsWidget 98000
+
+class KviConnectionOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviConnectionOptionsWidget(QWidget * parent);
+ ~KviConnectionOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviConnectionAdvancedOptionsWidget KVI_SMALLICON_WORLD
+#define KVI_OPTIONS_WIDGET_NAME_KviConnectionAdvancedOptionsWidget __tr2qs_no_lookup("Advanced")
+#define KVI_OPTIONS_WIDGET_PARENT_KviConnectionAdvancedOptionsWidget KviConnectionOptionsWidget
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviConnectionAdvancedOptionsWidget true
+
+class KviConnectionAdvancedOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviConnectionAdvancedOptionsWidget(QWidget * parent);
+ ~KviConnectionAdvancedOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviSSLOptionsWidget KVI_SMALLICON_SSL
+#define KVI_OPTIONS_WIDGET_NAME_KviSSLOptionsWidget __tr2qs_no_lookup("SSL")
+#define KVI_OPTIONS_WIDGET_PARENT_KviSSLOptionsWidget KviConnectionAdvancedOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviSSLOptionsWidget 30
+
+
+
+class KviSSLOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviSSLOptionsWidget(QWidget * parent);
+ ~KviSSLOptionsWidget();
+};
+
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTransportOptionsWidget KVI_SMALLICON_SOCKETERROR
+#define KVI_OPTIONS_WIDGET_NAME_KviTransportOptionsWidget __tr2qs_no_lookup("Socket")
+#define KVI_OPTIONS_WIDGET_PARENT_KviTransportOptionsWidget KviConnectionAdvancedOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviTransportOptionsWidget 20
+
+
+class KviTransportOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTransportOptionsWidget(QWidget * parent);
+ ~KviTransportOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIdentOptionsWidget KVI_SMALLICON_IDENT
+#define KVI_OPTIONS_WIDGET_NAME_KviIdentOptionsWidget __tr2qs_no_lookup("Ident Service")
+#define KVI_OPTIONS_WIDGET_PARENT_KviIdentOptionsWidget KviConnectionAdvancedOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIdentOptionsWidget 10
+
+class QRadioButton;
+
+class KviIdentOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIdentOptionsWidget(QWidget * parent);
+ ~KviIdentOptionsWidget();
+
+ virtual void commit();
+protected:
+ KviBoolSelector * m_pEnableIdent;
+ KviBoolSelector * m_pEnableIpv6;
+ KviBoolSelector * m_pIpv4InIpv6;
+
+ QRadioButton *m_pConsoleRadio;
+ QRadioButton *m_pActiveRadio;
+ QRadioButton *m_pQuietRadio;
+public slots:
+ void enableIpv4InIpv6(bool);
+};
+
+
+
+
+#endif //_OPTW_CONNECTION_H_
diff --git a/src/modules/options/optw_ctcp.cpp b/src/modules/options/optw_ctcp.cpp
new file mode 100644
index 00000000..3913751e
--- /dev/null
+++ b/src/modules/options/optw_ctcp.cpp
@@ -0,0 +1,90 @@
+//
+// File : optw_ctcp.cpp
+// Creation date : Sun Dec 2 20:40:43 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 "optw_ctcp.h"
+
+#include "kvi_settings.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+
+//#ifdef COMPILE_INFO_TIPS
+// #include "kvi_tal_tooltip.h"
+//#endif
+
+KviCtcpOptionsWidget::KviCtcpOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ctcp_options_widget")
+{
+
+ createLayout(4,1);
+
+ QLabel * l;
+ l = addLabel(0,0,0,0,__tr2qs_ctx("<center><b>Settings for CTCP.</b></center>"\
+ "<p>The <b>Client-To-Client Protocol</b> (CTCP) " \
+ "is used to transmit special control messages over an IRC connection. " \
+ "These messages can request information from clients or negotiate file transfers." \
+ "<br><br></p>","options"));
+
+
+ KviTalGroupBox *gs = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("CTCP Replies","options"));
+ KviStringSelector * s = addStringSelector(gs, __tr2qs_ctx("Append to VERSION reply:","options"),KviOption_stringCtcpVersionPostfix);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(s,
+ __tr2qs_ctx("<center>This text will be appended to the CTCP VERSION reply.<br>For example, you can place a script name here.</center>","options"));
+#endif
+
+ s = addStringSelector(gs, __tr2qs_ctx("Append to SOURCE reply:","options"),KviOption_stringCtcpSourcePostfix);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(s,
+ __tr2qs_ctx("<center>This text will be appended to the CTCP SOURCE reply.<br>For example, you can place the source URL for a script here.</center>","options"));
+#endif
+
+// s = addStringSelector(gs, __tr2qs_ctx("USERINFO reply:","options"),KviOption_stringCtcpUserinfoReply);
+
+//#ifdef COMPILE_INFO_TIPS
+// mergeTip(s,
+// __tr2qs_ctx("<center>This is the CTCP USERINFO reply.<br>It can contain some information about yourself.</center>","options"));
+//#endif
+
+ s = addStringSelector(gs, __tr2qs_ctx("PAGE reply:","options"),KviOption_stringCtcpPageReply);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(s,
+ __tr2qs_ctx("<center>This is the CTCP PAGE reply.<br>It should contain some sort of acknowledgement for CTCP PAGE messages.</center>","options"));
+#endif
+
+ addBoolSelector(gs,__tr2qs_ctx("Show the CTCP replies in the active window","options"),KviOption_boolCtcpRepliesToActiveWindow);
+
+ addBoolSelector(gs,__tr2qs_ctx("Show dialog for CTCP page requests","options"),KviOption_boolShowDialogOnCtcpPage);
+
+ addRowSpacer(0,3,0,3);
+
+}
+
+
+KviCtcpOptionsWidget::~KviCtcpOptionsWidget()
+{
+}
+
+
+#include "m_optw_ctcp.moc"
diff --git a/src/modules/options/optw_ctcp.h b/src/modules/options/optw_ctcp.h
new file mode 100644
index 00000000..55bdb238
--- /dev/null
+++ b/src/modules/options/optw_ctcp.h
@@ -0,0 +1,41 @@
+#ifndef _OPTW_CTCP_H_
+#define _OPTW_CTCP_H_
+//
+// File : optw_ctcp.h
+// Creation date : Sun Dec 2 20:40:43 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviCtcpOptionsWidget KVI_SMALLICON_CTCPREQUESTREPLIED
+#define KVI_OPTIONS_WIDGET_NAME_KviCtcpOptionsWidget __tr2qs_no_lookup("CTCP")
+#define KVI_OPTIONS_WIDGET_PARENT_KviCtcpOptionsWidget KviToolsOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviCtcpOptionsWidget 70000
+
+class KviCtcpOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviCtcpOptionsWidget(QWidget * parent);
+ ~KviCtcpOptionsWidget();
+};
+
+
+#endif //_OPTW_CTCP_H_
diff --git a/src/modules/options/optw_ctcpfloodprotection.cpp b/src/modules/options/optw_ctcpfloodprotection.cpp
new file mode 100644
index 00000000..f814858e
--- /dev/null
+++ b/src/modules/options/optw_ctcpfloodprotection.cpp
@@ -0,0 +1,116 @@
+//
+// File : optw_ctcpfloodprotection.cpp
+// Creation date : Sun Jan 21 2001 14:35:06 CEST 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 "optw_ctcpfloodprotection.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+#include <qlabel.h>
+
+/*
+ @doc: ctcpfloodprotectionoptions
+ @type:
+ widget
+ @title:
+ CTCP flood protection options
+ @short:
+ Protection against CTCP flooding
+ @keyterms:
+ ctcp flood
+ @body:
+ Here, you can configure the CTCP flood protection system.[br]
+ The CTCP engine in IRC clients may be subject to an attack, called "CTCP flooding".[br]
+ Basically, the attackers (usually there is more than one offending client) sends a stream
+ of CTCP requests to the victim's client, and the client attempts to respond to all requests
+ by sending a stream of replies to the server, which causes the server to disconnect the user
+ due to "excess flood" for sending too many messages before the server can process them.[br]
+ Many user defined scripts choose to completely ignore all the CTCP requests in order to prevent such attacks.[br]
+ KVIrc offers an alternative method that allows you to take advantage of the CTCP protocol
+ and at the same time prevent the flood attacks.[br]
+ The method is really simple: The client will only respond to a limited number of CTCP requests within a
+ specified time interval.[br]
+ The "Use flood protection" option enables this protection method.[br]
+ In the "Allowed up to" field you should enter the maximum number of CTCP requests that KVIrc should
+ respond to within the interval of time defined in the second field.[br]
+ A strong protection against floods would be replying to 4 requests every 20 seconds.[br]
+ The minimum effective setting is about 3 messages every 6 seconds.[br]
+ Please note that 3 messages every 6 seconds is NOT the same as 10 messages every 20 seconds;
+ the first setting would allow 3 requests within one second, but the client would
+ ignore all the requests for the next 5 seconds, the second setting would allow 10 messages within one second
+ and ignore everything for the next 19 seconds. Therefore, 3/6 is a safer setting.[br]
+ The maximum protection you can set is 0 messages within any number of seconds; in that case any
+ CTCP request will be considered a flood and ignored.[br]
+ [br][br]
+ You can also decide to ignore specific CTCP requests. For example, if you don't want to reply to PING
+ requests, just select "PING" under the "Ignored Requests" section.[br]
+ [br][br]
+ Some specific protection options can be set also in other CTCP options sections:
+ see the [widget:ctcpavatarprotooptions]CTCP AVATAR protocol options[/widget] and [widget:ctcpdccprotooptions]CTCP DCC protocol options[/widget].[br]
+*/
+
+
+KviCtcpFloodProtectionOptionsWidget::KviCtcpFloodProtectionOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ctcpfloodprotection_options_widget")
+{
+ createLayout(4,2);
+
+ KviBoolSelector * b = addBoolSelector(0,0,1,0,__tr2qs_ctx("Use flood protection (recommended)","options"),KviOption_boolUseCtcpFloodProtection);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>This option makes KVIrc only respond to a limited number of CTCP requests within a specified time interval, to prevent \"flooding\" CTCP messages.</center>","options"));
+#endif
+ KviUIntSelector * u = addUIntSelector(0,1,0,1,__tr2qs_ctx("Allow up to:","options"),KviOption_uintMaxCtcpRequests,0,10000,3,KVI_OPTION_BOOL(KviOption_boolUseCtcpFloodProtection));
+ u->setSuffix(__tr2qs_ctx(" requests","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(u,__tr2qs_ctx("<center>Minimum value: <b>0 requests</b><br>Maximum value: <b>10000 requests</b></center>","options"));
+#endif
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+ u = addUIntSelector(1,1,1,1,__tr2qs_ctx("within:","options"),KviOption_uintCtcpFloodCheckInterval,1,3600,6,KVI_OPTION_BOOL(KviOption_boolUseCtcpFloodProtection));
+ u->setSuffix(__tr2qs_ctx(" sec","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(u,__tr2qs_ctx("<center>Minimum value: <b>1 sec</b><br>Maximum value: <b>3600 sec</b></center>","options"));
+#endif
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ KviTalGroupBox * g = addGroupBox(0,2,1,2,2,Qt::Horizontal,__tr2qs_ctx("Ignored Requests","options"));
+ addBoolSelector(g,__tr2qs_ctx("PING","options"),KviOption_boolIgnoreCtcpPing);
+ addBoolSelector(g,__tr2qs_ctx("FINGER","options"),KviOption_boolIgnoreCtcpFinger);
+ addBoolSelector(g,__tr2qs_ctx("CLIENTINFO","options"),KviOption_boolIgnoreCtcpClientinfo);
+ addBoolSelector(g,__tr2qs_ctx("USERINFO","options"),KviOption_boolIgnoreCtcpUserinfo);
+ addBoolSelector(g,__tr2qs_ctx("VERSION","options"),KviOption_boolIgnoreCtcpVersion);
+ addBoolSelector(g,__tr2qs_ctx("SOURCE","options"),KviOption_boolIgnoreCtcpSource);
+ addBoolSelector(g,__tr2qs_ctx("TIME","options"),KviOption_boolIgnoreCtcpTime);
+ addBoolSelector(g,__tr2qs_ctx("PAGE","options"),KviOption_boolIgnoreCtcpPage);
+ addBoolSelector(g,__tr2qs_ctx("AVATAR","options"),KviOption_boolIgnoreCtcpAvatar);
+ addBoolSelector(g,__tr2qs_ctx("DCC/TDCC","options"),KviOption_boolIgnoreCtcpDcc);
+
+ addRowSpacer(0,3,1,3);
+}
+
+KviCtcpFloodProtectionOptionsWidget::~KviCtcpFloodProtectionOptionsWidget()
+{
+}
+
+
+#include "m_optw_ctcpfloodprotection.moc"
diff --git a/src/modules/options/optw_ctcpfloodprotection.h b/src/modules/options/optw_ctcpfloodprotection.h
new file mode 100644
index 00000000..43f28fbe
--- /dev/null
+++ b/src/modules/options/optw_ctcpfloodprotection.h
@@ -0,0 +1,41 @@
+#ifndef _OPTW_CTCPFLOODPROTECTION_H_
+#define _OPTW_CTCPFLOODPROTECTION_H_
+
+//
+// File : optw_ctcpfloodprotection.h
+// Creation date : Sun Jan 21 2000 14:34:12 CEST 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviCtcpFloodProtectionOptionsWidget KVI_SMALLICON_CTCPREQUESTFLOOD
+#define KVI_OPTIONS_WIDGET_NAME_KviCtcpFloodProtectionOptionsWidget __tr2qs_no_lookup("Flood Protection")
+#define KVI_OPTIONS_WIDGET_PARENT_KviCtcpFloodProtectionOptionsWidget KviProtectionOptionsWidget
+
+class KviCtcpFloodProtectionOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+// Q_CLASSINFO("help","ctcpfloodprotectionoptions")
+public:
+ KviCtcpFloodProtectionOptionsWidget(QWidget * parent);
+ ~KviCtcpFloodProtectionOptionsWidget();
+};
+
+#endif //!_OPTW_CTCPFLOODPROTECTION_H_
diff --git a/src/modules/options/optw_dcc.cpp b/src/modules/options/optw_dcc.cpp
new file mode 100644
index 00000000..1b792da3
--- /dev/null
+++ b/src/modules/options/optw_dcc.cpp
@@ -0,0 +1,393 @@
+//=============================================================================
+//
+// File : optw_dcc.cpp
+// Creation date : Fri Aug 17 22:08:09 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2004 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 "optw_dcc.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+//#warning "Info tips"
+
+KviDccOptionsWidget::KviDccOptionsWidget(QWidget * pParent)
+: KviOptionsWidget(pParent)
+{
+}
+
+KviDccOptionsWidget::~KviDccOptionsWidget()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviDccGeneralOptionsWidget::KviDccGeneralOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"dccgeneral_options_widget")
+{
+ createLayout(2,1);
+
+ KviBoolSelector * b = addBoolSelector(0,0,0,0,__tr2qs_ctx("Use workaround for firewall","options"),KviOption_boolCantAcceptIncomingDccConnections);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>Enable this option if you can't accept incoming connections.<br>" \
+ "KVIrc will try to use different methods to send and receive files.<br>" \
+ "Please note that these methods may NOT work when communicating with a non-KVIrc client.</center>","options"));
+#endif
+
+ addRowSpacer(0,1,0,1);
+}
+
+KviDccGeneralOptionsWidget::~KviDccGeneralOptionsWidget()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviDccAdvancedOptionsWidget::KviDccAdvancedOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"dccgeneral_options_widget")
+{
+ createLayout(5,1);
+
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Network Properties","options"));
+
+ KviBoolSelector * b = addBoolSelector(g,__tr2qs_ctx("Use user-defined address or network interface","options"),KviOption_boolDccListenOnSpecifiedInterfaceByDefault);
+
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>Enable this option if you are on a multihost machine and want " \
+ "to force one of the available IP addresses to be used for outgoing DCCs.<br>This is especially useful " \
+ "when you use IPv6 and IPv4 addresses.<br>You can force KVIrc to always choose the IPv4 interface.</center>","options"));
+#endif
+
+ KviStringSelector * s = addStringSelector(g,__tr2qs_ctx("Listen on address/interface:","options"),KviOption_stringDccListenDefaultInterface,KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault));
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(s,__tr2qs_ctx("<center>This is the IP address or name of the interface to use by default for outgoing DCC transfers.<br>" \
+ "On UNIX systems that support it, you can also specify IPv4 interface names (such as <b>ppp0</b>).<br>" \
+ "If you set it to <b>0.0.0.0</b>, KVIrc will try to use the first available IPv4 interface</center>","options"));
+#endif
+
+ connect(b,SIGNAL(toggled(bool)),s,SLOT(setEnabled(bool)));
+
+ b = addBoolSelector(g,__tr2qs_ctx("Use user-defined port range","options"),KviOption_boolUserDefinedPortRange);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>Enable this option if you want specify a local port range for DCC.</center>","options"));
+#endif
+
+ KviTalHBox * hb = new KviTalHBox(g);
+ hb->setSpacing(4);
+ KviUIntSelector * u = addUIntSelector(hb,__tr2qs_ctx("Lowest port:","options"),KviOption_uintDccMinPort,1,65535,5000,KVI_OPTION_BOOL(KviOption_boolUserDefinedPortRange));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ u = addUIntSelector(hb,__tr2qs_ctx("Highest port:","options"),KviOption_uintDccMaxPort,1,65535,30000,KVI_OPTION_BOOL(KviOption_boolUserDefinedPortRange));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ b = addBoolSelector(g,__tr2qs_ctx("Send a fixed address in requests","options"),KviOption_boolDccSendFakeAddressByDefault);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>Enable this option if you want to always send a fake IP address in your DCC requests.<br>" \
+ "This might be useful if you're behind a router with a static address that does network address translation (NAT) and forwards all or a range of ports.</center>","options"));
+#endif
+
+ s = addStringSelector(g,__tr2qs_ctx("Send address/interface:","options"),KviOption_stringDefaultDccFakeAddress,KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault));
+ connect(b,SIGNAL(toggled(bool)),s,SLOT(setEnabled(bool)));
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(s,__tr2qs_ctx("<center>This is the fixed address that will be sent with all DCC requests if you enable the option above.</center>","options"));
+#endif
+
+ KviBoolSelector * b2;
+ b2 = addBoolSelector(g,__tr2qs_ctx("Guess address from IRC server if unroutable","options"),
+ KviOption_boolDccGuessIpFromServerWhenLocalIsUnroutable,!KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault));
+ connect(b,SIGNAL(toggled(bool)),b2,SLOT(setNotEnabled(bool)));
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b2,__tr2qs_ctx("<center>You can enable this option if you are behind a router that forwards all or a range of ports.<br>" \
+ "KVIrc will try to guess the IP address to use for DCC by looking up the local hostname as seen " \
+ "by the IRC server you're connected to.<br>This method is an exclusive alternative to the \"fixed address\" above.<br>" \
+ "It might guess the correct address automatically if certain conditions are met (e.g. the IRC server does not mask hostnames).</center>","options"));
+#endif
+
+ b = addBoolSelector(g,__tr2qs_ctx("Use \"broken bouncer hack\" to detect address","options"),
+ KviOption_boolDccBrokenBouncerHack,KVI_OPTION_BOOL(KviOption_boolDccGuessIpFromServerWhenLocalIsUnroutable));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>When you're behind a dialup router and also tunneling through a psyBNC bouncer, " \
+ "you can use a bug in the bouncer to force KVIrc to bind the DCC connections to the dialup router's address.<br>" \
+ "It's an ugly hack - use it only if nothing else works.</center>","options"));
+#endif
+
+ connect(b2,SIGNAL(toggled(bool)),b,SLOT(setEnabled(bool)));
+
+ b = addBoolSelector(0,1,1,1,__tr2qs_ctx("Notify failed DCC handshakes to the remote end","options"),
+ KviOption_boolNotifyFailedDccHandshakes);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>If you enable this option, when a DCC request from a remote " \
+ "user can't be satisfied KVIrc will notify him by a CTCP ERRMSG. This is " \
+ "a nice feature so it is a good idea to leave it on unless for some reason " \
+ "you have deactivated the antiflood system: in this case turning off this option " \
+ "might help if you often get attacked by CTCP floods.</center>","options"));
+#endif
+
+ u = addUIntSelector(0,2,1,2,__tr2qs_ctx("Maximum number of DCC sessions","options"),KviOption_uintMaxDccSlots,0,1000,64);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(u,__tr2qs_ctx("<center>This is the maximum number of concurrent DCC sessions " \
+ "and it includes all the DCC types (send,chat,recv...). " \
+ "KVIrc will refuse the requests when this limit is reached.</center>","options"));
+#endif
+
+ addUIntSelector(0,3,1,3,__tr2qs_ctx("DCC socket timeout:","options"),KviOption_uintDccSocketTimeout,10,65536,180);
+ u->setSuffix(__tr2qs_ctx(" sec","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(u,__tr2qs_ctx("<center>This is the amount of time that KVIrc will wait for a response before assuming that a DCC has failed " \
+ "because the remote client was unable to connect to our listening socket.</center>","options"));
+#endif
+
+ addRowSpacer(0,4,1,4);
+}
+
+KviDccAdvancedOptionsWidget::~KviDccAdvancedOptionsWidget()
+{
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviDccSendOptionsWidget::KviDccSendOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"dccsend_options_widget")
+{
+}
+
+KviDccSendOptionsWidget::~KviDccSendOptionsWidget()
+{
+}
+
+
+
+KviDccSendGeneralOptionsWidget::KviDccSendGeneralOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"dccsend_options_widget")
+{
+ createLayout(5,1);
+
+ KviBoolSelector * b;
+
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("On Incoming File","options"));
+ KviBoolSelector * b2 = addBoolSelector(g,__tr2qs_ctx("Automatically accept","options"),KviOption_boolAutoAcceptDccSend);
+ KviBoolSelector * b3 = addBoolSelector(g,__tr2qs_ctx("Open transfer window as minimized when auto-accepted","options"),KviOption_boolCreateMinimizedDccSendWhenAutoAccepted,!KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccSend));
+ KviBoolSelector * b4 = addBoolSelector(g,__tr2qs_ctx("Automatically resume when auto-accepted","options"),KviOption_boolAutoResumeDccSendWhenAutoAccepted,KVI_OPTION_BOOL(KviOption_boolAutoAcceptDccSend));
+
+ g = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Save Location","options"));
+ addDirectorySelector(g,__tr2qs_ctx("Download folder:","options"),KviOption_stringIncomingPath);
+ addBoolSelector(g,__tr2qs_ctx("Sort saved files by nicknames (create subfolders)","options"),KviOption_boolSortReceivedByDccFilesByNicks);
+ addBoolSelector(g,__tr2qs_ctx("Guess save path from media type","options"),KviOption_boolUseIncomingDccMediaTypeSavePath);
+
+
+ g = addGroupBox(0,2,0,2,1,Qt::Horizontal,__tr2qs_ctx("On Download Completion","options"));
+ addBoolSelector(g,__tr2qs_ctx("Notify completion in console","options"),KviOption_boolNotifyDccSendSuccessInConsole);
+ addBoolSelector(g,__tr2qs_ctx("Notify completion in notifier","options"),KviOption_boolNotifyDccSendSuccessInNotifier);
+ b = addBoolSelector(g,__tr2qs_ctx("Automatically clear transfer","options"),KviOption_boolAutoCloseDccSendOnSuccess);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option will cause succesfully terminated transfers " \
+ "to be automatically removed from the transfer window.</center>","options"));
+#endif //COMPILE_INFO_TIPS
+
+
+ KviBoolSelector * b1 = addBoolSelector(0,3,0,3,__tr2qs_ctx("Always open transfer window as minimized","options"),KviOption_boolCreateMinimizedDccSend);
+
+ connect(b1,SIGNAL(toggled(bool)),b3,SLOT(setNotEnabled(bool)));
+ connect(b2,SIGNAL(toggled(bool)),b4,SLOT(setEnabled(bool)));
+
+ addRowSpacer(0,4,0,4);
+}
+
+KviDccSendGeneralOptionsWidget::~KviDccSendGeneralOptionsWidget()
+{
+}
+
+
+KviDccSendAdvancedOptionsWidget::KviDccSendAdvancedOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"dccsend_advanced_options_widget")
+{
+ createLayout(4,1);
+
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Bug Compatibility","options"));
+ KviBoolSelector * b = addBoolSelector(g,__tr2qs_ctx("Send ACK for byte 0","options"),KviOption_boolSendZeroAckInDccRecv);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes KVIrc to send a zero-byte acknowledge to kick-start " \
+ "the DCC transfer with some buggy IRC clients.<br>" \
+ "Use it only if your DCC transfers stall just after establishing a connection without sending any data.</center>","options"));
+#endif //COMPILE_INFO_TIPS
+
+ b = addBoolSelector(g,__tr2qs_ctx("Accept broken RESUME (mIRC file.ext)","options"),KviOption_boolAcceptBrokenFileNameDccResumeRequests);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes KVIrc to accept RESUME requests with invalid filenames.<br>" \
+ "Use it if KVIrc fails to accept RESUME requests from other clients (e.g. some versions of mIRC).</center>","options"));
+#endif //COMPILE_INFO_TIPS
+
+ b = addBoolSelector(g,__tr2qs_ctx("Replace spaces with underscores in outgoing filenames","options"),KviOption_boolDCCFileTransferReplaceOutgoingSpacesWithUnderscores);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes KVIrc to replace spaces with underscores in filenames " \
+ "for all the outgoing file transfers. This will fix filename handling with some buggy clients (e.g. some versions of mIRC).","options"));
+#endif //COMPILE_INFO_TIPS
+
+
+ g = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Limits","options"));
+
+ KviTalHBox * hb = new KviTalHBox(g);
+ b = addBoolSelector(hb,__tr2qs_ctx("Limit upload bandwidth to","options"),KviOption_boolLimitDccSendSpeed);
+ KviUIntSelector * u = addUIntSelector(hb,"",KviOption_uintMaxDccSendSpeed,0,0xffffff1,1024,KVI_OPTION_BOOL(KviOption_boolLimitDccSendSpeed));
+ u->setSuffix(" " + __tr2qs_ctx("bytes/sec","options"));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ hb = new KviTalHBox(g);
+ b = addBoolSelector(hb,__tr2qs_ctx("Limit download bandwidth to","options"),KviOption_boolLimitDccRecvSpeed);
+ u = addUIntSelector(hb,"",KviOption_uintMaxDccRecvSpeed,0,0xffffff1,1024,KVI_OPTION_BOOL(KviOption_boolLimitDccRecvSpeed));
+ u->setSuffix(" " + __tr2qs_ctx("bytes/sec","options"));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+
+ u = addUIntSelector(g,__tr2qs_ctx("Maximum number of DCC transfers","options"),KviOption_uintMaxDccSendTransfers,0,1000,10);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(u,__tr2qs_ctx("<center>This is the maximum number of concurrent DCC transfers. " \
+ "KVIrc will refuse the requests when this limit is reached.</center>","options"));
+#endif
+
+ g = addGroupBox(0,2,0,2,1,Qt::Horizontal,__tr2qs_ctx("Tweaks","options"));
+
+ b = addBoolSelector(g,__tr2qs_ctx("Use fast send (send ahead)","options"),KviOption_boolUseFastDccSend);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>The \"send ahead\" DCC method allows data to be sent faster by breaking " \
+ "some of the rules of the original DCC SEND protocol specification.<br>" \
+ "Most clients can handle this kind of optimisation so disable it only if you have problems.</center>","options"));
+#endif //COMPILE_INFO_TIPS
+
+ hb = new KviTalHBox(g);
+
+ b = addBoolSelector(hb,__tr2qs_ctx("Force idle step","options"),KviOption_boolDccSendForceIdleStep);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>Enable this option when the dcc file transfers " \
+ "tend to block your computer by consuming too much CPU time. " \
+ "When this option is enabled the idle interval below will be " \
+ "forcibly inserted between each sent/received data packet.</center>","options"));
+#endif // COMPILE_INFO_TIPS
+
+ u = addUIntSelector(hb,__tr2qs_ctx("","options"),KviOption_uintDccSendIdleStepInMSec,1,65536,30,KVI_OPTION_BOOL(KviOption_boolDccSendForceIdleStep));
+ connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+ u->setSuffix(__tr2qs_ctx(" msec","options"));
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(u,
+ __tr2qs_ctx("<center>This parameter controls the average delay between two packets sent or received.<br>" \
+ "A smaller interval will cause you to send data faster but will also " \
+ "add load to your CPU, disk and network interface.<br>" \
+ "Reasonable values are from 5 to 50 milliseconds.</center>","options"));
+#endif //COMPILE_INFO_TIPS
+
+ u = addUIntSelector(g,__tr2qs_ctx("Packet size:","options"),KviOption_uintDccSendPacketSize,16,65536,1024);
+ u->setSuffix(__tr2qs_ctx(" bytes","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(u,
+ __tr2qs_ctx("<center>This parameter controls the packet size used for DCC SEND.<br>" \
+ "With bigger packets you will be probably send data faster, but " \
+ "you will also saturate your bandwidth and in some cases " \
+ "cause more disk activity.<br>" \
+ "Reasonable values are from 512 to 4096 bytes.</center>","options"));
+#endif //COMPILE_INFO_TIPS
+
+
+ addRowSpacer(0,3,0,3);
+
+}
+
+KviDccSendAdvancedOptionsWidget::~KviDccSendAdvancedOptionsWidget()
+{
+
+}
+
+
+//KviDccSendOptionsWidget::enableStuff(bool)
+//{
+// m_pOpenMinimizedAutoAccept->setEnabled(m_pAutoAccept->isChecked() && !m_pOpenMinimized->isChecked());
+//}
+
+
+KviDccChatOptionsWidget::KviDccChatOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"dccchat_options_widget")
+{
+ createLayout(3,1);
+
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("On Chat Request","options"));
+ KviBoolSelector * b = addBoolSelector(g,__tr2qs_ctx("Automatically accept","options"),KviOption_boolAutoAcceptDccChat);
+ b = addBoolSelector(g,__tr2qs_ctx("Open minimized when auto-accepted","options"),KviOption_boolCreateMinimizedDccChatWhenAutoAccepted,!KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat));
+
+ KviBoolSelector * b1 = addBoolSelector(0,1,0,1,__tr2qs_ctx("Always open as minimized","options"),KviOption_boolCreateMinimizedDccChat);
+
+ connect(b1,SIGNAL(toggled(bool)),b,SLOT(setNotEnabled(bool)));
+
+ addRowSpacer(0,2,0,2);
+}
+
+KviDccChatOptionsWidget::~KviDccChatOptionsWidget()
+{
+}
+
+
+KviDccVoiceOptionsWidget::KviDccVoiceOptionsWidget(QWidget *p):KviOptionsWidget(p)
+{
+ createLayout(8, 1);
+
+ KviBoolSelector * b1 = addBoolSelector(0,0,0,0,__tr2qs_ctx("Open all minimized","options"),KviOption_boolCreateMinimizedDccVoice);
+ KviTalGroupBox * g = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("On Voice Request","options"));
+ KviBoolSelector * b = addBoolSelector(g,__tr2qs_ctx("Automatically accept","options"),KviOption_boolAutoAcceptDccVoice);
+
+ b = addBoolSelector(g,__tr2qs_ctx("Open minimized when auto-accepted","options"),KviOption_boolCreateMinimizedDccVoiceWhenAutoAccepted,!KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVoice));
+ connect(b1,SIGNAL(toggled(bool)),b,SLOT(setNotEnabled(bool)));
+
+ addBoolSelector(0,2,0,2,__tr2qs_ctx("Force half-duplex mode on sound device","options"), KviOption_boolDccVoiceForceHalfDuplex);
+ addBoolSelector(0,3,0,3,__tr2qs_ctx("Volume slider controls PCM, not Master","options"), KviOption_boolDccVoiceVolumeSliderControlsPCM);
+
+ addStringSelector(0,4,0,4,__tr2qs_ctx("Sound device:","options"), KviOption_stringDccVoiceSoundDevice);
+ addStringSelector(0,5,0,5,__tr2qs_ctx("Mixer device:","options"), KviOption_stringDccVoiceMixerDevice);
+
+ KviUIntSelector * u = addUIntSelector(0,6,0,6,__tr2qs_ctx("Pre-buffer size:","options"), KviOption_uintDccVoicePreBufferSize, 2048, 65536, 32000);
+ u->setSuffix(" bytes");
+
+
+ addRowSpacer(0,7,0,7);
+}
+
+KviDccVoiceOptionsWidget::~KviDccVoiceOptionsWidget()
+{
+}
+
+#include "m_optw_dcc.moc"
diff --git a/src/modules/options/optw_dcc.h b/src/modules/options/optw_dcc.h
new file mode 100644
index 00000000..5dc67424
--- /dev/null
+++ b/src/modules/options/optw_dcc.h
@@ -0,0 +1,139 @@
+#ifndef _OPTW_DCC_H_
+#define _OPTW_DCC_H_
+//
+// File : optw_dcc.h
+// Creation date : Fri Aug 17 22:08:08 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviDccOptionsWidget KVI_SMALLICON_DCCERROR
+#define KVI_OPTIONS_WIDGET_NAME_KviDccOptionsWidget __tr2qs_no_lookup("DCC")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviDccOptionsWidget 70000
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviDccOptionsWidget true
+
+class KviDccOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviDccOptionsWidget(QWidget * parent);
+ ~KviDccOptionsWidget();
+};
+
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviDccGeneralOptionsWidget KVI_SMALLICON_DCCERROR
+#define KVI_OPTIONS_WIDGET_NAME_KviDccGeneralOptionsWidget __tr2qs_no_lookup("General")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviDccGeneralOptionsWidget 70000
+#define KVI_OPTIONS_WIDGET_PARENT_KviDccGeneralOptionsWidget KviDccOptionsWidget
+
+class KviDccGeneralOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviDccGeneralOptionsWidget(QWidget * parent);
+ ~KviDccGeneralOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviDccAdvancedOptionsWidget KVI_SMALLICON_DCCERROR
+#define KVI_OPTIONS_WIDGET_NAME_KviDccAdvancedOptionsWidget __tr2qs_no_lookup("Advanced")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviDccAdvancedOptionsWidget 70000
+#define KVI_OPTIONS_WIDGET_PARENT_KviDccAdvancedOptionsWidget KviDccOptionsWidget
+
+class KviDccAdvancedOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviDccAdvancedOptionsWidget(QWidget * parent);
+ ~KviDccAdvancedOptionsWidget();
+};
+
+
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviDccSendOptionsWidget KVI_SMALLICON_DCCMSG
+#define KVI_OPTIONS_WIDGET_NAME_KviDccSendOptionsWidget __tr2qs_no_lookup("File Transfer")
+#define KVI_OPTIONS_WIDGET_PARENT_KviDccSendOptionsWidget KviDccOptionsWidget
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviDccSendOptionsWidget true
+
+
+class KviDccSendOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviDccSendOptionsWidget(QWidget * parent);
+ ~KviDccSendOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviDccSendGeneralOptionsWidget KVI_SMALLICON_DCCMSG
+#define KVI_OPTIONS_WIDGET_NAME_KviDccSendGeneralOptionsWidget __tr2qs_no_lookup("General")
+#define KVI_OPTIONS_WIDGET_PARENT_KviDccSendGeneralOptionsWidget KviDccSendOptionsWidget
+
+
+class KviDccSendGeneralOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviDccSendGeneralOptionsWidget(QWidget * parent);
+ ~KviDccSendGeneralOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviDccSendAdvancedOptionsWidget KVI_SMALLICON_DCCMSG
+#define KVI_OPTIONS_WIDGET_NAME_KviDccSendAdvancedOptionsWidget __tr2qs_no_lookup("Advanced")
+#define KVI_OPTIONS_WIDGET_PARENT_KviDccSendAdvancedOptionsWidget KviDccSendOptionsWidget
+
+class KviDccSendAdvancedOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviDccSendAdvancedOptionsWidget(QWidget * parent);
+ ~KviDccSendAdvancedOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviDccChatOptionsWidget KVI_SMALLICON_DCCREQUEST
+#define KVI_OPTIONS_WIDGET_NAME_KviDccChatOptionsWidget __tr2qs_no_lookup("Chat")
+#define KVI_OPTIONS_WIDGET_PARENT_KviDccChatOptionsWidget KviDccOptionsWidget
+#define KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccChatOptionsWidget true
+
+class KviDccChatOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviDccChatOptionsWidget(QWidget * parent);
+ ~KviDccChatOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviDccVoiceOptionsWidget KVI_SMALLICON_DCCVOICE
+#define KVI_OPTIONS_WIDGET_NAME_KviDccVoiceOptionsWidget __tr2qs_no_lookup("Voice")
+#define KVI_OPTIONS_WIDGET_PARENT_KviDccVoiceOptionsWidget KviDccOptionsWidget
+#define KVI_OPTIONS_WIDGET_NOTCONTAINED_KviDccVoiceOptionsWidget true
+
+class KviDccVoiceOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviDccVoiceOptionsWidget(QWidget *);
+ ~KviDccVoiceOptionsWidget();
+};
+
+
+#endif //_OPTW_DCC_H_
diff --git a/src/modules/options/optw_generalopt.cpp b/src/modules/options/optw_generalopt.cpp
new file mode 100644
index 00000000..18f86902
--- /dev/null
+++ b/src/modules/options/optw_generalopt.cpp
@@ -0,0 +1,51 @@
+//=============================================================================
+//
+// File : optw_generalopt.cpp
+// Creation date : Wed Nov 19 09:25:16 2005 GMT by Grifisx & Noldor
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2005 Grifisx & 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 "optw_generalopt.h"
+
+#include "kvi_settings.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+
+
+KviGeneralOptOptionsWidget::KviGeneralOptOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"generalopt_options_widget")
+{
+
+ createLayout(1,4);
+
+ QLabel * l;
+ l = addLabel(0,0,4,0,__tr2qs_ctx("This section contains the general client options<br>"\
+ "<p>like<b> sound, mediafiles, URL handler </b> etc... " \
+ "</p>","options"));
+ addAdvancedButton(4,1,4,1);
+}
+
+
+KviGeneralOptOptionsWidget::~KviGeneralOptOptionsWidget()
+{
+}
+
+
+#include "m_optw_generalopt.moc"
diff --git a/src/modules/options/optw_generalopt.h b/src/modules/options/optw_generalopt.h
new file mode 100644
index 00000000..fbaaf192
--- /dev/null
+++ b/src/modules/options/optw_generalopt.h
@@ -0,0 +1,39 @@
+#ifndef _OPTW_GENERALOPT_H_
+#define _OPTW_GENERALOPT_H_
+//
+// File : optw_generalopt.h
+// Creation date : Wed Nov 19 09:25:16 2005 GMT by Grifisx & Noldor
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2005 Grifisx & 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 "kvi_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviGeneralOptOptionsWidget KVI_SMALLICON_OPTIONS
+#define KVI_OPTIONS_WIDGET_NAME_KviGeneralOptOptionsWidget __tr2qs_no_lookup("General options")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviGeneralOptOptionsWidget 40000
+
+class KviGeneralOptOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviGeneralOptOptionsWidget(QWidget * parent);
+ ~KviGeneralOptOptionsWidget();
+};
+
+#endif //_OPTW_CONNECTION_H_
diff --git a/src/modules/options/optw_highlighting.cpp b/src/modules/options/optw_highlighting.cpp
new file mode 100644
index 00000000..ef0f5442
--- /dev/null
+++ b/src/modules/options/optw_highlighting.cpp
@@ -0,0 +1,128 @@
+#ifndef _OPTW_HIGHLIGHTING_CPP_
+#define _OPTW_HIGHLIGHTING_CPP_
+//
+// File : optw_highlighting.cpp
+// Creation date : Sat Nov 3 18:09:35 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 "optw_highlighting.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+#include <qlabel.h>
+
+KviAlertHighlightingOptionsWidget::KviAlertHighlightingOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"highlighting_options_widget")
+{
+}
+
+KviAlertHighlightingOptionsWidget::~KviAlertHighlightingOptionsWidget()
+{
+}
+
+
+
+KviHighlightingOptionsWidget::KviHighlightingOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"highlighting_options_widget")
+{
+ createLayout(7,1);
+
+ KviBoolSelector * b;
+
+ connect(
+ addBoolSelector(0,0,0,0,__tr2qs_ctx("Enable word highlighting","options"),KviOption_boolUseWordHighlighting),
+ SIGNAL(toggled(bool)),
+ addStringListSelector(0,1,0,1,__tr2qs_ctx("Words to highlight:","options"),KviOption_stringlistHighlightWords,KVI_OPTION_BOOL(KviOption_boolUseWordHighlighting)),
+ SLOT(setEnabled(bool)));
+ addStringSelector(0,2,0,2,__tr2qs_ctx("Word splitters:","options"),KviOption_stringWordSplitters);
+ // This can be used even without Word highlighting
+ b = addBoolSelector(0,3,0,3,__tr2qs_ctx("Highlight messages containing my nickname","options"),KviOption_boolAlwaysHighlightNick);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>If this option is enabled, KVIrc will highlight any user message containing your current nickname</center>","options"));
+#endif
+ b = addBoolSelector(0,4,0,4,__tr2qs_ctx("Flash the system taskbar entry on highlighted messages","options"),KviOption_boolFlashWindowOnHighlightedMessages);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>If this option is enabled, KVIrc will (attempt to) flash the system taskbar entry when a highlighted message is printed and KVIrc is not the active window</center>","options"));
+#endif
+ b = addBoolSelector(0,5,0,5,__tr2qs_ctx("Popup the notifier window on highlighted messages","options"),KviOption_boolPopupNotifierOnHighlightedMessages);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>If this option is enabled, KVIrc will popup a little notifier window in the low right corner of your desktop when a highlighted message is printed and KVIrc is not the active window</center>","options"));
+#endif
+
+ addRowSpacer(0,6,0,6);
+}
+
+KviHighlightingOptionsWidget::~KviHighlightingOptionsWidget()
+{
+}
+
+
+
+
+
+
+KviAlertOptionsWidget::KviAlertOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"highlighting_options_widget")
+{
+ createLayout(2,1);
+
+ KviBoolSelector * b;
+
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Alert Restrictions","options"));
+ KviBoolSelector * b3 = addBoolSelector(g,__tr2qs_ctx("Restrict alert","options"),KviOption_boolHighlightOnlyNormalMsg);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b3, __tr2qs_ctx("<center>If this option is enabled, KVIrc will alert in the taskbar only if a normal message is received in a channel.<br>Actions like joins, parts and mode changes will be ignored.<br> This is useful if you are in channels with a high rate of traffic and only want to be alerted for messages that are interesting to you.</center>","options"));
+#endif
+ KviBoolSelector * b4 = addBoolSelector(g,__tr2qs_ctx("Alert for highlighted words","options"),KviOption_boolHighlightOnlyNormalMsgHighlightInChanToo,KVI_OPTION_BOOL(KviOption_boolHighlightOnlyNormalMsg));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b4, __tr2qs_ctx("<center>If this option is enabled, the taskbar will also alert for messages which contain a word from the highlighted words list above.</center>","options"));
+#endif
+ KviBoolSelector * b5 = addBoolSelector(g,__tr2qs_ctx("Alert for query messages","options"),KviOption_boolHighlightOnlyNormalMsgQueryToo,KVI_OPTION_BOOL(KviOption_boolHighlightOnlyNormalMsg));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b5, __tr2qs_ctx("<center>If this option is enabled, the taskbar will also alert for messages which are shown in queries.</center>","options"));
+#endif
+ connect(b3,SIGNAL(toggled(bool)),b4,SLOT(setEnabled(bool)));
+ connect(b3,SIGNAL(toggled(bool)),b5,SLOT(setEnabled(bool)));
+
+ KviBoolSelector * b6 = addBoolSelector(g,__tr2qs_ctx("Use custom alert level","options"),KviOption_boolHighlightOnlyAtCostumHighlightLevel);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b6, __tr2qs_ctx("<center>If this option is enabled, KVIrc will alert in the taskbar only if the specified alert level is reached.</center>","options"));
+#endif
+ KviUIntSelector * b7 = addUIntSelector(g,__tr2qs_ctx("Minimum alert level:","options"),KviOption_uintMinHighlightLevel,1,KVI_MSGTYPE_MAXLEVEL,KVI_MSGTYPE_MAXLEVEL,KVI_OPTION_UINT(KviOption_boolHighlightOnlyAtCostumHighlightLevel));
+ b7->setEnabled(KVI_OPTION_BOOL(KviOption_boolHighlightOnlyAtCostumHighlightLevel));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b6, __tr2qs_ctx("<center>This option sets the minimum alert level for the taskbar.</center>","options"));
+#endif
+ connect(b6,SIGNAL(toggled(bool)),b7,SLOT(setEnabled(bool)));
+
+ addRowSpacer(0,1,0,1);
+}
+
+KviAlertOptionsWidget::~KviAlertOptionsWidget()
+{
+}
+
+
+#include "m_optw_highlighting.moc"
+
+#endif //_OPTW_HIGHLIGHTING_CPP_
diff --git a/src/modules/options/optw_highlighting.h b/src/modules/options/optw_highlighting.h
new file mode 100644
index 00000000..f222412e
--- /dev/null
+++ b/src/modules/options/optw_highlighting.h
@@ -0,0 +1,67 @@
+#ifndef _OPTW_HIGHLIGHTING_H_
+#define _OPTW_HIGHLIGHTING_H_
+//
+// File : optw_highlighting.h
+// Creation date : Sat Nov 3 18:09:37 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviAlertHighlightingOptionsWidget KVI_SMALLICON_RAW
+#define KVI_OPTIONS_WIDGET_NAME_KviAlertHighlightingOptionsWidget __tr2qs_no_lookup("Alert/Highlight")
+#define KVI_OPTIONS_WIDGET_PARENT_KviAlertHighlightingOptionsWidget KviToolsOptionsWidget
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviAlertHighlightingOptionsWidget true
+
+class KviAlertHighlightingOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviAlertHighlightingOptionsWidget(QWidget * parent);
+ ~KviAlertHighlightingOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviHighlightingOptionsWidget KVI_SMALLICON_RAW
+#define KVI_OPTIONS_WIDGET_NAME_KviHighlightingOptionsWidget __tr2qs_no_lookup("Highlight")
+#define KVI_OPTIONS_WIDGET_PARENT_KviHighlightingOptionsWidget KviAlertHighlightingOptionsWidget
+
+class KviHighlightingOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviHighlightingOptionsWidget(QWidget * parent);
+ ~KviHighlightingOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviAlertOptionsWidget KVI_SMALLICON_RAW
+#define KVI_OPTIONS_WIDGET_NAME_KviAlertOptionsWidget __tr2qs_no_lookup("Taskbar Alert")
+#define KVI_OPTIONS_WIDGET_PARENT_KviAlertOptionsWidget KviAlertHighlightingOptionsWidget
+
+class KviAlertOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviAlertOptionsWidget(QWidget * parent);
+ ~KviAlertOptionsWidget();
+};
+
+
+#endif //_OPTW_HIGHLIGHTING_H_
diff --git a/src/modules/options/optw_ident.cpp b/src/modules/options/optw_ident.cpp
new file mode 100644
index 00000000..7dafdd52
--- /dev/null
+++ b/src/modules/options/optw_ident.cpp
@@ -0,0 +1,37 @@
+//================================================================================
+//
+// File : optw_ident.cpp
+// Creation date : Mon Oct 29 15:48:42 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2004 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 "optw_ident.h"
+
+#include <kvi_tal_groupbox.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_settings.h"
+
+//#warning "Info tips"
+
+
+
+#include "m_optw_ident.moc"
diff --git a/src/modules/options/optw_ident.h b/src/modules/options/optw_ident.h
new file mode 100644
index 00000000..89ea8975
--- /dev/null
+++ b/src/modules/options/optw_ident.h
@@ -0,0 +1,28 @@
+#ifndef _OPTW_IDENT_H_
+#define _OPTW_IDENT_H_
+//
+// File : optw_ident.h
+// Creation date : Mon Oct 29 15:48:40 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_optionswidget.h"
+
+
+#endif //_OPTW_IDENT_H_
diff --git a/src/modules/options/optw_identity.cpp b/src/modules/options/optw_identity.cpp
new file mode 100644
index 00000000..998ca5a4
--- /dev/null
+++ b/src/modules/options/optw_identity.cpp
@@ -0,0 +1,729 @@
+//============================================================================
+//
+// File : optw_identity.cpp
+// Creation date : Tue Nov 14 2000 23:06:53 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 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 "optw_identity.h"
+
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include "kvi_tal_tooltip.h"
+#include <qtabwidget.h>
+#include <qcombobox.h>
+#include <qmessagebox.h>
+#include <qtimer.h>
+#include <qvalidator.h>
+
+#include "kvi_defaults.h"
+#include "kvi_settings.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_window.h"
+#include "kvi_console.h"
+#include "kvi_optionswidget.h"
+#include "kvi_filedialog.h"
+#include "kvi_iconmanager.h"
+#include "kvi_http.h"
+
+
+//#warning "Info tips"
+
+
+KviNickAlternativesDialog::KviNickAlternativesDialog(QWidget * par,const QString &n1,const QString &n2,const QString &n3)
+: QDialog(par)
+{
+ QGridLayout * g = new QGridLayout(this,5,3,4,12);
+
+ setCaption(__tr2qs_ctx("Nickname alternatives","options"));
+
+ QLabel * l = new QLabel(this);
+ l->setText(__tr2qs_ctx("<center>Here you can choose up to three nicknames " \
+ "alternative to the primary one. KVIrc will use the alternatives " \
+ "if the primary nick is already used by someone else on a particular " \
+ "IRC network.</center>","options"));
+ g->addMultiCellWidget(l,0,0,0,2);
+
+ l = new QLabel(this);
+ l->setText(__tr2qs_ctx("Alt. Nickname 1:","options"));
+ g->addWidget(l,1,0);
+ m_pNickEdit1 = new QLineEdit(this);
+ g->addMultiCellWidget(m_pNickEdit1,1,1,1,2);
+ m_pNickEdit1->setText(n1);
+
+ l = new QLabel(this);
+ l->setText(__tr2qs_ctx("Alt. Nickname 2:","options"));
+ g->addWidget(l,2,0);
+ m_pNickEdit2 = new QLineEdit(this);
+ g->addMultiCellWidget(m_pNickEdit2,2,2,1,2);
+ m_pNickEdit2->setText(n2);
+
+ l = new QLabel(this);
+ l->setText(__tr2qs_ctx("Alt. Nickname 3:","options"));
+ g->addWidget(l,3,0);
+ m_pNickEdit3 = new QLineEdit(this);
+ g->addMultiCellWidget(m_pNickEdit3,3,3,1,2);
+ m_pNickEdit3->setText(n3);
+ KviTalHBox * h = new KviTalHBox(this);
+ h->setSpacing(8);
+ g->addWidget(h,4,2);
+
+ QPushButton * pb = new QPushButton(__tr2qs_ctx("Cancel","options"),h);
+ //g->addWidget(pb,4,2);
+ connect(pb,SIGNAL(clicked()),this,SLOT(reject()));
+
+ pb = new QPushButton(__tr2qs_ctx("Ok","options"),h);
+ pb->setDefault(true);
+ connect(pb,SIGNAL(clicked()),this,SLOT(accept()));
+
+ g->setColStretch(0,1);
+
+ //setMinimumSize(250,120);
+}
+
+KviNickAlternativesDialog::~KviNickAlternativesDialog()
+{
+}
+
+void KviNickAlternativesDialog::fill(QString &n1,QString &n2,QString &n3)
+{
+ n1 = m_pNickEdit1->text();
+ n2 = m_pNickEdit2->text();
+ n3 = m_pNickEdit3->text();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+KviAvatarDownloadDialog::KviAvatarDownloadDialog(QWidget * par,const QString &szUrl)
+: QDialog(par)
+{
+ setCaption(__tr2qs_ctx("Avatar Download - KVIrc","options"));
+
+ m_szUrl = szUrl;
+
+ QGridLayout * g = new QGridLayout(this,2,2,4,8);
+
+ m_pOutput = new QLabel(__tr2qs_ctx("<center>Please wait while the avatar is being downloaded</center>","options"),this);
+ g->addMultiCellWidget(m_pOutput,0,0,0,1);
+
+ QPushButton * b = new QPushButton(__tr2qs_ctx("Abort","options"),this);
+ g->addWidget(b,1,1);
+ connect(b,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+
+ m_pRequest = new KviHttpRequest();
+
+ QTimer::singleShot(0,this,SLOT(startDownload()));
+
+ g->setRowStretch(0,1);
+ g->setColStretch(0,1);
+
+ setMinimumSize(250,120);
+}
+
+KviAvatarDownloadDialog::~KviAvatarDownloadDialog()
+{
+ delete m_pRequest;
+}
+
+void KviAvatarDownloadDialog::startDownload()
+{
+ connect(m_pRequest,SIGNAL(terminated(bool)),this,SLOT(downloadTerminated(bool)));
+ connect(m_pRequest,SIGNAL(status(const char *)),this,SLOT(downloadMessage(const char *)));
+
+ QString tmp = m_szUrl;
+ g_pIconManager->urlToCachedFileName(tmp);
+ g_pApp->getLocalKvircDirectory(m_szLocalFileName,KviApp::Avatars,tmp);
+
+ m_pRequest->setExistingFileAction(KviHttpRequest::RenameExisting);
+ if(!m_pRequest->get(KviUrl(m_szUrl),KviHttpRequest::StoreToFile,m_szLocalFileName.utf8().data()))
+ {
+ m_szErrorMessage = __tr2qs_ctx("Failed to start the download","options");
+ reject();
+ }
+}
+
+void KviAvatarDownloadDialog::closeEvent(QCloseEvent * e)
+{
+ m_szErrorMessage = __tr2qs_ctx("Download aborted by user","options");
+ e->ignore();
+ reject();
+}
+
+void KviAvatarDownloadDialog::cancelClicked()
+{
+ m_szErrorMessage = __tr2qs_ctx("Download aborted by user","options");
+ reject();
+}
+
+void KviAvatarDownloadDialog::downloadMessage(const char * message)
+{
+ if(message)
+ {
+ QString txt = "<center>";
+ txt += message;
+ txt += "</center>";
+ m_pOutput->setText(message);
+ }
+}
+
+void KviAvatarDownloadDialog::downloadTerminated(bool bSuccess)
+{
+ if(bSuccess)
+ {
+ accept();
+ } else {
+ m_szErrorMessage = m_pRequest->lastError();
+ reject();
+ }
+}
+
+KviAvatarSelectionDialog::KviAvatarSelectionDialog(QWidget * par,const QString &szInitialPath)
+: QDialog(par)
+{
+ setCaption(__tr2qs_ctx("Choose Avatar - KVIrc","options"));
+
+ QGridLayout * g = new QGridLayout(this,3,3,4,8);
+
+
+ QString msg = "<center>";
+ msg += __tr2qs_ctx("Please select an avatar image. " \
+ "The full path to a local file or an image on the Web can be used.<br>" \
+ "If you wish to use a local image file, click the \"<b>Browse</b>\"" \
+ "button to browse local folders.<br>" \
+ "The full URL for an image (including <b>http://</b>) can be entered manually.","options");
+ msg += "</center><br>";
+
+ QLabel * l = new QLabel(msg,this);
+ l->setMinimumWidth(250);
+
+ g->addMultiCellWidget(l,0,0,0,2);
+
+ m_pLineEdit = new QLineEdit(this);
+ m_pLineEdit->setText(szInitialPath);
+ m_pLineEdit->setMinimumWidth(180);
+
+ g->addMultiCellWidget(m_pLineEdit,1,1,0,1);
+
+ QPushButton * b = new QPushButton(__tr2qs_ctx("&Browse...","options"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(chooseFileClicked()));
+ g->addWidget(b,1,2);
+ KviTalHBox * h = new KviTalHBox(this);h->setSpacing(8);g->addMultiCellWidget(h,2,2,1,2);
+ b = new QPushButton(__tr2qs_ctx("&OK","options"),h);
+ b->setMinimumWidth(80);
+ b->setDefault(true);
+ connect(b,SIGNAL(clicked()),this,SLOT(okClicked()));
+ //g->addWidget(b,2,1);
+
+ b = new QPushButton(__tr2qs_ctx("Cancel","options"),h);
+ b->setMinimumWidth(80);
+ connect(b,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ //g->addWidget(b,2,2);
+
+ g->setRowStretch(0,1);
+ g->setColStretch(0,1);
+ //setMinimumSize(250,120);
+}
+
+KviAvatarSelectionDialog::~KviAvatarSelectionDialog()
+{
+}
+
+void KviAvatarSelectionDialog::okClicked()
+{
+ m_szAvatarName = m_pLineEdit->text();
+ accept();
+}
+
+void KviAvatarSelectionDialog::cancelClicked()
+{
+ reject();
+}
+
+void KviAvatarSelectionDialog::chooseFileClicked()
+{
+ QString tmp;
+ if(KviFileDialog::askForOpenFileName(tmp,__tr2qs_ctx("Choose an Image File - KVIrc","options"),
+ QString::null,QString::null,false,true,this))
+ {
+ m_pLineEdit->setText(tmp);
+ }
+}
+
+void KviAvatarSelectionDialog::closeEvent(QCloseEvent * e)
+{
+ e->ignore();
+ reject();
+}
+
+
+
+
+
+
+KviIdentityOptionsWidget::KviIdentityOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+}
+
+KviIdentityOptionsWidget::~KviIdentityOptionsWidget()
+{
+}
+
+
+
+
+KviIdentityGeneralOptionsWidget::KviIdentityGeneralOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+ m_szAltNicknames[0] = KVI_OPTION_STRING(KviOption_stringNickname2);
+ m_szAltNicknames[1] = KVI_OPTION_STRING(KviOption_stringNickname3);
+ m_szAltNicknames[2] = KVI_OPTION_STRING(KviOption_stringNickname4);
+
+
+ createLayout(3,1);
+ layout()->setMargin(10);
+
+ KviTalGroupBox * gbox = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Basic Properties","options"));
+ KviTalHBox * hb = new KviTalHBox(gbox);
+ hb->setSpacing(3);
+
+ KviStringSelector * sel = addStringSelector(hb,__tr2qs_ctx("Nickname:","options"),KviOption_stringNickname1);
+ sel->setMinimumLabelWidth(120);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(sel,__tr2qs_ctx("<center>Your <b>nickname</b> is your primary form of identification on IRC.<br>" \
+ "Since servers cannot accept multiple users sharing the same nickname " \
+ "(case insensitive), you can provide alternative nicknames to be used in case"\
+ "the server refuses to accept the default one.</center>","options"));
+#endif
+ QValidator * v = new QRegExpValidator(QRegExp("[^-0-9 ][^ ]*"),hb);
+ sel->setValidator(v);
+
+ QPushButton * pb = new QPushButton(__tr2qs_ctx("Alternatives...","options"),hb);
+ connect(pb,SIGNAL(clicked()),this,SLOT(setNickAlternatives()));
+
+ sel = addStringSelector(gbox,__tr2qs_ctx("Username:","options"),KviOption_stringUsername);
+ sel->setMinimumLabelWidth(120);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(sel,__tr2qs_ctx("<center>This is the <b>username</b> that you will use to connect to the server.<br>" \
+ "In the past, it was used as a form of authentication, but it normally has no special use now.<br>" \
+ "In addition to your nickname, you are identified on IRC by your <b>username@hostname</b>.</br>" \
+ "Basically, you can enter any word you like here. :D</center>","options"));
+#endif
+ sel = addStringSelector(gbox,__tr2qs_ctx("Real name:","options"),KviOption_stringRealname);
+ sel->setMinimumLabelWidth(120);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(sel,__tr2qs_ctx("<center>This text will appear when someone does a /WHOIS on you.<br>" \
+ "It is intended to be your real name, but people tend to put random quotes and phrases here too.</center>","options"));
+#endif
+
+
+ QString szOptionalCtcpUserInfo = __tr2qs_ctx("This field is optional and will appear as part of the CTCP USERINFO reply.","options");
+ QString szCenterBegin("<center>");
+ QString szCenterEnd("</center>");
+ QString szTrailing = "<br><br>" + szOptionalCtcpUserInfo + szCenterEnd;
+
+ gbox = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Profile","options"));
+
+ hb = new KviTalHBox(gbox);
+ hb->setSpacing(4);
+
+ QLabel * l = new QLabel(__tr2qs_ctx("Age:","options"),hb);
+ l->setMinimumWidth(120);
+
+ m_pAgeCombo = new QComboBox(hb);
+#ifdef COMPILE_INFO_TIPS
+ QString szTip1 = szCenterBegin + __tr2qs_ctx("Here you can specify your age.","options") + szTrailing;
+ KviTalToolTip::add(l,szTip1);
+ KviTalToolTip::add(m_pAgeCombo,szTip1);
+#endif
+ m_pAgeCombo->insertItem(__tr2qs_ctx("Unspecified","options"));
+ unsigned int i;
+ for(i=1;i<120;i++)
+ {
+ QString tmp;
+ tmp.setNum(i);
+ m_pAgeCombo->insertItem(tmp);
+ }
+
+ bool bOk;
+ i = KVI_OPTION_STRING(KviOption_stringCtcpUserInfoAge).toUInt(&bOk);
+ if(!bOk)i = 0;
+ if(i > 120)i = 120;
+ m_pAgeCombo->setCurrentItem(i);
+
+ hb->setStretchFactor(m_pAgeCombo,1);
+
+
+ hb = new KviTalHBox(gbox);
+ hb->setSpacing(4);
+
+ l = new QLabel(__tr2qs_ctx("Gender:","options"),hb);
+ l->setMinimumWidth(120);
+
+ m_pGenderCombo = new QComboBox(hb);
+#ifdef COMPILE_INFO_TIPS
+ QString szTip2 = szCenterBegin + __tr2qs_ctx("Here you can specify your gender.","options") + szTrailing;
+ KviTalToolTip::add(l,szTip2);
+ KviTalToolTip::add(m_pGenderCombo,szTip2);
+#endif
+
+ m_pGenderCombo->insertItem(__tr2qs_ctx("Unspecified","options"));
+ m_pGenderCombo->insertItem(__tr2qs_ctx("Female","options"));
+ m_pGenderCombo->insertItem(__tr2qs_ctx("Male","options"));
+
+ if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender),"Male"))
+ m_pGenderCombo->setCurrentItem(2);
+ else if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender),"Female"))
+ m_pGenderCombo->setCurrentItem(1);
+ else
+ m_pGenderCombo->setCurrentItem(0);
+
+ hb->setStretchFactor(m_pGenderCombo,1);
+
+ sel = addStringSelector(gbox,__tr2qs_ctx("Location:","options"),KviOption_stringCtcpUserInfoLocation);
+ sel->setMinimumLabelWidth(120);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(sel,szCenterBegin + __tr2qs_ctx("You can describe here your approximate physical location. " \
+ "Something like \"Region, Country\" will be ok. Please note that this information will be viewable " \
+ "by anyone so putting more data (like the exact address), generally, <b>is not a good idea</b>.","options") + szTrailing);
+#endif
+
+ sel = addStringSelector(gbox,__tr2qs_ctx("Languages:","options"),KviOption_stringCtcpUserInfoLanguages);
+ sel->setMinimumLabelWidth(120);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(sel,szCenterBegin + __tr2qs_ctx("You can put here the short names of the languages you can speak. " \
+ "An example might be \"EN,IT\" that would mean that you speak both Italian and English.","options") + szTrailing);
+#endif
+
+ sel = addStringSelector(gbox,__tr2qs_ctx("Other:","options"),KviOption_stringCtcpUserInfoOther);
+ sel->setMinimumLabelWidth(120);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(sel,szCenterBegin + __tr2qs_ctx("You can put here some additional personal data. " \
+ "It might be a funny quote or your homepage url... " \
+ "Please note that this information will be viewable " \
+ "by anyone so <b>don't put any sensible data</b> (passwords, telephone or credit card numbers).","options") + szTrailing);
+#endif
+
+ addRowSpacer(0,2,0,2);
+}
+
+KviIdentityGeneralOptionsWidget::~KviIdentityGeneralOptionsWidget()
+{
+}
+
+void KviIdentityGeneralOptionsWidget::setNickAlternatives()
+{
+ KviNickAlternativesDialog * dlg = new KviNickAlternativesDialog(this,m_szAltNicknames[0],m_szAltNicknames[1],m_szAltNicknames[2]);
+ if(dlg->exec() != QDialog::Accepted)return;
+ dlg->fill(m_szAltNicknames[0],m_szAltNicknames[1],m_szAltNicknames[2]);
+ delete dlg;
+}
+
+
+void KviIdentityGeneralOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+
+ if(KVI_OPTION_STRING(KviOption_stringRealname).isEmpty()) KVI_OPTION_STRING(KviOption_stringUsername)=KVI_DEFAULT_REALNAME;
+ if(KVI_OPTION_STRING(KviOption_stringUsername).isEmpty()) KVI_OPTION_STRING(KviOption_stringUsername)=KVI_DEFAULT_USERNAME;
+
+ KVI_OPTION_STRING(KviOption_stringNickname2) = m_szAltNicknames[0];
+ KVI_OPTION_STRING(KviOption_stringNickname3) = m_szAltNicknames[1];
+ KVI_OPTION_STRING(KviOption_stringNickname4) = m_szAltNicknames[2];
+
+
+ int i = m_pAgeCombo->currentItem();
+ if(i < 0)i = 0;
+ if(i > 120)i = 120;
+ if(i <= 0)KVI_OPTION_STRING(KviOption_stringCtcpUserInfoAge) = "";
+ else KVI_OPTION_STRING(KviOption_stringCtcpUserInfoAge).setNum(i);
+
+ switch(m_pGenderCombo->currentItem())
+ {
+ case 1:
+ // this should be in english
+ KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender) = "Female";
+ break;
+ case 2:
+ // this should be in english
+ KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender) = "Male";
+ break;
+ default:
+ KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender) = "";
+ break;
+ }
+
+
+}
+
+
+KviIdentityAvatarOptionsWidget::KviIdentityAvatarOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+ createLayout(4,1);
+ layout()->setMargin(10);
+
+ m_pLocalAvatar = new KviPixmap(KVI_OPTION_PIXMAP(KviOption_pixmapMyAvatar));
+
+ bool bHaveAvatar = (!KVI_OPTION_STRING(KviOption_stringMyAvatar).isEmpty()) && m_pLocalAvatar->pixmap();
+
+#ifdef COMPILE_INFO_TIPS
+ QString szTip = __tr2qs_ctx("Here you can choose your avatar image. It will be visible<br>" \
+ "by other people that request it. Choose a nice image of yourself,<br>" \
+ "possibly avoiding obscenity and offending images. It is a good idea<br>" \
+ "to choose a relatively small file (say 150 Kb max) because<br>" \
+ "most clients have a limit on the size of avatars being downloaded.<br>" \
+ "The image also should be smaller than 800x600 pixels since<br>" \
+ "it will have to be viewable in everyone's monitor.","options");
+#endif
+
+ m_pUseAvatarCheck = new KviStyledCheckBox(__tr2qs_ctx("Use avatar","options"),this);
+ addWidgetToLayout(m_pUseAvatarCheck,0,0,0,0);
+ m_pUseAvatarCheck->setChecked(bHaveAvatar);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(m_pUseAvatarCheck,szTip);
+#endif
+
+ m_pAvatarPreview = new KviPixmapPreview(this);
+ addWidgetToLayout(m_pAvatarPreview,0,1,0,1);
+ m_pAvatarPreview->setPixmap(m_pLocalAvatar);
+ m_pAvatarPreview->setEnabled(bHaveAvatar);
+ connect(m_pUseAvatarCheck,SIGNAL(toggled(bool)),m_pAvatarPreview,SLOT(setEnabled(bool)));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(m_pAvatarPreview,szTip);
+#endif
+
+ KviTalHBox * hb = new KviTalHBox(this);
+ hb->setSpacing(4);
+ addWidgetToLayout(hb,0,2,0,2);
+
+ m_pAvatarNameEdit = new QLineEdit(hb);
+ m_pAvatarNameEdit->setReadOnly(true);
+ m_pAvatarNameEdit->setEnabled(bHaveAvatar);
+ m_pAvatarNameEdit->setText(KVI_OPTION_STRING(KviOption_stringMyAvatar));
+ connect(m_pUseAvatarCheck,SIGNAL(toggled(bool)),m_pAvatarNameEdit,SLOT(setEnabled(bool)));
+
+ m_pChooseAvatarButton = new QPushButton(__tr2qs_ctx("Choose...","options"),hb);
+ m_pChooseAvatarButton->setEnabled(bHaveAvatar);
+ connect(m_pUseAvatarCheck,SIGNAL(toggled(bool)),m_pChooseAvatarButton,SLOT(setEnabled(bool)));
+
+ connect(m_pChooseAvatarButton,SIGNAL(clicked()),this,SLOT(chooseAvatar()));
+
+ layout()->setRowStretch(1,2);
+}
+
+KviIdentityAvatarOptionsWidget::~KviIdentityAvatarOptionsWidget()
+{
+ delete m_pLocalAvatar;
+}
+
+
+void KviIdentityAvatarOptionsWidget::commit(void)
+{
+ KviOptionsWidget::commit();
+
+ QString szAvatarName = m_pAvatarNameEdit->text();
+
+ if(m_pUseAvatarCheck->isChecked() && m_pLocalAvatar->pixmap() && (!szAvatarName.isEmpty()))
+ {
+ KVI_OPTION_STRING(KviOption_stringMyAvatar) = szAvatarName;
+ KVI_OPTION_PIXMAP(KviOption_pixmapMyAvatar) = *m_pLocalAvatar;
+ g_pApp->setAvatarFromOptions();
+ } else {
+ KVI_OPTION_STRING(KviOption_stringMyAvatar) = "";
+ KVI_OPTION_PIXMAP(KviOption_pixmapMyAvatar) = KviPixmap();
+ }
+
+}
+
+
+void KviIdentityAvatarOptionsWidget::chooseAvatar()
+{
+ QString szCurrent = m_pAvatarNameEdit->text();
+
+ KviAvatarSelectionDialog dlg(this,szCurrent);
+ if(dlg.exec() != QDialog::Accepted)return;
+
+ szCurrent = dlg.avatarName();
+ szCurrent.stripWhiteSpace();
+
+ if(KviQString::equalCIN(szCurrent,"http://",7))
+ {
+ // this is an url
+ // first check if we have it in the cache
+ KviAvatar * a = g_pIconManager->getAvatar(QString::null,szCurrent);
+ if(!a)
+ {
+ // no cache... try downloading
+ KviAvatarDownloadDialog dlg(this,szCurrent);
+ if(dlg.exec() == QDialog::Accepted)
+ {
+ // downloaded!
+ // try to load it
+ if(!m_pLocalAvatar->load(dlg.localFileName()))
+ {
+ // unloadable
+ szCurrent = "";
+ QMessageBox::warning(this,__tr2qs_ctx("Failed to Load Avatar - KVIrc","options"),
+ __tr2qs_ctx("Failed to load the avatar image.<br>" \
+ "It may be an unaccessible file or an " \
+ "unsupported image format.","options"),QMessageBox::Ok,QMessageBox::NoButton);
+ } // else loaded!
+ } else {
+ // unloadable
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs_ctx("Failed to download the avatar image.<br>" \
+ "<b>%Q</b>","options"),&(dlg.errorMessage()));
+ QMessageBox::warning(this,__tr2qs_ctx("Avatar Download Failed - KVIrc","options"),tmp,QMessageBox::Ok,QMessageBox::NoButton);
+ szCurrent = "";
+ m_pLocalAvatar->setNull();
+ }
+ } else {
+ // else OK.. got it in the cache
+ m_pLocalAvatar->set(*(a->pixmap()),a->localPath());
+ delete a;
+ }
+ } else {
+ // this is a local path
+ if(m_pLocalAvatar->load(szCurrent))
+ {
+ // local path, loaded
+ QString tmp = szCurrent;
+ int idx = tmp.findRev("/");
+ if(idx != -1)
+ {
+ szCurrent = tmp.right(tmp.length() - (idx + 1));
+ tmp = szCurrent;
+ }
+ idx = tmp.findRev("\\");
+ if(idx != -1)
+ {
+ szCurrent = tmp.right(tmp.length() - (idx + 1));
+ tmp = szCurrent;
+ }
+ } else {
+ // unloadable
+ QMessageBox::warning(this,__tr2qs_ctx("Failed to Load Avatar - KVIrc","options"),
+ __tr2qs_ctx("Failed to load the avatar image.<br>" \
+ "It may be an unaccessible file or an " \
+ "unsupported image format.","options"),QMessageBox::Ok,QMessageBox::NoButton);
+ szCurrent = "";
+ }
+ }
+
+ if(m_pLocalAvatar->pixmap())
+ {
+ if((m_pLocalAvatar->pixmap()->width() > 1024) || (m_pLocalAvatar->pixmap()->height() > 768))
+ {
+ QMessageBox::warning(this,__tr2qs_ctx("Avatar Might Be Too Big - KVIrc","options"),
+ __tr2qs_ctx("The avatar you have choosen is bigger than 1024x768 pixels.<br>" \
+ "Such a big image will not be seen on all the user monitors<br>" \
+ "and will probably be scaled by the remote clients with poor quality<br>" \
+ "algorithms to improve performance. You *should* scale it manually<br>" \
+ "to a sane size (like 800x600) or choose a different image.","options"));
+ }
+ }
+
+ m_pAvatarNameEdit->setText(szCurrent);
+ m_pAvatarPreview->setPixmap(m_pLocalAvatar);
+}
+
+
+
+
+
+
+KviIdentityAdvancedOptionsWidget::KviIdentityAdvancedOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+ m_pISelector=0;
+ m_pWSelector=0;
+ m_pSSelector=0;
+
+ m_sModeStr = KVI_OPTION_STRING(KviOption_stringDefaultUserMode);
+ m_bI = m_sModeStr.contains('i');
+ m_bW = m_sModeStr.contains('w');
+ m_bS = m_sModeStr.contains('s');
+
+
+ createLayout(2,1);
+ layout()->setMargin(10);
+
+ KviTalGroupBox * gbox = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("User Mode","options"));
+ m_pISelector = addBoolSelector(gbox,__tr2qs_ctx("Invisible (+i)","options"),&m_bI);
+ m_pSSelector = addBoolSelector(gbox,__tr2qs_ctx("Server notices (+s)","options"),&m_bS);
+ m_pWSelector = addBoolSelector(gbox,__tr2qs_ctx("Wallops (+w)","options"),&m_bW);
+
+ gbox = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Default Messages","options"));
+
+
+ KviStringSelector * sel = addStringSelector(gbox, __tr2qs_ctx("Part message:","options"),KviOption_stringPartMessage);
+ sel->setMinimumLabelWidth(120);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(sel,__tr2qs_ctx("<center>This is the default part message that will be used when you<br>" \
+ "leave a channel by closing a channel window.</center>","options"));
+#endif
+
+ sel = addStringSelector(gbox, __tr2qs_ctx("Quit message:","options"),KviOption_stringQuitMessage);
+ sel->setMinimumLabelWidth(120);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(sel,__tr2qs_ctx("<center>This is the default quit message that will be used when you<br>" \
+ "quit your IRC session by closing the console window or disconnecting by pressing the disconnect button.</center>","options"));
+#endif
+
+ addRowSpacer(0,2,0,2);
+}
+
+KviIdentityAdvancedOptionsWidget::~KviIdentityAdvancedOptionsWidget()
+{
+}
+
+void KviIdentityAdvancedOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+
+ m_sModeStr = m_bI ? "i" : "";
+ if(m_bS)m_sModeStr += "s";
+ if(m_bW)m_sModeStr += "w";
+
+ KVI_OPTION_STRING(KviOption_stringDefaultUserMode) = m_sModeStr.ptr();
+}
+
+
+
+
+
+
+#include "m_optw_identity.moc"
diff --git a/src/modules/options/optw_identity.h b/src/modules/options/optw_identity.h
new file mode 100644
index 00000000..479614c4
--- /dev/null
+++ b/src/modules/options/optw_identity.h
@@ -0,0 +1,192 @@
+#ifndef _OPTW_IDENTITY_H_
+#define _OPTW_IDENTITY_H_
+
+//=============================================================================
+//
+// File : optw_identity.h
+// Creation date : Tue Nov 14 2000 23:06:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 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_optionswidget.h"
+#include "kvi_settings.h"
+#include "kvi_selectors.h"
+
+#include <qdialog.h>
+#include "kvi_pixmap.h"
+
+
+class QLineEdit;
+class QCheckBox;
+class QPushButton;
+class QComboBox;
+
+class KviNickAlternativesDialog : public QDialog
+{
+ friend class KviIdentityGeneralOptionsWidget;
+ Q_OBJECT
+protected:
+ KviNickAlternativesDialog(QWidget * par,const QString &n1,const QString &n2,const QString &n3);
+ ~KviNickAlternativesDialog();
+protected:
+ QLineEdit * m_pNickEdit1;
+ QLineEdit * m_pNickEdit2;
+ QLineEdit * m_pNickEdit3;
+protected:
+ void fill(QString &n1,QString &n2,QString &n3);
+};
+
+class KviAvatarSelectionDialog : public QDialog
+{
+ friend class KviIdentityAvatarOptionsWidget;
+ Q_OBJECT
+public:
+ KviAvatarSelectionDialog(QWidget * par,const QString &szInitialPath);
+ ~KviAvatarSelectionDialog();
+protected:
+ QLineEdit * m_pLineEdit;
+ QString m_szAvatarName;
+protected:
+ virtual void closeEvent(QCloseEvent * e);
+ const QString &avatarName(){ return m_szAvatarName; };
+protected slots:
+ void okClicked();
+ void cancelClicked();
+ void chooseFileClicked();
+};
+
+class KviHttpRequest;
+
+class KviAvatarDownloadDialog : public QDialog
+{
+ friend class KviIdentityAvatarOptionsWidget;
+ Q_OBJECT
+public:
+ KviAvatarDownloadDialog(QWidget * par,const QString &szUrl);
+ ~KviAvatarDownloadDialog();
+protected:
+ KviHttpRequest * m_pRequest;
+ QLabel * m_pOutput;
+ QString m_szErrorMessage;
+ QString m_szLocalFileName;
+ QString m_szUrl;
+protected:
+ virtual void closeEvent(QCloseEvent * e);
+ const QString & localFileName(){ return m_szLocalFileName; };
+ const QString & errorMessage(){ return m_szErrorMessage; };
+protected slots:
+ void startDownload();
+ void cancelClicked();
+ void downloadTerminated(bool bSuccess);
+ void downloadMessage(const char * msg);
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIdentityOptionsWidget KVI_SMALLICON_WHO
+#define KVI_OPTIONS_WIDGET_NAME_KviIdentityOptionsWidget __tr2qs_no_lookup("Identity")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityOptionsWidget 99998
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviIdentityOptionsWidget true
+
+
+class KviIdentityOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIdentityOptionsWidget(QWidget * parent);
+ ~KviIdentityOptionsWidget();
+};
+
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIdentityGeneralOptionsWidget KVI_SMALLICON_WHO
+#define KVI_OPTIONS_WIDGET_NAME_KviIdentityGeneralOptionsWidget __tr2qs_no_lookup("General")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityGeneralOptionsWidget 90000
+#define KVI_OPTIONS_WIDGET_PARENT_KviIdentityGeneralOptionsWidget KviIdentityOptionsWidget
+
+
+class KviIdentityGeneralOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIdentityGeneralOptionsWidget(QWidget * pParent);
+ ~KviIdentityGeneralOptionsWidget();
+protected:
+ QString m_szAltNicknames[3];
+
+ QComboBox * m_pAgeCombo;
+ QComboBox * m_pGenderCombo;
+protected slots:
+ void setNickAlternatives();
+protected:
+ virtual void commit(void);
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIdentityAvatarOptionsWidget KVI_SMALLICON_AVATAR
+#define KVI_OPTIONS_WIDGET_NAME_KviIdentityAvatarOptionsWidget __tr2qs_no_lookup("Avatar")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityAvatarOptionsWidget 80000
+#define KVI_OPTIONS_WIDGET_PARENT_KviIdentityAvatarOptionsWidget KviIdentityOptionsWidget
+
+
+class KviIdentityAvatarOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIdentityAvatarOptionsWidget(QWidget * pParent);
+ ~KviIdentityAvatarOptionsWidget();
+protected:
+ QCheckBox * m_pUseAvatarCheck;
+ QLineEdit * m_pAvatarNameEdit;
+ QPushButton * m_pChooseAvatarButton;
+ KviPixmap * m_pLocalAvatar;
+ KviPixmapPreview * m_pAvatarPreview;
+protected slots:
+ void chooseAvatar();
+protected:
+ virtual void commit(void);
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIdentityAdvancedOptionsWidget KVI_SMALLICON_SPY
+#define KVI_OPTIONS_WIDGET_NAME_KviIdentityAdvancedOptionsWidget __tr2qs_no_lookup("Advanced")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIdentityAdvancedOptionsWidget 70000
+#define KVI_OPTIONS_WIDGET_PARENT_KviIdentityAdvancedOptionsWidget KviIdentityOptionsWidget
+
+
+class KviIdentityAdvancedOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIdentityAdvancedOptionsWidget(QWidget * pParent);
+ ~KviIdentityAdvancedOptionsWidget();
+protected:
+ bool m_bI;
+ bool m_bW;
+ bool m_bS;
+ KviStr m_sModeStr;
+ KviBoolSelector * m_pISelector;
+ KviBoolSelector * m_pWSelector;
+ KviBoolSelector * m_pSSelector;
+protected:
+ virtual void commit(void);
+};
+
+#endif //!_OPTW_IDENTITY_H_
diff --git a/src/modules/options/optw_ignore.cpp b/src/modules/options/optw_ignore.cpp
new file mode 100644
index 00000000..26e4c0d9
--- /dev/null
+++ b/src/modules/options/optw_ignore.cpp
@@ -0,0 +1,62 @@
+//
+// File : optw_ignore.h
+// Creation date : Thu Feb 12 15:11:29 2002 GMT by Juanjo lvarez
+//
+// 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 "optw_ignore.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+//#warning "Info tips"
+
+
+KviIgnoreOptionsWidget::KviIgnoreOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ignore_options_widget")
+{
+ createLayout(3,1);
+
+ KviTalGroupBox *g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Enable Ignore For","options"));
+ m_pIgnorePrivmsg = addBoolSelector(g,__tr2qs_ctx("Private/channel messages","options"),KviOption_boolEnableIgnoreOnPrivMsg);
+ m_pIgnoreNotice = addBoolSelector(g,__tr2qs_ctx("Private/channel notices","options"),KviOption_boolEnableIgnoreOnNotice);
+
+ connect(m_pIgnorePrivmsg,SIGNAL(toggled(bool)),this,SLOT(enableVerbose(bool)));
+
+ m_pVerboseIgnore = addBoolSelector(0,1,0,1,__tr2qs_ctx("Use verbose ignore (show messages in console)","options"),
+ KviOption_boolVerboseIgnore,
+ KVI_OPTION_BOOL(KviOption_boolEnableIgnoreOnPrivMsg) || KVI_OPTION_BOOL(KviOption_boolEnableIgnoreOnNotice));
+
+ addRowSpacer(0,2,0,2);
+}
+
+KviIgnoreOptionsWidget::~KviIgnoreOptionsWidget()
+{
+}
+
+void KviIgnoreOptionsWidget::enableVerbose(bool)
+{
+ m_pVerboseIgnore->setEnabled(m_pIgnorePrivmsg->isChecked() || m_pIgnoreNotice->isChecked());
+}
+
+
+
+#include "m_optw_ignore.moc"
diff --git a/src/modules/options/optw_ignore.h b/src/modules/options/optw_ignore.h
new file mode 100644
index 00000000..cb7203f5
--- /dev/null
+++ b/src/modules/options/optw_ignore.h
@@ -0,0 +1,47 @@
+#ifndef _OPTW_IGNORE_H_
+#define _OPTW_IGNORE_H_
+//
+// File : optw_ignore.h
+// Creation date : Thu Feb 12 15:11:30 2002 GMT by Juanjo lvarez
+//
+// 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_optionswidget.h"
+#include "kvi_selectors.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIgnoreOptionsWidget KVI_SMALLICON_IGNORE
+#define KVI_OPTIONS_WIDGET_NAME_KviIgnoreOptionsWidget __tr2qs_no_lookup("Ignore")
+#define KVI_OPTIONS_WIDGET_PARENT_KviIgnoreOptionsWidget KviProtectionOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviIgnoreOptionsWidget __tr2qs_no_lookup("protection")
+
+class KviIgnoreOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIgnoreOptionsWidget(QWidget * parent);
+ ~KviIgnoreOptionsWidget();
+public:
+ KviBoolSelector * m_pIgnorePrivmsg;
+ KviBoolSelector * m_pIgnoreNotice;
+ KviBoolSelector * m_pVerboseIgnore;
+protected slots:
+ void enableVerbose(bool);
+};
+
+#endif //_OPTW_IGNORE_H_
diff --git a/src/modules/options/optw_input.cpp b/src/modules/options/optw_input.cpp
new file mode 100644
index 00000000..4dd73987
--- /dev/null
+++ b/src/modules/options/optw_input.cpp
@@ -0,0 +1,156 @@
+//
+// File : optw_input.cpp
+// Creation date : Sat Aug 11 2001 04:25:52 CEST 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 "optw_input.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+//#warning "Info tips"
+
+KviInputLookOptionsWidget::KviInputLookOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ircviewlook_options_widget")
+{
+ createLayout(10,2);
+
+ addFontSelector(0,0,1,0,__tr2qs_ctx("Font","options"),KviOption_fontInput);
+ addColorSelector(0,1,1,1,__tr2qs_ctx("Background color","options"),KviOption_colorInputBackground);
+ addColorSelector(0,2,1,2,__tr2qs_ctx("Foreground color","options"),KviOption_colorInputForeground);
+ addColorSelector(0,3,1,3,__tr2qs_ctx("Selection background color","options"),KviOption_colorInputSelectionBackground);
+ addColorSelector(0,4,1,4,__tr2qs_ctx("Selection foreground color","options"),KviOption_colorInputSelectionForeground);
+ addColorSelector(0,5,1,5,__tr2qs_ctx("Control char color","options"),KviOption_colorInputControl);
+ addColorSelector(0,6,1,6,__tr2qs_ctx("Cursor color","options"),KviOption_colorInputCursor);
+
+ addPixmapSelector(0,7,1,7,__tr2qs_ctx("Background image","options"),KviOption_pixmapInputBackground);
+
+ addLabel(0,8,0,8,__tr2qs_ctx("Horizontal align:","options"));
+ m_pHorizontalAlign=new QComboBox(this);
+ addWidgetToLayout(m_pHorizontalAlign,1,8,1,8);
+
+ addLabel(0,9,0,9,__tr2qs_ctx("Vertical align:","options"));
+ m_pVerticalAlign=new QComboBox(this);
+ addWidgetToLayout(m_pVerticalAlign,1,9,1,9);
+
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Tile","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Left","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Right","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Center","options"));
+
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Tile","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Top","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Bottom","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Center","options"));
+
+ switch( KVI_OPTION_UINT(KviOption_uintInputPixmapAlign) & Qt::AlignHorizontal_Mask)
+ {
+ case Qt::AlignLeft:
+ m_pHorizontalAlign->setCurrentItem(1);
+ break;
+ case Qt::AlignRight:
+ m_pHorizontalAlign->setCurrentItem(2);
+ break;
+ case Qt::AlignHCenter:
+ m_pHorizontalAlign->setCurrentItem(3);
+ break;
+ default:
+ m_pHorizontalAlign->setCurrentItem(0);
+ }
+
+ switch( KVI_OPTION_UINT(KviOption_uintInputPixmapAlign) & Qt::AlignVertical_Mask)
+ {
+ case Qt::AlignTop:
+ m_pVerticalAlign->setCurrentItem(1);
+ break;
+ case Qt::AlignBottom:
+ m_pVerticalAlign->setCurrentItem(2);
+ break;
+ case Qt::AlignVCenter:
+ m_pVerticalAlign->setCurrentItem(3);
+ break;
+ default:
+ m_pVerticalAlign->setCurrentItem(0);
+ }
+
+
+ layout()->setRowStretch(7,1);
+}
+
+KviInputLookOptionsWidget::~KviInputLookOptionsWidget()
+{
+}
+
+void KviInputLookOptionsWidget::commit()
+{
+ int iFlags=0;
+ switch(m_pHorizontalAlign->currentItem())
+ {
+ case 1:
+ iFlags|=Qt::AlignLeft;
+ break;
+ case 2:
+ iFlags|=Qt::AlignRight;
+ break;
+ case 3:
+ iFlags|=Qt::AlignHCenter;
+ break;
+ }
+ switch(m_pVerticalAlign->currentItem())
+ {
+ case 1:
+ iFlags|=Qt::AlignTop;
+ break;
+ case 2:
+ iFlags|=Qt::AlignBottom;
+ break;
+ case 3:
+ iFlags|=Qt::AlignVCenter;
+ break;
+ }
+
+ KVI_OPTION_UINT(KviOption_uintInputPixmapAlign)=iFlags;
+ KviOptionsWidget::commit();
+}
+
+
+
+KviInputFeaturesOptionsWidget::KviInputFeaturesOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ircviewfeatures_options_widget")
+{
+ createLayout(6,1);
+
+ addBoolSelector(0,0,0,0,__tr2qs_ctx("Warp cursor at the end of line when browsing history","options"),KviOption_boolInputHistoryCursorAtEnd);
+ addBoolSelector(0,1,0,1,__tr2qs_ctx("Disable the input history window and it's log memory.","options"),KviOption_boolDisableInputHistory); //G&N 2005
+ addBoolSelector(0,2,0,2,__tr2qs_ctx("Hide input toolbuttons by default","options"),KviOption_boolHideInputToolButtons);
+ KviTalGroupBox * g = addGroupBox(0,3,0,3,1,Qt::Horizontal,__tr2qs_ctx("Nick completion","options"));
+ addBoolSelector(g,__tr2qs_ctx("Use bash-like nick completion","options"),KviOption_boolBashLikeNickCompletion);
+ addStringSelector(g,__tr2qs_ctx("Nick completion postfix string","options"),KviOption_stringNickCompletionPostfix);
+ addBoolSelector(g,__tr2qs_ctx("Use the completion postfix string for the first word only","options"),KviOption_boolUseNickCompletionPostfixForFirstWordOnly);
+ addBoolSelector(0,4,0,4,__tr2qs_ctx("Commandline in user-friendly mode by default","options"),KviOption_boolCommandlineInUserFriendlyModeByDefault);
+ addRowSpacer(0,5,0,5);
+}
+
+KviInputFeaturesOptionsWidget::~KviInputFeaturesOptionsWidget()
+{
+}
+
+#include "m_optw_input.moc"
diff --git a/src/modules/options/optw_input.h b/src/modules/options/optw_input.h
new file mode 100644
index 00000000..eb088460
--- /dev/null
+++ b/src/modules/options/optw_input.h
@@ -0,0 +1,61 @@
+#ifndef _OPTW_INPUT_H_
+#define _OPTW_INPUT_H_
+
+//==================================================================================
+//
+// File : optw_input.h
+// Creation date : Sat Aug 11 2001 04:25:01 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2006 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_optionswidget.h"
+#include <qcombobox.h>
+
+#define KVI_OPTIONS_WIDGET_ICON_KviInputLookOptionsWidget KVI_SMALLICON_INPUT
+#define KVI_OPTIONS_WIDGET_NAME_KviInputLookOptionsWidget __tr2qs_no_lookup("Input")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviInputLookOptionsWidget __tr2qs_no_lookup("theme,colors,text")
+#define KVI_OPTIONS_WIDGET_GROUP_KviInputLookOptionsWidget "theme"
+
+class KviInputLookOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+private:
+ QComboBox* m_pHorizontalAlign;
+ QComboBox* m_pVerticalAlign;
+public:
+ KviInputLookOptionsWidget(QWidget * parent);
+ ~KviInputLookOptionsWidget();
+
+ virtual void commit();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviInputFeaturesOptionsWidget KVI_SMALLICON_INPUT
+#define KVI_OPTIONS_WIDGET_NAME_KviInputFeaturesOptionsWidget __tr2qs_no_lookup("Input")
+#define KVI_OPTIONS_WIDGET_PARENT_KviInputFeaturesOptionsWidget KviInterfaceFeaturesOptionsWidget
+
+class KviInputFeaturesOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviInputFeaturesOptionsWidget(QWidget * parent);
+ ~KviInputFeaturesOptionsWidget();
+};
+
+#endif //!_OPTW_INPUT_H_
diff --git a/src/modules/options/optw_interfacefeatures.cpp b/src/modules/options/optw_interfacefeatures.cpp
new file mode 100644
index 00000000..3cae7662
--- /dev/null
+++ b/src/modules/options/optw_interfacefeatures.cpp
@@ -0,0 +1,88 @@
+//=============================================================================
+//
+// File : optw_interfacefeatures.cpp
+// Creation date : Sat Jun 2 2001 14:52:53 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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 "optw_interfacefeatures.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <string.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_fileutils.h"
+
+KviInterfaceFeaturesOptionsWidget::KviInterfaceFeaturesOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"interfacefeatures_options_widget")
+{
+ createLayout(8,1);
+
+
+
+ addBoolSelector(0,0,0,0,__tr2qs_ctx("Minimize on startup","options"),KviOption_boolStartupMinimized);
+ addBoolSelector(0,1,0,1,__tr2qs_ctx("Confirm quit with active connections","options"),KviOption_boolConfirmCloseWhenThereAreConnections);
+ addBoolSelector(0,2,0,2,__tr2qs_ctx("Remember window properties","options"),KviOption_boolWindowsRememberProperties);
+
+ QString szSplashDisableFile;
+ g_pApp->getLocalKvircDirectory(szSplashDisableFile,KviApp::Pics,"disable-splash." KVI_VERSION);
+ bool bDisableSplash = KviFileUtils::fileExists(szSplashDisableFile);
+ m_pDisableSplash = new KviStyledCheckBox(__tr2qs_ctx("Disable splash screen","options"),this);
+ addWidgetToLayout(m_pDisableSplash,0,3,0,3);
+ m_pDisableSplash->setChecked(bDisableSplash);
+
+ addBoolSelector(0,4,0,4,__tr2qs_ctx("Enable visual effects","options"),KviOption_boolEnableVisualEffects);
+ addBoolSelector(0,5,0,5,__tr2qs_ctx("Hide Channel window tool buttons by default","options"),KviOption_boolHideWindowToolButtons);
+
+ KviTalGroupBox * g = addGroupBox(0,6,0,6,1,Qt::Horizontal,__tr2qs_ctx("Open Dialog Window For","options"));
+ addBoolSelector(g,__tr2qs_ctx("Preferences","options"),KviOption_boolShowGeneralOptionsDialogAsToplevel);
+ addBoolSelector(g,__tr2qs_ctx("Registered Users","options"),KviOption_boolShowRegisteredUsersDialogAsToplevel);
+ addBoolSelector(g,__tr2qs_ctx("Identity","options"),KviOption_boolShowIdentityDialogAsToplevel);
+ addBoolSelector(g,__tr2qs_ctx("Servers","options"),KviOption_boolShowServersConnectDialogAsToplevel);
+ addBoolSelector(g,__tr2qs_ctx("Join Channels","options"),KviOption_boolShowChannelsJoinDialogAsToplevel);
+ addRowSpacer(0,7,0,7);
+}
+
+KviInterfaceFeaturesOptionsWidget::~KviInterfaceFeaturesOptionsWidget()
+{
+}
+
+void KviInterfaceFeaturesOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+
+ QString szSplashDisableFile;
+ g_pApp->getLocalKvircDirectory(szSplashDisableFile,KviApp::Pics,"disable-splash." KVI_VERSION);
+
+ if(m_pDisableSplash->isChecked())
+ {
+ if(!KviFileUtils::fileExists(szSplashDisableFile))
+ KviFileUtils::writeFile(szSplashDisableFile,"");
+ } else {
+ if(KviFileUtils::fileExists(szSplashDisableFile))
+ KviFileUtils::removeFile(szSplashDisableFile);
+ }
+
+}
+
+#include "m_optw_interfacefeatures.moc"
diff --git a/src/modules/options/optw_interfacefeatures.h b/src/modules/options/optw_interfacefeatures.h
new file mode 100644
index 00000000..f85dfb9e
--- /dev/null
+++ b/src/modules/options/optw_interfacefeatures.h
@@ -0,0 +1,48 @@
+#ifndef _OPTW_INTERFACEFEATURES_H_
+#define _OPTW_INTERFACEFEATURES_H_
+
+//=============================================================================
+//
+// File : optw_interfacefeatures.h
+// Creation date : Sat Jun 2 2001 14:50:01 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviInterfaceFeaturesOptionsWidget KVI_SMALLICON_IDEA
+#define KVI_OPTIONS_WIDGET_NAME_KviInterfaceFeaturesOptionsWidget __tr2qs_no_lookup("Interface")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviInterfaceFeaturesOptionsWidget 50000
+
+class QCheckBox;
+
+class KviInterfaceFeaturesOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviInterfaceFeaturesOptionsWidget(QWidget * parent);
+ ~KviInterfaceFeaturesOptionsWidget();
+protected:
+ QCheckBox * m_pDisableSplash;
+public:
+ virtual void commit();
+};
+
+#endif //!_OPTW_INTERFACEFEATURES_H_
diff --git a/src/modules/options/optw_interfacelookglobal.cpp b/src/modules/options/optw_interfacelookglobal.cpp
new file mode 100644
index 00000000..50cf845f
--- /dev/null
+++ b/src/modules/options/optw_interfacelookglobal.cpp
@@ -0,0 +1,215 @@
+//
+// File : optw_interfacelookglobal.cpp
+// Creation date : Sun Jun 3 2001 20:50:13 CEST 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 "optw_interfacelookglobal.h"
+
+#include <qlayout.h>
+
+#include "kvi_settings.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviThemeGeneralOptionsWidget::KviThemeGeneralOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+ createLayout(4,2);
+
+ KviBoolSelector * b = addBoolSelector(0,1,1,1,__tr2qs_ctx("Use global application font","options"),KviOption_boolUseGlobalApplicationFont);
+ KviBoolSelector * g = addBoolSelector(0,0,1,0,__tr2qs_ctx("Hide icons in Popup","options"),KviOption_boolDisablePopupIcons);
+ KviFontSelector * f = addFontSelector(0,2,1,2,__tr2qs_ctx("Global application font:","options"),KviOption_fontApplication,
+ KVI_OPTION_BOOL(KviOption_boolUseGlobalApplicationFont));
+
+ connect(b,SIGNAL(toggled(bool)),f,SLOT(setEnabled(bool)));
+
+ addRowSpacer(0,3,1,3);
+}
+
+KviThemeGeneralOptionsWidget::~KviThemeGeneralOptionsWidget()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviThemeTransparencyOptionsWidget::KviThemeTransparencyOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+
+ #ifdef COMPILE_KDE_SUPPORT
+ createLayout(7,2);
+ #else
+ createLayout(5,2);
+ #endif
+
+ m_pUseTransparencyBoolSelector = addBoolSelector(0,0,1,0,__tr2qs_ctx("Enable fake transparency","options"),KviOption_boolUseGlobalPseudoTransparency);
+#ifdef COMPILE_INFO_TIPS
+ #ifdef COMPILE_KDE_SUPPORT
+ mergeTip(m_pUseTransparencyBoolSelector,
+ __tr2qs_ctx("<center>This option makes all KVIrc windows look " \
+ "transparent.<br>You must choose a blending " \
+ "background image to below or check the " \
+ "\"Use KDE desktop for transparency\" option.</center>","options"));
+ #else
+ mergeTip(m_pUseTransparencyBoolSelector,
+ __tr2qs_ctx("<center>This option makes all KVIrc windows look " \
+ "like transparent.<br>You must choose a blending " \
+ "background image to below.</center>","options"));
+ #endif
+#endif
+
+ KviUIntSelector * u = addUIntSelector(0,1,1,1,__tr2qs_ctx("Child window opacity:","options"),KviOption_uintGlobalTransparencyChildFadeFactor,
+ 0,100,35,KVI_OPTION_BOOL(KviOption_boolUseGlobalPseudoTransparency));
+ connect(m_pUseTransparencyBoolSelector,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ u = addUIntSelector(0,2,1,2,__tr2qs_ctx("Parent window opacity:","options"),KviOption_uintGlobalTransparencyParentFadeFactor,
+ 0,100,10,KVI_OPTION_BOOL(KviOption_boolUseGlobalPseudoTransparency));
+ connect(m_pUseTransparencyBoolSelector,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool)));
+
+ KviColorSelector * c = addColorSelector(0,3,1,3,__tr2qs_ctx("Blend color:","options"),KviOption_colorGlobalTransparencyFade,
+ KVI_OPTION_BOOL(KviOption_boolUseGlobalPseudoTransparency));
+ connect(m_pUseTransparencyBoolSelector,SIGNAL(toggled(bool)),c,SLOT(setEnabled(bool)));
+
+// addRowSpacer(0,13,0,13);
+#ifdef COMPILE_KDE_SUPPORT
+ m_pObtainBackgroundFromKdeBoolSelector = addBoolSelector(0,4,1,4,__tr2qs_ctx("Use KDE desktop for transparency","options"),KviOption_boolObtainGlobalBackgroundFromKde,
+ KVI_OPTION_BOOL(KviOption_boolUseGlobalPseudoTransparency));
+ connect(m_pUseTransparencyBoolSelector,SIGNAL(toggled(bool)),m_pObtainBackgroundFromKdeBoolSelector,SLOT(setEnabled(bool)));
+ connect(m_pObtainBackgroundFromKdeBoolSelector,SIGNAL(toggled(bool)),this,SLOT(enableUpdateKdeBackgroundBoolSelector(bool)));
+
+ m_pUpdateKdeBackgroundOnChangeBoolSelector = addBoolSelector(0,5,1,5,__tr2qs_ctx("Keep in sync with KDE background changes","options"),KviOption_boolUpdateKdeBackgroundOnChange,
+ KVI_OPTION_BOOL(KviOption_boolUseGlobalPseudoTransparency) && KVI_OPTION_BOOL(KviOption_boolObtainGlobalBackgroundFromKde));
+
+ m_pGlobalBackgroundPixmapSelector = addPixmapSelector(0,6,1,6,__tr2qs_ctx("Transparency blend image:","options"),KviOption_pixmapGlobalTransparencyBackground,
+ KVI_OPTION_BOOL(KviOption_boolUseGlobalPseudoTransparency) && !KVI_OPTION_BOOL(KviOption_boolObtainGlobalBackgroundFromKde));
+ layout()->setRowStretch(6,1);
+ connect(m_pObtainBackgroundFromKdeBoolSelector,SIGNAL(toggled(bool)),this,SLOT(enableGlobalBackgroundPixmapSelector(bool)));
+
+#else //!COMPILE_KDE_SUPPORT
+ m_pGlobalBackgroundPixmapSelector = addPixmapSelector(0,4,1,4,__tr2qs_ctx("Transparency blend image:","options"),KviOption_pixmapGlobalTransparencyBackground,
+ KVI_OPTION_BOOL(KviOption_boolUseGlobalPseudoTransparency));
+ layout()->setRowStretch(4,1);
+#endif //!COMPILE_KDE_SUPPORT
+ connect(m_pUseTransparencyBoolSelector,SIGNAL(toggled(bool)),this,SLOT(enableGlobalBackgroundPixmapSelector(bool)));
+ connect(m_pUseTransparencyBoolSelector,SIGNAL(toggled(bool)),this,SLOT(enableUpdateKdeBackgroundBoolSelector(bool)));
+#else
+ createLayout(1,1);
+ addRowSpacer(0,0,0,0);
+#endif
+}
+
+KviThemeTransparencyOptionsWidget::~KviThemeTransparencyOptionsWidget()
+{
+}
+
+void KviThemeTransparencyOptionsWidget::enableGlobalBackgroundPixmapSelector(bool)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ #ifdef COMPILE_KDE_SUPPORT
+ m_pGlobalBackgroundPixmapSelector->setEnabled(m_pUseTransparencyBoolSelector->isChecked() && !(m_pObtainBackgroundFromKdeBoolSelector->isChecked()));
+ #else
+ m_pGlobalBackgroundPixmapSelector->setEnabled(m_pUseTransparencyBoolSelector->isChecked());
+ #endif
+#endif
+}
+
+void KviThemeTransparencyOptionsWidget::enableUpdateKdeBackgroundBoolSelector(bool)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ #ifdef COMPILE_KDE_SUPPORT
+ m_pUpdateKdeBackgroundOnChangeBoolSelector->setEnabled(m_pUseTransparencyBoolSelector->isChecked() && m_pObtainBackgroundFromKdeBoolSelector->isChecked());
+ #endif
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviThemeMdiCaptionsOptionsWidget::KviThemeMdiCaptionsOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+ createLayout(7,1);
+
+ addColorSelector(0,0,0,0,__tr2qs_ctx("Active Background","options"),KviOption_colorMdiCaptionActive);
+ addColorSelector(0,1,0,1,__tr2qs_ctx("Inactive Background","options"),KviOption_colorMdiCaptionInactive);
+ addColorSelector(0,2,0,2,__tr2qs_ctx("Active Text (Primary)","options"),KviOption_colorCaptionTextActive);
+ addColorSelector(0,3,0,3,__tr2qs_ctx("Active Text (Secondary)","options"),KviOption_colorCaptionTextActive2);
+ addColorSelector(0,4,0,4,__tr2qs_ctx("Inactive Text (Primary)","options"),KviOption_colorCaptionTextInactive);
+ addColorSelector(0,5,0,5,__tr2qs_ctx("Inactive Text (Secondary)","options"),KviOption_colorCaptionTextInactive2);
+
+ addRowSpacer(0,6,0,6);
+}
+
+KviThemeMdiCaptionsOptionsWidget::~KviThemeMdiCaptionsOptionsWidget()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviThemeMdiAreaOptionsWidget::KviThemeMdiAreaOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+ createLayout(2,1);
+
+ addColorSelector(0,0,0,0,__tr2qs_ctx("Background","options"),KviOption_colorMdiBackground);
+ addPixmapSelector(0,1,0,1,__tr2qs_ctx("Background Image","options"),KviOption_pixmapMdiBackground);
+
+ layout()->setRowStretch(1,1);
+}
+
+KviThemeMdiAreaOptionsWidget::~KviThemeMdiAreaOptionsWidget()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviThemeToolBarAppletsOptionsWidget::KviThemeToolBarAppletsOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+ createLayout(9,1);
+
+ addFontSelector(0,0,0,0,__tr2qs_ctx("Font","options"),KviOption_fontIrcToolBarApplet);
+
+ addColorSelector(0,1,0,1,__tr2qs_ctx("Background","options"),KviOption_colorIrcToolBarAppletBackground);
+ addColorSelector(0,2,0,2,__tr2qs_ctx("Low-Contrast Foreground","options"),KviOption_colorIrcToolBarAppletForegroundLowContrast);
+ addColorSelector(0,3,0,3,__tr2qs_ctx("Mid-Contrast Foreground","options"),KviOption_colorIrcToolBarAppletForegroundMidContrast);
+ addColorSelector(0,4,0,4,__tr2qs_ctx("Active High-Contrast Foreground (Primary)","options"),KviOption_colorIrcToolBarAppletForegroundHighContrastActive1);
+ addColorSelector(0,5,0,5,__tr2qs_ctx("Active High-Contrast Foreground (Secondary)","options"),KviOption_colorIrcToolBarAppletForegroundHighContrastActive2);
+ addColorSelector(0,6,0,6,__tr2qs_ctx("Inactive High-Contrast Foreground (Primary)","options"),KviOption_colorIrcToolBarAppletForegroundHighContrastInactive1);
+ addColorSelector(0,7,0,7,__tr2qs_ctx("Inactive High-Contrast Foreground (Secondary)","options"),KviOption_colorIrcToolBarAppletForegroundHighContrastInactive2);
+
+ addPixmapSelector(0,8,0,8,__tr2qs_ctx("Background Image","options"),KviOption_pixmapIrcToolBarAppletBackground);
+
+ layout()->setRowStretch(8,1);
+}
+
+KviThemeToolBarAppletsOptionsWidget::~KviThemeToolBarAppletsOptionsWidget()
+{
+}
+
+
+#include "m_optw_interfacelookglobal.moc"
diff --git a/src/modules/options/optw_interfacelookglobal.h b/src/modules/options/optw_interfacelookglobal.h
new file mode 100644
index 00000000..ac4153b1
--- /dev/null
+++ b/src/modules/options/optw_interfacelookglobal.h
@@ -0,0 +1,113 @@
+#ifndef _OPTW_INTERFACELOOKGLOBAL_H_
+#define _OPTW_INTERFACELOOKGLOBAL_H_
+
+//
+// File : optw_interfacelookglobal.h
+// Creation date : Sun Jun 3 2001 20:49:02 CEST 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_settings.h"
+#include "kvi_optionswidget.h"
+#include "kvi_selectors.h"
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviThemeGeneralOptionsWidget KVI_SMALLICON_GUI
+#define KVI_OPTIONS_WIDGET_NAME_KviThemeGeneralOptionsWidget __tr2qs_no_lookup("General")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeGeneralOptionsWidget __tr2qs_no_lookup("theme")
+#define KVI_OPTIONS_WIDGET_GROUP_KviThemeGeneralOptionsWidget "theme"
+
+
+class KviThemeGeneralOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviThemeGeneralOptionsWidget(QWidget * parent);
+ ~KviThemeGeneralOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviThemeTransparencyOptionsWidget KVI_SMALLICON_TRANSPARENT
+#define KVI_OPTIONS_WIDGET_NAME_KviThemeTransparencyOptionsWidget __tr2qs_no_lookup("Transparency")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeTransparencyOptionsWidget __tr2qs_no_lookup("theme,background")
+#define KVI_OPTIONS_WIDGET_GROUP_KviThemeTransparencyOptionsWidget "theme"
+
+
+class KviThemeTransparencyOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviThemeTransparencyOptionsWidget(QWidget * parent);
+ ~KviThemeTransparencyOptionsWidget();
+protected:
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ KviPixmapSelector * m_pGlobalBackgroundPixmapSelector;
+ KviBoolSelector * m_pUseTransparencyBoolSelector;
+ #ifdef COMPILE_KDE_SUPPORT
+ KviBoolSelector * m_pObtainBackgroundFromKdeBoolSelector;
+ KviBoolSelector * m_pUpdateKdeBackgroundOnChangeBoolSelector;
+ #endif
+#endif
+protected slots:
+ void enableGlobalBackgroundPixmapSelector(bool);
+ void enableUpdateKdeBackgroundBoolSelector(bool);
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviThemeMdiCaptionsOptionsWidget KVI_SMALLICON_CAPTION
+#define KVI_OPTIONS_WIDGET_NAME_KviThemeMdiCaptionsOptionsWidget __tr2qs_no_lookup("Window Captions")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeMdiCaptionsOptionsWidget __tr2qs_no_lookup("theme,mdi")
+#define KVI_OPTIONS_WIDGET_GROUP_KviThemeMdiCaptionsOptionsWidget "theme"
+
+class KviThemeMdiCaptionsOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviThemeMdiCaptionsOptionsWidget(QWidget * parent);
+ ~KviThemeMdiCaptionsOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviThemeMdiAreaOptionsWidget KVI_SMALLICON_APPLET
+#define KVI_OPTIONS_WIDGET_NAME_KviThemeMdiAreaOptionsWidget __tr2qs_no_lookup("Workspace")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeMdiAreaOptionsWidget __tr2qs_no_lookup("theme,mdi")
+#define KVI_OPTIONS_WIDGET_GROUP_KviThemeMdiAreaOptionsWidget "theme"
+
+class KviThemeMdiAreaOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviThemeMdiAreaOptionsWidget(QWidget * parent);
+ ~KviThemeMdiAreaOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviThemeToolBarAppletsOptionsWidget KVI_SMALLICON_APPLET
+#define KVI_OPTIONS_WIDGET_NAME_KviThemeToolBarAppletsOptionsWidget __tr2qs_no_lookup("ToolBar Applets")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeToolBarAppletsOptionsWidget __tr2qs_no_lookup("theme,toolbar")
+#define KVI_OPTIONS_WIDGET_GROUP_KviThemeToolBarAppletsOptionsWidget "theme"
+
+
+class KviThemeToolBarAppletsOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviThemeToolBarAppletsOptionsWidget(QWidget * parent);
+ ~KviThemeToolBarAppletsOptionsWidget();
+};
+
+#endif //!_OPTW_INTERFACELOOKGLOBAL_H_
diff --git a/src/modules/options/optw_irc.cpp b/src/modules/options/optw_irc.cpp
new file mode 100644
index 00000000..537fde9a
--- /dev/null
+++ b/src/modules/options/optw_irc.cpp
@@ -0,0 +1,220 @@
+//
+// File : optw_irc.cpp
+// Creation date : Sun Dec 2 18:59:48 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 "optw_irc.h"
+
+#include "kvi_settings.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_ircmask.h"
+
+#include <qcombobox.h>
+
+
+KviIrcOptionsWidget::KviIrcOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"irc_options_widget")
+{
+}
+
+
+KviIrcOptionsWidget::~KviIrcOptionsWidget()
+{
+}
+
+
+KviIrcGeneralOptionsWidget::KviIrcGeneralOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"irc_options_widget")
+{
+ createLayout(3,1);
+ KviBoolSelector *b = addBoolSelector(0,0,0,0,__tr2qs_ctx("Minimize console after successful login","options"),KviOption_boolMinimizeConsoleAfterConnect);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>This option will cause KVIrc to minimize the console window after successfully logging into a server.</center>","options"));
+#endif
+
+ b = addBoolSelector(0,1,0,1,__tr2qs_ctx("Show network name in console taskbar entry","options"),KviOption_boolShowNetworkNameForConsoleTaskBarEntry);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>This option will cause KVIrc to show the network name as the console taskbar entry instead of the server name. This is nice to keep on unless your servers are not organized in networks or you often connect to two servers of the same network.</center>","options"));
+#endif
+
+
+ addRowSpacer(0,2,0,2);
+}
+
+
+KviIrcGeneralOptionsWidget::~KviIrcGeneralOptionsWidget()
+{
+}
+
+
+
+KviIrcAdvancedOptionsWidget::KviIrcAdvancedOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"irc_advanced_options_widget")
+{
+ createLayout(3,1);
+ KviBoolSelector *b = addBoolSelector(0,0,0,0,__tr2qs_ctx("Force immediate quit","options"),KviOption_boolForceBrutalQuit);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes KVIrc to close " \
+ "the connection immediately after sending the QUIT message.<br>" \
+ "When this option is disabled, KVIrc will wait for the server " \
+ "to close the connection.<br>" \
+ "Note that if you use this, your QUIT message may be not displayed.</center>","options"));
+#endif
+ addBoolSelector(0,1,0,1,__tr2qs_ctx("Prepend gender info to realname","options"),KviOption_boolPrependGenderInfoToRealname);
+}
+
+KviIrcAdvancedOptionsWidget::~KviIrcAdvancedOptionsWidget()
+{
+}
+
+
+
+
+
+KviChannelOptionsWidget::KviChannelOptionsWidget(QWidget * pParent)
+: KviOptionsWidget(pParent)
+{
+}
+
+KviChannelOptionsWidget::~KviChannelOptionsWidget()
+{
+}
+
+
+KviChannelGeneralOptionsWidget::KviChannelGeneralOptionsWidget(QWidget * pParent)
+: KviOptionsWidget(pParent)
+{
+ createLayout(5,1);
+
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("On Channel Kick","options"));
+
+ KviBoolSelector *b = addBoolSelector(g,__tr2qs_ctx("Rejoin channel","options"),KviOption_boolRejoinChannelOnKick);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option will cause KVIrc to attempt " \
+ "to rejoin a channel after being kicked.</center>","options"));
+#endif
+ b = addBoolSelector(g,__tr2qs_ctx("Keep channel open","options"),KviOption_boolKeepChannelOpenOnKick);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option will cause KVIrc to keep " \
+ "the channel window open after being kicked.<br>" \
+ "It might be a good idea to also enable the " \
+ "\"Rejoin channel\" option.</center>","options"));
+#endif
+
+ g = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("On Channel Part","options"));
+
+ b = addBoolSelector(g,__tr2qs_ctx("Keep channel open","options"),KviOption_boolKeepChannelOpenOnPart);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option will cause KVIrc to keep " \
+ "the channel window open after leaving it.</center>","options"));
+#endif
+
+ b = addBoolSelector(0,2,0,2,__tr2qs_ctx("Automatically join channel on invite","options"),KviOption_boolAutoJoinOnInvite);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option will cause KVIrc to automatically " \
+ "join a channel when an INVITE message for that channel is received.<br>" \
+ "<b>Warning:</b> This may help spammers harass you. :)</center>","options"));
+#endif
+
+ b = addBoolSelector(0,3,0,3, __tr2qs_ctx("Always open channels as minimized","options"),KviOption_boolCreateMinimizedChannels);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes newly created " \
+ "channel windows to be immediately minimized.<br>" \
+ "Enable this if you don't like channels " \
+ "popping up while you're typing something in a channel. :D</center>","options"));
+#endif
+
+
+ addRowSpacer(0,4,0,4);
+}
+
+KviChannelGeneralOptionsWidget::~KviChannelGeneralOptionsWidget()
+{
+}
+
+
+KviChannelAdvancedOptionsWidget::KviChannelAdvancedOptionsWidget(QWidget * pParent)
+: KviOptionsWidget(pParent)
+{
+ createLayout(6,4);
+
+ KviBoolSelector * b = addBoolSelector(0,0,4,0,__tr2qs_ctx("Log joined channels history","options"),KviOption_boolLogChannelHistory);
+
+ addLabel(0,1,0,1,__tr2qs_ctx("Default ban mask:","options"));
+
+ m_pBanTypeCombo=new QComboBox(this);
+ addWidgetToLayout(m_pBanTypeCombo,1,1,4,1);
+
+ KviIrcMask hostmask("nick!user@machine.host.top");
+ KviIrcMask ipmask("nick!user@192.168.1.2");
+ QString tmp1;
+ QString tmp2;
+ for(int i=0;i<=26;i++)
+ {
+
+ hostmask.mask(tmp1,(KviIrcMask::MaskType)i);
+ ipmask.mask(tmp2,(KviIrcMask::MaskType)i);
+ m_pBanTypeCombo->insertItem(QString("%1 (%2)").arg(tmp1).arg(tmp2));
+ }
+ m_pBanTypeCombo->setCurrentItem(KVI_OPTION_UINT(KviOption_uintDefaultBanType));
+
+ KviTalGroupBox * g = addGroupBox(0,2,4,2,1,Qt::Horizontal,__tr2qs_ctx("On Channel Join","options"));
+ addBoolSelector(g,__tr2qs_ctx("Do not send /WHO request","options"),KviOption_boolDisableWhoRequestOnJoin);
+ addBoolSelector(g,__tr2qs_ctx("Do not request ban list","options"),KviOption_boolDisableBanListRequestOnJoin);
+ addBoolSelector(g,__tr2qs_ctx("Do not request ban exception list","options"),KviOption_boolDisableBanExceptionListRequestOnJoin);
+ addBoolSelector(g,__tr2qs_ctx("Do not request invite list","options"),KviOption_boolDisableInviteListRequestOnJoin);
+
+ b = addBoolSelector(0,3,4,3,__tr2qs_ctx("Do not update the away list","options"),KviOption_boolDisableAwayListUpdates);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>KVIrc sends out a channel /WHO message every now and then to keep " \
+ "the channel away list in sync. Use this option to disable this feature (and to save " \
+ "your IRC bandwidth.</center>","options"));
+#endif
+
+ g = addGroupBox(0,4,4,4,1,Qt::Horizontal,__tr2qs_ctx("On Channel Join","options"));
+ addBoolSelector(g,__tr2qs_ctx("Echo channel topic","options"),KviOption_boolEchoNumericTopic);
+ addBoolSelector(g,__tr2qs_ctx("Show channel sync time","options"),KviOption_boolShowChannelSyncTime);
+
+ addRowSpacer(0,5,4,5);
+}
+
+KviChannelAdvancedOptionsWidget::~KviChannelAdvancedOptionsWidget()
+{
+}
+
+void KviChannelAdvancedOptionsWidget::commit()
+{
+ KVI_OPTION_UINT(KviOption_uintDefaultBanType)=m_pBanTypeCombo->currentItem();
+ if((KVI_OPTION_UINT(KviOption_uintDefaultBanType)<0 )|| (KVI_OPTION_UINT(KviOption_uintDefaultBanType)>26)) KVI_OPTION_UINT(KviOption_uintDefaultBanType)=7;
+ KviOptionsWidget::commit();
+}
+
+#include "m_optw_irc.moc"
diff --git a/src/modules/options/optw_irc.h b/src/modules/options/optw_irc.h
new file mode 100644
index 00000000..cc33d284
--- /dev/null
+++ b/src/modules/options/optw_irc.h
@@ -0,0 +1,116 @@
+#ifndef _OPTW_IRC_H_
+#define _OPTW_IRC_H_
+//=============================================================================
+//
+// File : optw_irc.h
+// Creation date : Sun Dec 2 18:59:49 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2006 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_optionswidget.h"
+
+class QComboBox;
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIrcOptionsWidget KVI_SMALLICON_IRC
+#define KVI_OPTIONS_WIDGET_NAME_KviIrcOptionsWidget __tr2qs_no_lookup("IRC")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIrcOptionsWidget 80000
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviIrcOptionsWidget true
+
+class KviIrcOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIrcOptionsWidget(QWidget * parent);
+ ~KviIrcOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIrcGeneralOptionsWidget KVI_SMALLICON_IRC
+#define KVI_OPTIONS_WIDGET_NAME_KviIrcGeneralOptionsWidget __tr2qs_no_lookup("General")
+#define KVI_OPTIONS_WIDGET_PARENT_KviIrcGeneralOptionsWidget KviIrcOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIrcGeneralOptionsWidget 80000
+
+class KviIrcGeneralOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIrcGeneralOptionsWidget(QWidget * parent);
+ ~KviIrcGeneralOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIrcAdvancedOptionsWidget KVI_SMALLICON_IRC
+#define KVI_OPTIONS_WIDGET_NAME_KviIrcAdvancedOptionsWidget __tr2qs_no_lookup("Advanced")
+#define KVI_OPTIONS_WIDGET_PARENT_KviIrcAdvancedOptionsWidget KviIrcOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIrcAdvancedOptionsWidget 50000
+
+class KviIrcAdvancedOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIrcAdvancedOptionsWidget(QWidget * parent);
+ ~KviIrcAdvancedOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviChannelOptionsWidget KVI_SMALLICON_CHANNEL
+#define KVI_OPTIONS_WIDGET_NAME_KviChannelOptionsWidget __tr2qs_no_lookup("Channel")
+#define KVI_OPTIONS_WIDGET_PARENT_KviChannelOptionsWidget KviIrcOptionsWidget
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviChannelOptionsWidget true
+#define KVI_OPTIONS_WIDGET_NOTCONTAINED_KviChannelOptionsWidget true
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviChannelOptionsWidget 90000
+
+class KviChannelOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviChannelOptionsWidget(QWidget * parent);
+ ~KviChannelOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviChannelGeneralOptionsWidget KVI_SMALLICON_CHANNEL
+#define KVI_OPTIONS_WIDGET_NAME_KviChannelGeneralOptionsWidget __tr2qs_no_lookup("General")
+#define KVI_OPTIONS_WIDGET_PARENT_KviChannelGeneralOptionsWidget KviChannelOptionsWidget
+
+class KviChannelGeneralOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviChannelGeneralOptionsWidget(QWidget * parent);
+ ~KviChannelGeneralOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviChannelAdvancedOptionsWidget KVI_SMALLICON_CHANNEL
+#define KVI_OPTIONS_WIDGET_NAME_KviChannelAdvancedOptionsWidget __tr2qs_no_lookup("Advanced")
+#define KVI_OPTIONS_WIDGET_PARENT_KviChannelAdvancedOptionsWidget KviChannelOptionsWidget
+
+class KviChannelAdvancedOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviChannelAdvancedOptionsWidget(QWidget * parent);
+ ~KviChannelAdvancedOptionsWidget();
+public:
+ virtual void commit();
+protected:
+ QComboBox * m_pBanTypeCombo;
+};
+
+#endif //_OPTW_IRC_H_
diff --git a/src/modules/options/optw_ircoutput.cpp b/src/modules/options/optw_ircoutput.cpp
new file mode 100644
index 00000000..cfa28456
--- /dev/null
+++ b/src/modules/options/optw_ircoutput.cpp
@@ -0,0 +1,94 @@
+//
+// File : optw_ircoutput.cpp
+// Creation date : Wed Nov 15 2000 11:45:06 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 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 "optw_ircoutput.h"
+
+#include <qlayout.h>
+
+#include "kvi_settings.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+#include <qcombobox.h>
+#include <qlabel.h>
+
+#ifdef COMPILE_INFO_TIPS
+ #include "kvi_tal_tooltip.h"
+#endif
+
+KviIrcOutputOptionsWidget::KviIrcOutputOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ircoutput_options_widget")
+{
+ createLayout(7,2);
+
+ QLabel * l =new QLabel(__tr2qs_ctx("Output verbosity","options"),this);
+ addWidgetToLayout(l,0,0,0,0);
+
+ m_pVerbosityCombo = new QComboBox(false,this);
+ addWidgetToLayout(m_pVerbosityCombo,1,0,1,0);
+
+ m_pVerbosityCombo->insertItem(__tr2qs_ctx("Mute","options"));
+ m_pVerbosityCombo->insertItem(__tr2qs_ctx("Quiet","options"));
+ m_pVerbosityCombo->insertItem(__tr2qs_ctx("Normal","options"));
+ m_pVerbosityCombo->insertItem(__tr2qs_ctx("Verbose","options"));
+ m_pVerbosityCombo->insertItem(__tr2qs_ctx("Paranoic","options"));
+
+ if(KVI_OPTION_UINT(KviOption_uintOutputVerbosityLevel) > KVI_VERBOSITY_LEVEL_PARANOIC)
+ KVI_OPTION_UINT(KviOption_uintOutputVerbosityLevel) = KVI_VERBOSITY_LEVEL_NORMAL;
+ m_pVerbosityCombo->setCurrentItem(KVI_OPTION_UINT(KviOption_uintOutputVerbosityLevel));
+
+ KviTalGroupBox * g = addGroupBox(0,1,1,1,1,Qt::Horizontal,__tr2qs_ctx("Show in active window","options"));
+ addBoolSelector(g,__tr2qs_ctx("External messages","options"),KviOption_boolExternalMessagesToActiveWindow);
+ addBoolSelector(g,__tr2qs_ctx("External CTCP replies","options"),KviOption_boolCtcpRepliesToActiveWindow);
+ addBoolSelector(g,__tr2qs_ctx("Whois replies","options"),KviOption_boolWhoisRepliesToActiveWindow);
+ addBoolSelector(g,__tr2qs_ctx("ChanServ and NickServ notices","options"),KviOption_boolServicesNoticesToActiveWindow);
+ addBoolSelector(g,__tr2qs_ctx("Invite messages","options"),KviOption_boolInvitesToActiveWindow);
+ addBoolSelector(g,__tr2qs_ctx("Server replies","options"),KviOption_boolServerRepliesToActiveWindow);
+ addBoolSelector(g,__tr2qs_ctx("Server notices","options"),KviOption_boolServerNoticesToActiveWindow);
+ addBoolSelector(g,__tr2qs_ctx("Broadcast and WALLOPS messages","options"),KviOption_boolOperatorMessagesToActiveWindow);
+// if(KVI_OPTION_UINT(KviOption_uintUserExperienceLevel)>=2)
+// {
+ addBoolSelector(0,2,1,2,__tr2qs_ctx("Show extended server information","options"),KviOption_boolShowExtendedServerInfo);
+ addBoolSelector(0,3,1,3,__tr2qs_ctx("Show server pings","options"),KviOption_boolShowPingPong);
+ addBoolSelector(0,4,1,4,__tr2qs_ctx("Show own parts in the console","options"),KviOption_boolShowOwnParts);
+ addBoolSelector(0,5,1,5,__tr2qs_ctx("Show compact mode changes","options"),KviOption_boolShowCompactModeChanges);
+
+ addRowSpacer(0,6,1,6);
+// } else {
+// addRowSpacer(0,2,1,2);
+// }
+}
+
+KviIrcOutputOptionsWidget::~KviIrcOutputOptionsWidget()
+{
+}
+
+void KviIrcOutputOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+
+ int i = m_pVerbosityCombo->currentItem();
+ if((i < 0) || (i > KVI_VERBOSITY_LEVEL_PARANOIC))i = KVI_VERBOSITY_LEVEL_NORMAL;
+ KVI_OPTION_UINT(KviOption_uintOutputVerbosityLevel) = i;
+}
+
+#include "m_optw_ircoutput.moc"
diff --git a/src/modules/options/optw_ircoutput.h b/src/modules/options/optw_ircoutput.h
new file mode 100644
index 00000000..27e5c4c8
--- /dev/null
+++ b/src/modules/options/optw_ircoutput.h
@@ -0,0 +1,49 @@
+#ifndef _OPTW_IRCOUTPUT_H_
+#define _OPTW_IRCOUTPUT_H_
+
+//
+// File : optw_ircoutput.h
+// Creation date : Wed Nov 15 2000 11:47:51 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 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_optionswidget.h"
+#include "kvi_tal_listview.h"
+
+class QComboBox;
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIrcOutputOptionsWidget KVI_SMALLICON_RAW
+#define KVI_OPTIONS_WIDGET_NAME_KviIrcOutputOptionsWidget __tr2qs_no_lookup("Verbosity And Output")
+#define KVI_OPTIONS_WIDGET_PARENT_KviIrcOutputOptionsWidget KviIrcOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcOutputOptionsWidget __tr2qs_no_lookup("debug")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIrcOutputOptionsWidget 75000
+
+class KviIrcOutputOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIrcOutputOptionsWidget(QWidget * parent);
+ ~KviIrcOutputOptionsWidget();
+protected:
+ QComboBox * m_pVerbosityCombo;
+protected:
+ virtual void commit();
+};
+
+#endif //!_OPTW_IRCOUTPUT_H_
diff --git a/src/modules/options/optw_ircview.cpp b/src/modules/options/optw_ircview.cpp
new file mode 100644
index 00000000..860f80c5
--- /dev/null
+++ b/src/modules/options/optw_ircview.cpp
@@ -0,0 +1,168 @@
+//
+// File : optw_ircview.cpp
+// Creation date : Sat Aug 11 2001 03:29:52 CEST 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 "optw_ircview.h"
+
+#include <qlayout.h>
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+//#warning "Info tips"
+
+KviIrcViewThemeOptionsWidget::KviIrcViewThemeOptionsWidget(QWidget * pParent)
+: KviOptionsWidget(pParent)
+{
+}
+
+KviIrcViewThemeOptionsWidget::~KviIrcViewThemeOptionsWidget()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviIrcViewLookOptionsWidget::KviIrcViewLookOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ircviewlook_options_widget")
+{
+ createLayout(6,2);
+
+ addFontSelector(0,0,1,0,__tr2qs_ctx("Font:","options"),KviOption_fontIrcView);
+ addColorSelector(0,1,1,1,__tr2qs_ctx("Background color:","options"),KviOption_colorIrcViewBackground);
+
+ addPixmapSelector(0,2,1,2,__tr2qs_ctx("Background image:","options"),KviOption_pixmapIrcViewBackground);
+
+ addLabel(0,3,0,3,__tr2qs_ctx("Horizontal align:","options"));
+ m_pHorizontalAlign=new QComboBox(this);
+ addWidgetToLayout(m_pHorizontalAlign,1,3,1,3);
+
+ addLabel(0,4,0,4,__tr2qs_ctx("Vertical align:","options"));
+ m_pVerticalAlign=new QComboBox(this);
+ addWidgetToLayout(m_pVerticalAlign,1,4,1,4);
+
+ addColorSelector(0,5,1,5,__tr2qs_ctx("Mark Line:","options"),KviOption_colorIrcViewMarkLine);
+
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Tile","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Left","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Right","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Center","options"));
+
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Tile","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Top","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Bottom","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Center","options"));
+
+ switch( KVI_OPTION_UINT(KviOption_uintIrcViewPixmapAlign) & Qt::AlignHorizontal_Mask)
+ {
+ case Qt::AlignLeft:
+ m_pHorizontalAlign->setCurrentItem(1);
+ break;
+ case Qt::AlignRight:
+ m_pHorizontalAlign->setCurrentItem(2);
+ break;
+ case Qt::AlignHCenter:
+ m_pHorizontalAlign->setCurrentItem(3);
+ break;
+ default:
+ m_pHorizontalAlign->setCurrentItem(0);
+ }
+
+ switch( KVI_OPTION_UINT(KviOption_uintIrcViewPixmapAlign) & Qt::AlignVertical_Mask)
+ {
+ case Qt::AlignTop:
+ m_pVerticalAlign->setCurrentItem(1);
+ break;
+ case Qt::AlignBottom:
+ m_pVerticalAlign->setCurrentItem(2);
+ break;
+ case Qt::AlignVCenter:
+ m_pVerticalAlign->setCurrentItem(3);
+ break;
+ default:
+ m_pVerticalAlign->setCurrentItem(0);
+ }
+
+ layout()->setRowStretch(2,1);
+}
+
+KviIrcViewLookOptionsWidget::~KviIrcViewLookOptionsWidget()
+{
+}
+
+void KviIrcViewLookOptionsWidget::commit()
+{
+ int iFlags=0;
+ switch(m_pHorizontalAlign->currentItem())
+ {
+ case 1:
+ iFlags|=Qt::AlignLeft;
+ break;
+ case 2:
+ iFlags|=Qt::AlignRight;
+ break;
+ case 3:
+ iFlags|=Qt::AlignHCenter;
+ break;
+ }
+ switch(m_pVerticalAlign->currentItem())
+ {
+ case 1:
+ iFlags|=Qt::AlignTop;
+ break;
+ case 2:
+ iFlags|=Qt::AlignBottom;
+ break;
+ case 3:
+ iFlags|=Qt::AlignVCenter;
+ break;
+ }
+
+ KVI_OPTION_UINT(KviOption_uintIrcViewPixmapAlign)=iFlags;
+ KviOptionsWidget::commit();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviIrcViewFeaturesOptionsWidget::KviIrcViewFeaturesOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"ircviewfeatures_options_widget")
+{
+ createLayout(14,1);
+
+
+
+ addBoolSelector(0,7,0,7,__tr2qs_ctx("Enable URL highlighting","options"),KviOption_boolIrcViewUrlHighlighting);
+ addBoolSelector(0,8,0,8,__tr2qs_ctx("Use line wrap margin","options"),KviOption_boolIrcViewWrapMargin);
+ KviUIntSelector * s = addUIntSelector(0,9,0,9,__tr2qs_ctx("Maximum buffer size:","options"),KviOption_uintIrcViewMaxBufferSize,32,32767,2048);
+ s->setSuffix(__tr2qs_ctx(" lines","options"));
+ s = addUIntSelector(0,10,0,10,__tr2qs_ctx("Link tooltip show delay:","options"),KviOption_uintIrcViewToolTipTimeoutInMsec,256,10000,1800);
+ s->setSuffix(__tr2qs_ctx(" msec","options"));
+ s = addUIntSelector(0,11,0,11,__tr2qs_ctx("Link tooltip hide delay:","options"),KviOption_uintIrcViewToolTipHideTimeoutInMsec,256,10000,12000);
+ s->setSuffix(__tr2qs_ctx(" msec","options"));
+ addBoolSelector(0,12,0,12,__tr2qs_ctx("Track last read text line","options"),KviOption_boolTrackLastReadTextViewLine);
+ addRowSpacer(0,13,0,13);
+
+}
+
+KviIrcViewFeaturesOptionsWidget::~KviIrcViewFeaturesOptionsWidget()
+{
+}
+
+
+
+#include "m_optw_ircview.moc"
diff --git a/src/modules/options/optw_ircview.h b/src/modules/options/optw_ircview.h
new file mode 100644
index 00000000..3da03a5a
--- /dev/null
+++ b/src/modules/options/optw_ircview.h
@@ -0,0 +1,83 @@
+#ifndef _OPTW_IRCVIEW_H_
+#define _OPTW_IRCVIEW_H_
+
+//=============================================================================
+//
+// File : optw_ircview.h
+// Creation date : Sat Aug 11 2001 03:28:19 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2006 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_optionswidget.h"
+#include <qcombobox.h>
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIrcViewThemeOptionsWidget KVI_SMALLICON_IRCVIEW
+#define KVI_OPTIONS_WIDGET_NAME_KviIrcViewThemeOptionsWidget __tr2qs_no_lookup("Output")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcViewThemeOptionsWidget __tr2qs_no_lookup("theme,colors,output")
+#define KVI_OPTIONS_WIDGET_GROUP_KviIrcViewThemeOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviIrcViewThemeOptionsWidget true
+
+class KviIrcViewThemeOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIrcViewThemeOptionsWidget(QWidget * pParent);
+ ~KviIrcViewThemeOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIrcViewLookOptionsWidget KVI_SMALLICON_IRCVIEW
+#define KVI_OPTIONS_WIDGET_NAME_KviIrcViewLookOptionsWidget __tr2qs_no_lookup("Look")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviIrcViewLookOptionsWidget __tr2qs_no_lookup("theme,colors,output")
+#define KVI_OPTIONS_WIDGET_GROUP_KviIrcViewLookOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_PARENT_KviIrcViewLookOptionsWidget KviIrcViewThemeOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIrcViewLookOptionsWidget 30
+
+class KviIrcViewLookOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+private:
+ QComboBox* m_pHorizontalAlign;
+ QComboBox* m_pVerticalAlign;
+public:
+ KviIrcViewLookOptionsWidget(QWidget * parent);
+ ~KviIrcViewLookOptionsWidget();
+public:
+ virtual void commit();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviIrcViewFeaturesOptionsWidget KVI_SMALLICON_IRCVIEW
+#define KVI_OPTIONS_WIDGET_NAME_KviIrcViewFeaturesOptionsWidget __tr2qs_no_lookup("Features")
+#define KVI_OPTIONS_WIDGET_GROUP_KviIrcViewFeaturesOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_PARENT_KviIrcViewFeaturesOptionsWidget KviIrcViewThemeOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviIrcViewFeaturesOptionsWidget 20
+
+class KviIrcViewFeaturesOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviIrcViewFeaturesOptionsWidget(QWidget * parent);
+ ~KviIrcViewFeaturesOptionsWidget();
+};
+
+
+
+#endif //!_OPTW_IRCVIEW_H_
diff --git a/src/modules/options/optw_lag.cpp b/src/modules/options/optw_lag.cpp
new file mode 100644
index 00000000..8c9cf201
--- /dev/null
+++ b/src/modules/options/optw_lag.cpp
@@ -0,0 +1,85 @@
+//
+// File : optw_lag.cpp
+// Creation date : Wed Cct 16 10:45:54 CEST 2002 by Juanjo lvarez (juanjux@yahoo.es)
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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 "optw_lag.h"
+
+#include <qlayout.h>
+#include "kvi_tal_tooltip.h"
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+//#warning "Info tips"
+
+
+KviLagOptionsWidget::KviLagOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"lag_options_widget")
+{
+ createLayout(3,1);
+
+ KviBoolSelector * pUse = addBoolSelector(0,0,0,0, __tr2qs_ctx("Enable lag meter","options"), KviOption_boolUseLagMeterEngine);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(pUse,__tr2qs_ctx("<center>This enables the lag meter engine, which checks at regular intervals how much lag (latency) the server has.</center>","options"));
+#endif
+ KviTalGroupBox *g = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Configuration","options"),KVI_OPTION_BOOL(KviOption_boolUseLagMeterEngine));
+ KviUIntSelector * pInterval = addUIntSelector(g, __tr2qs_ctx("Lag meter heartbeat:","options"),KviOption_uintLagMeterHeartbeat,2000,10000,5000,KVI_OPTION_BOOL(KviOption_boolUseLagMeterEngine));
+ pInterval->setSuffix(__tr2qs_ctx(" msec","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(pInterval,
+ __tr2qs_ctx("<center>This option allows you to set the lag meter heartbeat interval.<br>" \
+ "The lower the heartbeat interval the higher will be the accuracy of the lag check " \
+ "but also higher cpu usage and data traffic to the server.<br>" \
+ "Please note that this is NOT the interval between pings sent to the server: " \
+ "the pings (if any) will be sent really less often. " \
+ "5000 is a reasonable value.</center>","options"));
+#endif
+ connect(pUse,SIGNAL(toggled(bool)),pInterval,SLOT(setEnabled(bool)));
+
+ KviUIntSelector * pAlarm = addUIntSelector(g, __tr2qs_ctx("Trigger event if lag exceeds:","options"), KviOption_uintLagAlarmTime,5000,1000000,30000, KVI_OPTION_BOOL(KviOption_boolUseLagMeterEngine));
+ pAlarm->setSuffix(__tr2qs_ctx(" msec","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(pAlarm,__tr2qs_ctx("<center>This option controls the threshold for the " \
+ "OnLagAlarmTimeUp and OnLagAlarmTimeDown events. When the lag goes above " \
+ "the threshold OnLagAlarmTimeUp will be triggered and when the lag falls " \
+ "back below the threshold then OnLagAlarmTimeDown will be triggered</center>","options"));
+#endif
+ connect(pUse,SIGNAL(toggled(bool)),pAlarm,SLOT(setEnabled(bool)));
+
+ KviBoolSelector * pShow = addBoolSelector(g, __tr2qs_ctx("Show lag in IRC context display","options"), KviOption_boolShowLagOnContextDisplay, KVI_OPTION_BOOL(KviOption_boolUseLagMeterEngine));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(pShow,__tr2qs_ctx("<center>This makes the IRC context display applet show the current lag after the user's nickname (in seconds)</center>","options"));
+#endif
+
+ connect(pUse,SIGNAL(toggled(bool)),pShow,SLOT(setEnabled(bool)));
+ connect(pUse,SIGNAL(toggled(bool)),g,SLOT(setEnabled(bool)));
+
+ addRowSpacer(0,2,0,2);
+
+}
+
+KviLagOptionsWidget::~KviLagOptionsWidget()
+{
+}
+
+
+#include "m_optw_lag.moc"
diff --git a/src/modules/options/optw_lag.h b/src/modules/options/optw_lag.h
new file mode 100644
index 00000000..7e49cafd
--- /dev/null
+++ b/src/modules/options/optw_lag.h
@@ -0,0 +1,40 @@
+#ifndef _OPTW_LAG_H_
+#define _OPTW_LAG_H_
+//
+// File : optw_lag.h
+// Creation date : wed oct 16 10:45:14 CEST 2002 by Juanjo �varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviLagOptionsWidget KVI_SMALLICON_STATS
+#define KVI_OPTIONS_WIDGET_NAME_KviLagOptionsWidget __tr2qs_no_lookup("Lag")
+#define KVI_OPTIONS_WIDGET_PARENT_KviLagOptionsWidget KviToolsOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviLagOptionsWidget __tr2qs_no_lookup("time,ping")
+
+class KviLagOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviLagOptionsWidget(QWidget * parent);
+ ~KviLagOptionsWidget();
+};
+
+#endif //_OPTW_LAG_H_
diff --git a/src/modules/options/optw_logging.cpp b/src/modules/options/optw_logging.cpp
new file mode 100644
index 00000000..9d77836d
--- /dev/null
+++ b/src/modules/options/optw_logging.cpp
@@ -0,0 +1,64 @@
+//
+// File : optw_logging.cpp
+// Creation date : Mon Oct 29 15:37:16 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 "optw_logging.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+//#warning "Info tips"
+
+
+KviLoggingOptionsWidget::KviLoggingOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"logging_options_widget")
+{
+ createLayout(4,1);
+
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Automatically Log","options"));
+ addBoolSelector(g,__tr2qs_ctx("Query windows","options"),KviOption_boolAutoLogQueries);
+ addBoolSelector(g,__tr2qs_ctx("Channel windows","options"),KviOption_boolAutoLogChannels);
+ addBoolSelector(g,__tr2qs_ctx("DCC Chat windows","options"),KviOption_boolAutoLogDccChat);
+ addBoolSelector(g,__tr2qs_ctx("Console windows","options"),KviOption_boolAutoLogConsole);
+#ifdef COMPILE_ZLIB_SUPPORT
+ addBoolSelector(0,1,0,1,__tr2qs_ctx("Gzip logs","options"),KviOption_boolGzipLogs);
+#endif
+ addBoolSelector(0,2,0,2,__tr2qs_ctx("Strip colors in logs","options"),KviOption_boolStripControlCodesInLogs);
+ KviUIntSelector* us = addUIntSelector(0,3,0,3,__tr2qs_ctx("Auto flush logs every","options"),KviOption_uintAutoFlushLogs,0,99999,0);
+ us->setSuffix(__tr2qs_ctx(" min","options"));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(us,
+ __tr2qs_ctx("<center>Save logs with the current interval<br>" \
+ "Set to 0 to disable this feature</center>","options"));
+#endif
+ addRowSpacer(0,4,0,4);
+}
+
+KviLoggingOptionsWidget::~KviLoggingOptionsWidget()
+{
+}
+
+
+
+#include "m_optw_logging.moc"
diff --git a/src/modules/options/optw_logging.h b/src/modules/options/optw_logging.h
new file mode 100644
index 00000000..f3f3e1c4
--- /dev/null
+++ b/src/modules/options/optw_logging.h
@@ -0,0 +1,42 @@
+#ifndef _OPTW_LOGGING_H_
+#define _OPTW_LOGGING_H_
+//
+// File : optw_logging.h
+// Creation date : Mon Oct 29 15:37:18 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviLoggingOptionsWidget KVI_SMALLICON_LOG
+#define KVI_OPTIONS_WIDGET_NAME_KviLoggingOptionsWidget __tr2qs_no_lookup("Logging")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviLoggingOptionsWidget __tr2qs_no_lookup("save,output")
+#define KVI_OPTIONS_WIDGET_PARENT_KviLoggingOptionsWidget KviToolsOptionsWidget
+
+//noway #define KVI_OPTIONS_WIDGET_NO_PARENT_KviLoggingOptionsWidget KviIrcOptionsWidget
+
+class KviLoggingOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviLoggingOptionsWidget(QWidget * parent);
+ ~KviLoggingOptionsWidget();
+};
+
+#endif //_OPTW_LOGGING_H_
diff --git a/src/modules/options/optw_mediatypes.cpp b/src/modules/options/optw_mediatypes.cpp
new file mode 100644
index 00000000..c798a4eb
--- /dev/null
+++ b/src/modules/options/optw_mediatypes.cpp
@@ -0,0 +1,262 @@
+//
+// File : optw_mediatypes.cpp
+// Creation date : Sat Jan 20 2001 16:14:53 CEST 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 "optw_mediatypes.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include "kvi_tal_tooltip.h"
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+// kvi_app.cpp
+extern KVIRC_API KviMediaManager * g_pMediaManager;
+
+static void copyMediaType(KviMediaType * dst,const KviMediaType * src)
+{
+ dst->szFileMask = src->szFileMask;
+ dst->szIanaType = src->szIanaType;
+ dst->szDescription = src->szDescription;
+ dst->szMagicBytes = src->szMagicBytes;
+ dst->szSavePath = src->szSavePath;
+ dst->szCommandline = src->szCommandline;
+ dst->szRemoteExecCommandline = src->szRemoteExecCommandline;
+ dst->szIcon = src->szIcon;
+}
+
+KviMediaTypeListViewItem::KviMediaTypeListViewItem(KviTalListView * w,KviMediaType * t)
+: KviTalListViewItem(w)
+{
+ copyData(t);
+}
+
+KviMediaTypeListViewItem::~KviMediaTypeListViewItem()
+{
+}
+
+void KviMediaTypeListViewItem::copyData(KviMediaType * t)
+{
+ copyMediaType(&m_data,t);
+ setText(0,m_data.szFileMask.ptr());
+ setText(1,m_data.szIanaType.ptr());
+ setText(2,m_data.szDescription.ptr());
+}
+
+KviMediaTypesOptionsWidget::KviMediaTypesOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"mediatypes_options_widget")
+{
+ createLayout(11,3);
+
+ m_pListView = new KviTalListView(this);
+ m_pListView->addColumn(__tr2qs_ctx("Pattern","options"));
+ m_pListView->addColumn(__tr2qs_ctx("MIME Type","options"));
+ m_pListView->addColumn(__tr2qs_ctx("Description","options"));
+ m_pListView->setAllColumnsShowFocus(true);
+
+
+
+ connect(m_pListView,SIGNAL(currentChanged(KviTalListViewItem *)),this,SLOT(currentItemChanged(KviTalListViewItem *)));
+
+ layout()->addMultiCellWidget(m_pListView,0,0,0,2);
+
+ QLabel * l = new QLabel(__tr2qs_ctx("Description:","options"),this);
+ layout()->addWidget(l,1,0);
+ m_pDescription = new QLineEdit(this);
+ layout()->addMultiCellWidget(m_pDescription,1,1,1,2);
+
+ l = new QLabel(__tr2qs_ctx("MIME type:","options"),this);
+ layout()->addWidget(l,2,0);
+ m_pIanaType = new QLineEdit(this);
+ layout()->addMultiCellWidget(m_pIanaType,2,2,1,2);
+
+ l = new QLabel(__tr2qs_ctx("File pattern:","options"),this);
+ layout()->addWidget(l,3,0);
+ m_pFileMask = new QLineEdit(this);
+ layout()->addMultiCellWidget(m_pFileMask,3,3,1,2);
+
+ l = new QLabel(__tr2qs_ctx("Magic bytes:","options"),this);
+ layout()->addWidget(l,4,0);
+ m_pMagicBytes = new QLineEdit(this);
+ layout()->addMultiCellWidget(m_pMagicBytes,4,4,1,2);
+
+ l = new QLabel(__tr2qs_ctx("Save path:","options"),this);
+ layout()->addWidget(l,5,0);
+ m_pSavePath = new QLineEdit(this);
+ layout()->addMultiCellWidget(m_pSavePath,5,5,1,2);
+
+ l = new QLabel(__tr2qs_ctx("Local open command:","options"),this);
+ layout()->addWidget(l,6,0);
+ m_pCommandline = new QLineEdit(this);
+ layout()->addMultiCellWidget(m_pCommandline,6,6,1,2);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(m_pCommandline,__tr2qs_ctx("<center>This field contains the command to execute to open a local file.<br>" \
+ "<tt>$0</tt> is used in place of the filename</center>","options"));
+#endif
+
+ l = new QLabel(__tr2qs_ctx("Remote open command:","options"),this);
+ layout()->addWidget(l,7,0);
+ m_pRemoteExecCommandline = new QLineEdit(this);
+ layout()->addMultiCellWidget(m_pRemoteExecCommandline,7,7,1,2);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(m_pRemoteExecCommandline,__tr2qs_ctx("<center>This field contains the command to execute when automatically opening a received file.<br>" \
+ "<tt>$0</tt> is used in place of the filename</center>","options"));
+#endif
+
+ l = new QLabel(__tr2qs_ctx("Icon","options"),this);
+ layout()->addWidget(l,8,0);
+ m_pIcon = new QLineEdit(this);
+ layout()->addMultiCellWidget(m_pIcon,8,8,1,2);
+
+ QFrame * f = new QFrame(this);
+ f->setFrameStyle(QFrame::Sunken | QFrame::HLine);
+ layout()->addMultiCellWidget(f,9,9,0,2);
+
+ QPushButton * b = new QPushButton(__tr2qs_ctx("&New","options"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(newMediaType()));
+ layout()->addWidget(b,10,1);
+
+ m_pDelete = new QPushButton(__tr2qs_ctx("Re&move","options"),this);
+ connect(m_pDelete,SIGNAL(clicked()),this,SLOT(delMediaType()));
+ layout()->addWidget(m_pDelete,10,2);
+
+
+ layout()->setColStretch(1,1);
+ layout()->setColStretch(2,1);
+ layout()->setRowStretch(0,1);
+
+ m_pLastItem = 0;
+
+ fillListView();
+}
+
+KviMediaTypesOptionsWidget::~KviMediaTypesOptionsWidget()
+{
+}
+
+void KviMediaTypesOptionsWidget::fillListView()
+{
+ m_pListView->clear();
+ g_pMediaManager->lock();
+ KviPointerList<KviMediaType> * l = g_pMediaManager->mediaTypeList();
+ KviMediaTypeListViewItem * it;
+ for(KviMediaType * t = l->first();t;t = l->next())
+ {
+ it = new KviMediaTypeListViewItem(m_pListView,t);
+ }
+ g_pMediaManager->unlock();
+ enableOrDisable();
+}
+
+void KviMediaTypesOptionsWidget::saveLastItem()
+{
+ if(m_pLastItem)
+ {
+ KviMediaType t;
+ t.szDescription = m_pDescription->text();
+ t.szIanaType = m_pIanaType->text();
+ t.szFileMask = m_pFileMask->text();
+ t.szSavePath = m_pSavePath->text();
+ t.szCommandline = m_pCommandline->text();
+ t.szMagicBytes = m_pMagicBytes->text();
+ t.szRemoteExecCommandline = m_pRemoteExecCommandline->text();
+ t.szIcon = m_pIcon->text();
+
+ if(t.szDescription.isEmpty())t.szDescription = __tr2qs_ctx("[Unknown Media Type]","options");
+
+ m_pLastItem->copyData(&t);
+ }
+}
+
+void KviMediaTypesOptionsWidget::enableOrDisable()
+{
+ m_pDescription->setEnabled(m_pLastItem);
+ m_pIanaType->setEnabled(m_pLastItem);
+ m_pFileMask->setEnabled(m_pLastItem);
+ m_pSavePath->setEnabled(m_pLastItem);
+ m_pCommandline->setEnabled(m_pLastItem);
+ m_pMagicBytes->setEnabled(m_pLastItem);
+ m_pRemoteExecCommandline->setEnabled(m_pLastItem);
+ m_pDelete->setEnabled(m_pLastItem);
+ m_pIcon->setEnabled(m_pLastItem);
+}
+
+void KviMediaTypesOptionsWidget::setLineEdits()
+{
+ m_pDescription->setText(m_pLastItem ? m_pLastItem->data()->szDescription.ptr() : "");
+ m_pIanaType->setText(m_pLastItem ? m_pLastItem->data()->szIanaType.ptr() : "");
+ m_pFileMask->setText(m_pLastItem ? m_pLastItem->data()->szFileMask.ptr() : "");
+ m_pSavePath->setText(m_pLastItem ? m_pLastItem->data()->szSavePath.ptr() : "");
+ m_pCommandline->setText(m_pLastItem ? m_pLastItem->data()->szCommandline.ptr() : "");
+ m_pMagicBytes->setText(m_pLastItem ? m_pLastItem->data()->szMagicBytes.ptr() : "");
+ m_pRemoteExecCommandline->setText(m_pLastItem ? m_pLastItem->data()->szRemoteExecCommandline.ptr() : "");
+ m_pIcon->setText(m_pLastItem ? m_pLastItem->data()->szIcon.ptr() : "");
+}
+
+void KviMediaTypesOptionsWidget::currentItemChanged(KviTalListViewItem *it)
+{
+ saveLastItem();
+ m_pLastItem = (KviMediaTypeListViewItem *)it;
+ if(it)
+ {
+ if(!it->isSelected())m_pListView->setSelected(it,true);
+ }
+ setLineEdits();
+ enableOrDisable();
+}
+
+void KviMediaTypesOptionsWidget::newMediaType()
+{
+ KviMediaType empty;
+ empty.szDescription = __tr2qs_ctx("New Media Type","options");
+ KviMediaTypeListViewItem * it = new KviMediaTypeListViewItem(m_pListView,&empty);
+ m_pListView->setCurrentItem(it);
+ m_pListView->setSelected(it,true);
+}
+
+void KviMediaTypesOptionsWidget::delMediaType()
+{
+ if(m_pLastItem)
+ {
+ KviMediaTypeListViewItem * it = m_pLastItem;
+ m_pLastItem = 0;
+ delete it;
+ }
+}
+
+void KviMediaTypesOptionsWidget::commit()
+{
+ saveLastItem();
+ KviMediaTypeListViewItem * it = (KviMediaTypeListViewItem *)m_pListView->firstChild();
+ g_pMediaManager->lock();
+ g_pMediaManager->clear();
+ while(it)
+ {
+ KviMediaType * t = new KviMediaType;
+ copyMediaType(t,it->data());
+ g_pMediaManager->insertMediaType(t);
+ it = (KviMediaTypeListViewItem *)it->nextSibling();
+ }
+ g_pMediaManager->unlock();
+}
+
+#include "m_optw_mediatypes.moc"
diff --git a/src/modules/options/optw_mediatypes.h b/src/modules/options/optw_mediatypes.h
new file mode 100644
index 00000000..22fab930
--- /dev/null
+++ b/src/modules/options/optw_mediatypes.h
@@ -0,0 +1,83 @@
+#ifndef _OPTW_MEDIATYPES_H_
+#define _OPTW_MEDIATYPES_H_
+
+//
+// File : optw_mediatypes.h
+// Creation date : Sat Jan 20 2001 16:12:10 CEST 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_optionswidget.h"
+#include "kvi_tal_listview.h"
+#include <qlineedit.h>
+#include <qpushbutton.h>
+
+#include "kvi_mediatype.h"
+
+class KviMediaTypeListViewItem : public KviTalListViewItem
+{
+public:
+ KviMediaTypeListViewItem(KviTalListView * w,KviMediaType * t);
+ ~KviMediaTypeListViewItem();
+private:
+ KviMediaType m_data;
+public:
+ void copyData(KviMediaType * t);
+ const KviMediaType * data(){ return &m_data; };
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviMediaTypesOptionsWidget KVI_SMALLICON_FILE
+#define KVI_OPTIONS_WIDGET_NAME_KviMediaTypesOptionsWidget __tr2qs_no_lookup("Media Types")
+#define KVI_OPTIONS_WIDGET_PARENT_KviMediaTypesOptionsWidget KviGeneralOptOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviMediaTypesOptionsWidget __tr2qs_no_lookup("file,audio,video,programs")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviMediaTypesOptionsWidget 60000
+//#define KVI_OPTIONS_WIDGET_HIDDEN_KviMediaTypesOptionsWidget true
+
+class KviMediaTypesOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviMediaTypesOptionsWidget(QWidget * parent);
+ ~KviMediaTypesOptionsWidget();
+private:
+ KviTalListView * m_pListView;
+ QLineEdit * m_pDescription;
+ QLineEdit * m_pIanaType;
+ QLineEdit * m_pFileMask;
+ QLineEdit * m_pSavePath;
+ QLineEdit * m_pCommandline;
+ QLineEdit * m_pMagicBytes;
+ QLineEdit * m_pRemoteExecCommandline;
+ QLineEdit * m_pIcon;
+ QPushButton * m_pDelete;
+ KviMediaTypeListViewItem * m_pLastItem;
+private:
+ void fillListView();
+ void saveLastItem();
+ void enableOrDisable();
+ void setLineEdits();
+private slots:
+ void currentItemChanged(KviTalListViewItem *it);
+ void newMediaType();
+ void delMediaType();
+public:
+ virtual void commit();
+};
+
+#endif //!_OPTW_IDENTITY_H_
diff --git a/src/modules/options/optw_messages.cpp b/src/modules/options/optw_messages.cpp
new file mode 100644
index 00000000..54b4629a
--- /dev/null
+++ b/src/modules/options/optw_messages.cpp
@@ -0,0 +1,693 @@
+//=============================================================================
+//
+// File : optw_messages.cpp
+// Creation date : Sat Aug 11 2001 18:12:00 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2004 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 _WANT_OPTION_FLAGS_
+
+#include "optw_messages.h"
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include "kvi_tal_vbox.h"
+#include <qcursor.h>
+#include <qpainter.h>
+#include "kvi_styled_controls.h"
+
+#include "kvi_settings.h"
+
+#ifndef COMPILE_ON_WINDOWS
+ #include <unistd.h> // symlink()
+#endif
+
+#include "kvi_options.h"
+#include "kvi_app.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_config.h"
+#include "kvi_filedialog.h"
+
+//#warning "Info tips"
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ extern KVIRC_API QPixmap * g_pShadedChildGlobalDesktopBackground;
+#endif
+
+
+KviMessageOptionsWidget::KviMessageOptionsWidget(QWidget * pParent)
+: KviOptionsWidget(pParent)
+{
+}
+
+KviMessageOptionsWidget::~KviMessageOptionsWidget()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviPrivmsgOptionsWidget::KviPrivmsgOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"privmsg_options_widget")
+{
+ createLayout(4,1);
+
+ KviBoolSelector * b1;
+ KviBoolSelector * b2;
+
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("General","options"));
+
+ addBoolSelector(g,__tr2qs_ctx("Show message icons","options"),KviOption_boolIrcViewShowImages);
+ addBoolSelector(g,__tr2qs_ctx("Draw some emoticons (smileys) as pictures","options"),KviOption_boolDrawEmoticons);
+ addBoolSelector(g,__tr2qs_ctx("Don't show colors in user messages","options"),KviOption_boolStripMircColorsInUserMessages);
+
+
+
+
+ g = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Nicknames","options"));
+
+ b1 = addBoolSelector(g,__tr2qs_ctx("\"Smart\" nickname colors","options"),KviOption_boolColorNicks);
+ b2 = addBoolSelector(g,__tr2qs_ctx("Use same colors as in the userlist","options"),KviOption_boolUseUserListColorsAsNickColors,!KVI_OPTION_BOOL(KviOption_boolColorNicks));
+ connect(b1,SIGNAL(toggled(bool)),b2,SLOT(setNotEnabled(bool)));
+ addBoolSelector(g,__tr2qs_ctx("Show nicknames in bold","options"),KviOption_boolBoldedNicks);
+ addBoolSelector(g,__tr2qs_ctx("Show user and host","options"),KviOption_boolShowUserAndHostInPrivmsgView);
+ addBoolSelector(g,__tr2qs_ctx("Show channel mode prefix","options"),KviOption_boolShowChannelUserFlagInPrivmsgView);
+ KviBoolSelector * b = addBoolSelector(g,__tr2qs_ctx("User-defined prefix and postfix","options"),KviOption_boolUseExtendedPrivmsgView);
+
+ QLabel * l = addLabel(g,__tr2qs_ctx("[PREFIX]nickname[!user@host][POSTFIX] message","options"));
+
+ l->setEnabled(KVI_OPTION_BOOL(KviOption_boolUseExtendedPrivmsgView));
+ connect(b,
+ SIGNAL(toggled(bool)),
+ l,
+ SLOT(setEnabled(bool)));
+
+ KviTalVBox * vb = new KviTalVBox(g);
+ vb->setSpacing(5);
+
+ connect(
+ b,
+ SIGNAL(toggled(bool)),
+ addStringSelector(vb,__tr2qs_ctx("Prefix:","options"),KviOption_stringExtendedPrivmsgPrefix,KVI_OPTION_BOOL(KviOption_boolUseExtendedPrivmsgView)),
+ SLOT(setEnabled(bool)));
+ connect(
+ b,
+ SIGNAL(toggled(bool)),
+ addStringSelector(vb,__tr2qs_ctx("Postfix:","options"),KviOption_stringExtendedPrivmsgPostfix,KVI_OPTION_BOOL(KviOption_boolUseExtendedPrivmsgView)),
+ SLOT(setEnabled(bool)));
+ addRowSpacer(0,3,0,3);
+}
+
+KviPrivmsgOptionsWidget::~KviPrivmsgOptionsWidget()
+{
+
+}
+
+KviTimestampOptionsWidget::KviTimestampOptionsWidget(QWidget * pParent)
+: KviOptionsWidget(pParent)
+{
+ createLayout(5,1);
+ m_pUseTimestampSelector = addBoolSelector(0,0,0,0,__tr2qs_ctx("Show timestamp","options"),KviOption_boolIrcViewTimestamp);
+
+ connect(m_pUseTimestampSelector,SIGNAL(toggled(bool)),this,SLOT(enableDisableTimestampSelector(bool)));
+ KviBoolSelector* b = addBoolSelector(0,1,0,1,__tr2qs_ctx("Use UTC time for timestamp","options"),KviOption_boolIrcViewTimestampUTC,KVI_OPTION_BOOL(KviOption_boolIrcViewTimestamp));
+
+ connect(m_pUseTimestampSelector,SIGNAL(toggled(bool)),b,SLOT(setEnabled(bool)));
+
+ KviTalHBox *hb = new KviTalHBox(this);
+ addWidgetToLayout(hb,0,2,0,2);
+
+ m_pSpecialTimestampColorSelector = addBoolSelector(hb,__tr2qs_ctx("Use special color for timestamps","options"),KviOption_boolUseSpecialColorForTimestamp,KVI_OPTION_BOOL(KviOption_boolIrcViewTimestamp));
+ connect(m_pSpecialTimestampColorSelector,SIGNAL(toggled(bool)),this,SLOT(enableDisableTimestampSelector(bool)));
+ connect(m_pUseTimestampSelector,SIGNAL(toggled(bool)),m_pSpecialTimestampColorSelector,SLOT(setEnabled(bool)));
+
+ m_pTimestampColorSelector = addMircTextColorSelector(hb,"",KviOption_uintTimeStampForeground,KviOption_uintTimeStampBackground,KVI_OPTION_BOOL(KviOption_boolIrcViewTimestamp) && KVI_OPTION_BOOL(KviOption_boolUseSpecialColorForTimestamp));
+
+ KviStringSelector * st=addStringSelector(0,3,0,3,__tr2qs_ctx("Timestamp format:","options"),KviOption_stringIrcViewTimestampFormat);
+ connect(m_pUseTimestampSelector,SIGNAL(toggled(bool)),st,SLOT(setEnabled(bool)));
+
+ connect(m_pUseTimestampSelector,SIGNAL(toggled(bool)),m_pSpecialTimestampColorSelector,SLOT(setEnabled(bool)));
+ addRowSpacer(0,4,0,4);
+}
+
+KviTimestampOptionsWidget::~KviTimestampOptionsWidget()
+{
+}
+
+void KviTimestampOptionsWidget::enableDisableTimestampSelector(bool)
+{
+ m_pTimestampColorSelector->setEnabled(m_pUseTimestampSelector->isChecked() && m_pSpecialTimestampColorSelector->isChecked());
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviStandardColorsOptionsWidget::KviStandardColorsOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"stdcolors")
+{
+ createLayout(5,4);
+
+ addColorSelector(0,0,0,0,"0:",&(KVI_OPTION_MIRCCOLOR(0)));
+ addColorSelector(1,0,1,0,"1:",&(KVI_OPTION_MIRCCOLOR(1)));
+ addColorSelector(2,0,2,0,"2:",&(KVI_OPTION_MIRCCOLOR(2)));
+ addColorSelector(3,0,3,0,"3:",&(KVI_OPTION_MIRCCOLOR(3)));
+ addColorSelector(0,1,0,1,"4:",&(KVI_OPTION_MIRCCOLOR(4)));
+ addColorSelector(1,1,1,1,"5:",&(KVI_OPTION_MIRCCOLOR(5)));
+ addColorSelector(2,1,2,1,"6:",&(KVI_OPTION_MIRCCOLOR(6)));
+ addColorSelector(3,1,3,1,"7:",&(KVI_OPTION_MIRCCOLOR(7)));
+ addColorSelector(0,2,0,2,"8:",&(KVI_OPTION_MIRCCOLOR(8)));
+ addColorSelector(1,2,1,2,"9:",&(KVI_OPTION_MIRCCOLOR(9)));
+ addColorSelector(2,2,2,2,"10:",&(KVI_OPTION_MIRCCOLOR(10)));
+ addColorSelector(3,2,3,2,"11:",&(KVI_OPTION_MIRCCOLOR(11)));
+ addColorSelector(0,3,0,3,"12:",&(KVI_OPTION_MIRCCOLOR(12)));
+ addColorSelector(1,3,1,3,"13:",&(KVI_OPTION_MIRCCOLOR(13)));
+ addColorSelector(2,3,2,3,"14:",&(KVI_OPTION_MIRCCOLOR(14)));
+ addColorSelector(3,3,3,3,"15:",&(KVI_OPTION_MIRCCOLOR(15)));
+
+ addRowSpacer(0,4,3,4);
+
+ layout()->setRowStretch(4,1);
+}
+
+KviStandardColorsOptionsWidget::~KviStandardColorsOptionsWidget()
+{
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviMessageListView::KviMessageListView(QWidget * par)
+: KviTalListView(par)
+{
+ setItemMargin(2);
+}
+
+KviMessageListView::~KviMessageListView()
+{
+}
+
+
+void KviMessageListView::paintEmptyAreaInternal(QPainter * p,const QRect &viewportRect,const QRect &painterRect)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = viewport()->mapToGlobal(viewportRect.topLeft());
+ p->drawTiledPixmap(painterRect.x(),painterRect.y(),painterRect.width(),painterRect.height(),*g_pShadedChildGlobalDesktopBackground,pnt.x(),pnt.y());
+ } else {
+#endif
+ QPixmap * pix = KVI_OPTION_PIXMAP(KviOption_pixmapIrcViewBackground).pixmap();
+ if(pix)
+ {
+ QPoint pnt = viewportToContents(viewportRect.topLeft());
+ p->fillRect(painterRect.x(),painterRect.y(),painterRect.width(),painterRect.height(),KVI_OPTION_COLOR(KviOption_colorIrcViewBackground));
+ p->drawTiledPixmap(painterRect.x(),painterRect.y(),painterRect.width(),painterRect.height(),*pix,pnt.x(),pnt.y());
+ } else {
+ p->fillRect(painterRect.x(),painterRect.y(),painterRect.width(),painterRect.height(),KVI_OPTION_COLOR(KviOption_colorIrcViewBackground));
+ }
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+}
+
+void KviMessageListView::paintEmptyArea(QPainter * p,const QRect &rct)
+{
+ paintEmptyAreaInternal(p,rct,rct);
+ KviTalListView::paintEmptyArea(p,rct);
+}
+
+
+
+
+
+
+KviMessageListViewItem::KviMessageListViewItem(KviTalListView * l,int optId)
+: KviTalListViewItem(l)
+{
+ m_iOptId = optId;
+ setText(0,"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW");
+ m_pMsgType = new KviMsgType(KVI_OPTION_MSGTYPE(optId));
+ setPixmap(0,*(g_pIconManager->getSmallIcon(0))); // just a dummy one to ensure that the size of the item is at least 20 pixels (16 + 2 * margin)
+}
+
+KviMessageListViewItem::~KviMessageListViewItem()
+{
+ delete m_pMsgType;
+}
+
+void KviMessageListViewItem::paintCell(QPainter * p,const QColorGroup &,int,int w,int)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = listView()->viewport()->mapToGlobal(QPoint(int(p->worldMatrix().dx()),int(p->worldMatrix().dy())));
+ p->drawTiledPixmap(0,0,w,height(),*g_pShadedChildGlobalDesktopBackground,pnt.x(),pnt.y());
+ } else {
+#endif
+ QPixmap * pix = KVI_OPTION_PIXMAP(KviOption_pixmapIrcViewBackground).pixmap();
+ if(pix)
+ {
+ QPoint pnt = listView()->viewportToContents(QPoint(int(p->worldMatrix().dx()),int(p->worldMatrix().dy())));
+ p->fillRect(0,0,w,height(),KVI_OPTION_COLOR(KviOption_colorIrcViewBackground));
+ p->drawTiledPixmap(0,0,w,height(),*pix,pnt.x(),pnt.y());
+ } else {
+ p->fillRect(0,0,w,height(),KVI_OPTION_COLOR(KviOption_colorIrcViewBackground));
+ }
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+
+
+ p->drawPixmap(listView()->itemMargin(),(height() - 16) / 2,*(g_pIconManager->getSmallIcon(m_pMsgType->pixId())));
+ // draw the background
+ if(m_pMsgType->back() < 16)
+ {
+ QColor bColor = KVI_OPTION_MIRCCOLOR(m_pMsgType->back());
+ p->fillRect(22,listView()->itemMargin(),w - 24,height() - (listView()->itemMargin() * 2),bColor);
+ }
+ unsigned char ucFore = m_pMsgType->fore();
+ if(ucFore > 15)ucFore = 0;
+ p->setPen(QPen(KVI_OPTION_MIRCCOLOR(ucFore)));
+ // skip the msgtype prefix
+ QString txt = (g_msgtypeOptionsTable[m_iOptId].name + 7);
+ txt += " (";
+ txt += __tr2qs_no_xgettext(QString::fromUtf8(m_pMsgType->type()));
+ txt += ")";
+ p->drawText(24,listView()->itemMargin(),w - 24,height() - (listView()->itemMargin() * 2),Qt::AlignLeft | Qt::AlignVCenter,txt);
+ if(isSelected())
+ {
+#ifdef COMPILE_USE_QT4
+ QPen pen(KVI_OPTION_COLOR(KviOption_colorIrcViewBackground));
+ pen.setStyle(Qt::DashLine);
+ p->setPen( pen);
+ p->drawRect(0,0,w,height());
+ p->drawRect(1,1,w - 2,height() - 2);
+#else
+
+ p->drawWinFocusRect(0,0,w,height(),KVI_OPTION_COLOR(KviOption_colorIrcViewBackground));
+ p->drawWinFocusRect(1,1,w - 2,height() - 2,KVI_OPTION_COLOR(KviOption_colorIrcViewBackground));
+#endif
+ }
+}
+
+
+KviMessageColorListBoxItem::KviMessageColorListBoxItem(KviTalListBox * b,const QColor &clr,int idx)
+: KviTalListBoxText(b,QString::null)
+{
+ m_clr = clr;
+ m_iClrIdx = idx;
+ if((idx < 0) || (idx > 15))setText(__tr2qs_ctx("Transparent","options"));
+}
+
+KviMessageColorListBoxItem::~KviMessageColorListBoxItem()
+{
+}
+
+void KviMessageColorListBoxItem::paint(QPainter * p)
+{
+ QColor clr;
+
+ const KviTalListBox * lb = (const KviTalListBox *)listBox();
+
+ if((m_iClrIdx >= 0) && (m_iClrIdx <= 15))
+ {
+ clr = lb->isEnabled() ? KVI_OPTION_MIRCCOLOR(m_iClrIdx) : Qt::gray;
+ p->fillRect(0,0,width(lb),height(lb),clr);
+ } else {
+ clr = listBox()->colorGroup().background();
+ KviTalListBoxText::paint(p);
+ }
+#if QT_VERSION >= 300
+ if(isSelected())
+#else
+ if(selected())
+#endif
+ {
+#ifdef COMPILE_USE_QT4
+ QPen pen(clr);
+ pen.setStyle(Qt::DashLine);
+ p->setPen( pen);
+ p->drawRect(0,0,width(lb),height(lb));
+ p->drawRect(1,1,width(lb) - 2,height(lb) - 2);
+ p->drawRect(2,2,width(lb) - 4,height(lb) - 4);
+#else
+ p->drawWinFocusRect(0,0,width(lb),height(lb),clr);
+ p->drawWinFocusRect(1,1,width(lb) - 2,height(lb) - 2,clr);
+ p->drawWinFocusRect(2,2,width(lb) - 4,height(lb) - 4,clr);
+#endif
+ }
+}
+/*
+int KviMessageColorListBoxItem::width(const KviTalListBox * lb) const
+{
+ int w = lb->width();
+ if(w < 30)w = 30;
+ if(w > 150)w = 150;
+ return w;
+}
+
+int KviMessageColorListBoxItem::height(const KviTalListBox *) const
+{
+ return 30;
+}
+*/
+
+/*
+KviIrcColorsOptionsWidget::KviIrcColorsOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"irccolors","options")
+{
+ createLayout(5,4);
+
+ addRowSpacer(0,4,3,4);
+}
+
+KviIrcColorsOptionsWidget::~KviIrcColorsOptionsWidget()
+{
+}
+*/
+
+KviMessageColorsOptionsWidget::KviMessageColorsOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"messages")
+{
+ int i;
+
+ createLayout(2,4);
+
+ m_pLastItem = 0;
+
+
+ m_pListView = new KviMessageListView(this);
+ m_pListView->addColumn(__tr2qs_ctx("Message Type","options"));
+ m_pListView->setAllColumnsShowFocus(true);
+ m_pListView->setSelectionMode(KviTalListView::Single);
+ m_pListView->setFont(KVI_OPTION_FONT(KviOption_fontIrcView));
+ m_pListView->setStaticBackground(true);
+#ifdef COMPILE_USE_QT4
+ m_pListView->viewport()->setBackgroundMode(Qt::NoBackground);
+#else
+ m_pListView->viewport()->setBackgroundMode(QWidget::NoBackground);
+#endif
+
+ addWidgetToLayout(m_pListView,0,0,2,0);
+
+ KviTalVBox * box = new KviTalVBox(this);
+ addWidgetToLayout(box,3,0,3,0);
+
+ QLabel * l = new QLabel(__tr2qs_ctx("Background:","options"),box);
+
+ m_pBackListBox = new KviTalListBox(box);
+ m_pBackItems[16] = new KviMessageColorListBoxItem(m_pBackListBox,Qt::gray,KVI_TRANSPARENT);
+ for(i=0;i<16;i++)
+ {
+ m_pBackItems[i] = new KviMessageColorListBoxItem(m_pBackListBox,KVI_OPTION_MIRCCOLOR(i),i);
+ }
+
+ l = new QLabel(__tr2qs_ctx("Foreground:","options"),box);
+
+ m_pForeListBox = new KviTalListBox(box);
+ for(i=0;i<16;i++)
+ {
+ m_pForeItems[i] = new KviMessageColorListBoxItem(m_pForeListBox,KVI_OPTION_MIRCCOLOR(i),i);
+ }
+
+ l = new QLabel(__tr2qs_ctx("Alert level:","options"),box);
+
+ m_pLevelListBox = new KviTalListBox(box);
+ KviTalListBoxText * lbt;
+ for(i=0;i<6;i++)
+ {
+ QString tmpn;
+ tmpn.setNum(i);
+ lbt = new KviTalListBoxText(m_pLevelListBox,tmpn);
+ }
+
+ m_pIconButton = new KviStyledToolButton(box);
+ connect(m_pIconButton,SIGNAL(clicked()),this,SLOT(iconButtonClicked()));
+
+ m_pIconPopup = new KviTalPopupMenu(this);
+ KviIconWidget * iw = new KviIconWidget(m_pIconPopup);
+ connect(iw,SIGNAL(selected(int)),this,SLOT(newIconSelected(int)));
+ m_pIconPopup->insertItem(iw);
+
+
+ m_pEnableLogging = new KviStyledCheckBox(__tr2qs_ctx("Log this","options"),box);
+
+ KviTalHBox * h = new KviTalHBox(this);
+ addWidgetToLayout(h,0,1,3,1);
+ QPushButton * b = new QPushButton(__tr2qs_ctx("Load From...","options"),h);
+ connect(b,SIGNAL(clicked()),this,SLOT(load()));
+ b = new QPushButton(__tr2qs_ctx("Save As...","options"),h);
+ connect(b,SIGNAL(clicked()),this,SLOT(save()));
+
+
+ KviMessageListViewItem * it;
+
+ for(i=0;i<KVI_NUM_MSGTYPE_OPTIONS;i++)
+ {
+ it = new KviMessageListViewItem(m_pListView,i);
+ }
+
+ layout()->setRowStretch(0,1);
+ layout()->setColStretch(0,1);
+
+ connect(m_pListView,SIGNAL(selectionChanged(KviTalListViewItem *)),this,SLOT(itemChanged(KviTalListViewItem *)));
+ connect(m_pForeListBox,SIGNAL(selectionChanged(KviTalListBoxItem *)),this,SLOT(colorChanged(KviTalListBoxItem *)));
+ connect(m_pBackListBox,SIGNAL(selectionChanged(KviTalListBoxItem *)),this,SLOT(colorChanged(KviTalListBoxItem *)));
+
+ itemChanged(0);
+}
+
+KviMessageColorsOptionsWidget::~KviMessageColorsOptionsWidget()
+{
+}
+
+void KviMessageColorsOptionsWidget::newIconSelected(int iconId)
+{
+ if(!m_pLastItem)return;
+ if(iconId >= KVI_NUM_SMALL_ICONS)return;
+ m_pLastItem->msgType()->setPixId(iconId);
+ m_pIconButton->setIconSet(*(g_pIconManager->getSmallIcon(iconId)));
+ m_pListView->repaintItem(m_pLastItem);
+}
+
+void KviMessageColorsOptionsWidget::saveLastItem()
+{
+ if(!m_pLastItem)return;
+
+ int curIt = m_pForeListBox->currentItem();
+ if(curIt != -1)
+ {
+ //debug("Setting fore %d",curIt);
+ KviMessageColorListBoxItem * fore = (KviMessageColorListBoxItem *)m_pForeListBox->item(curIt);
+ //debug("And is %d",fore);
+ if(fore)m_pLastItem->msgType()->setFore(fore->m_iClrIdx);
+ }
+ curIt = m_pBackListBox->currentItem();
+ if(curIt != -1)
+ {
+ KviMessageColorListBoxItem * back = (KviMessageColorListBoxItem *)m_pBackListBox->item(curIt);
+ if(back)m_pLastItem->msgType()->setBack(back->m_iClrIdx);
+ }
+ m_pLastItem->msgType()->enableLogging(m_pEnableLogging->isChecked());
+ //debug("Updating","options");
+ curIt = m_pLevelListBox->currentItem();
+ if(curIt < 0 || curIt > 5)curIt = 1;
+ m_pLastItem->msgType()->setLevel(curIt);
+ m_pListView->repaintItem(m_pLastItem);
+}
+
+void KviMessageColorsOptionsWidget::itemChanged(KviTalListViewItem * it)
+{
+ //debug("Item changed","options");
+ if(m_pLastItem)saveLastItem();
+
+ m_pLastItem = 0; // do NOT save in this routine
+
+ m_pForeListBox->setEnabled(it);
+ m_pBackListBox->setEnabled(it);
+ m_pEnableLogging->setEnabled(it);
+ m_pIconButton->setEnabled(it);
+ m_pLevelListBox->setEnabled(it);
+
+ if(it)
+ {
+ int back = ((KviMessageListViewItem *)it)->msgType()->back();
+ int fore = ((KviMessageListViewItem *)it)->msgType()->fore();
+ if(fore >= 0 && fore <= 15)
+ {
+ m_pForeListBox->setCurrentItem(m_pForeItems[fore]);
+ }
+ if(back >= 0 && back <= 15)
+ {
+ m_pBackListBox->setCurrentItem(m_pBackItems[back]);
+ } else {
+ m_pBackListBox->setCurrentItem(m_pBackItems[16]);
+ }
+ m_pLevelListBox->setCurrentItem(((KviMessageListViewItem *)it)->msgType()->level());
+ m_pEnableLogging->setChecked(((KviMessageListViewItem *)it)->msgType()->logEnabled());
+ m_pIconButton->setIconSet(*(g_pIconManager->getSmallIcon(((KviMessageListViewItem *)it)->msgType()->pixId())));
+ }
+
+ // Ok...can save from now on
+ m_pLastItem = (KviMessageListViewItem *)it;
+
+}
+
+void KviMessageColorsOptionsWidget::colorChanged(KviTalListBoxItem *)
+{
+ if(m_pLastItem)saveLastItem();
+}
+
+void KviMessageColorsOptionsWidget::iconButtonClicked()
+{
+ m_pIconPopup->popup(QCursor::pos());
+}
+
+void KviMessageColorsOptionsWidget::commit()
+{
+ saveLastItem();
+
+ mergeResetFlag(KviOption_resetUpdateGui);
+
+ KviMessageListViewItem * it = (KviMessageListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ KVI_OPTION_MSGTYPE(it->optionId()) = *(it->msgType());
+ it = (KviMessageListViewItem *)(it->nextSibling());
+ }
+
+ KviOptionsWidget::commit();
+}
+
+void KviMessageColorsOptionsWidget::save()
+{
+ QString szName;
+ QString szInit;
+ g_pApp->getLocalKvircDirectory(szInit,KviApp::MsgColors);
+
+ if(KviFileDialog::askForSaveFileName(szName,__tr2qs_ctx("Choose a Filename - KVIrc","options"),szInit))
+ {
+ if(m_pLastItem)saveLastItem();
+
+ KviConfig cfg(szName,KviConfig::Write);
+
+ cfg.setGroup("Messages");
+
+ KviStr tmp;
+
+
+ KviMessageListViewItem * it = (KviMessageListViewItem *)m_pListView->firstChild();
+
+ while(it)
+ {
+ tmp.sprintf("Fore%d",it->optionId());
+ cfg.writeEntry(tmp.ptr(),it->msgType()->fore());
+ tmp.sprintf("Back%d",it->optionId());
+ cfg.writeEntry(tmp.ptr(),it->msgType()->back());
+ tmp.sprintf("Icon%d",it->optionId());
+ cfg.writeEntry(tmp.ptr(),it->msgType()->pixId());
+ tmp.sprintf("Log%d",it->optionId());
+ cfg.writeEntry(tmp.ptr(),it->msgType()->logEnabled());
+ tmp.sprintf("Level%d",it->optionId());
+ cfg.writeEntry(tmp.ptr(),it->msgType()->level());
+ it = (KviMessageListViewItem *)(it->nextSibling());
+ }
+
+ }
+}
+
+//#include <errno.h>
+
+void KviMessageColorsOptionsWidget::load()
+{
+
+ //KviStr szName;
+ QString szName;
+ //KviStr szInit;
+ QString szInit;
+ g_pApp->getLocalKvircDirectory(szInit,KviApp::MsgColors);
+
+#ifndef COMPILE_ON_WINDOWS
+ // symlink local to global
+ //KviStr szGlobal;
+ QString szGlobal;
+ g_pApp->getGlobalKvircDirectory(szGlobal,KviApp::MsgColors);
+ //KviStr szLocal;
+ QString szLocal;
+ g_pApp->getLocalKvircDirectory(szLocal,KviApp::MsgColors,"presets");
+ //debug("SYMLINKING %s to %s",szGlobal.ptr(),szLocal.ptr());
+ //debug("SYMLINK RETURNS %d (%d)",::symlink(szGlobal.ptr(),szLocal.ptr()));
+ //debug("ERRNO (%d)",errno);
+ symlink(szGlobal,szLocal);
+ // FIXME: Do it also on windows...
+#endif
+
+ if(KviFileDialog::askForOpenFileName(szName,__tr2qs_ctx("Choose a Filename - KVIrc ","options"),szInit))
+ {
+
+ itemChanged(0);
+
+
+ KviConfig cfg(szName,KviConfig::Read);
+
+ cfg.setGroup("Messages");
+
+ //KviStr tmp;
+ QString tmp;
+ KviMessageListViewItem * it = (KviMessageListViewItem *)m_pListView->firstChild();
+
+ while(it)
+ {
+ tmp.sprintf("Fore%d",it->optionId());
+ int fore = cfg.readIntEntry(tmp,it->msgType()->fore());
+ if(fore < 0 || fore > 15)fore = 0;
+ it->msgType()->setFore(fore);
+
+ tmp.sprintf("Back%d",it->optionId());
+ int back = cfg.readIntEntry(tmp,it->msgType()->back());
+ if(back < 0 || back > 15)back = KVI_TRANSPARENT;
+ it->msgType()->setBack(back);
+
+ tmp.sprintf("Icon%d",it->optionId());
+ int ico = cfg.readIntEntry(tmp,it->msgType()->pixId());
+ if(ico < 0 || ico >= KVI_NUM_SMALL_ICONS)ico = 0;
+ it->msgType()->setPixId(ico);
+
+ tmp.sprintf("Log%d",it->optionId());
+ bool bLog = cfg.readBoolEntry(tmp,it->msgType()->logEnabled());
+ it->msgType()->enableLogging(bLog);
+
+ tmp.sprintf("Level%d",it->optionId());
+ int iLevel = cfg.readIntEntry(tmp,it->msgType()->level());
+ it->msgType()->setLevel(iLevel);
+
+ m_pListView->repaintItem(it);
+
+ it = (KviMessageListViewItem *)(it->nextSibling());
+ }
+
+ }
+}
+
+#include "m_optw_messages.moc"
diff --git a/src/modules/options/optw_messages.h b/src/modules/options/optw_messages.h
new file mode 100644
index 00000000..7f82a145
--- /dev/null
+++ b/src/modules/options/optw_messages.h
@@ -0,0 +1,186 @@
+#ifndef _OPTW_MESSAGES_H_
+#define _OPTW_MESSAGES_H_
+
+//
+// File : optw_messages.h
+// Creation date : Sat Aug 11 2001 18:11:21 CEST 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_optionswidget.h"
+
+#include "kvi_msgtype.h"
+
+#include "kvi_tal_listview.h"
+#include "kvi_tal_listbox.h"
+#include <qcheckbox.h>
+#include <qtoolbutton.h>
+#include "kvi_tal_popupmenu.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviMessageOptionsWidget KVI_SMALLICON_MESSAGES
+#define KVI_OPTIONS_WIDGET_NAME_KviMessageOptionsWidget __tr2qs_no_lookup("Text")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviMessageOptionsWidget __tr2qs_no_lookup("theme,colors,output")
+#define KVI_OPTIONS_WIDGET_GROUP_KviMessageOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviMessageOptionsWidget true
+
+class KviMessageOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviMessageOptionsWidget(QWidget * pParent);
+ ~KviMessageOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviPrivmsgOptionsWidget KVI_SMALLICON_RAW
+#define KVI_OPTIONS_WIDGET_NAME_KviPrivmsgOptionsWidget __tr2qs_no_lookup("Message Style")
+#define KVI_OPTIONS_WIDGET_PARENT_KviPrivmsgOptionsWidget KviMessageOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviPrivmsgOptionsWidget 40
+#define KVI_OPTIONS_WIDGET_GROUP_KviPrivmsgOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviPrivmsgOptionsWidget __tr2qs_no_lookup("theme,privmsg,output,format")
+
+class KviPrivmsgOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviPrivmsgOptionsWidget(QWidget * parent);
+ ~KviPrivmsgOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTimestampOptionsWidget KVI_SMALLICON_TIME
+#define KVI_OPTIONS_WIDGET_NAME_KviTimestampOptionsWidget __tr2qs_no_lookup("Timestamp")
+#define KVI_OPTIONS_WIDGET_PARENT_KviTimestampOptionsWidget KviMessageOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviTimestampOptionsWidget 20
+#define KVI_OPTIONS_WIDGET_GROUP_KviTimestampOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTimestampOptionsWidget __tr2qs_no_lookup("time,timestamp")
+
+class KviTimestampOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTimestampOptionsWidget(QWidget * parent);
+ ~KviTimestampOptionsWidget();
+public:
+ KviBoolSelector * m_pUseTimestampSelector;
+ KviBoolSelector * m_pSpecialTimestampColorSelector;
+ KviMircTextColorSelector * m_pTimestampColorSelector;
+protected slots:
+ void enableDisableTimestampSelector(bool);
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviMessageColorsOptionsWidget KVI_SMALLICON_MESSAGES
+#define KVI_OPTIONS_WIDGET_NAME_KviMessageColorsOptionsWidget __tr2qs_no_lookup("Message Colors")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviMessageColorsOptionsWidget __tr2qs_no_lookup("theme,colors,messages,output")
+#define KVI_OPTIONS_WIDGET_GROUP_KviMessageColorsOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_PARENT_KviMessageColorsOptionsWidget KviMessageOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviMessageColorsOptionsWidget 30
+
+class KviMessageListView : public KviTalListView
+{
+ Q_OBJECT
+public:
+ KviMessageListView(QWidget * par);
+ ~KviMessageListView();
+protected:
+ void paintEmptyAreaInternal(QPainter * p,const QRect &viewportRect,const QRect &painterRect);
+public:
+ void paintEmptyArea(QPainter * p,const QRect &rct);
+};
+
+
+class KviMessageListViewItem : public KviTalListViewItem
+{
+public:
+ KviMessageListViewItem(KviTalListView * l,int optId);
+ ~KviMessageListViewItem();
+private:
+ int m_iOptId;
+ KviMsgType * m_pMsgType;
+public:
+ int optionId(){ return m_iOptId; };
+ KviMsgType * msgType(){ return m_pMsgType; };
+ virtual void paintCell(QPainter * p,const QColorGroup &,int,int,int);
+};
+
+
+class KviMessageColorListBoxItem : public KviTalListBoxText
+{
+public:
+ KviMessageColorListBoxItem(KviTalListBox * b,const QColor & clr,int idx);
+ ~KviMessageColorListBoxItem();
+public:
+ int m_iClrIdx;
+ QColor m_clr;
+public:
+ virtual void paint(QPainter * p);
+ virtual int width(const KviTalListBox * lv) const { return 120; };
+};
+
+
+
+
+class KviMessageColorsOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviMessageColorsOptionsWidget(QWidget * parent);
+ ~KviMessageColorsOptionsWidget();
+public:
+ KviMessageListView * m_pListView;
+ KviTalListBox * m_pForeListBox;
+ KviTalListBox * m_pBackListBox;
+ KviTalListBox * m_pLevelListBox;
+ KviMessageColorListBoxItem * m_pForeItems[16];
+ KviMessageColorListBoxItem * m_pBackItems[17];
+ KviMessageListViewItem * m_pLastItem;
+ QCheckBox * m_pEnableLogging;
+ QToolButton * m_pIconButton;
+ KviTalPopupMenu * m_pIconPopup;
+public:
+ void saveLastItem();
+protected slots:
+ void itemChanged(KviTalListViewItem * it);
+ void colorChanged(KviTalListBoxItem *);
+ void iconButtonClicked();
+ void newIconSelected(int iconId);
+ virtual void commit();
+ virtual void save();
+ virtual void load();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviStandardColorsOptionsWidget KVI_SMALLICON_COLORS
+#define KVI_OPTIONS_WIDGET_NAME_KviStandardColorsOptionsWidget __tr2qs_no_lookup("Color Set")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviStandardColorsOptionsWidget __tr2qs_no_lookup("theme,colors,messages,output")
+#define KVI_OPTIONS_WIDGET_GROUP_KviStandardColorsOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviStandardColorsOptionsWidget 20
+#define KVI_OPTIONS_WIDGET_PARENT_KviStandardColorsOptionsWidget KviMessageOptionsWidget
+
+class KviStandardColorsOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviStandardColorsOptionsWidget(QWidget * par);
+ ~KviStandardColorsOptionsWidget();
+
+};
+
+
+
+
+#endif //!_OPTW_MESSAGES_H_
diff --git a/src/modules/options/optw_nickserv.cpp b/src/modules/options/optw_nickserv.cpp
new file mode 100644
index 00000000..f182dc32
--- /dev/null
+++ b/src/modules/options/optw_nickserv.cpp
@@ -0,0 +1,368 @@
+//=============================================================================
+//
+// File : optw_nickserv.cpp
+// Creation date : Fri Aug 10 2001 03:38:10 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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 "optw_nickserv.h"
+
+#include <qlayout.h>
+#include "kvi_tal_tooltip.h"
+#include "kvi_tal_listview.h"
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qmessagebox.h>
+
+#include "kvi_qstring.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_nickserv.h"
+#include "kvi_ircmask.h"
+
+// kvi_app.cpp
+extern KVIRC_API KviNickServRuleSet * g_pNickServRuleSet;
+
+
+KviNickServRuleEditor::KviNickServRuleEditor(QWidget * par,bool bUseServerMaskField)
+: QDialog(par)
+{
+ setCaption(__tr2qs_ctx("NickServ Authentication Rule","options"));
+
+ QString html_center_begin = "<center>";
+ QString html_center_end = "</center>";
+
+ QGridLayout * gl = new QGridLayout(this,bUseServerMaskField ? 7 : 6,4,10,5);
+
+ QLabel * l = new QLabel(__tr2qs_ctx("Registered NickName","options"),this);
+ gl->addWidget(l,0,0);
+
+ m_pRegisteredNickEdit = new QLineEdit(this);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pRegisteredNickEdit,html_center_begin + __tr2qs_ctx("Put here the nickname that you have registered with NickServ","options") + html_center_end);
+#endif
+ gl->addMultiCellWidget(m_pRegisteredNickEdit,0,0,1,3);
+
+ l = new QLabel(__tr2qs_ctx("NickServ Mask","options"),this);
+ gl->addWidget(l,1,0);
+
+ m_pNickServMaskEdit = new QLineEdit(this);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pNickServMaskEdit,
+ html_center_begin + __tr2qs_ctx("This is the mask that NickServ must match to be correctly identified as the NickServ service. " \
+ "This usually will be something like <b>NickServ!service@services.dalnet</b>.<br>" \
+ "You can use wildcards for this field, but generally it is a security flaw. " \
+ "If you're 100%% sure that NO user on the network can use the nickname \"NickServ\", " \
+ "the mask <b>NickServ!*@*</b> may be safe to use in this field.","options") + html_center_end);
+#endif
+ gl->addMultiCellWidget(m_pNickServMaskEdit,1,1,1,3);
+
+ l = new QLabel(__tr2qs_ctx("Message Regexp","options"),this);
+ gl->addWidget(l,2,0);
+
+ m_pMessageRegexpEdit = new QLineEdit(this);
+ gl->addMultiCellWidget(m_pMessageRegexpEdit,2,2,1,3);
+
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pMessageRegexpEdit,
+ html_center_begin + __tr2qs_ctx("This is the simple regular expression that the identification request message " \
+ "from NickServ must match in order to be correctly recognized.<br>" \
+ "The message is usually something like \"To identify yourself please use /ns IDENTIFY password\" " \
+ "and it is sent when the NickServ wants you to authenticate yourself. " \
+ "You can use the * and ? wildcards.","options") + html_center_end);
+#endif
+ l = new QLabel(__tr2qs_ctx("Identify Command","options"),this);
+ gl->addWidget(l,3,0);
+
+ m_pIdentifyCommandEdit = new QLineEdit(this);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pIdentifyCommandEdit,
+ html_center_begin + __tr2qs_ctx("This is the command that will be executed when NickServ requests authentication " \
+ "for the nickname described in this rule (if the both server and NickServ mask are matched). " \
+ "This usually will be something like <b>msg NickServ identify &lt;yourpassword&gt;</b>.<br>" \
+ "You can use <b>msg -q</b> if you don't want the password echoed on the screen. " \
+ "Please note that there is no leading slash in this command.","options") + html_center_end);
+#endif
+ gl->addMultiCellWidget(m_pIdentifyCommandEdit,3,3,1,3);
+
+
+ int iNextLine = 4;
+
+ if(bUseServerMaskField)
+ {
+ l = new QLabel(__tr2qs_ctx("Server mask","options"),this);
+ gl->addWidget(l,4,0);
+
+ m_pServerMaskEdit = new QLineEdit(this);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pServerMaskEdit,
+ html_center_begin + __tr2qs_ctx("This is the mask that the current server must match in order " \
+ "for this rule to apply. It can contain * and ? wildcards.<br>Do NOT use simply \"*\" here...","options") + html_center_end);
+#endif
+ gl->addMultiCellWidget(m_pServerMaskEdit,4,4,1,3);
+ iNextLine++;
+ } else {
+ m_pServerMaskEdit = 0;
+ }
+
+
+#ifdef COMPILE_INFO_TIPS
+ l = new QLabel(html_center_begin + __tr2qs_ctx("Hint: Move the mouse cursor over the fields to get help","options") + html_center_end,this);
+#else
+ l = new QLabel("",this);
+#endif
+ l->setMargin(10);
+ gl->addMultiCellWidget(l,iNextLine,iNextLine,0,3);
+
+ iNextLine++;
+
+ QPushButton * p = new QPushButton(__tr2qs_ctx("Cancel","options"),this);
+ p->setMinimumWidth(100);
+ connect(p,SIGNAL(clicked()),this,SLOT(reject()));
+ gl->addWidget(p,iNextLine,2);
+
+ m_pOkButton = new QPushButton(__tr2qs_ctx("OK","options"),this);
+ m_pOkButton->setMinimumWidth(100);
+ m_pOkButton->setDefault(true);
+ connect(m_pOkButton,SIGNAL(clicked()),this,SLOT(okPressed()));
+ gl->addWidget(m_pOkButton,iNextLine,3);
+
+ gl->setColStretch(1,1);
+ gl->setRowStretch(bUseServerMaskField ? 5 : 4,1);
+
+ setMinimumWidth(250);
+}
+
+KviNickServRuleEditor::~KviNickServRuleEditor()
+{
+}
+
+
+
+bool KviNickServRuleEditor::validate()
+{
+ QString s = m_pRegisteredNickEdit->text();
+
+ QString m = __tr2qs_ctx("Invalid NickServ Rule","options");
+ QString o = __tr2qs_ctx("OK","options");
+
+ if(s.isEmpty())
+ {
+ QMessageBox::warning(this,m,__tr2qs_ctx("The Nickname field can't be empty!","options"),o);
+ return false;
+ }
+
+ if(s.find(QChar(' ')) != -1)
+ {
+ QMessageBox::warning(this,m,__tr2qs_ctx("The Nickname field can't contain spaces!","options"),o);
+ return false;
+ }
+
+ s = m_pNickServMaskEdit->text();
+
+ if(s.isEmpty())
+ {
+ QMessageBox::warning(this,m,__tr2qs_ctx("The NickServ mask can't be empty!<br>You must put at least * there.","options"),o);
+ return false;
+ }
+
+ s = m_pMessageRegexpEdit->text();
+
+ if(s.isEmpty())
+ {
+ QMessageBox::warning(this,m,__tr2qs_ctx("The Message Regexp can't be empty!<br>You must put at least * there.","options"),o);
+ return false;
+ }
+
+ s = m_pIdentifyCommandEdit->text();
+
+ if(s.isEmpty())
+ {
+ QMessageBox::warning(this,m,__tr2qs_ctx("The Identify Command can't be empty!","options"),o);
+ return false;
+ }
+
+ return true;
+}
+
+void KviNickServRuleEditor::okPressed()
+{
+ if(!validate())return;
+ accept();
+}
+
+
+bool KviNickServRuleEditor::editRule(KviNickServRule * r)
+{
+ m_pRegisteredNickEdit->setText(r->registeredNick().isEmpty() ? QString("MyNick") : r->registeredNick());
+ m_pNickServMaskEdit->setText(r->nickServMask().isEmpty() ? QString("NickServ!*@*") : r->nickServMask());
+ m_pMessageRegexpEdit->setText(r->messageRegexp().isEmpty() ? QString("*IDENTIFY*") : r->messageRegexp());
+ m_pIdentifyCommandEdit->setText(r->identifyCommand().isEmpty() ? QString("msg -q NickServ IDENTIFY <password>") : r->identifyCommand());
+ if(m_pServerMaskEdit)
+ m_pServerMaskEdit->setText(r->serverMask().isEmpty() ? QString("irc.yourserver.org") : r->serverMask());
+ m_pRegisteredNickEdit->selectAll();
+ if(exec() != QDialog::Accepted)return false;
+ r->setRegisteredNick(m_pRegisteredNickEdit->text());
+ r->setNickServMask(m_pNickServMaskEdit->text());
+ r->setMessageRegexp(m_pMessageRegexpEdit->text());
+ r->setIdentifyCommand(m_pIdentifyCommandEdit->text());
+ if(m_pServerMaskEdit)
+ r->setServerMask(m_pServerMaskEdit->text());
+ return true;
+}
+
+
+
+KviNickServOptionsWidget::KviNickServOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"nickserv_options_widget")
+{
+ createLayout(3,3);
+
+ QGridLayout * gl = layout();
+
+ KviNickServRuleSet * rs = g_pNickServRuleSet;
+ bool bNickServEnabled = rs ? (rs->isEnabled() && !rs->isEmpty()) : false;
+
+ m_pNickServCheck = new KviStyledCheckBox(__tr2qs_ctx("Enable NickServ Identification","options"),this);
+ gl->addMultiCellWidget(m_pNickServCheck,0,0,0,2);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pNickServCheck,
+ __tr2qs_ctx("This check enables the automatic identification with NickServ","options"));
+#endif
+ m_pNickServCheck->setChecked(bNickServEnabled);
+
+ m_pNickServListView = new KviTalListView(this);
+ m_pNickServListView->setSelectionMode(KviTalListView::Single);
+ m_pNickServListView->setAllColumnsShowFocus(true);
+ m_pNickServListView->addColumn(__tr2qs_ctx("Nickname","options"));
+ m_pNickServListView->addColumn(__tr2qs_ctx("Server mask","options"));
+ m_pNickServListView->addColumn(__tr2qs_ctx("NickServ Mask","options"));
+ m_pNickServListView->addColumn(__tr2qs_ctx("NickServ Request Mask","options"));
+ m_pNickServListView->addColumn(__tr2qs_ctx("Identify Command","options"));
+ connect(m_pNickServListView,SIGNAL(selectionChanged()),this,SLOT(enableDisableNickServControls()));
+
+ gl->addMultiCellWidget(m_pNickServListView,1,1,0,2);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pNickServListView,
+ __tr2qs_ctx("<center>This is a list of NickServ identification rules. " \
+ "KVIrc will use them to model its automatic interaction with NickServ on all the networks.<br>" \
+ "Please be aware that this feature can cause your NickServ passwords to be stolen " \
+ "if used improperly. Make sure that you fully understand the NickServ authentication protocol.<br>" \
+ "In other words, be sure to know what you're doing.<br>" \
+ "Also note that the password that you provide is stored as <b>PLAIN TEXT</b>.<br>" \
+ "KVIrc supports also per-network NickServ authentication rules that can be " \
+ "created in the \"Advanced...\" network options (accessible from the servers dialog)."
+ "</center>","options"));
+#endif
+
+ m_pAddRuleButton = new QPushButton(__tr2qs_ctx("Add Rule","options"),this);
+ connect(m_pAddRuleButton,SIGNAL(clicked()),this,SLOT(addNickServRule()));
+ gl->addWidget(m_pAddRuleButton,2,0);
+
+ m_pEditRuleButton = new QPushButton(__tr2qs_ctx("Edit Rule","options"),this);
+ connect(m_pEditRuleButton,SIGNAL(clicked()),this,SLOT(editNickServRule()));
+ gl->addWidget(m_pEditRuleButton,2,1);
+
+ m_pDelRuleButton = new QPushButton(__tr2qs_ctx("Delete Rule","options"),this);
+ connect(m_pDelRuleButton,SIGNAL(clicked()),this,SLOT(delNickServRule()));
+ gl->addWidget(m_pDelRuleButton,2,2);
+
+ connect(m_pNickServCheck,SIGNAL(toggled(bool)),this,SLOT(enableDisableNickServControls()));
+
+ if(rs && rs->rules())
+ {
+ KviPointerList<KviNickServRule> * ll = rs->rules();
+ for(KviNickServRule * rule = ll->first();rule;rule = ll->next())
+ {
+ (void)new KviTalListViewItem(m_pNickServListView,rule->registeredNick(),rule->serverMask(),rule->nickServMask(),rule->messageRegexp(),rule->identifyCommand());
+ }
+ }
+
+ enableDisableNickServControls();
+
+ gl->setRowStretch(1,1);
+
+
+}
+
+KviNickServOptionsWidget::~KviNickServOptionsWidget()
+{
+}
+
+void KviNickServOptionsWidget::editNickServRule()
+{
+ KviTalListViewItem * it = m_pNickServListView->currentItem();
+ if(!it)return;
+ KviNickServRule r(it->text(0),it->text(2),it->text(3),it->text(4),it->text(1));
+ KviNickServRuleEditor ed(this,true);
+ if(ed.editRule(&r))
+ {
+ it->setText(0,r.registeredNick());
+ it->setText(1,r.serverMask());
+ it->setText(2,r.nickServMask());
+ it->setText(3,r.messageRegexp());
+ it->setText(4,r.identifyCommand());
+ }
+}
+
+void KviNickServOptionsWidget::addNickServRule()
+{
+ KviNickServRule r;
+ KviNickServRuleEditor ed(this,true);
+ if(ed.editRule(&r))
+ (void)new KviTalListViewItem(m_pNickServListView,r.registeredNick(),r.serverMask(),r.nickServMask(),r.messageRegexp(),r.identifyCommand());
+}
+
+void KviNickServOptionsWidget::delNickServRule()
+{
+ KviTalListViewItem * it = m_pNickServListView->currentItem();
+ if(!it)return;
+ delete it;
+ enableDisableNickServControls();
+}
+
+void KviNickServOptionsWidget::enableDisableNickServControls()
+{
+ bool bEnabled = m_pNickServCheck->isChecked();
+ m_pNickServListView->setEnabled(bEnabled);
+ m_pAddRuleButton->setEnabled(bEnabled);
+ bEnabled = bEnabled && (m_pNickServListView->childCount() > 0) && m_pNickServListView->currentItem();
+ m_pDelRuleButton->setEnabled(bEnabled);
+ m_pEditRuleButton->setEnabled(bEnabled);
+}
+
+void KviNickServOptionsWidget::commit()
+{
+ g_pNickServRuleSet->clear();
+ if(m_pNickServListView->childCount() > 0)
+ {
+ g_pNickServRuleSet->setEnabled(m_pNickServCheck->isChecked());
+ KviTalListViewItem * it = m_pNickServListView->firstChild();
+ while(it)
+ {
+ g_pNickServRuleSet->addRule(KviNickServRule::createInstance(it->text(0),it->text(2),it->text(3),it->text(4),it->text(1)));
+ it = it->nextSibling();
+ }
+ }
+ KviOptionsWidget::commit();
+}
+
+#include "m_optw_nickserv.moc"
diff --git a/src/modules/options/optw_nickserv.h b/src/modules/options/optw_nickserv.h
new file mode 100644
index 00000000..b9e41e90
--- /dev/null
+++ b/src/modules/options/optw_nickserv.h
@@ -0,0 +1,89 @@
+#ifndef _OPTW_NICKSERV_H_
+#define _OPTW_NICKSERV_H_
+
+//=============================================================================
+//
+// File : optw_nickserv.h
+// Creation date : Fri Aug 10 2001 03:37:21 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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 "kvi_optionswidget.h"
+
+#include <qdialog.h>
+
+#define KVI_OPTIONS_WIDGET_ICON_KviNickServOptionsWidget KVI_SMALLICON_NICKSERV
+#define KVI_OPTIONS_WIDGET_NAME_KviNickServOptionsWidget __tr2qs_no_lookup("NickServ")
+#define KVI_OPTIONS_WIDGET_PARENT_KviNickServOptionsWidget KviToolsOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviNickServOptionsWidget __tr2qs_no_lookup("authentication,identify")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviNickServOptionsWidget 10000
+//#define KVI_OPTIONS_WIDGET_HIDDEN_KviNickServOptionsWidget true
+
+class QLineEdit;
+class QPushButton;
+class KviNickServRule;
+class KviTalListView;
+class QCheckBox;
+
+class KviNickServRuleEditor : public QDialog
+{
+ Q_OBJECT
+public:
+ KviNickServRuleEditor(QWidget * par,bool bUseServerMaskField = false);
+ ~KviNickServRuleEditor();
+protected:
+ QLineEdit * m_pRegisteredNickEdit;
+ QLineEdit * m_pNickServMaskEdit;
+ QLineEdit * m_pMessageRegexpEdit;
+ QLineEdit * m_pIdentifyCommandEdit;
+ QLineEdit * m_pServerMaskEdit;
+ QPushButton * m_pOkButton;
+public:
+ bool editRule(KviNickServRule * r);
+protected:
+ bool validate();
+protected slots:
+ void okPressed();
+};
+
+class KviNickServOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviNickServOptionsWidget(QWidget * parent);
+ ~KviNickServOptionsWidget();
+protected:
+ KviTalListView * m_pNickServListView;
+ QCheckBox * m_pNickServCheck;
+ QPushButton * m_pAddRuleButton;
+ QPushButton * m_pDelRuleButton;
+ QPushButton * m_pEditRuleButton;
+protected slots:
+ void enableDisableNickServControls();
+ void addNickServRule();
+ void delNickServRule();
+ void editNickServRule();
+public:
+ virtual void commit();
+};
+
+#endif //!_OPTW_NICKSERV_H_
diff --git a/src/modules/options/optw_notify.cpp b/src/modules/options/optw_notify.cpp
new file mode 100644
index 00000000..6ee5dc05
--- /dev/null
+++ b/src/modules/options/optw_notify.cpp
@@ -0,0 +1,134 @@
+//
+// File : optw_notify.cpp
+// Creation date : Sun Oct 28 15:11:29 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 "optw_notify.h"
+
+#include <qlayout.h>
+#include "kvi_settings.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+
+//#warning "Info tips"
+
+
+KviNotifyOptionsWidget::KviNotifyOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"notify_options_widget")
+{
+ createLayout(5,1);
+
+ KviBoolSelector * b = addBoolSelector(0,0,0,0,__tr2qs_ctx("Use online notify list","options"),KviOption_boolUseNotifyList);
+ KviTalGroupBox *g = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Configuration","options"));
+ connect(b,SIGNAL(toggled(bool)),g,SLOT(setEnabled(bool)));
+
+ connect(b,
+ SIGNAL(toggled(bool)),
+ addBoolSelector(g,__tr2qs_ctx("Show notifications in active window","options"),
+ KviOption_boolNotifyListChangesToActiveWindow,KVI_OPTION_BOOL(KviOption_boolUseNotifyList)),
+ SLOT(setEnabled(bool)));
+ connect(b,
+ SIGNAL(toggled(bool)),
+ addBoolSelector(g,__tr2qs_ctx("Flash window when users are going online","options"),
+ KviOption_boolFlashWindowOnNotifyOnLine,KVI_OPTION_BOOL(KviOption_boolUseNotifyList)),
+ SLOT(setEnabled(bool)));
+ connect(b,
+ SIGNAL(toggled(bool)),
+ addBoolSelector(g,__tr2qs_ctx("Popup notifier when users are going online","options"),
+ KviOption_boolPopupNotifierOnNotifyOnLine,KVI_OPTION_BOOL(KviOption_boolUseNotifyList)),
+ SLOT(setEnabled(bool)));
+
+ g = addGroupBox(0,2,0,2,1,Qt::Horizontal,__tr2qs_ctx("Advanced configuration","options"));
+ connect(b,SIGNAL(toggled(bool)),g,SLOT(setEnabled(bool)));
+
+ connect(b,
+ SIGNAL(toggled(bool)),
+ addBoolSelector(g,__tr2qs_ctx("Check USERHOST for online users","options"),
+ KviOption_boolNotifyListSendUserhostForOnlineUsers,KVI_OPTION_BOOL(KviOption_boolUseNotifyList)),
+ SLOT(setEnabled(bool)));
+ connect(b,
+ SIGNAL(toggled(bool)),
+ addBoolSelector(g,__tr2qs_ctx("Use \"smart\" notify list manager","options"),
+ KviOption_boolUseIntelligentNotifyListManager,KVI_OPTION_BOOL(KviOption_boolUseNotifyList)),
+ SLOT(setEnabled(bool)));
+ connect(b,
+ SIGNAL(toggled(bool)),
+ addBoolSelector(g,__tr2qs_ctx("Use the WATCH method if available","options"),
+ KviOption_boolUseWatchListIfAvailable,KVI_OPTION_BOOL(KviOption_boolUseNotifyList)),
+ SLOT(setEnabled(bool)));
+ connect(b,
+ SIGNAL(toggled(bool)),
+ addUIntSelector(g,__tr2qs_ctx("Check interval (in seconds)","options"),
+ KviOption_uintNotifyListCheckTimeInSecs,
+ 5,3600,180,KVI_OPTION_BOOL(KviOption_boolUseNotifyList)),
+ SLOT(setEnabled(bool)));
+ connect(b,
+ SIGNAL(toggled(bool)),
+ addUIntSelector(g,__tr2qs_ctx("ISON delay (in seconds)","options"),
+ KviOption_uintNotifyListIsOnDelayTimeInSecs,
+ 5,180,6,KVI_OPTION_BOOL(KviOption_boolUseNotifyList)),
+ SLOT(setEnabled(bool)));
+ connect(b,
+ SIGNAL(toggled(bool)),
+ addUIntSelector(g,__tr2qs_ctx("USERHOST delay (in seconds)","options"),
+ KviOption_uintNotifyListUserhostDelayTimeInSecs,
+ 5,180,6,KVI_OPTION_BOOL(KviOption_boolUseNotifyList)),
+ SLOT(setEnabled(bool)));
+
+ addLabel(0,3,0,3,__tr2qs_ctx("<p><b>Note:</b><br>The notify list is managed using the \"Registered Users\" settings.</p>","options"));
+ addRowSpacer(0,4,0,4);
+}
+
+KviNotifyOptionsWidget::~KviNotifyOptionsWidget()
+{
+}
+
+
+
+
+KviNotifierOptionsWidget::KviNotifierOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"notifier_options_widget")
+{
+ createLayout(3,1);
+
+ KviBoolSelector * b = addBoolSelector(0,0,0,0,__tr2qs_ctx("Forcibly and completely disable the notifier","options"),KviOption_boolForciblyDisableNotifier);
+#ifdef COMPILE_INFO_TIPS
+ QString tip = "<center>";
+ tip += __tr2qs_ctx("This is an option for the impatient: it allows to forcibly and permanently disable " \
+ "the notifier window. Please note that if this option is activated then " \
+ "the notifier will NOT popup even if all the other options around specify " \
+ "to use it in response to particular events. Also note that this option " \
+ "will make all the /notifier.* commands fail silently.","options");
+ tip += "</center>";
+ mergeTip(b,tip);
+#endif
+ addBoolSelector(0,1,0,1,__tr2qs_ctx("Disable notifier window flashing","options"),KviOption_boolDisableNotifierFlashing);
+ addBoolSelector(0,2,0,2,__tr2qs_ctx("Disable notifier window fade effect","options"),KviOption_boolDisableNotifierFadein);
+
+ addRowSpacer(0,3,0,3);
+}
+
+KviNotifierOptionsWidget::~KviNotifierOptionsWidget()
+{
+}
+
+
+#include "m_optw_notify.moc"
diff --git a/src/modules/options/optw_notify.h b/src/modules/options/optw_notify.h
new file mode 100644
index 00000000..374ddc21
--- /dev/null
+++ b/src/modules/options/optw_notify.h
@@ -0,0 +1,54 @@
+#ifndef _OPTW_NOTIFY_H_
+#define _OPTW_NOTIFY_H_
+//
+// File : optw_notify.h
+// Creation date : Sun Oct 28 15:11:30 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviNotifyOptionsWidget KVI_SMALLICON_REGUSERS
+#define KVI_OPTIONS_WIDGET_NAME_KviNotifyOptionsWidget __tr2qs_no_lookup("Contacts")
+#define KVI_OPTIONS_WIDGET_PARENT_KviNotifyOptionsWidget KviToolsOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviNotifyOptionsWidget __tr2qs_no_lookup("notify,buddy,buddies,friends")
+#define KVI_OPTIONS_WIDGET_MINIMAL_USER_EXPERIENCE_LEVEL_KviNotifyOptionsWidget 2
+
+class KviNotifyOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviNotifyOptionsWidget(QWidget * parent);
+ ~KviNotifyOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviNotifierOptionsWidget KVI_SMALLICON_ALERT
+#define KVI_OPTIONS_WIDGET_NAME_KviNotifierOptionsWidget __tr2qs_no_lookup("Notifier")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviNotifierOptionsWidget __tr2qs_no_lookup("popup")
+#define KVI_OPTIONS_WIDGET_PARENT_KviNotifierOptionsWidget KviInterfaceFeaturesOptionsWidget
+
+class KviNotifierOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviNotifierOptionsWidget(QWidget * parent);
+ ~KviNotifierOptionsWidget();
+};
+
+#endif //_OPTW_NOTIFY_H_
diff --git a/src/modules/options/optw_protection.cpp b/src/modules/options/optw_protection.cpp
new file mode 100644
index 00000000..27a0f4b1
--- /dev/null
+++ b/src/modules/options/optw_protection.cpp
@@ -0,0 +1,50 @@
+//=============================================================================
+//
+// File : optw_protection.cpp
+// Creation date : Wed Ott 19 16:15:16 2005 GMT by Grifisx & Noldor
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2005 Grifisx & 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 "optw_protection.h"
+
+#include <qlayout.h>
+
+#include "kvi_settings.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+KviProtectionOptionsWidget::KviProtectionOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"protection_options_widget")
+{
+
+ createLayout(1,1);
+
+ QLabel * l;
+ l = addLabel(0,0,0,0,__tr2qs_ctx("This section contains irc protection tools<br>"\
+ "<p>like<b> flood, ignore, antispam. </b> " \
+ "</p>","options"));
+
+}
+
+KviProtectionOptionsWidget::~KviProtectionOptionsWidget()
+{
+}
+
+#include "m_optw_protection.moc"
diff --git a/src/modules/options/optw_protection.h b/src/modules/options/optw_protection.h
new file mode 100644
index 00000000..5ac37e43
--- /dev/null
+++ b/src/modules/options/optw_protection.h
@@ -0,0 +1,48 @@
+#ifndef _OPTW_PROTECTION_H_
+#define _OPTW_PROTECTION_H_
+
+//=============================================================================
+//
+// File : optw_protection.h
+//
+// This file is part of the KVirc irc client distribution
+// Creation date : Wed Ott 19 16:15:16 2005 GMT by Grifisx & Noldor
+//
+// Copyright (C) 2005 Grifisx & 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 "kvi_settings.h"
+#include "kvi_optionswidget.h"
+#include "kvi_selectors.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviProtectionOptionsWidget KVI_SMALLICON_SPY
+#define KVI_OPTIONS_WIDGET_NAME_KviProtectionOptionsWidget __tr2qs_no_lookup("Protection")
+#define KVI_OPTIONS_WIDGET_PARENT_KviProtectionOptionsWidget KviIrcOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviProtectionOptionsWidget 60000
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviProtectionOptionsWidget __tr2qs_no_lookup("ctcp,flood")
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviProtectionOptionsWidget true
+#define KVI_OPTIONS_WIDGET_NOTCONTAINED_KviProtectionOptionsWidget true
+
+class KviProtectionOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviProtectionOptionsWidget(QWidget * parent);
+ ~KviProtectionOptionsWidget();
+};
+
+#endif //!_OPTW_PROTECTION_H_
diff --git a/src/modules/options/optw_proxy.cpp b/src/modules/options/optw_proxy.cpp
new file mode 100644
index 00000000..523d3c79
--- /dev/null
+++ b/src/modules/options/optw_proxy.cpp
@@ -0,0 +1,367 @@
+//
+// File : optw_proxy.cpp
+// Creation date : Mon Jun 24 2000 22:02:11 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 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 "optw_proxy.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_proxydb.h"
+#include "kvi_ipeditor.h"
+#include "kvi_netutils.h"
+#include "kvi_settings.h"
+#include "kvi_options.h"
+#include "kvi_styled_controls.h"
+
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+#include <kvi_tal_groupbox.h>
+#include "kvi_tal_popupmenu.h"
+#include <qcursor.h>
+#include "kvi_tal_tooltip.h"
+#include <qtoolbutton.h>
+
+
+KviProxyOptionsListViewItem::KviProxyOptionsListViewItem(KviTalListView *parent,const QPixmap &pm,KviProxy * prx)
+: KviTalListViewItem(parent,prx->m_szHostname.ptr())
+{
+ setPixmap(0,pm);
+ m_pProxyData = new KviProxy(*prx);
+}
+
+KviProxyOptionsListViewItem::~KviProxyOptionsListViewItem()
+{
+ delete m_pProxyData;
+}
+
+KviProxyOptionsWidget::KviProxyOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"proxy_options_widget")
+{
+ createLayout(3,2);
+
+ addBoolSelector(0,0,1,0,__tr2qs_ctx("Use proxy","options"),KviOption_boolUseProxyHost);
+
+ m_pListView = new KviTalListView(this);
+ addWidgetToLayout(m_pListView,0,1,0,1);
+ m_pListView->addColumn(__tr2qs_ctx("Proxy","options"));
+ m_pListView->setRootIsDecorated(true);
+ m_pListView->setAllColumnsShowFocus(true);
+ m_pListView->setSelectionMode(KviTalListView::Single);
+
+ connect(m_pListView,SIGNAL(selectionChanged(KviTalListViewItem *)),
+ this,SLOT(listViewItemSelectionChanged(KviTalListViewItem *)));
+ connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),
+ this,SLOT(listViewRightButtonPressed(KviTalListViewItem *,const QPoint &,int)));
+
+#ifdef COMPILE_INFO_TIPS
+ QString tiptxt = __tr2qs_ctx("<center>This is the list of available proxy servers.<br>" \
+ "Right-click on the list to add or remove proxies.</center>","options");
+ mergeTip(m_pListView,tiptxt);
+ mergeTip(m_pListView->viewport(),tiptxt);
+#endif
+
+ KviTalVBox * vbox = new KviTalVBox(this);
+ addWidgetToLayout(vbox,1,1,1,1);
+
+ QToolButton * tb = new KviStyledToolButton(vbox);
+ tb->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_PROXY)));
+ tb->setAutoRaise(true);
+ connect(tb,SIGNAL(clicked()),this,SLOT(newProxy()));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(tb,__tr2qs_ctx("New Proxy","options"));
+#endif
+
+ tb = new KviStyledToolButton(vbox);
+ tb->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CUT)));
+ //tb->setEnabled(false);
+ tb->setAutoRaise(true);
+ connect(tb,SIGNAL(clicked()),this,SLOT(removeCurrent()));
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(tb,__tr2qs_ctx("Remove Proxy","options"));
+#endif
+
+ QFrame * lll = new QFrame(vbox);
+ vbox->setStretchFactor(lll,100);
+
+
+ KviTalGroupBox * gbox = addGroupBox(0,2,1,2,2,Qt::Horizontal,__tr2qs_ctx("Configuration","options"),this);
+ //QGridLayout * gl = new QGridLayout(gbox->layout());
+ //gl->setMargin(2);
+ //gl->setSpacing(4);
+
+ m_pProxyLabel = new QLabel(__tr2qs_ctx("Proxy:","options"),gbox);
+
+ m_pProxyEdit = new QLineEdit(gbox);
+
+ m_pPortLabel = new QLabel(__tr2qs_ctx("Port:","options"),gbox);
+
+ m_pPortEdit = new QLineEdit(gbox);
+
+ m_pIpLabel = new QLabel(__tr2qs_ctx("IP address:","options"),gbox);
+
+ m_pIpEditor = new KviIpEditor(gbox,KviIpEditor::IpV4);
+
+ m_pUserLabel = new QLabel(__tr2qs_ctx("Username:","options"),gbox);
+
+ m_pUserEdit = new QLineEdit(gbox);
+
+ m_pPassLabel = new QLabel(__tr2qs_ctx("Password:","options"),gbox);
+
+ m_pPassEdit = new QLineEdit(gbox);
+
+ m_pProtocolLabel = new QLabel(__tr2qs_ctx("Protocol:","options"),gbox);
+
+ m_pProtocolBox = new QComboBox(false,gbox);
+
+ QStringList l;
+ KviProxy::getSupportedProtocolNames(l);
+
+ m_pProtocolBox->insertStringList(l);
+
+ m_pIpV6Check = new KviStyledCheckBox(__tr2qs_ctx("Use IPv6 protocol","options"),gbox);
+ connect(m_pIpV6Check,SIGNAL(toggled(bool)),this,SLOT(ipV6CheckToggled(bool)));
+#ifndef COMPILE_IPV6_SUPPORT
+ m_pIpV6Check->setEnabled(false);
+#endif
+
+ m_pLastEditedItem = 0;
+
+ fillProxyList();
+
+ layout()->setRowStretch(0,1);
+ layout()->setColStretch(0,1);
+
+ m_pContextPopup = new KviTalPopupMenu(this);
+
+
+}
+
+KviProxyOptionsWidget::~KviProxyOptionsWidget()
+{
+}
+
+
+void KviProxyOptionsWidget::ipV6CheckToggled(bool bEnabled)
+{
+ m_pIpEditor->setAddressType(bEnabled ? KviIpEditor::IpV6 : KviIpEditor::IpV4);
+}
+
+void KviProxyOptionsWidget::fillProxyList()
+{
+ KviProxyOptionsListViewItem * prx;
+
+ KviPointerList<KviProxy> * l = g_pProxyDataBase->proxyList();
+
+ for(KviProxy * p = l->first();p;p = l->next())
+ {
+ prx = new KviProxyOptionsListViewItem(m_pListView,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_PROXY)),p);
+ if(p == g_pProxyDataBase->currentProxy())
+ {
+ m_pListView->setSelected(prx,true);
+ m_pListView->ensureItemVisible(prx);
+ }
+ }
+ if(!(g_pProxyDataBase->currentProxy()))listViewItemSelectionChanged(0);
+}
+
+void KviProxyOptionsWidget::listViewItemSelectionChanged(KviTalListViewItem *it)
+{
+ if(m_pLastEditedItem)saveLastItem();
+ m_pLastEditedItem = (KviProxyOptionsListViewItem *)it;
+
+ m_pProxyLabel->setEnabled(m_pLastEditedItem);
+ m_pProxyEdit->setEnabled(m_pLastEditedItem);
+ m_pIpLabel->setEnabled(m_pLastEditedItem);
+ m_pIpEditor->setEnabled(m_pLastEditedItem);
+ m_pUserLabel->setEnabled(m_pLastEditedItem);
+ m_pUserEdit->setEnabled(m_pLastEditedItem);
+ m_pPassLabel->setEnabled(m_pLastEditedItem);
+ m_pPassEdit->setEnabled(m_pLastEditedItem);
+ m_pProtocolLabel->setEnabled(m_pLastEditedItem);
+ m_pProtocolBox->setEnabled(m_pLastEditedItem);
+ m_pPortLabel->setEnabled(m_pLastEditedItem);
+ m_pPortEdit->setEnabled(m_pLastEditedItem);
+
+#ifdef COMPILE_IPV6_SUPPORT
+ m_pIpV6Check->setEnabled(m_pLastEditedItem);
+#else
+ m_pIpV6Check->setEnabled(false);
+#endif
+ if(m_pLastEditedItem)
+ {
+ m_pProxyEdit->setText(m_pLastEditedItem->m_pProxyData->m_szHostname.ptr());
+
+ for(int i=0;i<m_pProtocolBox->count();i++)
+ {
+ KviStr txt = m_pProtocolBox->text(i);
+ if(kvi_strEqualCI(m_pLastEditedItem->m_pProxyData->protocolName(),txt.ptr()))
+ {
+ m_pProtocolBox->setCurrentItem(i);
+ break;
+ }
+ }
+
+#ifdef COMPILE_IPV6_SUPPORT
+ m_pIpV6Check->setChecked(m_pLastEditedItem->m_pProxyData->isIpV6());
+ m_pIpEditor->setAddressType(m_pLastEditedItem->m_pProxyData->isIpV6() ? KviIpEditor::IpV6 : KviIpEditor::IpV4);
+#else
+ m_pIpV6Check->setChecked(false);
+ m_pIpEditor->setAddressType(KviIpEditor::IpV4);
+#endif
+
+
+ if(!m_pIpEditor->setAddress(m_pLastEditedItem->m_pProxyData->m_szIp.ptr()))
+ {
+#ifdef COMPILE_IPV6_SUPPORT
+ m_pIpEditor->setAddress(m_pLastEditedItem->m_pProxyData->isIpV6() ? "0:0:0:0:0:0:0:0" : "0.0.0.0");
+#else
+ m_pIpEditor->setAddress("0.0.0.0");
+#endif
+ }
+
+ m_pUserEdit->setText(m_pLastEditedItem->m_pProxyData->m_szUser.ptr());
+ m_pPassEdit->setText(m_pLastEditedItem->m_pProxyData->m_szPass.ptr());
+ KviStr tmp(KviStr::Format,"%u",m_pLastEditedItem->m_pProxyData->m_uPort);
+ m_pPortEdit->setText(tmp.ptr());
+ } else {
+ m_pProxyEdit->setText("");
+ m_pUserEdit->setText("");
+ m_pPassEdit->setText("");
+ m_pPortEdit->setText("");
+ m_pIpEditor->setAddress("0.0.0.0");
+ m_pIpV6Check->setEnabled(false);
+ }
+}
+
+
+void KviProxyOptionsWidget::saveLastItem()
+{
+ if(m_pLastEditedItem)
+ {
+ KviStr tmp = m_pProxyEdit->text();
+ if(tmp.isEmpty())tmp = "irc.unknown.net";
+ m_pLastEditedItem->setText(0,tmp.ptr());
+ m_pLastEditedItem->m_pProxyData->m_szHostname = tmp;
+#ifdef COMPILE_IPV6_SUPPORT
+ m_pLastEditedItem->m_pProxyData->m_bIsIpV6 = m_pIpV6Check->isChecked();
+#else
+ m_pLastEditedItem->m_pProxyData->m_bIsIpV6 = false;
+#endif
+ m_pLastEditedItem->m_pProxyData->m_szIp = "";
+ KviStr tmpAddr = m_pIpEditor->address();
+
+ if(!m_pIpEditor->hasEmptyFields())
+ {
+#ifdef COMPILE_IPV6_SUPPORT
+ if(m_pIpV6Check->isChecked())
+ {
+ if((!kvi_strEqualCI(tmpAddr.ptr(),"0:0:0:0:0:0:0:0")) &&
+ kvi_isValidStringIp_V6(tmpAddr.ptr()))
+ {
+ m_pLastEditedItem->m_pProxyData->m_szIp = tmpAddr;
+ }
+ } else {
+#endif
+ if((!kvi_strEqualCI(tmpAddr.ptr(),"0.0.0.0")) &&
+ kvi_isValidStringIp(tmpAddr.ptr()))
+ {
+ m_pLastEditedItem->m_pProxyData->m_szIp = tmpAddr;
+ }
+#ifdef COMPILE_IPV6_SUPPORT
+ }
+#endif
+ }
+
+ m_pLastEditedItem->m_pProxyData->m_szPass = m_pPassEdit->text();
+ m_pLastEditedItem->m_pProxyData->m_szUser = m_pUserEdit->text();
+ tmp = m_pPortEdit->text();
+ bool bOk;
+ kvi_u32_t uPort = tmp.toUInt(&bOk);
+ if(!bOk)uPort = 1080;
+ m_pLastEditedItem->m_pProxyData->m_uPort = uPort;
+// m_pLastEditedItem->m_pProxyData->m_bSocksV5 = m_pSocks5Check->isChecked();
+ tmp = m_pProtocolBox->currentText();
+ m_pLastEditedItem->m_pProxyData->setNamedProtocol(tmp.ptr());
+ }
+}
+
+void KviProxyOptionsWidget::commit()
+{
+ saveLastItem();
+ g_pProxyDataBase->clear();
+ KviProxyOptionsListViewItem * it = (KviProxyOptionsListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ KviStr tmp = it->text(0);
+ if(tmp.hasData())
+ {
+ KviProxy * prx = new KviProxy(*(((KviProxyOptionsListViewItem *)it)->m_pProxyData));
+ g_pProxyDataBase->insertProxy(prx);
+
+ if(it == m_pLastEditedItem)g_pProxyDataBase->setCurrentProxy(prx);
+ }
+ it = (KviProxyOptionsListViewItem *)it->nextSibling();
+ }
+
+ if(g_pProxyDataBase->currentProxy() == 0)
+ {
+ g_pProxyDataBase->setCurrentProxy(g_pProxyDataBase->proxyList()->first());
+ }
+
+ KviOptionsWidget::commit();
+}
+
+void KviProxyOptionsWidget::listViewRightButtonPressed(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ m_pContextPopup->clear();
+ m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_PROXY)),__tr2qs_ctx("&New Proxy","options"),this,SLOT(newProxy()));
+ m_pContextPopup->setItemEnabled(m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CUT)),__tr2qs_ctx("Re&move Proxy","options"),this,SLOT(removeCurrent())),it);
+ m_pContextPopup->popup(QCursor::pos());
+}
+
+void KviProxyOptionsWidget::newProxy()
+{
+ KviProxy prx;
+ KviProxyOptionsListViewItem * it = new KviProxyOptionsListViewItem(m_pListView,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_PROXY)),&prx);
+ m_pListView->setSelected(it,true);
+ m_pListView->ensureItemVisible(it);
+}
+
+
+void KviProxyOptionsWidget::removeCurrent()
+{
+ if(m_pLastEditedItem)
+ {
+ delete m_pLastEditedItem;
+ m_pLastEditedItem = 0;
+ KviTalListViewItem * it = m_pListView->firstChild();
+ if(it)
+ {
+ m_pListView->setSelected(it,true);
+ m_pListView->ensureItemVisible(it);
+ } else {
+ listViewItemSelectionChanged(0);
+ }
+ }
+}
+
+#include "m_optw_proxy.moc"
diff --git a/src/modules/options/optw_proxy.h b/src/modules/options/optw_proxy.h
new file mode 100644
index 00000000..a6f18ada
--- /dev/null
+++ b/src/modules/options/optw_proxy.h
@@ -0,0 +1,94 @@
+#ifndef _OPTW_PROXY_H_
+#define _OPTW_PROXY_H_
+
+//
+// File : optw_proxy.h
+// Creation date : Mon Jun 24 2000 21:58:25 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 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_optionswidget.h"
+#include "kvi_tal_listview.h"
+
+
+class KviProxy;
+class KviProxyDataBase;
+
+extern KVIRC_API KviProxyDataBase * g_pProxyDataBase;
+
+class KviProxyOptionsListViewItem : public KviTalListViewItem
+{
+public:
+ KviProxyOptionsListViewItem(KviTalListView *parent,const QPixmap &pm,KviProxy * prx);
+ ~KviProxyOptionsListViewItem();
+public:
+ KviProxy * m_pProxyData;
+};
+
+class QLabel;
+class QLineEdit;
+class KviIpEditor;
+class QCheckBox;
+class KviTalPopupMenu;
+class QComboBox;
+
+#define KVI_OPTIONS_WIDGET_ICON_KviProxyOptionsWidget KVI_SMALLICON_PROXY
+#define KVI_OPTIONS_WIDGET_NAME_KviProxyOptionsWidget __tr2qs_no_lookup("Proxy Hosts")
+#define KVI_OPTIONS_WIDGET_PARENT_KviProxyOptionsWidget KviConnectionOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviProxyOptionsWidget __tr2qs_no_lookup("connection,servers")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviProxyOptionsWidget 70000
+
+class KviProxyOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviProxyOptionsWidget(QWidget * parent);
+ ~KviProxyOptionsWidget();
+protected:
+ KviTalListView * m_pListView;
+ QLabel * m_pProxyLabel;
+ QLineEdit * m_pProxyEdit;
+ QLabel * m_pIpLabel;
+ KviIpEditor * m_pIpEditor;
+ QLabel * m_pUserLabel;
+ QLineEdit * m_pUserEdit;
+ QLabel * m_pPassLabel;
+ QLineEdit * m_pPassEdit;
+ QLabel * m_pPortLabel;
+ QLineEdit * m_pPortEdit;
+ QLabel * m_pProtocolLabel;
+ QComboBox * m_pProtocolBox;
+ KviTalPopupMenu * m_pContextPopup;
+ QCheckBox * m_pIpV6Check;
+ KviProxyOptionsListViewItem * m_pLastEditedItem;
+private:
+
+ void fillProxyList();
+ void saveLastItem();
+protected slots:
+ void listViewItemSelectionChanged(KviTalListViewItem *it);
+ void listViewRightButtonPressed(KviTalListViewItem *it,const QPoint &pnt,int col);
+ void newProxy();
+ void removeCurrent();
+ void ipV6CheckToggled(bool bEnabled);
+public:
+ virtual void commit();
+};
+
+#endif //!_OPTW_PROXY_H_
diff --git a/src/modules/options/optw_query.cpp b/src/modules/options/optw_query.cpp
new file mode 100644
index 00000000..d0026c6e
--- /dev/null
+++ b/src/modules/options/optw_query.cpp
@@ -0,0 +1,115 @@
+//
+// File : optw_query.cpp
+// Creation date : Mon Oct 29 15:37:16 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 "optw_query.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_settings.h"
+
+
+#ifdef COMPILE_KDE_SUPPORT
+ #include <kdeversion.h>
+#endif
+
+KviQueryOptionsWidget::KviQueryOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"query_options_widget")
+{
+ createLayout(8,1);
+
+ KviTalGroupBox *g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Open Query For","options"));
+ KviBoolSelector *b = addBoolSelector(g, __tr2qs_ctx("Private messages","options"),KviOption_boolCreateQueryOnPrivmsg);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option enables query window creation " \
+ "when a private message (PRIVMSG) is received.<br>" \
+ "If you disable this, private messages will " \
+ "be shown in the active window or a common channel.</center>","options"));
+#endif
+
+ b = addBoolSelector(g, __tr2qs_ctx("Private notices","options"),KviOption_boolCreateQueryOnNotice);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option enables query window creation " \
+ "when a private notice (NOTICE) is received.<br>" \
+ "If you disable this, private notices will " \
+ "be shown in the active window or a common channel.</center>","options"));
+#endif
+
+
+ b = addBoolSelector(0,1,0,1,__tr2qs_ctx("Always open queries as minimized","options"),KviOption_boolCreateMinimizedQuery);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes newly created " \
+ "query windows to be immediately minimized.<br>" \
+ "Enable this if you don't like queries " \
+ "popping up while you're typing something in a channel. :D</center>","options"));
+#endif
+
+
+
+ b = addBoolSelector(0,2,0,2, __tr2qs_ctx("Enable target user tracking","options"),KviOption_boolEnableQueryTracing);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option will enable target user tracking.<br>" \
+ "Some actions of the target user (e.g. joins and parts) " \
+ "will be displayed in the window.<br></center>","options"));
+#endif
+
+#if defined(COMPILE_ON_WINDOWS) || (defined(COMPILE_KDE_SUPPORT) && (KDE_VERSION_MAJOR >= 3) && (KDE_VERSION_MINOR >= 2))
+ b = addBoolSelector(0,3,0,3,__tr2qs_ctx("Flash system taskbar on new query message","options"),KviOption_boolFlashQueryWindowOnNewMessages);
+ #ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes the system taskbar entry for KVIrc to flash when a new query message " \
+ "is received and the KVIrc window is not the active.</center>","options"));
+ #endif
+#endif
+
+ b = addBoolSelector(0,4,0,4, __tr2qs_ctx("Popup notifier on new query message","options"),KviOption_boolPopupNotifierOnNewQueryMessages);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes a small notifier window to pop up " \
+ "in the low right corner of the screen when a new message is received " \
+ "and the KVIrc window is not active.</center>","options"));
+#endif
+ b = addBoolSelector(0,5,0,5, __tr2qs_ctx("Show information about query target at the top of the query","options"),KviOption_boolShowExtendedInfoInQueryLabel);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option enables query window information " \
+ "label. It can show you known information about query target at the top of the window.<br>" \
+ "Uncheck if you think,that it wastes your query space/" \
+ "</center>","options"));
+#endif
+
+ addRowSpacer(0,6,0,6);
+}
+
+KviQueryOptionsWidget::~KviQueryOptionsWidget()
+{
+}
+
+
+#include "m_optw_query.moc"
diff --git a/src/modules/options/optw_query.h b/src/modules/options/optw_query.h
new file mode 100644
index 00000000..bae1c7bc
--- /dev/null
+++ b/src/modules/options/optw_query.h
@@ -0,0 +1,43 @@
+#ifndef _OPTW_QUERY_H_
+#define _OPTW_QUERY_H_
+//
+// File : optw_query.h
+// Creation date : Tue Mar 05 22:31:18 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Szymon Stefanek (pragma@kvirc.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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviQueryOptionsWidget KVI_SMALLICON_QUERY
+#define KVI_OPTIONS_WIDGET_NAME_KviQueryOptionsWidget __tr2qs_no_lookup("Query")
+#define KVI_OPTIONS_WIDGET_PARENT_KviQueryOptionsWidget KviIrcOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviQueryOptionsWidget __tr2qs_no_lookup("chat")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviQueryOptionsWidget 80000
+#define KVI_OPTIONS_WIDGET_NOTCONTAINED_KviQueryOptionsWidget true
+
+class KviQueryOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviQueryOptionsWidget(QWidget * parent);
+ ~KviQueryOptionsWidget();
+protected:
+};
+
+#endif //_OPTW_away_H_
diff --git a/src/modules/options/optw_servers.cpp b/src/modules/options/optw_servers.cpp
new file mode 100644
index 00000000..0b50bc78
--- /dev/null
+++ b/src/modules/options/optw_servers.cpp
@@ -0,0 +1,1712 @@
+//=============================================================================
+//
+// File : optw_servers.cpp
+// Creation date : Wed Jun 12 2000 03:29:51 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 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 "optw_servers.h"
+#include "optw_proxy.h"
+#include "kvi_query.h"
+#include "kvi_channel.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_ircserverdb.h"
+#include "kvi_ipeditor.h"
+#include "kvi_netutils.h"
+#include "kvi_settings.h"
+#include "kvi_filedialog.h"
+#include "kvi_config.h"
+#include "kvi_scripteditor.h"
+#include "kvi_options.h"
+
+#include "kvi_app.h"
+#include "kvi_console.h"
+#include "kvi_ircurl.h"
+#include "kvi_module.h"
+#include "kvi_modulemanager.h"
+#include "kvi_moduleextension.h"
+#include "kvi_msgbox.h"
+#include "kvi_mexserverimport.h"
+#include "kvi_nickserv.h"
+#include "optw_nickserv.h" // for the NickServ rule editor
+#include "kvi_proxydb.h"
+#include "kvi_kvs_script.h"
+#include "kvi_styled_controls.h"
+
+#include <qtoolbutton.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include "kvi_tal_popupmenu.h"
+#include <qcursor.h>
+#include "kvi_tal_tooltip.h"
+#include <qvalidator.h>
+#include <qmessagebox.h>
+#include "kvi_pointerhashtable.h"
+#include <qcombobox.h>
+#include <qbuttongroup.h>
+#include <qmessagebox.h>
+#include <qinputdialog.h>
+#include <qmessagebox.h>
+
+
+KviNetworkDetailsWidget::KviNetworkDetailsWidget(QWidget * par,KviIrcNetwork * n)
+ : QDialog(par,"network_details",true)
+{
+ m_pOnConnectEditor=0;
+ m_pOnLoginEditor=0;
+
+ m_pUserEditor=0;
+ m_pPassEditor=0;
+ m_pNickEditor=0;
+ m_pRealEditor=0;
+ m_pDescEditor=0;
+
+ m_pEncodingEditor=0;
+
+ m_pAutoConnectCheck=0;
+
+ m_pNickServListView=0;
+ m_pNickServCheck=0;
+ m_pAddRuleButton=0;
+ m_pDelRuleButton=0;
+ m_pEditRuleButton=0;
+
+ m_pChannelListSelector=0;
+
+ QGridLayout * g = new QGridLayout(this,4,4,10,4);
+
+ setCaption(__tr2qs_ctx("Network Details","options"));
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_WORLD)));
+
+ QString szTmp = "<font size=\"+1\"><b>";
+ szTmp += n->name();
+ szTmp += "</b></font>";
+
+ QLabel * l = new QLabel(szTmp,this);
+ l->setFrameStyle(QFrame::Raised | QFrame::StyledPanel);
+ l->setAlignment(Qt::AlignCenter);
+ l->setMargin(10);
+ g->addMultiCellWidget(l,0,0,0,3);
+ l->setMinimumWidth(200);
+
+ l = new QLabel(__tr2qs_ctx("Description:","options"),this);
+ g->addWidget(l,1,0);
+ m_pDescEditor = new QLineEdit(this);
+ g->addMultiCellWidget(m_pDescEditor,1,1,1,3);
+ m_pDescEditor->setText(n->description());
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pDescEditor,__tr2qs_ctx("<center>Put here a brief description of the network.</center>","options"));
+#endif
+
+ // Identity tab
+
+ QTabWidget * tw = new QTabWidget(this);
+ g->addMultiCellWidget(tw,2,2,0,3);
+
+ QWidget * tab = new QWidget(tw);
+ QGridLayout * gl = new QGridLayout(tab,4,2,10,4);
+
+ KviTalGroupBox *gbox = new KviTalGroupBox(2,Qt::Horizontal,__tr2qs_ctx("Properties","options"),tab);
+ gl->addMultiCellWidget(gbox,0,0,0,1);
+
+ l = new QLabel(__tr2qs_ctx("Username:","options"),gbox);
+ m_pUserEditor = new QLineEdit(gbox);
+ m_pUserEditor->setText(n->userName());
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pUserEditor,__tr2qs_ctx("<center>This is the <b>username</b> that KVIrc will use to login to servers on this network.\n" \
+ "If this field is left empty (most common case), KVIrc will use the default username " \
+ "specified in the \"Identity\" options tab.</center>","options"));
+#endif
+
+ l = new QLabel(__tr2qs_ctx("Nickname:","options"),gbox);
+ m_pNickEditor = new QLineEdit(gbox);
+ QValidator * v = new QRegExpValidator(QRegExp("[^-0-9 ][^ ]*","options"),gbox);
+ m_pNickEditor->setValidator(v);
+ m_pNickEditor->setText(n->nickName());
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pNickEditor,__tr2qs_ctx("<center>You can specify a \"special\" <b>nickname</b> that will be used to log in to the servers on this network.<br>" \
+ "If this field is left empty (most common case), the default nickname (specified in the \"Identity\" settings) will be used.</center>","options"));
+#endif
+
+ l = new QLabel(__tr2qs_ctx("Real name:","options"),gbox);
+ m_pRealEditor = new QLineEdit(gbox);
+ m_pRealEditor->setText(n->realName());
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pRealEditor,__tr2qs_ctx("<center>You can specify a \"special\" <b>real name</b> that will be used to login with the servers on this network.<br>" \
+ "If you leave this field empty (most common case), the default \"real name\" (specified in the \"Identity\" settings) will be used.</center>","options"));
+#endif
+
+
+ l = new QLabel(__tr2qs_ctx("Encoding:","options"),tab);
+ gl->addWidget(l,1,0);
+ m_pEncodingEditor = new QComboBox(false,tab);
+ m_pEncodingEditor->setDuplicatesEnabled(false);
+ gl->addWidget(m_pEncodingEditor,1,1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pEncodingEditor,__tr2qs_ctx("<center>This box allows you to choose the preferred encoding for the servers in this network. " \
+ "If you choose \"Use System Encoding\" then the encoding will be set to the systemwide " \
+ "value that you choose in the \"Encoding\" page of the options dialog.</center>","options"));
+#endif
+
+ int i = 0;
+ int current = 0;
+ KviLocale::EncodingDescription * d = KviLocale::encodingDescription(i);
+ QString tmp;
+ m_pEncodingEditor->insertItem(__tr2qs_ctx("Use System Encoding","options"));
+ while(d->szName)
+ {
+ KviQString::sprintf(tmp,"%s (%s)",d->szName,d->szDescription);
+ m_pEncodingEditor->insertItem(tmp);
+ if(KviQString::equalCI(d->szName,n->encoding()))current = i + 1;
+ i = i + 1;
+ d = KviLocale::encodingDescription(i);
+ }
+
+ m_pEncodingEditor->setCurrentItem(current);
+
+ m_pAutoConnectCheck = new KviStyledCheckBox(__tr2qs_ctx("Connect to this network at startup","options"),tab);
+ m_pAutoConnectCheck->setChecked(n->autoConnect());
+ gl->addMultiCellWidget(m_pAutoConnectCheck,2,2,0,1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pAutoConnectCheck,__tr2qs_ctx("<center>This option will cause KVIrc to automatically connect to this network at startup</center>","options"));
+#endif
+
+
+ l = new QLabel("",tab);
+ gl->addWidget(l,3,0);
+
+ gl->setRowStretch(3,1);
+ gl->setColStretch(1,1);
+
+ tw->addTab(tab,__tr2qs_ctx("General","options"));
+
+ // after login join channels
+ tab = new QWidget(tw);
+
+ gl = new QGridLayout(tab,1,1,10,4);
+
+ if(n->autoJoinChannelList())
+ m_lstChannels = *(n->autoJoinChannelList());
+ m_pChannelListSelector = new KviCahnnelListSelector(tab,
+ __tr2qs_ctx("Channels to join automatically upon connect:","options"),&m_lstChannels,true);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pChannelListSelector,__tr2qs_ctx("<center>Here you can set a list of channels to be joined automatically " \
+ "after a connection to a server in this network has been established. To add a channel, type its name in the " \
+ "text input below and click \"<b>Add</b>\".</center>","options"));
+#endif
+ gl->addWidget(m_pChannelListSelector,0,0);
+
+ tw->addTab(tab,__tr2qs_ctx("Join Channels","options"));
+
+ // after connect execute
+ tab = new QWidget(tw);
+ gl = new QGridLayout(tab,1,1,10,4);
+
+ m_pOnConnectEditor = KviScriptEditor::createInstance(tab);
+ gl->addWidget(m_pOnConnectEditor,0,0);
+ m_pOnConnectEditor->setText(n->onConnectCommand());
+ m_pOnConnectEditor->setMinimumHeight(150);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pOnConnectEditor,__tr2qs_ctx("<center>The following commands will be executed after a connection to a server in this network has been established.<br>" \
+ "<b>Important:</b> Enter commands <b>without</b> a preceding slash (e.g. <tt>quote pass secret</tt> instead of <tt>/quote pass secret</tt>).<br>"\
+ "KVIrc will first send the USER command, then eventually PASS and NICK and then execute this " \
+ "command sequence.</center>","options"));
+#endif
+
+ tw->addTab(tab,__tr2qs_ctx("On Connect","options"));
+
+
+ // after login execute
+ tab = new QWidget(tw);
+ gl = new QGridLayout(tab,1,1,10,4);
+
+ m_pOnLoginEditor = KviScriptEditor::createInstance(tab);
+ gl->addWidget(m_pOnLoginEditor,0,0);
+ m_pOnLoginEditor->setText(n->onLoginCommand());
+
+ m_pOnLoginEditor->setMinimumHeight(150);
+
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pOnLoginEditor,
+ __tr2qs_ctx("<center>The following commands will be executed after a successful login to a server in this network.<br>" \
+ "<b>Important:</b> Enter commands <b>without</b> a preceding slash (e.g. <tt>quote privatelog</tt> instead of <tt>/quote privatelog</tt>).<br>"
+ "This is useful for automatically opening queries, setting variables, etc.</center>","options"));
+#endif
+
+ tw->addTab(tab,__tr2qs_ctx("On Login","options"));
+
+
+ // nick serv rules
+
+ tab = new QWidget(tw);
+ gl = new QGridLayout(tab,3,3,10,5);
+
+ KviNickServRuleSet * rs = n->nickServRuleSet();
+ bool bNickServEnabled = rs ? (rs->isEnabled() && !rs->isEmpty()) : false;
+
+ m_pNickServCheck = new KviStyledCheckBox(__tr2qs_ctx("Enable NickServ Identification","options"),tab);
+ gl->addMultiCellWidget(m_pNickServCheck,0,0,0,2);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pNickServCheck,
+ __tr2qs_ctx("This check enables the automatic identification with NickServ","options"));
+#endif
+ m_pNickServCheck->setChecked(bNickServEnabled);
+
+ m_pNickServListView = new KviTalListView(tab);
+ m_pNickServListView->setSelectionMode(KviTalListView::Single);
+ m_pNickServListView->setAllColumnsShowFocus(true);
+ m_pNickServListView->addColumn(__tr2qs_ctx("Nickname","options"));
+ m_pNickServListView->addColumn(__tr2qs_ctx("NickServ Mask","options"));
+ m_pNickServListView->addColumn(__tr2qs_ctx("NickServ Request Mask","options"));
+ m_pNickServListView->addColumn(__tr2qs_ctx("Identify Command","options"));
+ connect(m_pNickServListView,SIGNAL(selectionChanged()),this,SLOT(enableDisableNickServControls()));
+
+ gl->addMultiCellWidget(m_pNickServListView,1,1,0,2);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pNickServListView,
+ __tr2qs_ctx("<center>This is a list of NickServ identification rules. " \
+ "KVIrc will use them to model its automatic interaction with NickServ on this network.<br>" \
+ "Please be aware that this feature can cause your NickServ passwords to be stolen " \
+ "if used improperly. Make sure that you fully understand the NickServ authentication protocol.<br>" \
+ "In other words, be sure to know what you're doing.<br>" \
+ "Also note that the password that you provide is stored as <b>PLAIN TEXT</b>.</center>","options"));
+#endif
+
+ m_pAddRuleButton = new QPushButton(__tr2qs_ctx("Add Rule","options"),tab);
+ connect(m_pAddRuleButton,SIGNAL(clicked()),this,SLOT(addNickServRule()));
+ gl->addWidget(m_pAddRuleButton,2,0);
+
+
+ m_pEditRuleButton = new QPushButton(__tr2qs_ctx("Edit Rule","options"),tab);
+ connect(m_pEditRuleButton,SIGNAL(clicked()),this,SLOT(editNickServRule()));
+ gl->addWidget(m_pEditRuleButton,2,1);
+
+ m_pDelRuleButton = new QPushButton(__tr2qs_ctx("Delete Rule","options"),tab);
+ connect(m_pDelRuleButton,SIGNAL(clicked()),this,SLOT(delNickServRule()));
+ gl->addWidget(m_pDelRuleButton,2,2);
+
+ connect(m_pNickServCheck,SIGNAL(toggled(bool)),this,SLOT(enableDisableNickServControls()));
+
+ if(rs && rs->rules())
+ {
+ KviPointerList<KviNickServRule> * ll = rs->rules();
+ for(KviNickServRule * rule = ll->first();rule;rule = ll->next())
+ {
+ (void)new KviTalListViewItem(m_pNickServListView,rule->registeredNick(),rule->nickServMask(),rule->messageRegexp(),rule->identifyCommand());
+ }
+ }
+
+ enableDisableNickServControls();
+
+ gl->setRowStretch(1,1);
+
+ tw->addTab(tab,__tr2qs_ctx("NickServ","options"));
+
+ QPushButton * b = new QPushButton(__tr2qs_ctx("&OK","options"),this);
+ b->setMinimumWidth(80);
+ g->addWidget(b,3,2);
+ b->setDefault(true);
+ connect(b,SIGNAL(clicked()),this,SLOT(accept()));
+
+ b = new QPushButton(__tr2qs_ctx("Cancel","options"),this);
+ g->addWidget(b,3,3);
+ b->setMinimumWidth(80);
+ connect(b,SIGNAL(clicked()),this,SLOT(reject()));
+
+
+ g->setRowStretch(2,1);
+ g->setColStretch(1,1);
+
+ tw->setMinimumWidth(375);
+}
+
+
+
+KviNetworkDetailsWidget::~KviNetworkDetailsWidget()
+{
+ if(m_pOnConnectEditor) KviScriptEditor::destroyInstance(m_pOnConnectEditor);
+ if(m_pOnLoginEditor) KviScriptEditor::destroyInstance(m_pOnLoginEditor);
+}
+
+void KviNetworkDetailsWidget::editNickServRule()
+{
+ KviTalListViewItem * it = m_pNickServListView->currentItem();
+ if(!it)return;
+ KviNickServRule r(it->text(0),it->text(1),it->text(2),it->text(3));
+ KviNickServRuleEditor ed(this,false);
+ if(ed.editRule(&r))
+ {
+ it->setText(0,r.registeredNick());
+ it->setText(1,r.nickServMask());
+ it->setText(2,r.messageRegexp());
+ it->setText(3,r.identifyCommand());
+ }
+}
+
+void KviNetworkDetailsWidget::addNickServRule()
+{
+ KviNickServRule r;
+ KviNickServRuleEditor ed(this,false);
+ if(ed.editRule(&r))
+ (void)new KviTalListViewItem(m_pNickServListView,r.registeredNick(),r.nickServMask(),r.messageRegexp(),r.identifyCommand());
+}
+
+void KviNetworkDetailsWidget::delNickServRule()
+{
+ KviTalListViewItem * it = m_pNickServListView->currentItem();
+ if(!it)return;
+ delete it;
+ enableDisableNickServControls();
+}
+
+void KviNetworkDetailsWidget::enableDisableNickServControls()
+{
+ bool bEnabled = m_pNickServCheck->isChecked();
+ m_pNickServListView->setEnabled(bEnabled);
+ m_pAddRuleButton->setEnabled(bEnabled);
+ bEnabled = bEnabled && (m_pNickServListView->childCount() > 0) && m_pNickServListView->currentItem();
+ m_pDelRuleButton->setEnabled(bEnabled);
+ m_pEditRuleButton->setEnabled(bEnabled);
+}
+
+void KviNetworkDetailsWidget::fillData(KviIrcNetwork * n)
+{
+ n->setUserName(m_pUserEditor->text());
+ n->setNickName(m_pNickEditor->text());
+ n->setRealName(m_pRealEditor->text());
+ n->setDescription(m_pDescEditor->text());
+ if(m_pAutoConnectCheck)
+ n->setAutoConnect(m_pAutoConnectCheck->isChecked());
+ if(m_pEncodingEditor)
+ if(m_pEncodingEditor->currentItem() <= 0)n->setEncoding(QString::null);
+ else {
+ KviLocale::EncodingDescription * d = KviLocale::encodingDescription(m_pEncodingEditor->currentItem() - 1);
+ n->setEncoding(d->szName);
+ }
+ if(m_pChannelListSelector)
+ m_pChannelListSelector->commit();
+ if(m_lstChannels.isEmpty())n->setAutoJoinChannelList(0);
+ else n->setAutoJoinChannelList(new QStringList(m_lstChannels));
+ if(m_pNickServListView)
+ {
+ if(m_pNickServListView->childCount() > 0)
+ {
+ KviNickServRuleSet * rs = KviNickServRuleSet::createInstance();
+ rs->setEnabled(m_pNickServCheck->isChecked());
+ KviTalListViewItem * it = m_pNickServListView->firstChild();
+ while(it)
+ {
+ rs->addRule(KviNickServRule::createInstance(it->text(0),it->text(1),it->text(2),it->text(3)));
+ it = it->nextSibling();
+ }
+ n->setNickServRuleSet(rs);
+ } else n->setNickServRuleSet(0);
+ }
+ if(m_pOnConnectEditor)
+ {
+ QString tmp;
+ m_pOnConnectEditor->getText(tmp);
+ n->setOnConnectCommand(tmp);
+ }
+ if(m_pOnLoginEditor)
+ {
+ QString tmp;
+ m_pOnLoginEditor->getText(tmp);
+ n->setOnLoginCommand(tmp);
+ }
+}
+
+
+
+
+
+
+
+KviServerDetailsWidget::KviServerDetailsWidget(QWidget * par,KviIrcServer * s)
+ : QDialog(par,"server_details",true)
+{
+ m_szHostname = s->hostName();
+ QGridLayout * g = new QGridLayout(this,4,4,10,4);
+
+ setCaption(__tr2qs_ctx("Server Details","options"));
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVER)));
+
+ m_pHeaderLabel = new QLabel("",this); // the text will be set later
+ m_pHeaderLabel->setFrameStyle(QFrame::Raised | QFrame::StyledPanel);
+ m_pHeaderLabel->setAlignment(Qt::AlignCenter);
+ m_pHeaderLabel->setMargin(10);
+ g->addMultiCellWidget(m_pHeaderLabel,0,0,0,3);
+ m_pHeaderLabel->setMinimumWidth(200);
+
+ QLabel * l = new QLabel(__tr2qs_ctx("Description:","options"),this);
+ g->addWidget(l,1,0);
+ m_pDescEditor = new QLineEdit(this);
+ g->addMultiCellWidget(m_pDescEditor,1,1,1,3);
+ m_pDescEditor->setText(s->description());
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pDescEditor,__tr2qs_ctx("<center>This is a brief description of this server. " \
+ "This field has no restrictions but many server lists use it to describe the server's physical location</center>","options"));
+#endif
+
+ // Identity tab
+
+ QTabWidget * tw = new QTabWidget(this);
+ g->addMultiCellWidget(tw,2,2,0,3);
+
+ QWidget * tab = new QWidget(tw);
+ QGridLayout * gl = new QGridLayout(tab,3,1,10,4);
+
+ KviTalGroupBox *gbox = new KviTalGroupBox(2,Qt::Horizontal,__tr2qs_ctx("Properties","options"),tab);
+ gl->addWidget(gbox,0,0);
+
+ l = new QLabel(__tr2qs_ctx("Username:","options"),gbox);
+ m_pUserEditor = new QLineEdit(gbox);
+ m_pUserEditor->setText(s->userName());
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pUserEditor,__tr2qs_ctx("<center>This is the <b>username</b> that KVIrc will use to login to this server.\n" \
+ "If this field is left empty (most common case), KVIrc will first look if an username is specified " \
+ "for the network that this server belongs to, and if that is empty then KVIrc will use the default username " \
+ "specified in the \"Identity\" options tab.</center>","options"));
+#endif
+
+ l = new QLabel(__tr2qs_ctx("Password:","options"),gbox);
+ m_pPassEditor = new QLineEdit(gbox);
+ m_pPassEditor->setEchoMode(QLineEdit::Password);
+ m_pPassEditor->setText(s->password());
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pPassEditor,__tr2qs_ctx("<center>If this server requires a password, put it in this field, otherwise leave it empty.</center>","options"));
+#endif
+
+ l = new QLabel(__tr2qs_ctx("Nickname:","options"),gbox);
+ m_pNickEditor = new QLineEdit(gbox);
+ QValidator * v = new QRegExpValidator(QRegExp("[^-0-9 ][^ ]*"),gbox);
+ m_pNickEditor->setValidator(v);
+ m_pNickEditor->setText(s->nickName());
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pNickEditor,__tr2qs_ctx("<center>You can specify a \"special\" <b>nickname</b> that will be used to log in to this server.<br>" \
+ "If this field is left empty (most common case), KVIrc will first look if a nickname is specified " \
+ "for the network that this server belongs to, and if that is empty then the default nickname (specified in the \"Identity\" settings) will be used.</center>","options"));
+#endif
+
+ l = new QLabel(__tr2qs_ctx("Real name:","options"),gbox);
+ m_pRealEditor = new QLineEdit(gbox);
+ m_pRealEditor->setText(s->realName());
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pRealEditor,__tr2qs_ctx("<center>You can specify a \"special\" <b>real name</b> that will be used to login with this server.<br>" \
+ "If you leave this field empty (most common case), KVIrc will first look if a real name is specified " \
+ "for the network that this server belongs to, and if that is empty the default \"real name\" (specified in the \"Identity\" settings) will be used.</center>","options"));
+#endif
+ gbox = new KviTalGroupBox(1,Qt::Horizontal,__tr2qs_ctx("User Mode","options"),tab);
+ gl->addWidget(gbox,1,0);
+
+ m_pUseDefaultInitUMode = new KviStyledCheckBox(__tr2qs_ctx("Use default user mode","options"),gbox);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pUseDefaultInitUMode,__tr2qs_ctx("<center>If this is enabled, the global initial <b>user mode</b> (configured from"\
+ " the identity dialog) will be used. If disabled, you can configure an initial user mode for this server","options"));
+#endif
+ bool bHasUmode = !(s->initUMode().isEmpty());
+ KviStr szDefUMode = KVI_OPTION_STRING(KviOption_stringDefaultUserMode);
+ m_pUseDefaultInitUMode->setChecked(!bHasUmode);
+ connect(m_pUseDefaultInitUMode,SIGNAL(toggled(bool)),this,SLOT(useDefaultInitUModeToggled(bool)));
+
+ m_pIMode = new KviStyledCheckBox(__tr2qs_ctx("Invisible (+i)","options"),gbox);
+ m_pIMode->setEnabled(bHasUmode);
+ m_pIMode->setChecked(bHasUmode ? s->initUMode().contains('i',false) : szDefUMode.contains('i',false));
+
+ m_pSMode = new KviStyledCheckBox(__tr2qs_ctx("Server notices (+s)","options"),gbox);
+ m_pSMode->setEnabled(bHasUmode);
+ m_pSMode->setChecked(bHasUmode ? s->initUMode().contains('s',false) : szDefUMode.contains('s',false));
+
+ m_pWMode = new KviStyledCheckBox(__tr2qs_ctx("Wallops (+w)","options"),gbox);
+ m_pWMode->setEnabled(bHasUmode);
+ m_pWMode->setChecked(bHasUmode ? s->initUMode().contains('w',false) : szDefUMode.contains('w',false));
+
+ l = new QLabel("",tab);
+ gl->addWidget(l,2,0);
+
+ gl->setRowStretch(2,1);
+ //gl->setColStretch(1,1);
+
+ tw->addTab(tab,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_WHO)),__tr2qs_ctx("Identity","options"));
+
+ // Connection tab
+
+ tab = new QWidget(tw);
+ gl = new QGridLayout(tab,11,1,10,4);
+
+ l = new QLabel(__tr2qs_ctx("Port:","options"),tab);
+ gl->addWidget(l,0,0);
+
+
+ m_pPortEditor = new QLineEdit(tab);
+ gl->addWidget(m_pPortEditor,0,1);
+ QString tmpz;
+ tmpz.setNum(s->port());
+ m_pPortEditor->setText(tmpz);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pPortEditor,__tr2qs_ctx("<center>This is the default <b>port</b> that this server will be contacted on.<br>Usually <b>6667</b> is OK.</center>","options"));
+#endif
+ connect(m_pPortEditor,SIGNAL(textChanged(const QString &)),this,SLOT(portEditorTextChanged(const QString &)));
+
+
+
+ l = new QLabel(__tr2qs_ctx("IP address:","options"),tab);
+ gl->addWidget(l,1,0);
+ m_pIpEditor = new KviIpEditor(tab,KviIpEditor::IpV4);
+ gl->addWidget(m_pIpEditor,1,1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pIpEditor,__tr2qs_ctx("<center>This is the <b>IP address</b> of this server, it is here for caching purposes.<br>" \
+ "If you leave this field empty, KVIrc will fill it in the first time it connects to the server. " \
+ "If you enable the \"cache IP address\" option below, KVIrc will use it as a \"cached result\" " \
+ "and avoid looking it up again.</center>","options"));
+#endif
+#ifdef COMPILE_IPV6_SUPPORT
+ m_pIpEditor->setAddressType(s->isIpV6() ? KviIpEditor::IpV6 : KviIpEditor::IpV4);
+#else
+ m_pIpEditor->setAddressType(KviIpEditor::IpV4);
+#endif
+
+ if(!m_pIpEditor->setAddress(s->m_szIp))
+ {
+#ifdef COMPILE_IPV6_SUPPORT
+ m_pIpEditor->setAddress(s->isIpV6() ? "0:0:0:0:0:0:0:0" : "0.0.0.0");
+#else
+ m_pIpEditor->setAddress("0.0.0.0");
+#endif
+ }
+
+ m_pCacheIpCheck = new KviStyledCheckBox(__tr2qs_ctx("Cache IP address","options"),tab);
+ gl->addMultiCellWidget(m_pCacheIpCheck,2,2,0,1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pCacheIpCheck,__tr2qs_ctx("<center>This check will enable <b>IP address caching</b> for this server:<br>" \
+ "DNS lookups can be time-consuming and might be blocking on some platforms; " \
+ "this option will cause KVIrc to look up the server hostname only once.<br><br> " \
+ "Advanced: you can also use this option to force a certain server name to resolve " \
+ "to a fixed ip address when either the dns for that server is temporairly " \
+ "unreachable or you want to avoid the round-robin lookups.</center>","options"));
+#endif
+ m_pCacheIpCheck->setChecked(s->cacheIp());
+
+
+ m_pUseIPV6Check = new KviStyledCheckBox(__tr2qs_ctx("Use IPv6 protocol","options"),tab);
+ gl->addMultiCellWidget(m_pUseIPV6Check,3,3,0,1);
+#ifdef COMPILE_IPV6_SUPPORT
+ m_pUseIPV6Check->setChecked(s->isIpV6());
+#else
+ m_pUseIPV6Check->setEnabled(false);
+#endif
+ connect(m_pUseIPV6Check,SIGNAL(toggled(bool)),this,SLOT(useIPV6CheckToggled(bool)));
+
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pUseIPV6Check,__tr2qs_ctx("<center>This check identifies IPv6 servers.<br>If enabled, KVIrc will attempt to use the IPv6 protocol " \
+ "(thus your OS <b>must</b> have a working IPv6 stack and you <b>must</b> have an IPv6 connection).</center>","options"));
+#endif
+
+
+ m_pUseSSLCheck = new KviStyledCheckBox(__tr2qs_ctx("Use SSL protocol","options"),tab);
+ gl->addMultiCellWidget(m_pUseSSLCheck,4,4,0,1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pUseSSLCheck,__tr2qs_ctx("<center>This check will cause the connection to use the <b>Secure Socket Layer</b> " \
+ "encryption support. Obviously, this server must have support for this, too. :)</center>","options"));
+#endif
+#ifndef COMPILE_SSL_SUPPORT
+ m_pUseSSLCheck->setEnabled(false);
+#endif
+ m_pUseSSLCheck->setChecked(s->useSSL());
+
+
+ m_pUseAutoConnect = new KviStyledCheckBox(__tr2qs_ctx("Connect to this server at startup","options"),tab);
+ m_pUseAutoConnect->setChecked(s->autoConnect());
+
+ gl->addMultiCellWidget(m_pUseAutoConnect,5,5,0,1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pUseAutoConnect,__tr2qs_ctx("<center>This option will cause KVIrc to connect to the IRC server when it is started.</center>","options"));
+#endif
+
+ l = new QLabel(__tr2qs_ctx("Encoding:","options"),tab);
+ gl->addWidget(l,6,0);
+ m_pEncodingEditor = new QComboBox(false,tab);
+ m_pEncodingEditor->setDuplicatesEnabled(false);
+ gl->addWidget(m_pEncodingEditor,6,1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pEncodingEditor,__tr2qs_ctx("<center>This box allows you to choose the preferred encoding for this sever. " \
+ "If you choose \"Use Network Encoding\" then the encoding will be inherited from the " \
+ "network that this server belongs to.</center>","options"));
+#endif
+
+ int i = 0;
+ int current = 0;
+ KviLocale::EncodingDescription * d = KviLocale::encodingDescription(i);
+ QString tmp;
+ m_pEncodingEditor->insertItem(__tr2qs_ctx("Use Network Encoding","options"));
+ while(d->szName)
+ {
+ KviQString::sprintf(tmp,"%s (%s)",d->szName,d->szDescription);
+ m_pEncodingEditor->insertItem(tmp);
+ if(KviQString::equalCI(d->szName,s->encoding()))current = i + 1;
+ i = i + 1;
+ d = KviLocale::encodingDescription(i);
+ }
+
+ m_pEncodingEditor->setCurrentItem(current);
+
+
+ l = new QLabel(__tr2qs_ctx("Link filter:","options"),tab);
+ gl->addWidget(l,7,0);
+ m_pLinkFilterEditor = new QComboBox(true,tab);
+ m_pLinkFilterEditor->setDuplicatesEnabled(false);
+ gl->addWidget(m_pLinkFilterEditor,7,1);
+
+ m_pLinkFilterEditor->insertItem("");
+
+ g_pModuleManager->loadModulesByCaps("linkfilter");
+ KviModuleExtensionDescriptorList * mexl = KviModuleExtensionManager::instance()->getExtensionList("linkfilter");
+
+
+
+ if(mexl)
+ {
+ for(KviModuleExtensionDescriptor * d = mexl->first();d;d = mexl->next())
+ m_pLinkFilterEditor->insertItem(d->name().ptr());
+ } else {
+ if(!s->linkFilter().isEmpty())
+ m_pLinkFilterEditor->insertItem(s->linkFilter());
+ }
+
+ if(!s->linkFilter().isEmpty())
+ m_pLinkFilterEditor->setCurrentText(s->linkFilter());
+ else
+ m_pLinkFilterEditor->setCurrentText("");
+
+
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pLinkFilterEditor,__tr2qs_ctx("<center>This field specifies the name of a module that exports a link filter for this type of server.<br>" \
+ "For plain IRC connections, you don't need any link filters; this is used for incompatible protocols.</center>","options"));
+#endif
+
+ l = new QLabel(__tr2qs_ctx("Id:","options"),tab);
+ gl->addWidget(l,8,0);
+ m_pIdEditor = new QLineEdit(tab);
+ if(s->id().isEmpty())s->generateUniqueId();
+ m_pIdEditor->setText(s->id());
+ gl->addWidget(m_pIdEditor,8,1);
+
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pIdEditor,__tr2qs_ctx("<center>This field allows you to specify a really unique id for this server. " \
+ "You will then be able to use /server -x &lt;this_id&gt; to make the connection. This is especially " \
+ "useful when you have multiple server entries with the same hostname and port in different networks (bouncers?)</center>","options"));
+#endif
+
+
+ l = new QLabel(__tr2qs_ctx("Proxy server:","options"),tab);
+ gl->addWidget(l,9,0);
+ m_pProxyEditor = new QComboBox(tab);
+ gl->addWidget(m_pProxyEditor,9,1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pProxyEditor,__tr2qs_ctx("<center>This is the <b>proxy</b> that KVIrc will use to connect to thos server.\n" \
+ "If this field is set in \"Default\" KVirc will use global proxy settings, if it is set in \"Direct connection\" " \
+ "KVirc will connect to this server without proxy. You can define new proxy server in global options' \"Proxy servers\" menu.</center>","options"));
+#endif
+
+ m_pProxyEditor->insertItem(__tr2qs_ctx("Default","options"));
+ m_pProxyEditor->insertItem(__tr2qs_ctx("Direct connection","options"));
+
+ KviPointerList<KviProxy> * proxylist = g_pProxyDataBase->proxyList();
+ for(KviProxy * p = proxylist->first();p;p = proxylist->next())
+ {
+ m_pProxyEditor->insertItem(QString("%1:%2").arg(p->hostname()).arg(p->port()));
+ }
+ if(m_pProxyEditor->count() > (s->proxy()+2))
+ m_pProxyEditor->setCurrentItem(s->proxy()+2);
+
+
+ l = new QLabel("",tab);
+ gl->addMultiCellWidget(l,10,10,0,1);
+
+ gl->setRowStretch(10,1);
+
+ tw->addTab(tab,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SOCKETWARNING)),__tr2qs_ctx("Connection","options"));
+
+ // after login join channels
+ tab = new QWidget(tw);
+
+ gl = new QGridLayout(tab,1,1,10,4);
+
+ if(s->autoJoinChannelList())
+ m_lstChannels = *(s->autoJoinChannelList());
+ m_pChannelListSelector = new KviCahnnelListSelector(tab,
+ __tr2qs_ctx("Channels to join automatically upon connect:","options"),&m_lstChannels,true);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pChannelListSelector,__tr2qs_ctx("<center>Here you can set a list of channels to be joined automatically " \
+ "after a connection to this server has been established. To add a channel, type its name in the " \
+ "text input below and click \"<b>Add</b>\".</center>","options"));
+#endif
+ gl->addWidget(m_pChannelListSelector,0,0);
+
+ tw->addTab(tab,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)),__tr2qs_ctx("Join Channels","options"));
+
+ // after connect execute
+ tab = new QWidget(tw);
+ gl = new QGridLayout(tab,1,1,10,4);
+
+
+ m_pOnConnectEditor = KviScriptEditor::createInstance(tab);
+ gl->addWidget(m_pOnConnectEditor,0,0);
+ m_pOnConnectEditor->setText(s->onConnectCommand());
+ m_pOnConnectEditor->setMinimumHeight(150);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pOnConnectEditor,__tr2qs_ctx("<center>The following commands will be executed after a connection has been established.<br>" \
+ "<b>Important:</b> Enter commands <b>without</b> a preceding slash (e.g. <tt>quote pass secret</tt> instead of <tt>/quote pass secret</tt>).<br>"\
+ "KVIrc will first send the USER command, then eventually PASS and NICK and then execute this " \
+ "command sequence.<br>This is particularly useful for IRC bouncers that require login commands.</center>","options"));
+#endif
+
+ tw->addTab(tab,__tr2qs_ctx("On Connect","options"));
+ // after login execute
+
+ tab = new QWidget(tw);
+ gl = new QGridLayout(tab,1,1,10,4);
+
+ m_pOnLoginEditor = KviScriptEditor::createInstance(tab);
+ gl->addWidget(m_pOnLoginEditor,0,0);
+ m_pOnLoginEditor->setText(s->onLoginCommand());
+
+ m_pOnLoginEditor->setMinimumHeight(150);
+
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pOnLoginEditor,
+ __tr2qs_ctx("<center>The following commands will be executed after a successful login to this server.<br>" \
+ "<b>Important:</b> Enter commands <b>without</b> a preceding slash (e.g. <tt>quote privatelog</tt> instead of <tt>/quote privatelog</tt>).<br>"
+ "This is useful for automatically opening queries, setting variables, etc.</center>","options"));
+#endif
+
+ tw->addTab(tab,__tr2qs_ctx("On Login","options"));
+
+ QPushButton * b = new QPushButton(__tr2qs_ctx("OK","options"),this);
+ b->setMinimumWidth(80);
+ g->addWidget(b,3,2);
+ b->setDefault(true);
+ connect(b,SIGNAL(clicked()),this,SLOT(accept()));
+
+ b = new QPushButton(__tr2qs_ctx("Cancel","options"),this);
+ g->addWidget(b,3,3);
+ b->setMinimumWidth(80);
+ connect(b,SIGNAL(clicked()),this,SLOT(reject()));
+
+ g->setRowStretch(2,1);
+ g->setColStretch(1,1);
+
+ tw->setMinimumWidth(390);
+
+ setHeaderLabelText();
+}
+
+KviServerDetailsWidget::~KviServerDetailsWidget()
+{
+ if(m_pOnConnectEditor) KviScriptEditor::destroyInstance(m_pOnConnectEditor);
+ if(m_pOnLoginEditor) KviScriptEditor::destroyInstance(m_pOnLoginEditor);
+}
+
+void KviServerDetailsWidget::useIPV6CheckToggled(bool)
+{
+#ifdef COMPILE_IPV6_SUPPORT
+ m_pIpEditor->setAddressType(m_pUseIPV6Check->isChecked() ? KviIpEditor::IpV6 : KviIpEditor::IpV4);
+#else
+ m_pIpEditor->setAddressType(KviIpEditor::IpV4);
+#endif
+ setHeaderLabelText();
+}
+
+void KviServerDetailsWidget::portEditorTextChanged(const QString &)
+{
+ setHeaderLabelText();
+}
+
+void KviServerDetailsWidget::setHeaderLabelText()
+{
+ QString szTmp = "<font size=\"+1\"><b>irc";
+ if(m_pUseIPV6Check->isChecked())szTmp += "6";
+ szTmp += "://";
+ szTmp += m_szHostname;
+ szTmp += ":";
+
+ bool bOk;
+
+ QString num = m_pPortEditor->text();
+ unsigned int uPort = num.toUInt(&bOk);
+ if(!bOk)uPort = 6667;
+ num.setNum(uPort);
+ szTmp += num;
+ szTmp += "</b></font>";
+
+ m_pHeaderLabel->setText(szTmp);
+}
+
+void KviServerDetailsWidget::fillData(KviIrcServer * s)
+{
+ s->setUserName(m_pUserEditor->text());
+ s->setPassword(m_pPassEditor->text());
+ s->setNickName(m_pNickEditor->text());
+ s->setRealName(m_pRealEditor->text());
+ if(m_pDescEditor)
+ s->setDescription(m_pDescEditor->text());
+ if(m_pLinkFilterEditor)
+ s->setLinkFilter(m_pLinkFilterEditor->lineEdit()->text());
+ if(m_pEncodingEditor)
+ if(m_pEncodingEditor->currentItem() <= 0)s->m_szEncoding = "";
+ else {
+ KviLocale::EncodingDescription * d = KviLocale::encodingDescription(m_pEncodingEditor->currentItem() - 1);
+ s->m_szEncoding = d->szName;
+ }
+ s->setIpAddress("");
+ if(m_pCacheIpCheck)
+ s->setCacheIp(m_pCacheIpCheck->isChecked());
+ if(m_pUseSSLCheck)
+ s->setUseSSL(m_pUseSSLCheck->isChecked());
+ if(m_pIdEditor)
+ s->setId(m_pIdEditor->text());
+ if(s->id().isEmpty())s->generateUniqueId();
+
+ if(m_pUseDefaultInitUMode)
+ {
+ KviStr szUMode;
+ if(!m_pUseDefaultInitUMode->isChecked())
+ {
+ if(m_pIMode->isChecked())szUMode.append('i');
+ if(m_pWMode->isChecked())szUMode.append('w');
+ if(m_pSMode->isChecked())szUMode.append('s');
+ }
+ s->setInitUMode(szUMode.ptr());
+ }
+
+ QString tmp = m_pPortEditor->text();
+ bool bOk;
+ kvi_u32_t uPort = tmp.toUInt(&bOk);
+ if(!bOk)uPort = 6667;
+ s->m_uPort = uPort;
+#ifdef COMPILE_IPV6_SUPPORT
+ s->setIpV6(m_pUseIPV6Check->isChecked());
+#else
+ s->setIpV6(false);
+#endif
+
+ if(m_pIpEditor)
+ {
+ KviStr tmpAddr = m_pIpEditor->address();
+
+ if(!m_pIpEditor->hasEmptyFields())
+ {
+#ifdef COMPILE_IPV6_SUPPORT
+ if(s->isIpV6())
+ {
+ if((!kvi_strEqualCI(tmpAddr.ptr(),"0:0:0:0:0:0:0:0")) && kvi_isValidStringIp_V6(tmpAddr.ptr()))
+ {
+ s->setIpAddress(tmpAddr.ptr());
+ } else {
+ s->setCacheIp(false);
+ s->setIpAddress("");
+ }
+ } else {
+#endif
+ if((!kvi_strEqualCI(tmpAddr.ptr(),"0.0.0.0")) && kvi_isValidStringIp(tmpAddr.ptr()))
+ {
+ s->setIpAddress(tmpAddr.ptr());
+ } else {
+ s->setCacheIp(false);
+ s->setIpAddress("");
+ }
+#ifdef COMPILE_IPV6_SUPPORT
+ }
+#endif
+ } else {
+ s->setCacheIp(false);
+ s->setIpAddress("");
+ }
+ }
+ if(m_pOnConnectEditor)
+ {
+ QString tmp;
+ m_pOnConnectEditor->getText(tmp);
+ s->setOnConnectCommand(tmp);
+ }
+ if(m_pOnLoginEditor)
+ {
+ QString tmp;
+ m_pOnLoginEditor->getText(tmp);
+ s->setOnLoginCommand(tmp);
+ }
+ if(m_pChannelListSelector)
+ m_pChannelListSelector->commit();
+ if(m_lstChannels.isEmpty())s->setAutoJoinChannelList(0);
+ else s->setAutoJoinChannelList(new QStringList(m_lstChannels));
+ if(m_pUseAutoConnect)
+ s->setAutoConnect(m_pUseAutoConnect->isChecked());
+ if(m_pProxyEditor)
+ s->setProxy(m_pProxyEditor->currentItem()-2);
+}
+
+void KviServerDetailsWidget::useDefaultInitUModeToggled(bool b)
+{
+ m_pIMode->setEnabled(!b);
+ m_pWMode->setEnabled(!b);
+ m_pSMode->setEnabled(!b);
+}
+
+// kvi_app.cpp
+extern KVIRC_API KviIrcServerDataBase * g_pIrcServerDataBase;
+
+KviServerOptionsListViewItem::KviServerOptionsListViewItem(KviTalListView *parent,const QPixmap &pm,const KviIrcNetwork *n)
+ : KviTalListViewItem(parent)
+{
+ setPixmap(0,pm);
+ m_pServerData = 0;
+ m_pNetworkData = new KviIrcNetwork(*n);
+ setText(0,n->name());
+ setText(1,n->description());
+}
+
+KviServerOptionsListViewItem::KviServerOptionsListViewItem(KviTalListViewItem *parent,const QPixmap &pm,const KviIrcServer *s)
+ : KviTalListViewItem(parent)
+{
+ setPixmap(0,pm);
+ m_pServerData = new KviIrcServer(*s);
+ setText(0,s->hostName());
+ setText(1,s->description());
+ m_pNetworkData = 0;
+}
+
+KviServerOptionsListViewItem::~KviServerOptionsListViewItem()
+{
+ if(m_pServerData)delete m_pServerData;
+ if(m_pNetworkData)delete m_pNetworkData;
+}
+
+void KviServerOptionsListViewItem::updateVisibleStrings()
+{
+ if(m_pNetworkData)
+ {
+ setText(0,m_pNetworkData->name());
+ setText(1,m_pNetworkData->description());
+ return;
+ }
+ if(m_pServerData)
+ {
+ setText(0,m_pServerData->hostName());
+ setText(1,m_pServerData->description());
+ }
+}
+
+
+
+
+
+
+
+
+KviServerOptionsWidget::KviServerOptionsWidget(QWidget * parent)
+ : KviOptionsWidget(parent,"server_options_widget")
+{
+ createLayout(4,2);
+
+ m_pContextPopup = new KviTalPopupMenu(this);
+ m_pImportPopup = new KviTalPopupMenu(this);
+
+ connect(m_pImportPopup,SIGNAL(aboutToShow()),this,SLOT(importPopupAboutToShow()));
+ connect(m_pImportPopup,SIGNAL(activated(int)),this,SLOT(importPopupActivated(int)));
+
+ m_pServerDetailsDialog = 0;
+ m_pNetworkDetailsDialog = 0;
+ m_pImportFilter = 0;
+
+ m_pListView = new KviTalListView(this);
+ addWidgetToLayout(m_pListView,0,0,0,0);
+ m_pListView->addColumn(__tr2qs_ctx("Server","options"));
+ m_pListView->addColumn(__tr2qs_ctx("Description","options"));
+ m_pListView->setRootIsDecorated(true);
+ m_pListView->setAllColumnsShowFocus(true);
+ m_pListView->setSelectionMode(KviTalListView::Single);
+ connect(m_pListView,SIGNAL(selectionChanged(KviTalListViewItem *)),
+ this,SLOT(listViewItemSelectionChanged(KviTalListViewItem *)));
+ connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),
+ this,SLOT(listViewRightButtonPressed(KviTalListViewItem *,const QPoint &,int)));
+ connect(m_pListView,SIGNAL(doubleClicked(KviTalListViewItem*, const QPoint&, int )),
+ this,SLOT(detailsClicked()));
+
+#ifdef COMPILE_INFO_TIPS
+ QString tiptxt = __tr2qs_ctx("<center>This is the list of available IRC servers.<br>" \
+ "Right-click on the list to add or remove servers and perform other actions.<br>"\
+ "Double-click on a item for advanced options.</center>","options");
+ KviTalToolTip::add(m_pListView,tiptxt);
+ KviTalToolTip::add(m_pListView->viewport(),tiptxt);
+#endif
+
+ KviTalVBox * vbox = new KviTalVBox(this);
+ addWidgetToLayout(vbox,1,0,1,0);
+
+ m_pNewNetworkButton = new KviStyledToolButton(vbox);
+ m_pNewNetworkButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_WORLD)));
+ m_pNewNetworkButton->setAutoRaise(true);
+ connect(m_pNewNetworkButton,SIGNAL(clicked()),this,SLOT(newNetwork()));
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pNewNetworkButton,__tr2qs_ctx("New Network","options"));
+#endif
+
+ m_pNewServerButton = new KviStyledToolButton(vbox);
+ m_pNewServerButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVER)));
+ m_pNewServerButton->setAutoRaise(true);
+ connect(m_pNewServerButton,SIGNAL(clicked()),this,SLOT(newServer()));
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pNewServerButton,__tr2qs_ctx("New Server","options"));
+#endif
+
+ m_pRemoveButton = new KviStyledToolButton(vbox);
+ m_pRemoveButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CUT)));
+ m_pRemoveButton->setEnabled(false);
+ m_pRemoveButton->setAutoRaise(true);
+ connect(m_pRemoveButton,SIGNAL(clicked()),this,SLOT(removeCurrent()));
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pRemoveButton,__tr2qs_ctx("Remove Network/Server","options"));
+#endif
+
+ QFrame * f = new QFrame(vbox);
+ f->setFrameStyle(QFrame::Sunken | QFrame::HLine);
+
+ m_pCopyServerButton = new KviStyledToolButton(vbox);
+ m_pCopyServerButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_COPY)));
+ m_pCopyServerButton->setEnabled(false);
+ m_pCopyServerButton->setAutoRaise(true);
+ connect(m_pCopyServerButton,SIGNAL(clicked()),this,SLOT(copyServer()));
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pCopyServerButton,__tr2qs_ctx("Copy Server","options"));
+#endif
+
+ m_pPasteServerButton = new KviStyledToolButton(vbox);
+ m_pPasteServerButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_PASTE)));
+ m_pPasteServerButton->setEnabled(false);
+ m_pPasteServerButton->setAutoRaise(true);
+ connect(m_pPasteServerButton,SIGNAL(clicked()),this,SLOT(pasteServer()));
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pPasteServerButton,__tr2qs_ctx("Paste Server","options"));
+#endif
+
+ f = new QFrame(vbox);
+ f->setFrameStyle(QFrame::Sunken | QFrame::HLine);
+
+ m_pImportButton = new KviStyledToolButton(vbox);
+ m_pImportButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)));
+ m_pImportButton->setAutoRaise(true);
+ m_pImportButton->setPopup(m_pImportPopup);
+ m_pImportButton->setPopupDelay(1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pImportButton,__tr2qs_ctx("Import List","options"));
+#endif
+
+ QFrame * lll = new QFrame(vbox);
+ vbox->setStretchFactor(lll,100);
+
+ KviTalGroupBox *gbox = addGroupBox(0,1,1,1,3,Qt::Horizontal,__tr2qs_ctx("Active Configuration","options"));
+ m_pSrvNetLabel = new QLabel(__tr2qs_ctx("Server:","options"),gbox);
+
+ m_pSrvNetEdit = new QLineEdit(gbox);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pSrvNetEdit,__tr2qs_ctx("<center>This is the name of the currently selected server or network</center>","options"));
+#endif
+
+/*
+ m_pIpV6Check = new KviStyledCheckBox(__tr2qs_ctx("Use IPv6 protocol","options"),gbox);
+
+#ifndef COMPILE_IPV6_SUPPORT
+ m_pIpV6Check->setEnabled(false);
+#endif
+
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pIpV6Check,__tr2qs_ctx("<center>This check identifies IPv6 servers.<br>If enabled, KVIrc will attempt to use the IPv6 protocol " \
+ "(thus your OS <b>must</b> have a working IPv6 stack and you <b>must</b> have an IPv6 connection).</center>","options"));
+#endif
+
+ m_pPortLabel = new QLabel(__tr2qs_ctx("Port:","options"),gbox);
+
+ m_pPortEdit = new QLineEdit(gbox);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pPortEdit,__tr2qs_ctx("<center>This is the default <b>port</b> that this server will be contacted on.<br>Usually <b>6667</b> is OK.</center>","options"));
+#endif
+*/
+
+ m_pDetailsButton = new QPushButton(__tr2qs_ctx("Advanced...","options"),gbox);
+ connect(m_pDetailsButton,SIGNAL(clicked()),this,SLOT(detailsClicked()));
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pDetailsButton,__tr2qs_ctx("<center>Click here to edit advanced options for this entry</center>","options"));
+#endif
+
+ m_pConnectCurrent = new QPushButton(__tr2qs_ctx("Connect &Now","options"),this);
+ addWidgetToLayout(m_pConnectCurrent,0,2,0,2);
+ connect(m_pConnectCurrent,SIGNAL(clicked()),this,SLOT(connectCurrentClicked()));
+
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(m_pConnectCurrent,__tr2qs_ctx("<center>Hit this button to connect to the currently selected server.</center>","options"));
+#endif
+
+ m_pRecentPopup = new KviTalPopupMenu(this);
+ connect(m_pRecentPopup,SIGNAL(aboutToShow()),this,SLOT(recentServersPopupAboutToShow()));
+ connect(m_pRecentPopup,SIGNAL(activated(int)),this,SLOT(recentServersPopupClicked(int)));
+
+ QToolButton * tb = new KviStyledToolButton(this);
+ addWidgetToLayout(tb,1,2,1,2);
+ tb->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)));
+ tb->setPopup(m_pRecentPopup);
+ tb->setPopupDelay(1);
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(tb,__tr2qs_ctx("<center>This button shows a list of recently used servers. It allows you to quickly find them in the list.</center>","options"));
+#endif
+
+
+ KviBoolSelector * b = addBoolSelector(0,3,1,3,__tr2qs_ctx("Show this dialog at startup","options"),KviOption_boolShowServersConnectDialogOnStart);
+
+#ifdef COMPILE_INFO_TIPS
+ KviTalToolTip::add(b,__tr2qs_ctx("<center>If this option is enabled, the Servers dialog will appear every time you start KVIrc</center>","options"));
+#endif
+
+ // KviBoolSelector * c = addBoolSelector(0,6,2,6,__tr("Close after connection","options"),KviOption_boolCloseServerWidgetAfterConnect);
+
+ m_pLastEditedItem = 0;
+
+ m_pClipboard = 0;
+
+ fillServerList();
+
+ layout()->setRowStretch(0,1);
+ //layout()->setColStretch(1,5);
+ //layout()->setColStretch(2,2);
+ layout()->setColStretch(0,1);
+ setMinimumWidth(320);
+}
+
+KviServerOptionsWidget::~KviServerOptionsWidget()
+{
+ if(m_pImportFilter)
+ {
+ disconnect(m_pImportFilter,0,this,0);
+ m_pImportFilter->die();
+ m_pImportFilter = 0;
+ }
+
+ if(m_pClipboard)delete m_pClipboard;
+ if(m_pServerDetailsDialog)delete m_pServerDetailsDialog;
+ if(m_pNetworkDetailsDialog)delete m_pNetworkDetailsDialog;
+}
+
+void KviServerOptionsWidget::recentServersPopupAboutToShow()
+{
+ g_pApp->fillRecentServersPopup(m_pRecentPopup);
+}
+
+void KviServerOptionsWidget::recentServersPopupClicked(int id)
+{
+ KviStr data = m_pRecentPopup->text(id);
+ data.cutToFirst('/');
+ while(data.firstCharIs('/'))data.cutLeft(1);
+ data.cutFromLast(':');
+ data.replaceAll("/","");
+ // we should have a full server name now , with no port
+
+ KviStr port = m_pRecentPopup->text(id);
+ port.cutToLast(':');
+ bool bOk;
+ kvi_u32_t uPort = port.toUInt(&bOk);
+ // we have the port too
+
+ KviTalListViewItem * pFoundNet = 0;
+ KviTalListViewItem * pFoundSrv = 0;
+
+ for(KviTalListViewItem * net = m_pListView->firstChild();net;net = net->nextSibling())
+ {
+ for(KviTalListViewItem * srv = net->firstChild();srv;srv = srv->nextSibling())
+ {
+ KviStr tmp = ((KviServerOptionsListViewItem *)srv)->m_pServerData->hostName();
+ if(kvi_strEqualCI(tmp.ptr(),data.ptr()))
+ {
+ if(((KviServerOptionsListViewItem *)srv)->m_pServerData->port() == uPort)
+ {
+ net->setOpen(true);
+ m_pListView->setCurrentItem(srv);
+ m_pListView->ensureItemVisible(srv);
+ return;
+ } else {
+ if(!pFoundNet)
+ {
+ // the port doesn't match.. check for
+ // another entry with the correct port
+ // but keep track of this entry in case we don't find it
+ pFoundNet = srv;
+ pFoundSrv = net;
+ }
+ }
+ }
+ }
+ }
+
+ // fallback to the server with the wrong port
+ if(pFoundNet)
+ {
+ pFoundNet->setOpen(true);
+ m_pListView->setCurrentItem(pFoundSrv);
+ m_pListView->ensureItemVisible(pFoundSrv);
+ }
+}
+
+
+void KviServerOptionsWidget::connectCurrentClicked()
+{
+ saveLastItem();
+ commit();
+ KviStr szServer = m_pSrvNetEdit->text();
+ if(szServer.isEmpty())return;
+ KviKvsScript::run("server -u",g_pApp->activeConsole());
+}
+
+
+void KviServerOptionsWidget::fillServerList()
+{
+ KviServerOptionsListViewItem * net;
+ KviServerOptionsListViewItem * srv;
+ KviServerOptionsListViewItem * cur = 0;
+
+ KviPointerHashTableIterator<QString,KviIrcServerDataBaseRecord> it(*(g_pIrcServerDataBase->recordDict()));
+
+ while(KviIrcServerDataBaseRecord * r = it.current())
+ {
+ net = new KviServerOptionsListViewItem(m_pListView,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_WORLD)),r->network());
+ KviPointerList<KviIrcServer> * sl = r->serverList();
+ bool bCurrent = r->network()->name() == g_pIrcServerDataBase->currentNetworkName().utf8().data();
+ net->setOpen(bCurrent);
+ for(KviIrcServer * s = sl->first();s;s = sl->next())
+ {
+ srv = new KviServerOptionsListViewItem(net,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVER)),s);
+
+ if((s == r->currentServer()) && bCurrent)
+ {
+ m_pListView->setSelected(srv,true);
+ cur = srv;
+ }
+ }
+ ++it;
+ }
+ if(cur)m_pListView->ensureItemVisible(cur);
+}
+
+void KviServerOptionsWidget::listViewItemSelectionChanged(KviTalListViewItem *it)
+{
+ saveLastItem();
+ m_pLastEditedItem = (KviServerOptionsListViewItem *)it;
+
+ if(m_pLastEditedItem)
+ {
+ m_pSrvNetLabel->setEnabled(true);
+ m_pSrvNetEdit->setEnabled(true);
+ m_pDetailsButton->setEnabled(true);
+ m_pConnectCurrent->setEnabled(m_pLastEditedItem->m_pServerData);
+
+ m_pRemoveButton->setEnabled(true);
+ m_pCopyServerButton->setEnabled(m_pLastEditedItem->m_pServerData);
+
+ if(m_pLastEditedItem->m_pServerData)
+ {
+ m_pSrvNetLabel->setText(__tr2qs_ctx("Server:","options"));
+ m_pSrvNetEdit->setText(m_pLastEditedItem->m_pServerData->m_szHostname);
+ } else {
+ m_pSrvNetLabel->setText(__tr2qs_ctx("Network:","options"));
+ m_pSrvNetEdit->setText(it->text(0));
+ }
+ } else {
+ m_pRemoveButton->setEnabled(false);
+ m_pCopyServerButton->setEnabled(true);
+
+ m_pConnectCurrent->setEnabled(false);
+ m_pSrvNetLabel->setEnabled(false);
+ m_pSrvNetEdit->setEnabled(false);
+ m_pSrvNetEdit->setText(__tr2qs_ctx("No selection","options"));
+ m_pDetailsButton->setEnabled(false);
+ }
+}
+
+
+
+void KviServerOptionsWidget::saveLastItem()
+{
+ if(!m_pLastEditedItem)return;
+ if(m_pLastEditedItem->m_pServerData)
+ {
+ KviStr tmp = m_pSrvNetEdit->text();
+ if(tmp.isEmpty())tmp = "irc.unknown.net";
+ m_pLastEditedItem->m_pServerData->m_szHostname = tmp;
+ m_pLastEditedItem->updateVisibleStrings();
+ } else if(m_pLastEditedItem->m_pNetworkData)
+ {
+ QString tmp = m_pSrvNetEdit->text();
+ if(tmp.isEmpty())tmp = __tr2qs_ctx("UnknownNet","options");
+ m_pLastEditedItem->m_pNetworkData->setName(tmp);
+ m_pLastEditedItem->updateVisibleStrings();
+ }
+}
+
+void KviServerOptionsWidget::commit()
+{
+ saveLastItem();
+ g_pIrcServerDataBase->clear();
+ KviServerOptionsListViewItem * it = (KviServerOptionsListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ QString tmp = it->m_pNetworkData ? it->m_pNetworkData->name() : QString::null;
+ if(!tmp.isEmpty())
+ {
+ KviIrcNetwork * net = 0;
+ KviIrcServerDataBaseRecord * r = g_pIrcServerDataBase->findRecord(tmp);
+ if(r)
+ {
+ net = r->network();
+ net->copyFrom(*(it->m_pNetworkData));
+ } else {
+ net = new KviIrcNetwork(tmp);
+ net->copyFrom(*(it->m_pNetworkData));
+ r = g_pIrcServerDataBase->insertNetwork(net);
+ }
+ if(it == m_pLastEditedItem)g_pIrcServerDataBase->setCurrentNetwork(net->name());
+
+ KviServerOptionsListViewItem * ch = (KviServerOptionsListViewItem *)it->firstChild();
+ KviIrcServer *srv;
+
+ while(ch)
+ {
+ if(ch->m_pServerData)
+ {
+ if(!ch->m_pServerData->m_szHostname.isEmpty())
+ {
+ srv = r->findServer(ch->m_pServerData);
+ if(!srv)
+ {
+ srv = new KviIrcServer(*(ch->m_pServerData));
+ r->insertServer(srv);
+ } else *srv = *(ch->m_pServerData);
+ if(srv->id().isEmpty())srv->generateUniqueId();
+ if(ch == m_pLastEditedItem)
+ {
+ g_pIrcServerDataBase->setCurrentNetwork(net->name());
+ r->setCurrentServer(srv);
+ }
+ }
+ }
+ ch = (KviServerOptionsListViewItem *)ch->nextSibling();
+ }
+ }
+ it = (KviServerOptionsListViewItem *)it->nextSibling();
+ }
+
+ KviOptionsWidget::commit();
+}
+
+void KviServerOptionsWidget::listViewRightButtonPressed(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ int id;
+ bool bServer = (it && ((KviServerOptionsListViewItem *)it)->m_pServerData);
+ m_pContextPopup->clear();
+ m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_WORLD)),__tr2qs_ctx("New Network","options"),this,SLOT(newNetwork()));
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CUT)),__tr2qs_ctx("Remove Network","options"),this,SLOT(removeCurrent()));
+ m_pContextPopup->setItemEnabled(id,!bServer);
+ m_pContextPopup->insertSeparator();
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVER)),__tr2qs_ctx("&New Server","options"),this,SLOT(newServer()));
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CUT)),__tr2qs_ctx("Re&move Server","options"),this,SLOT(removeCurrent()));
+ m_pContextPopup->setItemEnabled(id,bServer);
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_COPY)),__tr2qs_ctx("&Copy Server","options"),this,SLOT(copyServer()));
+ m_pContextPopup->setItemEnabled(id,bServer);
+ id = m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_PASTE)),__tr2qs_ctx("&Paste Server","options"),this,SLOT(pasteServer()));
+ m_pContextPopup->setItemEnabled(id,m_pClipboard);
+
+ m_pContextPopup->insertSeparator();
+ // m_pContextPopup->insertItem(__c2q(__tr("Merge list from server.ini","options")),this,SLOT(importFromIni()));
+ m_pContextPopup->insertItem(__tr2qs_ctx("Clear List","options"),this,SLOT(clearList()));
+ m_pContextPopup->insertSeparator();
+ m_pContextPopup->insertItem(__tr2qs_ctx("Import List","options"),m_pImportPopup);
+ m_pContextPopup->popup(QCursor::pos());
+}
+
+void KviServerOptionsWidget::importPopupAboutToShow()
+{
+ g_pModuleManager->loadModulesByCaps("serverimport");
+ m_pImportPopup->clear();
+
+ KviModuleExtensionDescriptorList * l = KviModuleExtensionManager::instance()->getExtensionList("serverimport");
+
+ if(!l)return;
+
+ int id;
+
+ for(KviModuleExtensionDescriptor * d = l->first();d;d = l->next())
+ {
+ if(d->icon())
+ id = m_pImportPopup->insertItem(*(d->icon()),d->visibleName());
+ else
+ id = m_pImportPopup->insertItem(d->visibleName());
+ m_pImportPopup->setItemParameter(id,d->id());
+ }
+}
+
+void KviServerOptionsWidget::importPopupActivated(int id)
+{
+ // ensure that we have all the modules : they could have been unloaded while the popup was displayed
+ g_pModuleManager->loadModulesByCaps("serverimport");
+
+ KviModuleExtensionDescriptorList * l = KviModuleExtensionManager::instance()->getExtensionList("serverimport");
+
+ if(!l)
+ {
+ // ops.. internal error: I thought to have a module capable of importing servers
+ // but actually it's not the case.. something weird happened (in the best case
+ // the user has just unloaded the module and removed it from disk ?)
+ KviMessageBox::warning(__tr2qs_ctx("Oops... something weird happened:<br>Can't find any module capable of importing servers.","options"));
+ return;
+ }
+
+ if(m_pImportFilter)
+ {
+ disconnect(m_pImportFilter,0,this,0);
+ m_pImportFilter->die();
+ m_pImportFilter = 0;
+ }
+
+ id = m_pImportPopup->itemParameter(id);
+
+ m_pImportFilter = (KviMexServerImport *)KviModuleExtensionManager::instance()->allocateExtension("serverimport",id,0);
+
+ if(!m_pImportFilter)
+ {
+ KviMessageBox::warning(__tr2qs_ctx("Oops... something weird happened:<br>Can't find the module that was capable of this import action. :(","options"));
+ return;
+ }
+
+ connect(m_pImportFilter,SIGNAL(server(const KviIrcServer &,const char *)),this,SLOT(importServer(const KviIrcServer &,const char *)));
+ connect(m_pImportFilter,SIGNAL(destroyed()),this,SLOT(importerDead()));
+
+ m_pImportFilter->start();
+}
+
+void KviServerOptionsWidget::importerDead()
+{
+ m_pImportFilter = 0;
+}
+
+void KviServerOptionsWidget::importServer(const KviIrcServer &s,const char * network)
+{
+ KviServerOptionsListViewItem * net = findNetItem(network);
+ if(!net)
+ {
+ KviIrcNetwork d(network);
+ net = new KviServerOptionsListViewItem(m_pListView,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_WORLD)),&d);
+ net->setOpen(true);
+ }
+
+ for(KviServerOptionsListViewItem * srv = (KviServerOptionsListViewItem *)net->firstChild();srv;srv = (KviServerOptionsListViewItem *)srv->nextSibling())
+ {
+ if((srv)->m_pServerData->useSSL() == s.useSSL())
+ {
+ if(srv->m_pServerData->isIpV6() == s.isIpV6())
+ {
+ if(KviQString::equalCI(srv->m_pServerData->hostName(),s.hostName()))
+ {
+ // update the port
+ srv->m_pServerData->setPort(s.port());
+ if(!s.ipAddress().isEmpty())srv->m_pServerData->setIpAddress(s.ipAddress());
+ if(!s.password().isEmpty())srv->m_pServerData->setPassword(s.password());
+ if(!s.nickName().isEmpty())srv->m_pServerData->setNickName(s.nickName());
+ m_pListView->setCurrentItem(srv);
+ m_pListView->ensureItemVisible(srv);
+ return;
+ }
+ }
+ }
+ }
+
+ // not found : add it!
+ KviServerOptionsListViewItem * newServer = new KviServerOptionsListViewItem(net,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVER)),&s);
+ m_pListView->setCurrentItem(newServer);
+ m_pListView->ensureItemVisible(newServer);
+}
+
+void KviServerOptionsWidget::newNetwork()
+{
+ KviIrcNetwork d(__tr2qs_ctx("New Network","options"));
+ KviServerOptionsListViewItem * it = new KviServerOptionsListViewItem(m_pListView,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_WORLD)),&d);
+ it->setOpen(true);
+ m_pListView->setSelected(it,true);
+ m_pListView->ensureItemVisible(it);
+}
+
+void KviServerOptionsWidget::newServer()
+{
+ if(m_pLastEditedItem)
+ {
+ KviServerOptionsListViewItem * net;
+ if(m_pLastEditedItem->m_pServerData)
+ {
+ net = (KviServerOptionsListViewItem *)m_pLastEditedItem->parent();
+ if(!net)return;
+ }
+ else net = m_pLastEditedItem;
+
+ KviIrcServer tmp;
+ tmp.m_szHostname = __tr2qs_ctx("irc.unknown.net","options");
+ tmp.setCacheIp(false);
+ tmp.generateUniqueId();
+
+ KviServerOptionsListViewItem * it = new KviServerOptionsListViewItem(net,
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVER)),&tmp);
+
+ net->setOpen(true);
+
+ m_pListView->setSelected(it,true);
+ m_pListView->ensureItemVisible(it);
+ }
+}
+
+void KviServerOptionsWidget::copyServer()
+{
+ if(m_pLastEditedItem)
+ {
+ if(m_pLastEditedItem->m_pServerData)
+ {
+ if(!m_pClipboard)m_pClipboard = new KviIrcServer();
+ *m_pClipboard = *(m_pLastEditedItem->m_pServerData);
+ m_pPasteServerButton->setEnabled(true);
+ }
+ }
+}
+
+void KviServerOptionsWidget::pasteServer()
+{
+ if(m_pClipboard)
+ {
+ if(m_pLastEditedItem)
+ {
+ KviServerOptionsListViewItem * net;
+ if(m_pLastEditedItem->m_pServerData)
+ {
+ net = (KviServerOptionsListViewItem *)m_pLastEditedItem->parent();
+ if(!net)return;
+ }
+ else net = m_pLastEditedItem;
+
+ KviServerOptionsListViewItem * it = new KviServerOptionsListViewItem(net,
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVER)),m_pClipboard);
+
+ net->setOpen(true);
+
+ m_pListView->setSelected(it,true);
+ m_pListView->ensureItemVisible(it);
+ }
+ }
+}
+
+void KviServerOptionsWidget::removeCurrent()
+{
+ if(m_pLastEditedItem)
+ {
+ KviTalListViewItem * it = m_pLastEditedItem->itemAbove();
+ if(!it)it = m_pLastEditedItem->firstChild() ? m_pLastEditedItem->nextSibling() : m_pLastEditedItem->itemBelow();
+ delete m_pLastEditedItem;
+ m_pLastEditedItem = 0;
+ if(!it)it = m_pListView->firstChild();
+ if(it)
+ {
+ m_pListView->setSelected(it,true);
+ m_pListView->ensureItemVisible(it);
+ }
+ }
+}
+
+KviServerOptionsListViewItem * KviServerOptionsWidget::findNetItem(const char * netname)
+{
+ KviServerOptionsListViewItem * it = (KviServerOptionsListViewItem *)m_pListView->firstChild();
+ while(it)
+ {
+ KviStr szNetName = it->text(0);
+ if(kvi_strEqualCI(szNetName.ptr(),netname))return it;
+ it = (KviServerOptionsListViewItem *)it->nextSibling();
+ }
+ return 0;
+}
+
+void KviServerOptionsWidget::clearList()
+{
+ m_pListView->clear();
+ m_pLastEditedItem = 0;
+ listViewItemSelectionChanged(0);
+}
+
+void KviServerOptionsWidget::detailsClicked()
+{
+ if(!m_pLastEditedItem)return;
+ if(m_pLastEditedItem->m_pServerData)
+ {
+ saveLastItem();
+
+ m_pServerDetailsDialog = new KviServerDetailsWidget(this,m_pLastEditedItem->m_pServerData);
+
+ int retCode = m_pServerDetailsDialog->exec();
+ if(retCode == QDialog::Accepted)
+ {
+ if(m_pLastEditedItem)
+ {
+ if(m_pLastEditedItem->m_pServerData)
+ {
+ m_pServerDetailsDialog->fillData(m_pLastEditedItem->m_pServerData);
+ saveLastItem();
+ }
+ }
+ }
+
+ delete m_pServerDetailsDialog;
+ m_pServerDetailsDialog = 0;
+ return;
+ }
+ if(m_pLastEditedItem->m_pNetworkData)
+ {
+ saveLastItem();
+
+ m_pNetworkDetailsDialog = new KviNetworkDetailsWidget(this,m_pLastEditedItem->m_pNetworkData);
+
+ int retCode = m_pNetworkDetailsDialog->exec();
+ if(retCode == QDialog::Accepted)
+ {
+ if(m_pLastEditedItem)
+ {
+ if(m_pLastEditedItem->m_pNetworkData)
+ {
+ m_pNetworkDetailsDialog->fillData(m_pLastEditedItem->m_pNetworkData);
+ saveLastItem();
+ }
+ }
+ }
+
+ delete m_pNetworkDetailsDialog;
+ m_pNetworkDetailsDialog = 0;
+ }
+}
+
+#include "m_optw_servers.moc"
diff --git a/src/modules/options/optw_servers.h b/src/modules/options/optw_servers.h
new file mode 100644
index 00000000..ea71c6d3
--- /dev/null
+++ b/src/modules/options/optw_servers.h
@@ -0,0 +1,210 @@
+#ifndef _OPTW_SERVERS_H_
+#define _OPTW_SERVERS_H_
+
+//=============================================================================
+//
+// File : optw_servers.h
+// Creation date : Wed Jun 12 2000 03:29:01 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 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_optionswidget.h"
+#include "kvi_tal_listview.h"
+#include <qdialog.h>
+#include <qbuttongroup.h>
+#include <qtabwidget.h>
+
+class KviIrcServer;
+class KviIrcNetwork;
+class KviIrcNetworkData;
+class KviMexServerImport;
+
+
+
+class KviServerOptionsListViewItem : public KviTalListViewItem
+{
+public:
+ KviServerOptionsListViewItem(KviTalListView *parent,const QPixmap &pm,const KviIrcNetwork *n);
+ KviServerOptionsListViewItem(KviTalListViewItem *parent,const QPixmap &pm,const KviIrcServer *s);
+ ~KviServerOptionsListViewItem();
+public:
+ KviIrcServer * m_pServerData;
+ KviIrcNetwork * m_pNetworkData;
+public:
+ void updateVisibleStrings();
+};
+
+class QLabel;
+class QLineEdit;
+class KviIpEditor;
+class KviIrcServer;
+class QCheckBox;
+class KviTalPopupMenu;
+class KviScriptEditor;
+class QComboBox;
+class QPushButton;
+class QToolButton;
+class KviNickServRule;
+class KviNickServRuleEditor;
+
+
+class KviNetworkDetailsWidget : public QDialog
+{
+ Q_OBJECT
+public:
+ KviNetworkDetailsWidget(QWidget * par,KviIrcNetwork * d);
+ ~KviNetworkDetailsWidget();
+protected:
+ KviScriptEditor * m_pOnConnectEditor;
+ KviScriptEditor * m_pOnLoginEditor;
+
+ QLineEdit * m_pUserEditor;
+ QLineEdit * m_pPassEditor;
+ QLineEdit * m_pNickEditor;
+ QLineEdit * m_pRealEditor;
+ QLineEdit * m_pDescEditor;
+
+ QComboBox * m_pEncodingEditor;
+
+ QCheckBox * m_pAutoConnectCheck;
+
+ KviTalListView * m_pNickServListView;
+ QCheckBox * m_pNickServCheck;
+ QPushButton * m_pAddRuleButton;
+ QPushButton * m_pDelRuleButton;
+ QPushButton * m_pEditRuleButton;
+
+ QStringList m_lstChannels;
+ KviCahnnelListSelector * m_pChannelListSelector;
+public:
+ void fillData(KviIrcNetwork * d);
+protected slots:
+ void enableDisableNickServControls();
+ void addNickServRule();
+ void delNickServRule();
+ void editNickServRule();
+};
+
+class KviServerDetailsWidget : public QDialog
+{
+ Q_OBJECT
+public:
+ KviServerDetailsWidget(QWidget * par,KviIrcServer * s);
+ ~KviServerDetailsWidget();
+protected:
+ QString m_szHostname;
+ QLabel * m_pHeaderLabel;
+ KviScriptEditor * m_pOnConnectEditor;
+ KviScriptEditor * m_pOnLoginEditor;
+ QLineEdit * m_pUserEditor;
+ QLineEdit * m_pPassEditor;
+ QLineEdit * m_pNickEditor;
+ QLineEdit * m_pRealEditor;
+ QLineEdit * m_pDescEditor;
+ QLineEdit * m_pIdEditor;
+ QComboBox * m_pLinkFilterEditor;
+ QComboBox * m_pEncodingEditor;
+ KviIpEditor * m_pIpEditor;
+ QCheckBox * m_pCacheIpCheck;
+ QCheckBox * m_pUseSSLCheck;
+ QCheckBox * m_pUseDefaultInitUMode;
+ QCheckBox * m_pIMode;
+ QCheckBox * m_pWMode;
+ QCheckBox * m_pSMode;
+ QCheckBox * m_pUseAutoConnect;
+ QCheckBox * m_pUseIPV6Check;
+ QLineEdit * m_pPortEditor;
+ QStringList m_lstChannels;
+ KviCahnnelListSelector * m_pChannelListSelector;
+
+ QComboBox * m_pProxyEditor;
+protected slots:
+ void useDefaultInitUModeToggled(bool);
+ void portEditorTextChanged(const QString &);
+ void useIPV6CheckToggled(bool);
+public:
+ void setHeaderLabelText();
+ void fillData(KviIrcServer *s);
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviServerOptionsWidget KVI_SMALLICON_SERVER
+#define KVI_OPTIONS_WIDGET_NAME_KviServerOptionsWidget __tr2qs_no_lookup("Servers")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviServerOptionsWidget __tr2qs_no_lookup("connection")
+//#define KVI_OPTIONS_WIDGET_NOPARENT_KviServerOptionsWidget KviConnectionOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviServerOptionsWidget 99000
+
+class KviServerOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviServerOptionsWidget(QWidget * parent);
+ ~KviServerOptionsWidget();
+protected:
+ KviTalListView * m_pListView;
+ QLabel * m_pSrvNetLabel;
+ QLineEdit * m_pSrvNetEdit;
+ //QLabel * m_pPortLabel;
+ //QLineEdit * m_pPortEdit;
+ QPushButton * m_pDetailsButton;
+ KviTalPopupMenu * m_pRecentPopup;
+ KviTalPopupMenu * m_pContextPopup;
+ KviTalPopupMenu * m_pImportPopup;
+ KviIrcServer * m_pClipboard;
+ //QCheckBox * m_pIpV6Check;
+ QPushButton * m_pConnectCurrent;
+ QPushButton * m_pConnectNew;
+ KviServerOptionsListViewItem * m_pLastEditedItem;
+ KviServerDetailsWidget * m_pServerDetailsDialog;
+ KviNetworkDetailsWidget * m_pNetworkDetailsDialog;
+ KviMexServerImport * m_pImportFilter;
+
+ QToolButton * m_pNewServerButton;
+ QToolButton * m_pNewNetworkButton;
+ QToolButton * m_pRemoveButton;
+ QToolButton * m_pCopyServerButton;
+ QToolButton * m_pPasteServerButton;
+ QToolButton * m_pImportButton;
+private:
+ void fillServerList();
+ void saveLastItem();
+ KviServerOptionsListViewItem * findNetItem(const char * netname);
+protected slots:
+ void importerDead();
+ void importServer(const KviIrcServer & s,const char * network);
+ void importPopupAboutToShow();
+ void listViewItemSelectionChanged(KviTalListViewItem *it);
+ void listViewRightButtonPressed(KviTalListViewItem *it,const QPoint &pnt,int col);
+ void newNetwork();
+ void removeCurrent();
+ void newServer();
+ void copyServer();
+ void pasteServer();
+ void clearList();
+ void detailsClicked();
+ void connectCurrentClicked();
+ void recentServersPopupAboutToShow();
+ void recentServersPopupClicked(int id);
+ void importPopupActivated(int id);
+public:
+ virtual void commit();
+};
+
+#endif //!_OPTW_SERVERS_H_
diff --git a/src/modules/options/optw_sound.cpp b/src/modules/options/optw_sound.cpp
new file mode 100644
index 00000000..9fec0a0c
--- /dev/null
+++ b/src/modules/options/optw_sound.cpp
@@ -0,0 +1,310 @@
+//=============================================================================
+//
+// File : optw_sound.cpp
+// Creation date : Fri Sep 6 02:18:23 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVsound sound client distribution
+// Copyright (C) 2002-2006 Szymon Stefanek (pragma at kvsound 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 "optw_sound.h"
+
+#include "kvi_settings.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_modulemanager.h"
+#include "kvi_pointerlist.h"
+#include "kvi_string.h"
+
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include "kvi_tal_hbox.h"
+
+#ifdef COMPILE_INFO_TIPS
+ #include "kvi_tal_tooltip.h"
+#endif
+
+// FIXME: This module doesn't Cancel properly when auto-detection is performed!
+
+
+
+KviSoundOptionsWidget::KviSoundOptionsWidget(QWidget * pParent)
+: KviOptionsWidget(pParent)
+{
+}
+
+KviSoundOptionsWidget::~KviSoundOptionsWidget()
+{
+}
+
+
+KviSoundGeneralOptionsWidget::KviSoundGeneralOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"sound_system_options_widget")
+{
+#ifdef COMPILE_ON_WINDOWS
+ createLayout(4,1);
+#else
+ createLayout(3,1);
+#endif
+ KviTalGroupBox * g = addGroupBox(0,0,0,0,1,Qt::Horizontal,__tr2qs_ctx("Sound System","options"),true);
+
+ KviTalToolTip::add(g,__tr2qs_ctx("This allows you to select the sound system to be used with KVIrc.","options"));
+
+ KviTalHBox * h = new KviTalHBox(g);
+
+ m_pSoundSystemBox = new QComboBox(false,h);
+
+ m_pSoundAutoDetectButton = new QPushButton(__tr2qs_ctx("Auto-detect","options"),h);
+ connect(m_pSoundAutoDetectButton,SIGNAL(clicked()),this,SLOT(soundAutoDetect()));
+
+ m_pSoundTestButton = new QPushButton(__tr2qs_ctx("Test","options"),h);
+ connect(m_pSoundTestButton,SIGNAL(clicked()),this,SLOT(soundTest()));
+
+
+ g = addGroupBox(0,1,0,1,1,Qt::Horizontal,__tr2qs_ctx("Media Player","options"),true);
+
+ KviTalToolTip::add(g,__tr2qs_ctx("This allows you to select the preferred media player to be used with " \
+ "the mediaplayer.* module commands and functions.","options"));
+
+ h = new KviTalHBox(g);
+
+ m_pMediaPlayerBox = new QComboBox(false,h);
+
+ m_pMediaAutoDetectButton = new QPushButton(__tr2qs_ctx("Auto-detect","options"),h);
+ connect(m_pMediaAutoDetectButton,SIGNAL(clicked()),this,SLOT(mediaAutoDetect()));
+
+ m_pMediaTestButton = new QPushButton(__tr2qs_ctx("Test","options"),h);
+ connect(m_pMediaTestButton,SIGNAL(clicked()),this,SLOT(mediaTest()));
+
+ addRowSpacer(0,2,0,2);
+
+ soundFillBox();
+ mediaFillBox();
+ // FIXME!
+ m_pSoundTestButton->setEnabled(false);
+ m_pMediaTestButton->setEnabled(false);
+
+ g = addGroupBox(0,2,0,2,1,Qt::Horizontal,__tr2qs_ctx("ID3 tags' encoding","options"),true);
+
+ KviTalToolTip::add(g,__tr2qs_ctx("This allows you to select encoding of mp3 tags.","options"));
+
+ h = new KviTalHBox(g);
+
+ m_pTagsEncodingCombo = new QComboBox(false,h);
+ m_pTagsEncodingCombo->insertItem(__tr2qs_ctx("Use Language Encoding","options"));
+
+ int i = 0;
+ int iMatch = 0;
+
+ KviLocale::EncodingDescription * d = KviLocale::encodingDescription(i);
+ while(d->szName)
+ {
+ if(KviQString::equalCI(d->szName,KVI_OPTION_STRING(KviOption_stringMp3TagsEncoding)))iMatch = i + 1;
+ m_pTagsEncodingCombo->insertItem(d->szName);
+ i++;
+ d = KviLocale::encodingDescription(i);
+ }
+ m_pTagsEncodingCombo->setCurrentItem(iMatch);
+
+#ifdef COMPILE_ON_WINDOWS
+ g = addGroupBox(0,3,0,3,1,Qt::Horizontal,__tr2qs_ctx("Winamp messages ecoding","options"),true);
+
+ KviTalToolTip::add(g,__tr2qs_ctx("This allows you to select encoding of winamp messages.","options"));
+
+ h = new KviTalHBox(g);
+
+ m_pWinampEncodingCombo = new QComboBox(false,h);
+
+ m_pWinampEncodingCombo->insertItem(__tr2qs_ctx("Use Language Encoding","options"));
+ i = 0;
+ iMatch = 0;
+
+ d = KviLocale::encodingDescription(i);
+ while(d->szName)
+ {
+ if(KviQString::equalCI(d->szName,KVI_OPTION_STRING(KviOption_stringWinampTextEncoding)))iMatch = i + 1;
+ m_pWinampEncodingCombo->insertItem(d->szName);
+ i++;
+ d = KviLocale::encodingDescription(i);
+ }
+ m_pWinampEncodingCombo->setCurrentItem(iMatch);
+#endif
+}
+
+
+KviSoundGeneralOptionsWidget::~KviSoundGeneralOptionsWidget()
+{
+}
+
+void KviSoundGeneralOptionsWidget::soundTest()
+{
+}
+
+void KviSoundGeneralOptionsWidget::mediaTest()
+{
+}
+
+
+void KviSoundGeneralOptionsWidget::soundAutoDetect()
+{
+ KviModule * m = g_pModuleManager->getModule("snd");
+ if(!m)return;
+ m->ctrl("detectSoundSystem",0);
+ soundFillBox();
+}
+
+void KviSoundGeneralOptionsWidget::mediaAutoDetect()
+{
+ KviModule * m = g_pModuleManager->getModule("mediaplayer");
+ if(!m)return;
+ m->ctrl("detectMediaPlayer",0);
+ mediaFillBox();
+}
+
+
+void KviSoundGeneralOptionsWidget::soundFillBox()
+{
+
+ QStringList l;
+ QStringList::Iterator it;
+ int cnt;
+ int i;
+ KviModule * m = g_pModuleManager->getModule("snd");
+
+
+ if(!m)goto disable;
+
+
+ if(!m->ctrl("getAvailableSoundSystems",&l))goto disable;
+
+ m_pSoundSystemBox->clear();
+
+ for ( it = l.begin(); it != l.end(); ++it )
+ {
+ m_pSoundSystemBox->insertItem(*it);
+ }
+
+ cnt = m_pSoundSystemBox->count();
+
+ for(i=0;i<cnt;i++)
+ {
+ QString t = m_pSoundSystemBox->text(i);
+ if(KviQString::equalCI(t,KVI_OPTION_STRING(KviOption_stringSoundSystem)))
+ {
+ m_pSoundSystemBox->setCurrentItem(i);
+ break;
+ }
+ }
+
+ return;
+disable:
+ m_pSoundSystemBox->clear();
+ m_pSoundSystemBox->setEnabled(false);
+ m_pSoundTestButton->setEnabled(false);
+ m_pSoundAutoDetectButton->setEnabled(false);
+}
+
+void KviSoundGeneralOptionsWidget::mediaFillBox()
+{
+ QStringList l;
+ QStringList::Iterator it;
+ int cnt;
+ int i;
+ KviModule * m = g_pModuleManager->getModule("mediaplayer");
+
+ if(!m)goto disable;
+ if(!m->ctrl("getAvailableMediaPlayers",&l))goto disable;
+ m_pMediaPlayerBox->clear();
+ for ( it = l.begin(); it != l.end(); ++it )
+ {
+ m_pMediaPlayerBox->insertItem(*it);
+ }
+ cnt = m_pMediaPlayerBox->count();
+
+ for(i=0;i<cnt;i++)
+ {
+ QString t = m_pMediaPlayerBox->text(i);
+ if(KviQString::equalCI(t,KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer)))
+ {
+ m_pMediaPlayerBox->setCurrentItem(i);
+ break;
+ }
+ }
+
+ return;
+disable:
+ m_pMediaPlayerBox->clear();
+ m_pMediaPlayerBox->setEnabled(false);
+ m_pMediaTestButton->setEnabled(false);
+ m_pMediaAutoDetectButton->setEnabled(false);
+}
+
+
+void KviSoundGeneralOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+ KVI_OPTION_STRING(KviOption_stringSoundSystem) = m_pSoundSystemBox->currentText();
+ KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer) = m_pMediaPlayerBox->currentText();
+
+ int idx = m_pTagsEncodingCombo->currentItem();
+ if(idx <= 0)
+ {
+ // guess from locale
+ KVI_OPTION_STRING(KviOption_stringMp3TagsEncoding) = "";
+ } else {
+ KVI_OPTION_STRING(KviOption_stringMp3TagsEncoding) = m_pTagsEncodingCombo->text(idx);
+ }
+
+
+#ifdef COMPILE_ON_WINDOWS
+ idx = m_pWinampEncodingCombo->currentItem();
+ if(idx <= 0)
+ {
+ // guess from locale
+ KVI_OPTION_STRING(KviOption_stringWinampTextEncoding) = "";
+ } else {
+ KVI_OPTION_STRING(KviOption_stringWinampTextEncoding) = m_pWinampEncodingCombo->text(idx);
+ }
+#endif
+}
+
+KviSoundsOptionsWidget::KviSoundsOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"sound_options_widget")
+{
+ createLayout(5,2);
+ addLabel(0,0,0,0,__tr2qs_ctx("New Query opened","options"));
+ addSoundSelector(1,0,1,0,"",KviOption_stringOnNewQueryOpenedSound);
+
+ addLabel(0,1,0,1,__tr2qs_ctx("New message in inactive query","options"));
+ addSoundSelector(1,1,1,1,"",KviOption_stringOnQueryMessageSound);
+
+ addLabel(0,2,0,2,__tr2qs_ctx("Highlighted message in inactive window","options"));
+ addSoundSelector(1,2,1,2,"",KviOption_stringOnHighlightedMessageSound);
+
+ addLabel(0,3,0,3,__tr2qs_ctx("Me have been kicked","options"));
+ addSoundSelector(1,3,1,3,"",KviOption_stringOnMeKickedSound);
+
+ addRowSpacer(0,4,1,4);
+
+}
+
+KviSoundsOptionsWidget::~KviSoundsOptionsWidget()
+{
+}
+
+#include "m_optw_sound.moc"
diff --git a/src/modules/options/optw_sound.h b/src/modules/options/optw_sound.h
new file mode 100644
index 00000000..37b3c0ed
--- /dev/null
+++ b/src/modules/options/optw_sound.h
@@ -0,0 +1,94 @@
+#ifndef _OPTW_SOUND_H_
+#define _OPTW_SOUND_H_
+//=============================================================================
+//
+// File : optw_sound.h
+// Creation date : Fri Sep 6 02:18:21 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2006 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_optionswidget.h"
+#include <qcombobox.h>
+#include <qpushbutton.h>
+
+#define KVI_OPTIONS_WIDGET_ICON_KviSoundOptionsWidget KVI_SMALLICON_SOUND
+#define KVI_OPTIONS_WIDGET_NAME_KviSoundOptionsWidget __tr2qs_no_lookup("Sound")
+#define KVI_OPTIONS_WIDGET_PARENT_KviSoundOptionsWidget KviGeneralOptOptionsWidget
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviSoundOptionsWidget true
+
+
+class KviSoundOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviSoundOptionsWidget(QWidget * parent);
+ ~KviSoundOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviSoundGeneralOptionsWidget KVI_SMALLICON_SOUND
+#define KVI_OPTIONS_WIDGET_NAME_KviSoundGeneralOptionsWidget __tr2qs_no_lookup("Sound System")
+#define KVI_OPTIONS_WIDGET_PARENT_KviSoundGeneralOptionsWidget KviSoundOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviSoundGeneralOptionsWidget __tr2qs_no_lookup("sound,xmms,audio,play,amarok")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviSoundGeneralOptionsWidget 70000
+
+class KviSoundGeneralOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviSoundGeneralOptionsWidget(QWidget * parent);
+ ~KviSoundGeneralOptionsWidget();
+protected:
+ QComboBox * m_pSoundSystemBox;
+ QPushButton * m_pSoundTestButton;
+ QPushButton * m_pSoundAutoDetectButton;
+ QComboBox * m_pMediaPlayerBox;
+ QPushButton * m_pMediaTestButton;
+ QPushButton * m_pMediaAutoDetectButton;
+
+#ifdef COMPILE_ON_WINDOWS
+ QComboBox * m_pWinampEncodingCombo;
+#endif
+ QComboBox * m_pTagsEncodingCombo;
+protected:
+ void soundFillBox();
+ void mediaFillBox();
+ virtual void commit();
+protected slots:
+ void soundTest();
+ void soundAutoDetect();
+ void mediaTest();
+ void mediaAutoDetect();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviSoundsOptionsWidget KVI_SMALLICON_SOUND
+#define KVI_OPTIONS_WIDGET_NAME_KviSoundsOptionsWidget __tr2qs_no_lookup("Sounds")
+#define KVI_OPTIONS_WIDGET_PARENT_KviSoundsOptionsWidget KviSoundOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviSoundsOptionsWidget __tr2qs_no_lookup("sound,events")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviSoundsOptionsWidget 80000
+
+class KviSoundsOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviSoundsOptionsWidget(QWidget * parent);
+ ~KviSoundsOptionsWidget();
+};
+
+#endif //_OPTW_SOUND_H_
diff --git a/src/modules/options/optw_ssl.cpp b/src/modules/options/optw_ssl.cpp
new file mode 100644
index 00000000..bf3ef46a
--- /dev/null
+++ b/src/modules/options/optw_ssl.cpp
@@ -0,0 +1,35 @@
+//
+// File : optw_ssl.cpp
+// Creation date : Thu Jul 20 20:52:30 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 "optw_ssl.h"
+
+#include <qlayout.h>
+#include <kvi_tal_groupbox.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+//#warning "Info tips"
+
+
+
+#include "m_optw_ssl.moc"
diff --git a/src/modules/options/optw_ssl.h b/src/modules/options/optw_ssl.h
new file mode 100644
index 00000000..9b7db6de
--- /dev/null
+++ b/src/modules/options/optw_ssl.h
@@ -0,0 +1,29 @@
+#ifndef _OPTW_SSL_H_
+#define _OPTW_SSL_H_
+//
+// File : optw_ssl.h
+// Creation date : Thu Jul 20 20:52:30 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_optionswidget.h"
+
+
+
+#endif //_OPTW_SSL_H_
diff --git a/src/modules/options/optw_taskbar.cpp b/src/modules/options/optw_taskbar.cpp
new file mode 100644
index 00000000..1b146d39
--- /dev/null
+++ b/src/modules/options/optw_taskbar.cpp
@@ -0,0 +1,255 @@
+//
+// File : optw_taskbar.cpp
+// Creation date : Wed Jan 16 04:30:39 2002 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 "optw_taskbar.h"
+
+#include "kvi_settings.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+
+
+KviTaskBarOptionsWidget::KviTaskBarOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"taskbar_options_widget")
+{
+
+ createLayout(7,1);
+
+ addBoolSelector(0,0,0,0,__tr2qs_ctx("Use tree taskbar","options"),KviOption_boolUseTreeWindowListTaskBar);
+ addBoolSelector(0,1,0,1,__tr2qs_ctx("Sort windows by name","options"),KviOption_boolSortTaskBarItemsByName);
+ addBoolSelector(0,2,0,2,__tr2qs_ctx("Show window icons in taskbar","options"),KviOption_boolUseTaskBarIcons);
+ KviBoolSelector * b = addBoolSelector(0,3,0,3,__tr2qs_ctx("Show activity meter in taskbar","options"),KviOption_boolUseTaskBarActivityMeter);
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(b,__tr2qs_ctx("<center>This option enables the usage of the taskbar activity meter. " \
+ "Each window entry will have a small indicator of the activity that is going on in that window. " \
+ "The indicator is a small square that changes colors, dark colors mean low activity, " \
+ "while bright colors signal high activity. KVIrc also uses some heuristics to determine " \
+ "whether the activity is somewhat \"human\" or it is generated by automated entities (such as bots " \
+ "or IRC servers). \"Human\" activity causes the indicator to be shaded red while automated " \
+ "activity causes the indicator to be shaded blue.</center>","options"));
+#endif
+ addBoolSelector(0,4,0,4,__tr2qs_ctx("Show IRC context indicator in taskbar","options"),KviOption_boolUseTaskBarIrcContextIndicator);
+ addBoolSelector(0,5,0,5,__tr2qs_ctx("Enable window tooltips","options"),KviOption_boolShowTaskBarToolTips);
+ addRowSpacer(0,6,0,6);
+}
+
+
+KviTaskBarOptionsWidget::~KviTaskBarOptionsWidget()
+{
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviTreeTaskBarOptionsWidget::KviTreeTaskBarOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"treetaskbar_options_widget")
+{
+}
+
+KviTreeTaskBarOptionsWidget::~KviTreeTaskBarOptionsWidget()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviTreeTaskBarForegroundOptionsWidget::KviTreeTaskBarForegroundOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"treetaskbar_options_widget")
+{
+ createLayout(3,1);
+
+ KviTalGroupBox *g = addGroupBox(0,0,0,0,2,Qt::Horizontal,__tr2qs_ctx("Text/Alert Colors","options"));
+
+ addColorSelector(g,__tr2qs_ctx("Normal:","options"),KviOption_colorTreeTaskBarForeground);
+ addColorSelector(g,__tr2qs_ctx("Selected:","options"),KviOption_colorTreeTaskBarActiveForeground);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 1:","options"),KviOption_colorTreeTaskBarHighlight1Foreground);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 2:","options"),KviOption_colorTreeTaskBarHighlight2Foreground);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 3:","options"),KviOption_colorTreeTaskBarHighlight3Foreground);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 4:","options"),KviOption_colorTreeTaskBarHighlight4Foreground);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 5:","options"),KviOption_colorTreeTaskBarHighlight5Foreground);
+
+ addColorSelector(0,1,0,1,__tr2qs_ctx("Progress bar color:","options"),KviOption_colorTreeTaskBarProgress);
+
+ addRowSpacer(0,2,0,2);
+}
+
+
+KviTreeTaskBarForegroundOptionsWidget::~KviTreeTaskBarForegroundOptionsWidget()
+{
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviTreeTaskBarBackgroundOptionsWidget::KviTreeTaskBarBackgroundOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"treetaskbar_options_widget")
+{
+ createLayout(4,2);
+
+ KviTalGroupBox * g = addGroupBox(0,0,1,0,2,Qt::Horizontal,__tr2qs_ctx("Background Colors","options"));
+ addColorSelector(g,__tr2qs_ctx("Normal:","options"),KviOption_colorTreeTaskBarBackground);
+ addColorSelector(g,__tr2qs_ctx("Selected:","options"),KviOption_colorTreeTaskBarActiveBackground);
+
+ addPixmapSelector(0,1,1,1,__tr2qs_ctx("Background image:","options"),KviOption_pixmapTreeTaskBarBackground);
+
+ addLabel(0,2,0,2,__tr2qs_ctx("Horizontal align:","options"));
+ m_pHorizontalAlign=new QComboBox(this);
+ addWidgetToLayout(m_pHorizontalAlign,1,2,1,2);
+
+ addLabel(0,3,0,3,__tr2qs_ctx("Vertical align:","options"));
+ m_pVerticalAlign=new QComboBox(this);
+ addWidgetToLayout(m_pVerticalAlign,1,3,1,3);
+
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Tile","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Left","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Right","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Center","options"));
+
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Tile","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Top","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Bottom","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Center","options"));
+
+ switch( KVI_OPTION_UINT(KviOption_uintTreeTaskBarPixmapAlign) & Qt::AlignHorizontal_Mask)
+ {
+ case Qt::AlignLeft:
+ m_pHorizontalAlign->setCurrentItem(1);
+ break;
+ case Qt::AlignRight:
+ m_pHorizontalAlign->setCurrentItem(2);
+ break;
+ case Qt::AlignHCenter:
+ m_pHorizontalAlign->setCurrentItem(3);
+ break;
+ default:
+ m_pHorizontalAlign->setCurrentItem(0);
+ }
+
+ switch( KVI_OPTION_UINT(KviOption_uintTreeTaskBarPixmapAlign) & Qt::AlignVertical_Mask)
+ {
+ case Qt::AlignTop:
+ m_pVerticalAlign->setCurrentItem(1);
+ break;
+ case Qt::AlignBottom:
+ m_pVerticalAlign->setCurrentItem(2);
+ break;
+ case Qt::AlignVCenter:
+ m_pVerticalAlign->setCurrentItem(3);
+ break;
+ default:
+ m_pVerticalAlign->setCurrentItem(0);
+ }
+
+ layout()->setRowStretch(1,1);
+}
+
+
+KviTreeTaskBarBackgroundOptionsWidget::~KviTreeTaskBarBackgroundOptionsWidget()
+{
+}
+
+void KviTreeTaskBarBackgroundOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+
+ int iFlags=0;
+ switch(m_pHorizontalAlign->currentItem())
+ {
+ case 1:
+ iFlags|=Qt::AlignLeft;
+ break;
+ case 2:
+ iFlags|=Qt::AlignRight;
+ break;
+ case 3:
+ iFlags|=Qt::AlignHCenter;
+ break;
+ }
+ switch(m_pVerticalAlign->currentItem())
+ {
+ case 1:
+ iFlags|=Qt::AlignTop;
+ break;
+ case 2:
+ iFlags|=Qt::AlignBottom;
+ break;
+ case 3:
+ iFlags|=Qt::AlignVCenter;
+ break;
+ }
+
+ KVI_OPTION_UINT(KviOption_uintTreeTaskBarPixmapAlign)=iFlags;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviTreeTaskBarFeaturesOptionsWidget::KviTreeTaskBarFeaturesOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"treetaskbar_options_widget")
+{
+ createLayout(4,1);
+
+ addBoolSelector(0,0,1,0,__tr2qs_ctx("Show header","options"),KviOption_boolShowTreeTaskbarHeader);
+
+ addUIntSelector(0,1,0,1,__tr2qs_ctx("Minimum width:","options"),KviOption_uintTreeTaskBarMinimumWidth,24,1024,125);
+ addUIntSelector(0,2,0,2,__tr2qs_ctx("Maximum width:","options"),KviOption_uintTreeTaskBarMaximumWidth,24,9999,125);
+
+ addRowSpacer(0,3,0,3);
+}
+
+
+KviTreeTaskBarFeaturesOptionsWidget::~KviTreeTaskBarFeaturesOptionsWidget()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviClassicTaskBarOptionsWidget::KviClassicTaskBarOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"classictaskbar_options_widget")
+{
+ createLayout(8,1);
+ addFontSelector(0,0,0,0,__tr2qs_ctx("Font:","options"),KviOption_fontTaskbar);
+ KviTalGroupBox *g = addGroupBox(0,1,0,1,2,Qt::Horizontal,__tr2qs_ctx("Text/Alert Colors","options"));
+ addColorSelector(g,__tr2qs_ctx("Normal:","options"),KviOption_colorTaskBarNormalText);
+ addColorSelector(g,__tr2qs_ctx("Minimized:","options"), KviOption_colorTaskBarMinimizedText);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 1:","options"),KviOption_colorTaskBarHighlight1Text);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 2:","options"),KviOption_colorTaskBarHighlight2Text);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 3:","options"),KviOption_colorTaskBarHighlight3Text);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 4:","options"),KviOption_colorTaskBarHighlight4Text);
+ addColorSelector(g,__tr2qs_ctx("Alert Level 5:","options"),KviOption_colorTaskBarHighlight5Text);
+ addColorSelector(0,2,0,2,__tr2qs_ctx("Progress bar color:","options"),KviOption_colorTaskBarProgressBar);
+ addUIntSelector(0,3,0,3,__tr2qs_ctx("Minimum width of buttons:","options"),KviOption_uintTaskBarButtonMinWidth,24,9999,100);
+ //addUIntSelector(0,4,0,4,__tr2qs_ctx("Maximum number of rows:","options"),KviOption_uintTaskBarMaximumRows,1,16,2);
+ addBoolSelector(0,4,0,4,__tr2qs_ctx("Set maximum button width","options"),KviOption_boolClassicTaskBarSetMaximumButtonWidth);
+ addUIntSelector(0,5,0,5,__tr2qs_ctx("Maximum width of buttons:","options"),KviOption_uintClassicTaskBarMaximumButtonWidth,24,9999,100);
+ addBoolSelector(0,6,0,6,__tr2qs_ctx("Use flat buttons","options"),KviOption_boolUseFlatClassicTaskbarButtons);
+ addRowSpacer(0,7,0,7);
+}
+
+
+KviClassicTaskBarOptionsWidget::~KviClassicTaskBarOptionsWidget()
+{
+}
+
+#include "m_optw_taskbar.moc"
diff --git a/src/modules/options/optw_taskbar.h b/src/modules/options/optw_taskbar.h
new file mode 100644
index 00000000..66990c26
--- /dev/null
+++ b/src/modules/options/optw_taskbar.h
@@ -0,0 +1,125 @@
+#ifndef _OPTW_TASKBAR_H_
+#define _OPTW_TASKBAR_H_
+
+//===============================================================================
+//
+// File : optw_taskbar.h
+// Creation date : Wed Jan 16 04:30:41 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2006 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_optionswidget.h"
+#include <qcombobox.h>
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTaskBarOptionsWidget KVI_SMALLICON_CLASSICTASKBAR
+#define KVI_OPTIONS_WIDGET_NAME_KviTaskBarOptionsWidget __tr2qs_no_lookup("Taskbar")
+#define KVI_OPTIONS_WIDGET_MINIMAL_USER_EXPERIENCE_LEVEL_KviTaskBarOptionsWidget 2
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTaskBarOptionsWidget __tr2qs_no_lookup("theme")
+#define KVI_OPTIONS_WIDGET_GROUP_KviTaskBarOptionsWidget "theme"
+
+class KviTaskBarOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTaskBarOptionsWidget(QWidget * parent);
+ ~KviTaskBarOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTreeTaskBarOptionsWidget KVI_SMALLICON_TREETASKBAR
+#define KVI_OPTIONS_WIDGET_NAME_KviTreeTaskBarOptionsWidget __tr2qs_no_lookup("Tree Taskbar")
+#define KVI_OPTIONS_WIDGET_PARENT_KviTreeTaskBarOptionsWidget KviTaskBarOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBarOptionsWidget __tr2qs_no_lookup("theme")
+#define KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviTreeTaskBarOptionsWidget true
+
+class KviTreeTaskBarOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTreeTaskBarOptionsWidget(QWidget * pParent);
+ ~KviTreeTaskBarOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTreeTaskBarForegroundOptionsWidget KVI_SMALLICON_TREETASKBAR
+#define KVI_OPTIONS_WIDGET_NAME_KviTreeTaskBarForegroundOptionsWidget __tr2qs_no_lookup("Foreground")
+#define KVI_OPTIONS_WIDGET_PARENT_KviTreeTaskBarForegroundOptionsWidget KviTreeTaskBarOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskForegroundBarOptionsWidget __tr2qs_no_lookup("theme")
+#define KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarForegroundOptionsWidget "theme"
+
+class KviTreeTaskBarForegroundOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTreeTaskBarForegroundOptionsWidget(QWidget * parent);
+ ~KviTreeTaskBarForegroundOptionsWidget();
+};
+
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTreeTaskBarBackgroundOptionsWidget KVI_SMALLICON_TREETASKBAR
+#define KVI_OPTIONS_WIDGET_NAME_KviTreeTaskBarBackgroundOptionsWidget __tr2qs_no_lookup("Background")
+#define KVI_OPTIONS_WIDGET_PARENT_KviTreeTaskBarBackgroundOptionsWidget KviTreeTaskBarOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskBackgroundBarOptionsWidget __tr2qs_no_lookup("theme")
+#define KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarBackgroundOptionsWidget "theme"
+
+class KviTreeTaskBarBackgroundOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+private:
+ QComboBox* m_pHorizontalAlign;
+ QComboBox* m_pVerticalAlign;
+public:
+ KviTreeTaskBarBackgroundOptionsWidget(QWidget * parent);
+ ~KviTreeTaskBarBackgroundOptionsWidget();
+
+ virtual void commit();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTreeTaskBarFeaturesOptionsWidget KVI_SMALLICON_TREETASKBAR
+#define KVI_OPTIONS_WIDGET_NAME_KviTreeTaskBarFeaturesOptionsWidget __tr2qs_no_lookup("Features")
+#define KVI_OPTIONS_WIDGET_PARENT_KviTreeTaskBarFeaturesOptionsWidget KviTreeTaskBarOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTreeTaskFeaturesBarOptionsWidget __tr2qs_no_lookup("theme")
+#define KVI_OPTIONS_WIDGET_GROUP_KviTreeTaskBarFeaturesOptionsWidget "theme"
+
+class KviTreeTaskBarFeaturesOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTreeTaskBarFeaturesOptionsWidget(QWidget * parent);
+ ~KviTreeTaskBarFeaturesOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviClassicTaskBarOptionsWidget KVI_SMALLICON_CLASSICTASKBAR
+#define KVI_OPTIONS_WIDGET_NAME_KviClassicTaskBarOptionsWidget __tr2qs_no_lookup("Classic Taskbar")
+#define KVI_OPTIONS_WIDGET_PARENT_KviClassicTaskBarOptionsWidget KviTaskBarOptionsWidget
+#define KVI_OPTIONS_WIDGET_MINIMAL_USER_EXPERIENCE_LEVEL_KviClassicTaskBarOptionsWidget 2
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviClassicTaskBarOptionsWidget __tr2qs_no_lookup("theme")
+#define KVI_OPTIONS_WIDGET_GROUP_KviClassicTaskBarOptionsWidget "theme"
+
+class KviClassicTaskBarOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviClassicTaskBarOptionsWidget(QWidget * parent);
+ ~KviClassicTaskBarOptionsWidget();
+};
+
+#endif //_OPTW_TASKBAR_H_
diff --git a/src/modules/options/optw_textencoding.cpp b/src/modules/options/optw_textencoding.cpp
new file mode 100644
index 00000000..431cdad0
--- /dev/null
+++ b/src/modules/options/optw_textencoding.cpp
@@ -0,0 +1,139 @@
+//
+// File : optw_textencoding.cpp
+// Creation date : Sat Aug 11 2001 03:29:52 CEST 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 "optw_textencoding.h"
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_qstring.h"
+#include "kvi_app.h"
+#include "kvi_fileutils.h"
+
+#include <qdir.h>
+#include <qmessagebox.h>
+
+QString g_szPrevSettedLocale;
+
+KviTextEncodingOptionsWidget::KviTextEncodingOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"textencoding_options_widget")
+{
+ createLayout(5,2);
+
+ addLabel(0,0,0,0,__tr2qs_ctx("Default text encoding:","options"));
+
+ m_pTextEncodingCombo = new QComboBox(this);
+ addWidgetToLayout(m_pTextEncodingCombo,1,0,1,0);
+
+ m_pTextEncodingCombo->insertItem(__tr2qs_ctx("Use Language Encoding","options"));
+ int i = 0;
+ int iMatch = 0;
+ KviLocale::EncodingDescription * d = KviLocale::encodingDescription(i);
+ while(d->szName)
+ {
+ if(KviQString::equalCI(d->szName,KVI_OPTION_STRING(KviOption_stringDefaultTextEncoding)))iMatch = i + 1;
+ m_pTextEncodingCombo->insertItem(d->szName);
+ i++;
+ d = KviLocale::encodingDescription(i);
+ }
+
+ m_pTextEncodingCombo->setCurrentItem(iMatch);
+
+ addLabel(0,1,0,1,__tr2qs_ctx("Force language:","options"));
+
+ m_pForcedLocaleCombo = new QComboBox(this);
+
+ addWidgetToLayout(m_pForcedLocaleCombo,1,1,1,1);
+
+ QLabel * l = new QLabel(__tr2qs_ctx("<b>Note:</b> You need to restart KVirc to apply a language changing","options"),this);
+ addWidgetToLayout(l,0,2,1,2);
+
+ m_pForcedLocaleCombo->insertItem(__tr2qs_ctx("Automatic detection","options"));
+ m_pForcedLocaleCombo->insertItem(__tr2qs_ctx("en","options"));
+
+ QString szLangFile=QString("%1/.kvirc_force_locale").arg(QDir::homeDirPath());
+
+ bool bIsDefaultLocale = !KviFileUtils::fileExists(szLangFile);
+ //We Have setted locale, but not restarted kvirc
+ if(!g_szPrevSettedLocale.isEmpty())
+ {
+ m_szLanguage=g_szPrevSettedLocale;
+ } else {
+ m_szLanguage=KviLocale::localeName();
+ }
+
+ QString szLocaleDir;
+ g_pApp->getGlobalKvircDirectory(szLocaleDir,KviApp::Locale);
+
+ QStringList list=QDir(szLocaleDir).entryList("kvirc_*.mo",QDir::Files);
+
+ i = 0;
+ iMatch = 0;
+
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
+ QString szTmp=*it;
+ szTmp.replace("kvirc_","");
+ szTmp.replace(".mo","");
+ m_pForcedLocaleCombo->insertItem(szTmp);
+ if(KviQString::equalCI(szTmp,m_szLanguage))
+ iMatch = i + 2;
+ i++;
+ }
+ if(bIsDefaultLocale)
+ m_pForcedLocaleCombo->setCurrentItem(0);
+ else if(KviQString::equalCI(m_szLanguage,"en"))
+ m_pForcedLocaleCombo->setCurrentItem(1);
+ else
+ m_pForcedLocaleCombo->setCurrentItem(iMatch);
+ addRowSpacer(0,3,1,3);
+}
+
+KviTextEncodingOptionsWidget::~KviTextEncodingOptionsWidget()
+{
+}
+
+void KviTextEncodingOptionsWidget::commit()
+{
+ int idx = m_pTextEncodingCombo->currentItem();
+ if(idx <= 0)
+ {
+ // guess from locale
+ KVI_OPTION_STRING(KviOption_stringDefaultTextEncoding) = "";
+ } else {
+ KVI_OPTION_STRING(KviOption_stringDefaultTextEncoding) = m_pTextEncodingCombo->text(idx);
+ }
+
+ idx=m_pForcedLocaleCombo->currentItem();
+ QString szLangFile=QString("%1/.kvirc_force_locale").arg(QDir::homeDirPath());
+ if(idx==0) {
+ if(KviFileUtils::fileExists(szLangFile))
+ KviFileUtils::removeFile(szLangFile);
+ } else {
+ g_szPrevSettedLocale=m_pForcedLocaleCombo->text(idx);
+ if(!KviFileUtils::writeFile(szLangFile,m_pForcedLocaleCombo->text(idx)))
+ {
+ QMessageBox::critical(this,"KVIrc",__tr2qs_ctx("Unable to write language information to","options")+"\n"+szLangFile,__tr2qs_ctx("Ok","options"));
+ }
+ }
+/* if(!KviQString::equalCI(m_pForcedLocaleCombo->text(idx),m_szLanguage))
+ QMessageBox::information(0,"KVIrc",__tr2qs_ctx("You need to restart KVirc to apply a language changing","options"),QMessageBox::Ok);*/
+}
+
+#include "m_optw_textencoding.moc"
diff --git a/src/modules/options/optw_textencoding.h b/src/modules/options/optw_textencoding.h
new file mode 100644
index 00000000..75bdeb75
--- /dev/null
+++ b/src/modules/options/optw_textencoding.h
@@ -0,0 +1,50 @@
+#ifndef _OPTW_TEXTENCODING_H_
+#define _OPTW_TEXTENCODING_H_
+
+//
+// File : optw_textencoding.h
+// Creation date : Sat Mar 02 2002 12:09:19 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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_optionswidget.h"
+
+#include <qcombobox.h>
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTextEncodingOptionsWidget KVI_SMALLICON_TEXTENCODING
+#define KVI_OPTIONS_WIDGET_NAME_KviTextEncodingOptionsWidget __tr2qs_no_lookup("Language")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviTextEncodingOptionsWidget 50000
+#define KVI_OPTIONS_WIDGET_PARENT_KviTextEncodingOptionsWidget KviGeneralOptOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTextEncodingOptionsWidget __tr2qs_no_lookup("language,encoding,charset,codepage")
+
+class KviTextEncodingOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTextEncodingOptionsWidget(QWidget * parent);
+ ~KviTextEncodingOptionsWidget();
+protected:
+ QString m_szLanguage;
+ QComboBox * m_pTextEncodingCombo;
+ QComboBox * m_pForcedLocaleCombo;
+public:
+ virtual void commit();
+};
+
+#endif //!_OPTW_TEXTENCODING_H_
diff --git a/src/modules/options/optw_texticons.cpp b/src/modules/options/optw_texticons.cpp
new file mode 100644
index 00000000..d1752c0f
--- /dev/null
+++ b/src/modules/options/optw_texticons.cpp
@@ -0,0 +1,244 @@
+//
+// File : optw_texticons.cpp
+// Creation date : Fri May 24 2002 00:16:13 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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 "optw_texticons.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_texticonmanager.h"
+#include "kvi_locale.h"
+#include "kvi_filedialog.h"
+
+#include <qlayout.h>
+#include <qcursor.h>
+#include "kvi_tal_hbox.h"
+
+
+KviTextIconEditor::KviTextIconEditor(QWidget * par,KviTextIcon * icon,KviTextIconTableItem* item)
+: KviTalHBox(par),m_pTableItem(item)
+{
+ m_pIconButton=new QToolButton(this);
+ m_pBrowseButton=new QToolButton(this);
+ m_pBrowseButton->setSizePolicy(QSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum));
+ m_pBrowseButton->setText("...");
+ m_pIcon = icon;
+ m_pPopup = 0;
+ updateIcon();
+ connect(m_pIconButton,SIGNAL(clicked()),this,SLOT(doPopup()));
+ connect(m_pBrowseButton,SIGNAL(clicked()),this,SLOT(chooseFromFile()));
+}
+
+
+KviTextIconEditor::~KviTextIconEditor()
+{
+
+}
+
+void KviTextIconEditor::doPopup()
+{
+ if(!m_pPopup)
+ {
+ m_pPopup = new KviTalPopupMenu(this);
+ KviIconWidget * iw = new KviIconWidget(m_pPopup);
+ connect(iw,SIGNAL(selected(int)),this,SLOT(iconSelected(int)));
+ m_pPopup->insertItem(iw);
+ }
+ m_pPopup->popup(QCursor::pos());
+}
+
+void KviTextIconEditor::iconSelected(int id)
+{
+ m_pIcon->setId(id);
+ updateIcon();
+}
+
+void KviTextIconEditor::chooseFromFile()
+{
+ QString szFile;
+ KviFileDialog::askForOpenFileName(szFile,"Choose icon filename",QString::null,"*.png","options");
+ if(!szFile.isEmpty())
+ {
+ if(g_pIconManager->getPixmap(szFile))
+ {
+ m_pIcon->setFilename(szFile);
+// debug("%s %s %i |%s| %p",__FILE__,__FUNCTION__,__LINE__,m_pIcon->filename().utf8().data(),m_pIcon);
+ updateIcon();
+ }
+ }
+}
+
+void KviTextIconEditor::updateIcon()
+{
+ if(m_pIcon)
+ {
+ QPixmap* pix=m_pIcon->pixmap();
+ if(pix)
+ m_pIconButton->setPixmap(*pix);
+ }
+}
+
+KviTextIconTableItem::KviTextIconTableItem(KviTalTable * t,KviTextIcon * icon)
+: KviTalTableItem(t,KviTalTableItem::WhenCurrent,QString::null)
+{
+ if(icon)
+ m_pIcon=icon;
+ else
+ m_pIcon=new KviTextIcon(0);
+ QPixmap* pix=m_pIcon->pixmap();
+ if(pix)
+ setPixmap(*pix);
+}
+
+KviTextIconTableItem::~KviTextIconTableItem()
+{
+ delete m_pIcon;
+}
+
+void KviTextIconTableItem::setId(int id)
+{
+ m_pIcon->setId(id);
+ QPixmap* pix=m_pIcon->pixmap();
+ if(pix)
+ setPixmap(*pix);
+}
+
+QWidget * KviTextIconTableItem::createEditor() const
+{
+ return new KviTextIconEditor(table()->viewport(),m_pIcon,(KviTextIconTableItem*)this);
+}
+
+
+void KviTextIconTableItem::setContentFromEditor(QWidget * w)
+{
+ if(w->inherits("KviTextIconEditor"))
+ {
+ QPixmap* pix=m_pIcon->pixmap();
+ if(pix)
+ setPixmap(*pix);
+ }
+}
+
+KviTextIconsOptionsWidget::KviTextIconsOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"texticons_options_widget")
+{
+ createLayout(2,2);
+
+ KviPointerHashTableIterator<QString,KviTextIcon> it(*(g_pTextIconManager->textIconDict()));
+
+ m_pTable = new KviTalTable(g_pTextIconManager->textIconDict()->count(),2,this);
+
+#ifdef COMPILE_INFO_TIPS
+ mergeTip(m_pTable->viewport(),__tr2qs_ctx("This table contains the text icon associations.<br>" \
+ "KVirc will use them to display the CTRL+I escape sequences and eventually the " \
+ "emoticons.","options"));
+#endif
+
+ int idx = 0;
+ while(KviTextIcon * i = it.current())
+ {
+ m_pTable->setText(idx,0,it.currentKey());
+ m_pTable->setItem(idx,1,new KviTextIconTableItem(m_pTable,new KviTextIcon(i)));
+ ++idx;
+ ++it;
+ }
+
+ layout()->addMultiCellWidget(m_pTable,0,0,0,1);
+
+ m_pAdd = new QPushButton(__tr2qs_ctx("Add","options"),this);
+ layout()->addWidget(m_pAdd,1,0);
+ connect(m_pAdd,SIGNAL(clicked()),this,SLOT(addClicked()));
+
+ m_pDel = new QPushButton(__tr2qs_ctx("Delete","options"),this);
+ layout()->addWidget(m_pDel,1,1);
+ connect(m_pDel,SIGNAL(clicked()),this,SLOT(delClicked()));
+
+ m_pDel->setEnabled(false);
+
+ connect(m_pTable,SIGNAL(selectionChanged()),this,SLOT(selectionChanged()));
+}
+
+KviTextIconsOptionsWidget::~KviTextIconsOptionsWidget()
+{
+}
+
+void KviTextIconsOptionsWidget::selectionChanged()
+{
+ int i = m_pTable->currentRow();
+ m_pDel->setEnabled(i >= 0 && i < m_pTable->numRows());
+}
+
+void KviTextIconsOptionsWidget::addClicked()
+{
+ m_pTable->setNumRows(m_pTable->numRows() + 1);
+ m_pTable->setText(m_pTable->numRows() - 1,0,__tr2qs_ctx("unnamed","options"));
+ m_pTable->setItem(m_pTable->numRows() - 1,1,new KviTextIconTableItem(m_pTable,0));
+ m_pDel->setEnabled(true);
+}
+
+void KviTextIconsOptionsWidget::delClicked()
+{
+ int i = m_pTable->currentRow();
+
+ if((i > -1) && (i < m_pTable->numRows()))
+ {
+ // remove row i
+ m_pTable->clearCell(i,0);
+ m_pTable->clearCell(i,1);
+ m_pTable->clearCell(i,2);
+
+ for(;i < (m_pTable->numRows() - 1);i++)
+ {
+ m_pTable->swapRows(i,i+1);
+ }
+
+ m_pTable->setNumRows(m_pTable->numRows() - 1);
+ if(m_pTable->numRows() == 0)m_pDel->setEnabled(false);
+ }
+}
+
+void KviTextIconsOptionsWidget::commit()
+{
+
+ KviOptionsWidget::commit();
+ g_pTextIconManager->clear();
+ int n = m_pTable->numRows();
+ for(int i=0;i < n;i++)
+ {
+ QString szVal = m_pTable->text(i,0);
+ if(!szVal.isEmpty())
+ {
+ KviTextIconTableItem * it = (KviTextIconTableItem *)m_pTable->item(i,1);
+ if(it)
+ {
+ g_pTextIconManager->insert(szVal,*(it->icon()));
+ }
+ }
+ }
+ g_pTextIconManager->checkDefaultAssociations();
+
+ for(int i=0; i<n; i++)
+ for (int j=0; j<m_pTable->numCols(); j++)
+ if (m_pTable->item(i,j))
+ m_pTable->clearCell(i,j);
+
+}
+
+#include "m_optw_texticons.moc"
diff --git a/src/modules/options/optw_texticons.h b/src/modules/options/optw_texticons.h
new file mode 100644
index 00000000..652c7da9
--- /dev/null
+++ b/src/modules/options/optw_texticons.h
@@ -0,0 +1,105 @@
+#ifndef _OPTW_TEXTICONS_H_
+#define _OPTW_TEXTICONS_H_
+
+//
+// File : optw_texticons.h
+// Creation date : Fri May 24 2002 00:14:02 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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_optionswidget.h"
+#include "kvi_texticonmanager.h"
+#define KVI_OPTIONS_WIDGET_ICON_KviTextIconsOptionsWidget KVI_SMALLICON_BIGGRIN
+#define KVI_OPTIONS_WIDGET_NAME_KviTextIconsOptionsWidget __tr2qs_no_lookup("Text icons")
+#define KVI_OPTIONS_WIDGET_PARENT_KviTextIconsOptionsWidget KviToolsOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTextIconsOptionsWidget __tr2qs_no_lookup("smileys,emoticons")
+
+
+
+#include <qtoolbutton.h>
+#include "kvi_tal_popupmenu.h"
+#include "kvi_tal_hbox.h"
+
+#ifdef COMPILE_USE_QT4
+#include <q3table.h>
+#define KviTalTable Q3Table
+#define KviTalTableItem Q3TableItem
+#else
+#include <qtable.h>
+#define KviTalTable QTable
+#define KviTalTableItem QTableItem
+#endif
+
+class KviTextIconTableItem;
+
+class KviTextIconEditor : public KviTalHBox
+{
+ Q_OBJECT
+public:
+ KviTextIconEditor(QWidget * par,KviTextIcon * icon,KviTextIconTableItem* item);
+ ~KviTextIconEditor();
+protected:
+ KviTextIconTableItem *m_pTableItem;
+ KviTextIcon *m_pIcon;
+ KviTalPopupMenu *m_pPopup;
+ QToolButton *m_pIconButton;
+ QToolButton *m_pBrowseButton;
+public:
+ void updateIcon();
+ KviTextIcon* icon() { return m_pIcon; };
+protected slots:
+ void iconSelected(int);
+ void doPopup();
+ void chooseFromFile();
+};
+
+class KviTextIconTableItem : public KviTalTableItem
+{
+ friend class KviTextIconsOptionsWidget;
+public:
+ KviTextIconTableItem(KviTalTable * t,KviTextIcon * icon);
+ ~KviTextIconTableItem();
+protected:
+ KviTextIcon * m_pIcon;
+public:
+ KviTextIcon * icon() { return m_pIcon; };
+ void setId(int id);
+ virtual QWidget * createEditor() const;
+ virtual void setContentFromEditor(QWidget * w);
+};
+
+class KviTextIconsOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTextIconsOptionsWidget(QWidget * parent);
+ ~KviTextIconsOptionsWidget();
+protected:
+ KviTalTable * m_pTable;
+ QPushButton * m_pAdd;
+ QPushButton * m_pDel;
+public:
+ virtual void commit();
+protected slots:
+ void selectionChanged();
+ void addClicked();
+ void delClicked();
+};
+
+#endif //!_OPTW_TEXTICONS_H_
diff --git a/src/modules/options/optw_theme.cpp b/src/modules/options/optw_theme.cpp
new file mode 100644
index 00000000..e3afeba4
--- /dev/null
+++ b/src/modules/options/optw_theme.cpp
@@ -0,0 +1,26 @@
+//=============================================================================
+//
+// File : optw_theme.cpp
+// Creation date : Sun May 25 2003 18:00:00 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2003 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 "m_optw_theme.moc"
diff --git a/src/modules/options/optw_theme.h b/src/modules/options/optw_theme.h
new file mode 100644
index 00000000..ee8945c2
--- /dev/null
+++ b/src/modules/options/optw_theme.h
@@ -0,0 +1,30 @@
+#ifndef _OPTW_THEME_H_
+#define _OPTW_THEME_H_
+
+//=============================================================================
+//
+// File : optw_theme.h
+// Creation date : Sun May 25 2003 18:03:11 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2003-2006 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.
+//
+//=============================================================================
+
+
+
+#endif //!_OPTW_THEME_H_
diff --git a/src/modules/options/optw_tools.cpp b/src/modules/options/optw_tools.cpp
new file mode 100644
index 00000000..b46b9a01
--- /dev/null
+++ b/src/modules/options/optw_tools.cpp
@@ -0,0 +1,50 @@
+//=============================================================================
+//
+// File : optw_tools.cpp
+// Creation date : Wed Ott 19 16:15:16 2005 GMT by Grifisx & Noldor
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2005 Grifisx & 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 "optw_tools.h"
+
+#include <qlayout.h>
+
+#include "kvi_settings.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+KviToolsOptionsWidget::KviToolsOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"tools_options_widget")
+{
+
+ createLayout(1,1);
+
+ QLabel * l;
+ l = addLabel(0,0,0,0,__tr2qs_ctx("This section contains irc tools<br>"\
+ "<p>like<b> away, lag and logging system. </b> " \
+ "</p>","options"));
+
+}
+
+KviToolsOptionsWidget::~KviToolsOptionsWidget()
+{
+}
+
+#include "m_optw_tools.moc"
diff --git a/src/modules/options/optw_tools.h b/src/modules/options/optw_tools.h
new file mode 100644
index 00000000..9ebf35e8
--- /dev/null
+++ b/src/modules/options/optw_tools.h
@@ -0,0 +1,46 @@
+#ifndef _OPTW_TOOLS_H_
+#define _OPTW_TOOLS_H_
+
+//=============================================================================
+//
+// File : optw_tools.h
+//
+// This file is part of the KVirc irc client distribution
+// Creation date : Wed Ott 19 16:15:16 2005 GMT by Grifisx & Noldor
+//
+// Copyright (C) 2005 Grifisx & 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 "kvi_settings.h"
+#include "kvi_optionswidget.h"
+#include "kvi_selectors.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviToolsOptionsWidget KVI_SMALLICON_ADDONS
+#define KVI_OPTIONS_WIDGET_NAME_KviToolsOptionsWidget __tr2qs_no_lookup("Tools")
+#define KVI_OPTIONS_WIDGET_PARENT_KviToolsOptionsWidget KviIrcOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviToolsOptionsWidget 50000
+#define KVI_OPTIONS_WIDGET_NOTCONTAINED_KviToolsOptionsWidget true
+
+class KviToolsOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviToolsOptionsWidget(QWidget * parent);
+ ~KviToolsOptionsWidget();
+};
+
+#endif //!_OPTW_FOLDERS_H_
diff --git a/src/modules/options/optw_topiclabel.cpp b/src/modules/options/optw_topiclabel.cpp
new file mode 100644
index 00000000..71bc2b64
--- /dev/null
+++ b/src/modules/options/optw_topiclabel.cpp
@@ -0,0 +1,43 @@
+//
+// File : optw_topiclabel.cpp
+// Creation date : Mon Sep 24 02:44:55 CEST 2001 by Krzysztof Godlewski
+//
+// 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_options.h"
+#include "kvi_locale.h"
+#include "optw_topiclabel.h"
+
+KviTopicLabelLookOptionsWidget::KviTopicLabelLookOptionsWidget(QWidget *p):KviOptionsWidget(p, "topic_label_look_options_widget")
+{
+ createLayout(4, 1);
+
+ addFontSelector(0, 0, 0, 0, __tr2qs_ctx("Font","options"), KviOption_fontLabel);
+ addColorSelector(0, 1, 0, 1, __tr2qs_ctx("Foreground color","options"), KviOption_colorLabelForeground);
+ addColorSelector(0, 2, 0, 2, __tr2qs_ctx("Background color","options"), KviOption_colorLabelBackground);
+ addPixmapSelector(0, 3, 0, 3, __tr2qs_ctx("Background image","options"), KviOption_pixmapLabelBackground);
+
+ layout()->setRowStretch(3, 1);
+}
+
+KviTopicLabelLookOptionsWidget::~KviTopicLabelLookOptionsWidget()
+{
+}
+
+#include "m_optw_topiclabel.moc"
diff --git a/src/modules/options/optw_topiclabel.h b/src/modules/options/optw_topiclabel.h
new file mode 100644
index 00000000..1185fae6
--- /dev/null
+++ b/src/modules/options/optw_topiclabel.h
@@ -0,0 +1,41 @@
+//
+// File : optw_topiclabel.cpp
+// Creation date : Mon Sep 24 02:44:55 CEST 2001 by Krzysztof Godlewski
+//
+// 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.
+//
+
+#ifndef OPTW_TOPICLABEL_H
+#define OPTW_TOPICLABEL_H
+
+#include "kvi_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTopicLabelLookOptionsWidget KVI_SMALLICON_TOPIC
+#define KVI_OPTIONS_WIDGET_NAME_KviTopicLabelLookOptionsWidget __tr2qs_no_lookup("Labels")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTopicLabelLookOptionsWidget __tr2qs_no_lookup("theme,topic")
+#define KVI_OPTIONS_WIDGET_GROUP_KviTopicLabelLookOptionsWidget "theme"
+
+class KviTopicLabelLookOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTopicLabelLookOptionsWidget(QWidget *);
+ ~KviTopicLabelLookOptionsWidget();
+};
+
+#endif /* !OPTW_TOPICLABEL_H */
diff --git a/src/modules/options/optw_transport.cpp b/src/modules/options/optw_transport.cpp
new file mode 100644
index 00000000..d7cf3971
--- /dev/null
+++ b/src/modules/options/optw_transport.cpp
@@ -0,0 +1,33 @@
+//
+// File : optw_transport.cpp
+// Creation date : Mon Nov 13 2000 14:14:22 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 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 "optw_transport.h"
+
+#include <kvi_tal_groupbox.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+
+
+
+#include "m_optw_transport.moc"
diff --git a/src/modules/options/optw_transport.h b/src/modules/options/optw_transport.h
new file mode 100644
index 00000000..971c215f
--- /dev/null
+++ b/src/modules/options/optw_transport.h
@@ -0,0 +1,29 @@
+#ifndef _OPTW_TRANSPORT_H_
+#define _OPTW_TRANSPORT_H_
+
+//
+// File : optw_transport.h
+// Creation date : Mon Nov 13 2000 14:13:11 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 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_optionswidget.h"
+#include "kvi_tal_listview.h"
+
+#endif //!_OPTW_TRANSPORT_H_
diff --git a/src/modules/options/optw_tray.cpp b/src/modules/options/optw_tray.cpp
new file mode 100644
index 00000000..e988ba54
--- /dev/null
+++ b/src/modules/options/optw_tray.cpp
@@ -0,0 +1,91 @@
+//
+// File : optw_tray.cpp
+// Creation date : Mon 14 Aug 2006 by Alexey Uzhva
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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 "optw_tray.h"
+
+#include <qlayout.h>
+#include "kvi_tal_tooltip.h"
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+//#warning "Info tips"
+
+
+KviTrayOptionsWidget::KviTrayOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"tray_options_widget")
+{
+ createLayout(7,1);
+
+ m_pEnable = addBoolSelector(0,0,0,0, __tr2qs_ctx("Enable tray icon","options"), KviOption_boolShowDockExtension);
+ m_pCloseInTray = addBoolSelector(0,1,0,1,__tr2qs_ctx("Close in tray","options"),KviOption_boolCloseInTray);
+ m_pMinimizeInTray = addBoolSelector(0,2,0,2,__tr2qs_ctx("Minimize in tray","options"),KviOption_boolMinimizeInTray);
+
+ m_pEnableFlashing = addBoolSelector(0,3,0,3,__tr2qs_ctx("Enable tray icon flashing","options"),KviOption_boolEnableTrayIconFlashing);
+ m_pLevelBasedNotify = addBoolSelector(0,4,0,4,__tr2qs_ctx("Enable level-based message notification (not a message-type based)","options"),KviOption_boolUseLevelBasedTrayNotification);
+
+ m_pLevelsGroup = addGroupBox(0,5,0,5,1,Qt::Horizontal,__tr2qs_ctx("Select message levels to notify","options"));
+
+ addUIntSelector(m_pLevelsGroup,__tr2qs_ctx("Minimum level for low-priority messages","options"),
+ KviOption_uintMinTrayLowLevelMessage,
+ 1,5,1,true);
+
+ addUIntSelector(m_pLevelsGroup,__tr2qs_ctx("Minimum level for high-priority message","options"),
+ KviOption_uintMinTrayHighLevelMessage,
+ 1,5,4,true);
+
+ addRowSpacer(0,6,0,6);
+
+ connect(m_pEnable,SIGNAL(toggled(bool)),this,SLOT(setEnabled(bool)));
+ connect(m_pLevelBasedNotify,SIGNAL(toggled(bool)),this,SLOT(setEnabled(bool)));
+ setEnabled(true);
+}
+
+KviTrayOptionsWidget::~KviTrayOptionsWidget()
+{
+}
+
+void KviTrayOptionsWidget::setEnabled(bool bEnabled)
+{
+ if(m_pEnable->isChecked())
+ {
+ m_pEnableFlashing->setEnabled(true);
+ m_pLevelBasedNotify->setEnabled(true);
+ m_pCloseInTray->setEnabled(true);
+ m_pMinimizeInTray->setEnabled(true);
+ if(m_pLevelBasedNotify->isChecked())
+ m_pLevelsGroup->setEnabled(true);
+ else
+ m_pLevelsGroup->setEnabled(false);
+
+ } else {
+ m_pCloseInTray->setEnabled(false);
+ m_pMinimizeInTray->setEnabled(false);
+ m_pEnableFlashing->setEnabled(false);
+ m_pLevelBasedNotify->setEnabled(false);
+ m_pLevelsGroup->setEnabled(false);
+ }
+}
+
+
+#include "m_optw_tray.moc"
diff --git a/src/modules/options/optw_tray.h b/src/modules/options/optw_tray.h
new file mode 100644
index 00000000..5be68f36
--- /dev/null
+++ b/src/modules/options/optw_tray.h
@@ -0,0 +1,50 @@
+#ifndef _OPTW_TRAY_H_
+#define _OPTW_TRAY_H_
+//
+// File : optw_tray.h
+// Creation date : Mon 14 Aug 2006 by Alexey Uzhva
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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_optionswidget.h"
+#include <qcombobox.h>
+
+#define KVI_OPTIONS_WIDGET_ICON_KviTrayOptionsWidget KVI_SMALLICON_DOCKWIDGET
+#define KVI_OPTIONS_WIDGET_NAME_KviTrayOptionsWidget __tr2qs_no_lookup("Tray icon")
+#define KVI_OPTIONS_WIDGET_PARENT_KviTrayOptionsWidget KviInterfaceFeaturesOptionsWidget
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviTrayOptionsWidget __tr2qs_no_lookup("tray,dockwidget")
+
+class KviTrayOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviTrayOptionsWidget(QWidget * parent);
+ ~KviTrayOptionsWidget();
+protected:
+ KviBoolSelector * m_pEnable;
+ KviBoolSelector * m_pEnableFlashing;
+ KviBoolSelector * m_pLevelBasedNotify;
+ KviBoolSelector * m_pMinimizeInTray;
+ KviBoolSelector * m_pCloseInTray;
+ KviTalGroupBox * m_pLevelsGroup;
+protected slots:
+ void setEnabled(bool);
+};
+
+#endif //_OPTW_TRAY_H_
diff --git a/src/modules/options/optw_uparser.cpp b/src/modules/options/optw_uparser.cpp
new file mode 100644
index 00000000..01036fb6
--- /dev/null
+++ b/src/modules/options/optw_uparser.cpp
@@ -0,0 +1,62 @@
+//
+// File : optw_uparser.cpp
+// Creation date : Sat Oct 27 16:32:26 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 "optw_uparser.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+#include <qlabel.h>
+
+
+KviUParserOptionsWidget::KviUParserOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"uparser_options_widget")
+{
+ createLayout(11,1);
+
+ addBoolSelector(0,0,0,0,__tr2qs_ctx("Disable parser warnings","options"),KviOption_boolAvoidParserWarnings);
+ addBoolSelector(0,1,0,1,__tr2qs_ctx("Disable broken event handlers","options"),KviOption_boolDisableBrokenEventHandlers);
+ addBoolSelector(0,2,0,2,__tr2qs_ctx("Kill broken timers","options"),KviOption_boolKillBrokenTimers);
+ addBoolSelector(0,3,0,3,__tr2qs_ctx("Send unknown commands as /RAW","options"),KviOption_boolSendUnknownCommandsAsRaw);
+
+ addSeparator(0,4,0,4);
+
+ addBoolSelector(0,5,0,5,__tr2qs_ctx("Automatically unload unused modules","options"),KviOption_boolCleanupUnusedModules);
+ addBoolSelector(0,6,0,6,__tr2qs_ctx("Ignore module versions (dangerous)","options"),KviOption_boolIgnoreModuleVersions);
+
+ addSeparator(0,7,0,7);
+
+ addBoolSelector(0,8,0,8,__tr2qs_ctx("Relay errors and warnings to debug window","options"),KviOption_boolScriptErrorsToDebugWindow);
+ addBoolSelector(0,9,0,9,__tr2qs_ctx("Create minimized debug window","options"),KviOption_boolShowMinimizedDebugWindow);
+
+ addRowSpacer(0,10,0,10);
+}
+
+KviUParserOptionsWidget::~KviUParserOptionsWidget()
+{
+}
+
+
+#include "m_optw_uparser.moc"
diff --git a/src/modules/options/optw_uparser.h b/src/modules/options/optw_uparser.h
new file mode 100644
index 00000000..1e35fe92
--- /dev/null
+++ b/src/modules/options/optw_uparser.h
@@ -0,0 +1,40 @@
+#ifndef _OPTW_UPARSER_H_
+#define _OPTW_UPARSER_H_
+//
+// File : optw_uparser.h
+// Creation date : Sat Oct 27 16:32:27 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviUParserOptionsWidget KVI_SMALLICON_PARSERWARNING
+#define KVI_OPTIONS_WIDGET_NAME_KviUParserOptionsWidget __tr2qs_no_lookup("Scripting Engine")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviUParserOptionsWidget __tr2qs_no_lookup("scripting,kvs,debug")
+#define KVI_OPTIONS_WIDGET_PARENT_KviUParserOptionsWidget KviGeneralOptOptionsWidget
+
+class KviUParserOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviUParserOptionsWidget(QWidget * parent);
+ ~KviUParserOptionsWidget();
+};
+
+#endif //_OPTW_UPARSER_H_
diff --git a/src/modules/options/optw_urlhandlers.cpp b/src/modules/options/optw_urlhandlers.cpp
new file mode 100644
index 00000000..48ea2297
--- /dev/null
+++ b/src/modules/options/optw_urlhandlers.cpp
@@ -0,0 +1,127 @@
+#ifndef _OPTW_URLHANDLERS_CPP_
+#define _OPTW_URLHANDLERS_CPP_
+//
+// File : optw_urlhandlers.cpp
+// Creation date : Fri Aug 23 02:57:40 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)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under 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 "optw_urlhandlers.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+
+#include <qlabel.h>
+
+
+KviUrlHandlersOptionsWidget::KviUrlHandlersOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"urlhandlers_options_widget")
+{
+#ifdef COMPILE_ON_WINDOWS
+ #define START_ROW 1
+#else
+ #define START_ROW 0
+#endif
+
+ createLayout(START_ROW+7,1);
+
+#ifdef COMPILE_ON_WINDOWS
+ KviBoolSelector *b = addBoolSelector(0,0,0,0,__tr2qs_ctx("Use system URL handlers","options"),KviOption_boolUseSystemUrlHandlers);
+#endif
+
+ m_pHttpHandler=addStringSelector(0,START_ROW+0,0,START_ROW+0,__tr2qs_ctx("<b>http://</b> handler command:","options"),KviOption_stringUrlHttpCommand);
+ m_pHttpsHandler=addStringSelector(0,START_ROW+1,0,START_ROW+1,__tr2qs_ctx("<b>https://</b> handler command:","options"),KviOption_stringUrlHttpsCommand);
+ m_pFtpHandler=addStringSelector(0,START_ROW+2,0,START_ROW+2,__tr2qs_ctx("<b>ftp://</b> handler command:","options"),KviOption_stringUrlFtpCommand);
+ m_pMailtoHandler=addStringSelector(0,START_ROW+3,0,START_ROW+3,__tr2qs_ctx("<b>mailto:</b> handler command:","options"),KviOption_stringUrlMailtoCommand);
+ m_pFileHandler=addStringSelector(0,START_ROW+4,0,START_ROW+4,__tr2qs_ctx("<b>file://</b> handler command:","options"),KviOption_stringUrlFileCommand);
+ m_pOtherHandler=addStringSelector(0,START_ROW+5,0,START_ROW+5,__tr2qs_ctx("Unknown protocol handler command:","options"),KviOption_stringUrlUnknownCommand);
+
+#ifdef COMPILE_ON_WINDOWS
+ m_pHttpHandler->setEnabled(!KVI_OPTION_BOOL(KviOption_boolUseSystemUrlHandlers));
+ m_pHttpsHandler->setEnabled(!KVI_OPTION_BOOL(KviOption_boolUseSystemUrlHandlers));
+ m_pFtpHandler->setEnabled(!KVI_OPTION_BOOL(KviOption_boolUseSystemUrlHandlers));
+ m_pFileHandler->setEnabled(!KVI_OPTION_BOOL(KviOption_boolUseSystemUrlHandlers));
+ m_pMailtoHandler->setEnabled(!KVI_OPTION_BOOL(KviOption_boolUseSystemUrlHandlers));
+ m_pOtherHandler->setEnabled(!KVI_OPTION_BOOL(KviOption_boolUseSystemUrlHandlers));
+
+ connect(b,SIGNAL(toggled(bool)),this,SLOT(toggleEditors(bool)));
+
+#endif
+
+ addRowSpacer(0,START_ROW+6,0,START_ROW+6);
+}
+
+KviUrlHandlersOptionsWidget::~KviUrlHandlersOptionsWidget()
+{
+}
+
+void KviUrlHandlersOptionsWidget::toggleEditors(bool bToggled)
+{
+ m_pHttpHandler->setEnabled(!bToggled);
+ m_pHttpsHandler->setEnabled(!bToggled);
+ m_pFtpHandler->setEnabled(!bToggled);
+ m_pFileHandler->setEnabled(!bToggled);
+ m_pMailtoHandler->setEnabled(!bToggled);
+ m_pOtherHandler->setEnabled(!bToggled);
+}
+
+void KviUrlHandlersOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+
+#ifdef COMPILE_ON_WINDOWS
+ KVI_OPTION_STRING(KviOption_stringUrlHttpCommand).replace("\\\\","@MAGIC@","options");
+ KVI_OPTION_STRING(KviOption_stringUrlHttpCommand).replace("\\","\\\\","options");
+ KVI_OPTION_STRING(KviOption_stringUrlHttpCommand).replace("@MAGIC@","\\\\","options");
+
+ KVI_OPTION_STRING(KviOption_stringUrlHttpsCommand).replace("\\\\","@MAGIC@","options");
+ KVI_OPTION_STRING(KviOption_stringUrlHttpsCommand).replace("\\","\\\\","options");
+ KVI_OPTION_STRING(KviOption_stringUrlHttpsCommand).replace("@MAGIC@","\\\\","options");
+
+ KVI_OPTION_STRING(KviOption_stringUrlFtpCommand).replace("\\\\","@MAGIC@","options");
+ KVI_OPTION_STRING(KviOption_stringUrlFtpCommand).replace("\\","\\\\","options");
+ KVI_OPTION_STRING(KviOption_stringUrlFtpCommand).replace("@MAGIC@","\\\\","options");
+
+ KVI_OPTION_STRING(KviOption_stringUrlMailtoCommand).replace("\\\\","@MAGIC@","options");
+ KVI_OPTION_STRING(KviOption_stringUrlMailtoCommand).replace("\\","\\\\","options");
+ KVI_OPTION_STRING(KviOption_stringUrlMailtoCommand).replace("@MAGIC@","\\\\","options");
+
+ KVI_OPTION_STRING(KviOption_stringUrlFileCommand).replace("\\\\","@MAGIC@","options");
+ KVI_OPTION_STRING(KviOption_stringUrlFileCommand).replace("\\","\\\\","options");
+ KVI_OPTION_STRING(KviOption_stringUrlFileCommand).replace("@MAGIC@","\\\\","options");
+
+ KVI_OPTION_STRING(KviOption_stringUrlUnknownCommand).replace("\\\\","@MAGIC@","options");
+ KVI_OPTION_STRING(KviOption_stringUrlUnknownCommand).replace("\\","\\\\","options");
+ KVI_OPTION_STRING(KviOption_stringUrlUnknownCommand).replace("@MAGIC@","\\\\","options");
+
+ //Check for escaped " in url handler ( \" )
+ KVI_OPTION_STRING(KviOption_stringUrlHttpCommand).replace("\\\\\"","\\\"","options");
+ KVI_OPTION_STRING(KviOption_stringUrlHttpsCommand).replace("\\\\\"","\\\"","options");
+ KVI_OPTION_STRING(KviOption_stringUrlFtpCommand).replace("\\\\\"","\\\"","options");
+ KVI_OPTION_STRING(KviOption_stringUrlMailtoCommand).replace("\\\\\"","\\\"","options");
+ KVI_OPTION_STRING(KviOption_stringUrlFileCommand).replace("\\\\\"","\\\"","options");
+ KVI_OPTION_STRING(KviOption_stringUrlUnknownCommand).replace("\\\\\"","\\\"","options");
+#endif
+}
+
+#include "m_optw_urlhandlers.moc"
+
+#endif //_OPTW_URLHANDLERS_CPP_
diff --git a/src/modules/options/optw_urlhandlers.h b/src/modules/options/optw_urlhandlers.h
new file mode 100644
index 00000000..9ed6c188
--- /dev/null
+++ b/src/modules/options/optw_urlhandlers.h
@@ -0,0 +1,52 @@
+#ifndef _OPTW_URLHANDLERS_H_
+#define _OPTW_URLHANDLERS_H_
+//
+// File : optw_urlhandlers.h
+// Creation date : Fri Aug 23 02:57:41 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)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under 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_optionswidget.h"
+
+#define KVI_OPTIONS_WIDGET_ICON_KviUrlHandlersOptionsWidget KVI_SMALLICON_WORLD
+#define KVI_OPTIONS_WIDGET_NAME_KviUrlHandlersOptionsWidget __tr2qs_no_lookup("URL handlers")
+#define KVI_OPTIONS_WIDGET_PARENT_KviUrlHandlersOptionsWidget KviGeneralOptOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviUrlHandlersOptionsWidget 70000
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviUrlHandlersOptionsWidget __tr2qs_no_lookup("url,programs")
+
+class KviUrlHandlersOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviUrlHandlersOptionsWidget(QWidget * parent);
+ ~KviUrlHandlersOptionsWidget();
+private:
+ KviStringSelector* m_pHttpHandler;
+ KviStringSelector* m_pHttpsHandler;
+ KviStringSelector* m_pFtpHandler;
+ KviStringSelector* m_pMailtoHandler;
+ KviStringSelector* m_pFileHandler;
+ KviStringSelector* m_pOtherHandler;
+public:
+ virtual void commit();
+public slots:
+ void toggleEditors(bool);
+};
+
+#endif //_OPTW_URLHANDLERS_H_
diff --git a/src/modules/options/optw_userlist.cpp b/src/modules/options/optw_userlist.cpp
new file mode 100644
index 00000000..07b39d0d
--- /dev/null
+++ b/src/modules/options/optw_userlist.cpp
@@ -0,0 +1,245 @@
+//
+// File : optw_userlist.cpp
+// Creation date : Sat Aug 11 2001 03:29:52 CEST 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 "optw_userlist.h"
+
+#include <qlayout.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_userlistview.h"
+
+//#warning "Info tips"
+
+KviUserListLookOptionsWidget::KviUserListLookOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"userlistlook_options_widget")
+{
+}
+
+KviUserListLookOptionsWidget::~KviUserListLookOptionsWidget()
+{
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviUserListLookForegroundOptionsWidget::KviUserListLookForegroundOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"userlistlook_foreground_options_widget")
+{
+ createLayout(2,2);
+
+ addFontSelector(0,0,1,0,__tr2qs_ctx("Font:","options"),KviOption_fontUserListView);
+
+ KviTalGroupBox * g = addGroupBox(0,1,1,1,1,Qt::Horizontal,__tr2qs_ctx("Nickname Colors","options"));
+ addColorSelector(g,__tr2qs_ctx("Normal:","options"),KviOption_colorUserListViewNormalForeground);
+ addColorSelector(g,__tr2qs_ctx("Selected:","options"),KviOption_colorUserListViewSelectionForeground);
+ addColorSelector(g,__tr2qs_ctx("Channel owner:","options"),KviOption_colorUserListViewChanOwnerForeground);
+ addColorSelector(g,__tr2qs_ctx("Channel admin:","options"),KviOption_colorUserListViewChanAdminForeground);
+ addColorSelector(g,__tr2qs_ctx("Op:","options"),KviOption_colorUserListViewOpForeground);
+ addColorSelector(g,__tr2qs_ctx("Half-op:","options"),KviOption_colorUserListViewHalfOpForeground);
+ addColorSelector(g,__tr2qs_ctx("Voice:","options"),KviOption_colorUserListViewVoiceForeground);
+ addColorSelector(g,__tr2qs_ctx("User-op:","options"),KviOption_colorUserListViewUserOpForeground);
+ addColorSelector(g,__tr2qs_ctx("Away:","options"),KviOption_colorUserListViewAwayForeground);
+
+ KviTalHBox * hb = new KviTalHBox(g);
+ hb->setSpacing(4);
+ KviBoolSelector * b = addBoolSelector(hb,__tr2qs_ctx("Use different color for own nick:","options"),KviOption_boolUseDifferentColorForOwnNick);
+ KviColorSelector * s = addColorSelector(hb,"",KviOption_colorUserListViewOwnForeground,KVI_OPTION_BOOL(KviOption_boolUseDifferentColorForOwnNick));
+ connect(b,SIGNAL(toggled(bool)),s,SLOT(setEnabled(bool)));
+
+ addRowSpacer(0,3,0,3);
+}
+
+KviUserListLookForegroundOptionsWidget::~KviUserListLookForegroundOptionsWidget()
+{
+}
+
+KviUserListGridOptionsWidget::KviUserListGridOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent)
+{
+ createLayout(5,1);
+ KviBoolSelector* b = addBoolSelector(0,0,0,0,__tr2qs_ctx("Draw nickname grid","options"),KviOption_boolUserListViewDrawGrid);
+
+ KviColorSelector* s = addColorSelector(0,1,0,1,__tr2qs_ctx("Grid color:","options"),KviOption_colorUserListViewGrid,KVI_OPTION_BOOL(KviOption_boolUserListViewDrawGrid));
+ connect(b,SIGNAL(toggled(bool)),s,SLOT(setEnabled(bool)));
+
+ KviTalHBox* hb = new KviTalHBox(this);
+ addWidgetToLayout(hb,0,2,0,2);
+ hb->setSpacing(4);
+
+ QLabel * l = new QLabel(__tr2qs_ctx("Grid type:","options"),hb);
+ l->setEnabled(KVI_OPTION_BOOL(KviOption_boolUserListViewDrawGrid));
+ connect(b,SIGNAL(toggled(bool)),l,SLOT(setEnabled(bool)));
+ m_pGridTypeCombo = new QComboBox(false,hb);
+ m_pGridTypeCombo->insertItem(__tr2qs_ctx("3D Grid","options"));
+ m_pGridTypeCombo->insertItem(__tr2qs_ctx("3D Buttons","options"));
+ m_pGridTypeCombo->insertItem(__tr2qs_ctx("Plain Grid","options"));
+ m_pGridTypeCombo->insertItem(__tr2qs_ctx("Dotted Grid","options"));
+ m_pGridTypeCombo->setCurrentItem(KVI_OPTION_UINT(KviOption_uintUserListViewGridType));
+ m_pGridTypeCombo->setEnabled(KVI_OPTION_BOOL(KviOption_boolUserListViewDrawGrid));
+ connect(b,SIGNAL(toggled(bool)),m_pGridTypeCombo,SLOT(setEnabled(bool)));
+ addRowSpacer(0,3,0,3);
+}
+
+KviUserListGridOptionsWidget::~KviUserListGridOptionsWidget()
+{
+}
+
+void KviUserListGridOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+ KVI_OPTION_UINT(KviOption_uintUserListViewGridType) = m_pGridTypeCombo->currentItem();
+ if(KVI_OPTION_UINT(KviOption_uintUserListViewGridType) > KVI_USERLISTVIEW_GRIDTYPE_MAXIMUM)
+ KVI_OPTION_UINT(KviOption_uintUserListViewGridType) = KVI_USERLISTVIEW_GRIDTYPE_DEFAULT;
+
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviUserListLookBackgroundOptionsWidget::KviUserListLookBackgroundOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"userlistlook_background_options_widget")
+{
+ createLayout(3,2);
+
+ KviTalGroupBox * g = addGroupBox(0,0,1,0,1,Qt::Horizontal,__tr2qs_ctx("Background Colors","options"));
+ addColorSelector(g,__tr2qs_ctx("Normal:","options"),KviOption_colorUserListViewBackground);
+ addColorSelector(g,__tr2qs_ctx("Selected:","options"),KviOption_colorUserListViewSelectionBackground);
+
+
+ addPixmapSelector(0,1,1,1,__tr2qs_ctx("Background image:","options"),KviOption_pixmapUserListViewBackground);
+
+ addLabel(0,2,0,2,__tr2qs_ctx("Horizontal Alignment:","options"));
+ m_pHorizontalAlign=new QComboBox(this);
+ addWidgetToLayout(m_pHorizontalAlign,1,2,1,2);
+
+ addLabel(0,3,0,3,__tr2qs_ctx("Vertical Alignment:","options"));
+ m_pVerticalAlign=new QComboBox(this);
+ addWidgetToLayout(m_pVerticalAlign,1,3,1,3);
+
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Tile","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Left","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Right","options"));
+ m_pHorizontalAlign->insertItem(__tr2qs_ctx("Center","options"));
+
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Tile","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Top","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Bottom","options"));
+ m_pVerticalAlign->insertItem(__tr2qs_ctx("Center","options"));
+
+ switch( KVI_OPTION_UINT(KviOption_uintUserListPixmapAlign) & Qt::AlignHorizontal_Mask)
+ {
+ case Qt::AlignLeft:
+ m_pHorizontalAlign->setCurrentItem(1);
+ break;
+ case Qt::AlignRight:
+ m_pHorizontalAlign->setCurrentItem(2);
+ break;
+ case Qt::AlignHCenter:
+ m_pHorizontalAlign->setCurrentItem(3);
+ break;
+ default:
+ m_pHorizontalAlign->setCurrentItem(0);
+ }
+
+ switch( KVI_OPTION_UINT(KviOption_uintUserListPixmapAlign) & Qt::AlignVertical_Mask)
+ {
+ case Qt::AlignTop:
+ m_pVerticalAlign->setCurrentItem(1);
+ break;
+ case Qt::AlignBottom:
+ m_pVerticalAlign->setCurrentItem(2);
+ break;
+ case Qt::AlignVCenter:
+ m_pVerticalAlign->setCurrentItem(3);
+ break;
+ default:
+ m_pVerticalAlign->setCurrentItem(0);
+ }
+
+
+
+ //layout()->setColStretch(0,1);
+ layout()->setRowStretch(1,1);
+}
+
+KviUserListLookBackgroundOptionsWidget::~KviUserListLookBackgroundOptionsWidget()
+{
+}
+
+
+void KviUserListLookBackgroundOptionsWidget::commit()
+{
+ KviOptionsWidget::commit();
+
+ int iFlags=0;
+ switch(m_pHorizontalAlign->currentItem())
+ {
+ case 1:
+ iFlags|=Qt::AlignLeft;
+ break;
+ case 2:
+ iFlags|=Qt::AlignRight;
+ break;
+ case 3:
+ iFlags|=Qt::AlignHCenter;
+ break;
+ }
+ switch(m_pVerticalAlign->currentItem())
+ {
+ case 1:
+ iFlags|=Qt::AlignTop;
+ break;
+ case 2:
+ iFlags|=Qt::AlignBottom;
+ break;
+ case 3:
+ iFlags|=Qt::AlignVCenter;
+ break;
+ }
+
+ KVI_OPTION_UINT(KviOption_uintUserListPixmapAlign)=iFlags;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviUserListFeaturesOptionsWidget::KviUserListFeaturesOptionsWidget(QWidget * parent)
+: KviOptionsWidget(parent,"userlistfeatures_options_widget")
+{
+ createLayout(7,1);
+
+ KviBoolSelector *b = addBoolSelector(0,0,0,0,__tr2qs_ctx("Show gender icons","options"),KviOption_boolDrawGenderIcons);
+ b = addBoolSelector(0,1,0,1,__tr2qs_ctx("Show user channel icons","options"),KviOption_boolShowUserChannelIcons);
+ b = addBoolSelector(0,2,0,2,__tr2qs_ctx("Show user channel activity indicator","options"),KviOption_boolShowUserChannelState);
+ b = addBoolSelector(0,3,0,3,__tr2qs_ctx("Hide users label","options"),KviOption_boolDisableUserListLabel);
+ b = addBoolSelector(0,4,0,4,__tr2qs_ctx("Enable user tooltips","options"),KviOption_boolShowUserListViewToolTips);
+ b = addBoolSelector(0,5,0,5,__tr2qs_ctx("Hide avatars","options"),KviOption_boolDisableAvatars);
+
+ addRowSpacer(0,6,0,6);
+}
+
+KviUserListFeaturesOptionsWidget::~KviUserListFeaturesOptionsWidget()
+{
+}
+
+#include "m_optw_userlist.moc"
diff --git a/src/modules/options/optw_userlist.h b/src/modules/options/optw_userlist.h
new file mode 100644
index 00000000..d5fd4c12
--- /dev/null
+++ b/src/modules/options/optw_userlist.h
@@ -0,0 +1,114 @@
+#ifndef _OPTW_USERLIST_H_
+#define _OPTW_USERLIST_H_
+
+//
+// File : optw_userlist.h
+// Creation date : Sat Mar 02 2002 12:09:19 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2006 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_optionswidget.h"
+#include <qcombobox.h>
+
+#define KVI_OPTIONS_WIDGET_ICON_KviUserListLookOptionsWidget KVI_SMALLICON_USERLIST
+#define KVI_OPTIONS_WIDGET_NAME_KviUserListLookOptionsWidget __tr2qs_no_lookup("Userlist")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListLookOptionsWidget __tr2qs_no_lookup("theme,userlist,channel")
+#define KVI_OPTIONS_WIDGET_GROUP_KviUserListLookOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_CONTAINER_KviUserListLookOptionsWidget true
+
+class KviUserListLookOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviUserListLookOptionsWidget(QWidget * parent);
+ ~KviUserListLookOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviUserListLookBackgroundOptionsWidget KVI_SMALLICON_TRANSPARENT
+#define KVI_OPTIONS_WIDGET_NAME_KviUserListLookBackgroundOptionsWidget __tr2qs_no_lookup("Background")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListLookBackgroundOptionsWidget __tr2qs_no_lookup("theme,userlist,channel,background")
+#define KVI_OPTIONS_WIDGET_GROUP_KviUserListLookBackgroundOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_PARENT_KviUserListLookBackgroundOptionsWidget KviUserListLookOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviUserListLookBackgroundOptionsWidget 30
+
+
+class KviUserListLookBackgroundOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviUserListLookBackgroundOptionsWidget(QWidget * parent);
+ ~KviUserListLookBackgroundOptionsWidget();
+protected:
+ QComboBox* m_pHorizontalAlign;
+ QComboBox* m_pVerticalAlign;
+public:
+ virtual void commit();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviUserListLookForegroundOptionsWidget KVI_SMALLICON_USERLIST
+#define KVI_OPTIONS_WIDGET_NAME_KviUserListLookForegroundOptionsWidget __tr2qs_no_lookup("Foreground")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListLookForegroundOptionsWidget __tr2qs_no_lookup("theme,userlist,channel,colors")
+#define KVI_OPTIONS_WIDGET_GROUP_KviUserListLookForegroundOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_PARENT_KviUserListLookForegroundOptionsWidget KviUserListLookOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviUserListLookForegroundOptionsWidget 20
+
+
+class KviUserListLookForegroundOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviUserListLookForegroundOptionsWidget(QWidget * parent);
+ ~KviUserListLookForegroundOptionsWidget();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviUserListGridOptionsWidget KVI_SMALLICON_GUI
+#define KVI_OPTIONS_WIDGET_NAME_KviUserListGridOptionsWidget __tr2qs_no_lookup("Nickname Grid")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListGridOptionsWidget __tr2qs_no_lookup("theme,userlist,channel,grid")
+#define KVI_OPTIONS_WIDGET_GROUP_KviUserListGridOptionsWidget "theme"
+#define KVI_OPTIONS_WIDGET_PARENT_KviUserListGridOptionsWidget KviUserListLookOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviUserListGridOptionsWidget 30
+
+
+class KviUserListGridOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviUserListGridOptionsWidget(QWidget * parent);
+ ~KviUserListGridOptionsWidget();
+protected:
+ QComboBox * m_pGridTypeCombo;
+public:
+ virtual void commit();
+};
+
+#define KVI_OPTIONS_WIDGET_ICON_KviUserListFeaturesOptionsWidget KVI_SMALLICON_GUI
+#define KVI_OPTIONS_WIDGET_NAME_KviUserListFeaturesOptionsWidget __tr2qs_no_lookup("Features")
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviUserListFeaturesOptionsWidget __tr2qs_no_lookup("userlist,channel")
+#define KVI_OPTIONS_WIDGET_PARENT_KviUserListFeaturesOptionsWidget KviUserListLookOptionsWidget
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviUserListFeaturesOptionsWidget 10
+
+class KviUserListFeaturesOptionsWidget : public KviOptionsWidget
+{
+ Q_OBJECT
+public:
+ KviUserListFeaturesOptionsWidget(QWidget * parent);
+ ~KviUserListFeaturesOptionsWidget();
+};
+
+#endif //!_OPTW_USERLIST_H_
diff --git a/src/modules/perl/Makefile.am b/src/modules/perl/Makefile.am
new file mode 100644
index 00000000..ea5e4a5b
--- /dev/null
+++ b/src/modules/perl/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviperl.la
+
+libkviperl_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviperl_la_SOURCES = libkviperl.cpp
+libkviperl_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/perl/libkviperl.cpp b/src/modules/perl/libkviperl.cpp
new file mode 100644
index 00000000..a898e43a
--- /dev/null
+++ b/src/modules/perl/libkviperl.cpp
@@ -0,0 +1,600 @@
+//=============================================================================
+//
+// File : libkviperl.cpp
+// Creation date : Tue Jul 13 13:03:31 2004 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2004-2005 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 "kvi_module.h"
+
+#include "kvi_fileutils.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_modulemanager.h"
+#include "kvi_out.h"
+
+#ifdef COMPILE_PERL_SUPPORT
+ #include "../perlcore/perlcoreinterface.h"
+
+ static KviModule * g_pPerlCoreModule = 0;
+#endif // COMPILE_PERL_SUPPORT
+
+#ifdef COMPILE_PERL_SUPPORT
+ #define KVS_CHECK_PERLCORE(_m,_c) \
+ g_pPerlCoreModule = g_pModuleManager->getModule("perlcore"); \
+ if(!g_pPerlCoreModule) \
+ { \
+ if(!_c->switches()->find('q',"quiet")) \
+ { \
+ _c->warning(__tr2qs_ctx("The perlcore module can't be loaded: perl support not available","perl")); \
+ _c->warning(__tr2qs_ctx("To see more details about loading failure try /perlcore.load","perl")); \
+ return true; \
+ } \
+ }
+#else // !COMPILE_PERL_SUPPORT
+ #define KVS_CHECK_PERLCORE(_m,_c)
+#endif // !COMPILE_PERL_SUPPORT
+
+#ifdef COMPILE_PERL_SUPPORT
+ #define KVS_CHECK_MODULE_STATE(_m,_c) KVS_CHECK_PERLCORE(_m,_c)
+#else // !COMPILE_PERL_SUPPORT
+ #define KVS_CHECK_MODULE_STATE(_m,_c) \
+ if(!_c->switches()->find('q',"quiet")) \
+ _c->warning(__tr2qs_ctx("This KVIrc executable has been compiled without perl scripting support","perl")); \
+ return true;
+#endif // !COMPILE_PERL_SUPPORT
+
+/*
+ @doc: perl_and_kvs
+ @type:
+ language
+ @title:
+ Using perl from KVS and vice-versa.
+ @short:
+ How to use perl from KVS and KVS from perl.
+ @body:
+ [big]Introduction[/big][br]
+ Starting from version 3.0.2 you can include perl code snippets
+ in KVS code and you can use KVS commands from within perl.
+ This feature is present only if a working perl installation
+ has been found at ./configure time.[br]
+ [br]
+
+ [big]Using perl from KVS[/big][br]
+ Using perl from KVIrc is really easy: just enclose
+ your perl code snippet inside [cmd]perl.begin[/cmd] and [cmd]perl.end[/cmd].
+ [example]
+ [cmd]perl.begin[/cmd]
+ &lt;perl code goes here&gt;
+ [cmd]perl.end[/cmd]
+ [/example]
+ For example:[br]
+ [example]
+ [cmd]perl.begin[/cmd]
+ open(MYFILE,'>>myfile.txt') or die "Can't open myfile.txt!";
+ print MYFILE "foo!\n";
+ close(MYFILE);
+ [cmd]perl.end[/cmd]
+ [/example]
+ A perl code snippet can appear anywhere a KVS code snippet can
+ with the only restriction that i must be enclosed in [cmd]perl.begin[/cmd]
+ and [cmd]perl.end[/cmd]. This means that you can write perl code
+ in the commandline, in the aliases, the event handlers, popups...anywhere.[br]
+ If you have already encountered the KVIrc's [cmd]eval[/cmd] command
+ that you probably also know how to execute a perl code snippet from a file :)[br]
+ [br]
+
+ [big]Using KVS from perl[/big][br]
+ KVIrc exports several commands to the perl namespace
+ that allow you to invoke KVIrc's functions from inside the perl code snippet.[br]
+ The nicest example is KVIrc::echo():
+ [example]
+ [cmd]perl.begin[/cmd]
+ KVIrc::echo("Hello KVIrc world from perl!");
+ [cmd]perl.end[/cmd]
+ [/example]
+ KVIrc::echo() is the counterpart of the [cmd]echo[/cmd].
+ The exact syntax is:[br]
+ &nbsp; &nbsp; [b]KVIrc::echo(&lt;text&gt;[,&lt;colorset&gt;[,&lt;windowid&gt;]])[/b][br]
+ &lt;text&gt; is obviously the text to be printed. &lt;colorset&gt; is
+ the equivalent of the [cmd]echo[/cmd] -i option and &lt;windowid&gt;
+ is the equivalent of the -w option. Both &lt;colorset&gt; and &lt;windowid&gt;
+ can be omitted (in this case KVIrc will use a default colorset and the current window).[br]
+ [br]
+
+ [big]Perl execution contexts[/big][br]
+ The perl code snippets are executed by the means of a perl interpreter.
+ Each perl interpreter has its own context and thus it's own variables,
+ own function namespace etc.[br]
+ [br]
+ In the example above KVIrc creates an interpreter when [cmd]perl.begin[/cmd]
+ is invoked and destroys it at [cmd]perl.end[/cmd] parsing time.
+ In fact, KVIrc can mantain multiple persistent interpreters that will
+ allow you to preserve your context across [cmd]perl.begin[/cmd] invocations.[br]
+ You can invoke a specific perl context by passing it as parameter to the [cmd]perl.begin[/cmd]
+ command.[br]
+ [example]
+ [cmd]perl.begin("mycontext")[/cmd]
+ $myvariable = "mycontext";
+ KVIrc::echo("This perl code is executed from ".$myvariable);
+ [cmd]perl.end[/cmd]
+ [/example]
+ The nice thing is that at a later time you can invoke this context again
+ and discover that $mycontext has preserved its value:[br]
+ [example]
+ [cmd]perl.begin("mycontext")[/cmd]
+ KVIrc::echo("myvariable is still equal to ".$myvariable);
+ [cmd]perl.end[/cmd]
+ [/example]
+ The first time you invoke a named perl context it gets automatically created and
+ it persists until KVIrc terminates or the perl context is explicitly destroyed
+ by the means of [cmd]perl.destroy[/cmd].[br]
+ [br]
+ In fact there is a third possibility to destroy a context: it's when the
+ perlcore module is forcibly unloaded (by the means of /perlcore.unload) but
+ this is really a rare case and should be threated just like a KVIrc restart (the
+ user probably WANTS the contexts to be reinitialized).[br]
+ [br]
+ The nice thing is that not only your variables will get preserved
+ but also any perl function or class you declare in a context will persist.
+ It's just like executing a long perl script file with pauses inside.[br]
+ [br]
+ If you omit the perl context name in the [cmd]perl.begin[/cmd] command
+ (or if you use an empty string in it's place)
+ then KVIrc will create a temporary context for the snippet execution
+ and will destroy it immediately after [cmd]perl.end[/cmd] has been called.[br]
+ [br]
+ The major side effect of keeping persistent perl contexts is that
+ the perl's symbol table will grow and if not used carefully the interpreter
+ may become a memory hog. So if you're going to use persistent contexts
+ either try to keep the symbol table clean or explicitly call [cmd]perl.destroy[/cmd]
+ once in a while to recreate the interpreter.[br]
+ If you just execute occasional perl code snippets and don't need to keep persistent variables
+ then just use the nameless temporary context provided by [cmd]perl.begin[/cmd]("").[br]
+ [br]
+
+ [big]Passing parameters to the perl script[/big][br]
+ The easiest way to pass parameters to the perl code snippet
+ is to put them as [cmd]perl.begin[/cmd] arguments.
+ In fact the complete syntax of [cmd]perl.begin[/cmd] is:[br]
+ [b]perl.begin(&lt;perl context&gt;,&lt;arg0&gt;,&lt;arg1&gt;,...)[/b][br]
+ Where the &lt;arg0&gt;,&lt;arg1&gt;...&lt;argN&gt; parameters
+ are passed to the perl context as elements of the $_[] array.[br]
+ [example]
+ [cmd]perl.begin[/cmd]("","Hello world!","Now I CAN",1,2,3)
+ for($i=0;$i<5;$i++)
+ KVIrc::echo($_[i],40);
+ [cmd]perl.end[/cmd]
+ [/example]
+ [br]
+
+ [big]Accessing the KVIrc scripting context from perl[/big][br]
+ KVIrc exposes the following functions that manipulate the
+ variables of the KVIrc's current KVS execution context.[br]
+ &nbsp; &nbsp; [b]KVIrc::getLocal(&lt;x&gt;)[/b][br]
+ Returns the value of the KVIrc's local variable %x.[br]
+ &nbsp; &nbsp; [b]KVIrc::getGlobal(&lt;Y&gt;)[/b][br]
+ Returns the value of the KVIrc's global variable %Y.[br]
+ &nbsp; &nbsp; [b]KVIrc::setLocal(&lt;x&gt;,&lt;value&gt;)[/b][br]
+ Sets the KVIrc's global variable %x to &lt;value&gt;[br]
+ &nbsp; &nbsp; [b]KVIrc::setGlobal(&lt;Y&gt;,&lt;value&gt;)[/b][br]
+ Sets the KVIrc's global variable %Y to &lt;value&gt;[br]
+ The local variables interested belong to the current KVS exection context
+ while the global variables are visible everywhere.[br]
+ [example]
+ %pippo = test
+ %Pluto = 12345
+ [cmd]perl.begin[/cmd]
+ $mypippo = KVIrc::getLocal("pippo");
+ $mypippo =~ s/^pi/ze/g;
+ $mypluto = KVIrc::getGlobal("Pluto");
+ $mypluto =~ s/23/xx/g;
+ KVIrc::setLocal("pippo",$mypluto);
+ KVIrc::setGlobal("Pluto",$mypippo);
+ [cmd]perl.end[/cmd]
+ [cmd]echo[/cmd] "\%pippo is" %pippo
+ [cmd]echo[/cmd] "\%Pluto is" %Pluto
+ [/example]
+ [br]
+
+ [big]Executing arbitrary KVIrc commands from perl[/big][br]
+ You can execute arbitrary KVS commands from perl by the means of:[br]
+ &nbsp; &nbsp; [b]KVIrc::eval(&lt;code&gt;)[/b][br]
+ This function behaves exactly like the ${ &lt;code&gt; } KVS construct:
+ it executes &lt;code&gt; in a child context and returns it's evaluation retult.[br]
+ The following two code snippets have equivalent visible effects:[br]
+ [example]
+ [cmd]echo[/cmd] ${ return "Yeah!"; }
+ [/example]
+ [example]
+ [cmd]perl.begin[/cmd]
+ KVIrc::echo(KVIrc::eval("return \"Yeah!\""));
+ [cmd]perl.end[/cmd]
+ [/example]
+ You can "eval" composite command sequences and variable ones.[br]
+ Remember that the perl code snippet is evaluated in a child KVS context
+ and thus the local variables are NOT visible!.
+ The following code snippets may easily fool you:[br]
+ [example]
+ %x = 10
+ [cmd]perl.begin[/cmd]
+ KVIrc::eval("echo \"The value is %x\"");
+ [cmd]perl.end[/cmd]
+ [/example]
+ This will print "The value is " since %x is not accessible from the eval's context.
+ If you have tried to write something like this then you probably need to rewrite it as:[br]
+ [example]
+ %x = 10
+ [cmd]perl.begin[/cmd]
+ $x = KVIrc::getLocal("x");
+ KVIrc::eval("echo \"The value is ".$x."\"");
+ [cmd]perl.end[/cmd]
+ [/example]
+ [br]
+ Note also that you must either escape the $ at the beginning of the KVIrc identifiers
+ or use the single quotes to prevent perl from catching the $ as the beginning of
+ a variable.
+ [example]
+ [comment]# This will not work as expected[/comment]
+ [cmd]perl.begin[/cmd]
+ KVIrc::echo(KVIrc::eval("return $window.caption"));
+ [cmd]perl.end[/cmd]
+ [comment]# But these will do[/comment]
+ [cmd]perl.begin[/cmd]
+ KVIrc::echo(KVIrc::eval("return \$window.caption"));
+ KVIrc::echo(KVIrc::eval('return $window.caption'));
+ [cmd]perl.end[/cmd]
+ [/example]
+
+ [big]A shortcut for KVIrc::eval("/say...")[/big][br]
+ Since KVIrc::eval("/say...") is a common calling pattern then say
+ has been added to the KVIrc perl namespace. You can now call
+ [example]
+ KVIrc::say("Hi all!");
+ [/example]
+ and that will mimic the behaviour of
+ [example]
+ /[cmd]say[/cmd] Hi all!
+ [/example]
+ The complete syntax for KVIrc::say() is:[br]
+ &nbsp; &nbsp; [b]KVIrc::say(&lt;text&gt;[,&lt;windowid&gt;])[/b][br]
+ and the semantics are obvious (see also /[cmd]say[/cmd]).
+ [br]
+
+ [big]The perl script return values[/big][br]
+ The [cmd]perl.begin[/cmd] command propagates the perl code return
+ value to the KVIrc context (just like a setreturn() would do).[br]
+ In fact the perl snippet return value is the last "thing" that
+ the interpreter evaluates.[br]
+ In this way you can write perl aliases that return values
+ without doing any variable passing equilibrism.[br]
+ [br]
+
+ [big]Executing perl scripts from files[/big][br]
+ [example]
+ [cmd]alias[/cmd](perlexec)
+ {
+ %tmp = "perl.begin(\"\",$1,$2,$3,$4,$5)";
+ %tmp .= $file.read($0);
+ %tmp .= "perl.end";
+ eval %tmp;
+ }
+ perlexec "/home/pragma/myperlscript.pl" "param1" "param2" "param3"
+ [comment]# or even[/comment]
+ [cmd]echo[/cmd] $perlexec("/home/pragma/computeprimelargerthan.pl","10000")
+ [/example]
+ [br]
+
+ [big]Other tricks[/big][br]
+ An interesting feature of the persistent perl contexts is
+ that you can prepare a context for a later fast execution.[br]
+ The idea is to declare perl functions in a single perl code snippet
+ and to call the single functions when a fast execution is needed.[br]
+ For example you might parse the following snippet at KVIrc's startup:[br]
+ [example]
+ [cmd]perl.begin[/cmd]("persistent")
+ sub handler_for_event_1
+ {
+ do_complex_perl_stuff_here
+ }
+ sub handler_for_event_2
+ {
+ do_complex_perl_stuff_here
+ }
+ [cmd]perl.end[/cmd]
+ [/example]
+ and later simply call:
+ [example]
+ [cmd]perl.begin[/cmd]("persistent",param1,param2)
+ handler_for_event_1($_[0],$_[1])
+ [cmd]perl.end[/cmd]
+ [/example]
+ [br]
+
+ [big]Curiosity[/big][br]
+ The perl support in KVIrc is implemented as a master-slave module pair.
+ The perl.* module is the master while perlcore is the slave.
+ When the perl support isn't compiled in, the perl.* commands
+ print some warnings and exit gracefully while the perlcore module
+ refuses to be loaded. When perl support is compiled in but
+ for some reason the libperl.so can't be found or loaded
+ then perlcore fails the dynamic loading stage but perl.* still fails
+ gracefully with just some warning messages. This trick allows
+ the scripters to check for perl support with [fnc]perl.isAvailable[/fnc]
+ and to embed perl code snippets in KVS even if the support is missing.
+ The snippets will be just skipped.[br]
+ [br]
+ Happy perl hacking :)[br]
+*/
+
+/*
+ @doc: perl.begin
+ @type:
+ command
+ @title:
+ perl.begin
+ @keyterms:
+ Including perl code snippets in KVS
+ @short:
+ Starts a perl code snippet
+ @syntax:
+ perl.begin [-n] [-q] [(<perl_context>[,<arg0>[,<arg1>[...]]])]
+ <perl code>
+ perl.end
+ @switches:
+ !sw: -q | --quiet
+ Prevents the command from printing any warnings.
+ !sw: -n | --no-return
+ Prevents the perl script return value to be propagated
+ to the current context.
+ !sw: -f | --fail-on-error
+ Treat perl errors as KVS errors and abort execution of the
+ current script. Incompatible with -q
+ @description:
+ Indicates the beginning of a snipped of perl code.
+ The whole code part between perl.begin and perl.end
+ is executed in a perl interpreter.
+ If perl.end is omitted then it is implicitly assumed
+ that the code from perl.begin to the end of the command
+ buffer is perl.[br]
+ Each perl code execution is bound to a
+ perl context (that is in fact a particular instance
+ of a perl interpreter). If <perl_context> is not specified
+ or it is an empty string then temporary perl interpreter is created
+ and destroyed just after the code snippet has terminated execution.
+ If <perl_context> is specified then a perl interpreter
+ keyed to that context is used: if it was already existing
+ then it is reused otherwise it is created.
+ Any <perl_context> is persistent: it mantains the function
+ declarations and perl variable states until explicitly
+ destroyed with [cmd]perl.destroy[/cmd] (or the perlcore
+ module is forcibly unloaded).[br]
+ The <arg0>,<arg1>,... arguments, if present, are passed
+ to the perl code snippet in the @_ array (accessible as $_[0],$_[1]...).[br]
+ The return value of the perl code is propagated to the current
+ context (just like [cmd]setreturn[/cmd] was called on it) unless
+ the -n switch is used.[br]
+ The -q switch prevents from the command from printing any
+ warning.[br]
+ See the [doc:perl_and_kvs]perl scripting documentation[/doc]
+ for more information.
+ @examples:
+ [example]
+ perl.begin
+ KVIrc::eval("echo \"Hello World from perl!\"");
+ perl.end
+ [/example]
+ @seealso:
+*/
+
+/*
+ @doc: perl.end
+ @type:
+ command
+ @title:
+ perl.end
+ @short:
+ Ends a perl code snippet
+ @syntax:
+ perl.begin[(<perl_context>)]
+ <perl code>
+ perl.end
+ @description:
+ Ends a perl code snippet. See [cmd]perl.begin[/cmd].
+ @seealso:
+ [cmd]perl.begin[/cmd]
+*/
+
+static bool perl_kvs_cmd_begin(KviKvsModuleCommandCall * c)
+{
+ // This command is somewhat special in the fact that has a dedicated
+ // parsing routine in the KVS core parser.
+ // The parser sets the perl code as the first parameter of our call,
+ // the remaining params are the context name and the arguments
+
+ QString szCode,szContext;
+ KviKvsVariantList vList;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("code",KVS_PT_STRING,0,szCode)
+ KVSM_PARAMETER("context",KVS_PT_STRING,KVS_PF_OPTIONAL,szContext)
+ KVSM_PARAMETER("args",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,vList)
+ KVSM_PARAMETERS_END(c)
+
+ KVS_CHECK_MODULE_STATE(m,c)
+
+#ifdef COMPILE_PERL_SUPPORT
+
+ KviPerlCoreCtrlCommand_execute ex;
+ ex.uSize = sizeof(KviPerlCoreCtrlCommand_execute);
+ ex.pKvsContext = c->context();
+ ex.szContext = szContext;
+ ex.szCode = szCode;
+ for(KviKvsVariant * v = vList.first();v;v = vList.next())
+ {
+ QString tmp;
+ v->asString(tmp);
+ ex.lArgs.append(tmp);
+ }
+ ex.bQuiet = c->switches()->find('q',"quiet");
+
+ if(!g_pPerlCoreModule->ctrl(KVI_PERLCORECTRLCOMMAND_EXECUTE,&ex))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs_ctx("The perlcore module failed to execute the code: something is wrong with the perl support","perl"));
+ return true;
+ }
+
+ if(!ex.lWarnings.isEmpty())
+ {
+ for(QStringList::Iterator it = ex.lWarnings.begin();it != ex.lWarnings.end();++it)
+ c->warning(*it);
+ }
+
+ if(!ex.bExitOk)
+ {
+ if(!c->switches()->find('q',"quiet"))
+ {
+
+ if(c->switches()->find('f',"fail-on-error"))
+ {
+ c->warning(__tr2qs_ctx("Perl execution error:","perl"));
+ c->warning(ex.szError);
+ return false;
+ } else {
+ c->warning(__tr2qs_ctx("Perl execution error:","perl"));
+ c->error(ex.szError);
+ }
+ }
+ }
+
+ if(!c->switches()->find('n',"no-return"))
+ c->context()->returnValue()->setString(ex.szRetVal);
+
+#endif //COMPILE_PERL_SUPPORT
+
+ return true;
+}
+
+/*
+ @doc: perl.destroy
+ @type:
+ command
+ @title:
+ perl.destroy
+ @short:
+ Destroys a perl execution context
+ @syntax:
+ perl.destroy [-q] <context_name:string>
+ @description:
+ Destroys the perl execution context <context_name>.
+ If the context is not existing then a warning is printed unless the
+ -q switch is used.[br]
+ The destruction will clear any state associated to the context
+ including the stored functions, classes and variable symbols.
+ You may want to destroy a context to re-initialize its state
+ or to simply clear it's memory when it's no longer needed.
+ @seealso:
+ [cmd]perl.begin[/cmd]
+*/
+
+static bool perl_kvs_cmd_destroy(KviKvsModuleCommandCall * c)
+{
+ QString szContext;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("context",KVS_PT_NONEMPTYSTRING,0,szContext)
+ KVSM_PARAMETERS_END(c)
+
+ KVS_CHECK_MODULE_STATE(m,c)
+
+#ifdef COMPILE_PERL_SUPPORT
+ KviPerlCoreCtrlCommand_destroy ex;
+ ex.uSize = sizeof(KviPerlCoreCtrlCommand_destroy);
+ ex.szContext = szContext;
+
+ if(!g_pPerlCoreModule->ctrl(KVI_PERLCORECTRLCOMMAND_DESTROY,&ex))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs_ctx("The perlcore module failed to execute the code: something is wrong with the perl support","perl"));
+ }
+#endif //COMPILE_PERL_SUPPORT
+
+ return true;
+}
+
+
+/*
+ @doc: perl.isAvailable
+ @type:
+ function
+ @title:
+ $perl.isAvailable
+ @short:
+ Check if perl scripting support is available
+ @syntax:
+ $perl.isAvailable
+ @description:
+ Returns 1 if the perl scripting support is available and 0 otherwise.
+*/
+
+static bool perl_kvs_fnc_isAvailable(KviKvsModuleFunctionCall * c)
+{
+#ifdef COMPILE_PERL_SUPPORT
+ g_pPerlCoreModule = g_pModuleManager->getModule("perlcore");
+ c->returnValue()->setBoolean(g_pPerlCoreModule ? true : false);
+#else //!COMPILE_PERL_SUPPORT
+ c->returnValue()->setBoolean(false);
+#endif //!COMPILE_PERL_SUPPORT
+ return true;
+}
+
+static bool perl_module_init(KviModule * m)
+{
+ // register the command anyway
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"begin",perl_kvs_cmd_begin);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"destroy",perl_kvs_cmd_destroy);
+
+ KVSM_REGISTER_FUNCTION(m,"isAvailable",perl_kvs_fnc_isAvailable);
+
+ // FIXME: perl.isSupported()
+#ifdef COMPILE_PERL_SUPPORT
+ g_pPerlCoreModule = g_pModuleManager->getModule("perlcore");
+#endif // COMPILE_PERL_SUPPORT
+ return true;
+}
+
+static bool perl_module_cleanup(KviModule *m)
+{
+#ifdef COMPILE_PERL_SUPPORT
+#endif // COMPILE_PERL_SUPPORT
+ return true;
+}
+
+KVIRC_MODULE(
+ "Perl", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Perl scripting engine",
+ perl_module_init,
+ 0,
+ 0,
+ perl_module_cleanup
+)
diff --git a/src/modules/perlcore/KVIrc.xs b/src/modules/perlcore/KVIrc.xs
new file mode 100644
index 00000000..37b040cf
--- /dev/null
+++ b/src/modules/perlcore/KVIrc.xs
@@ -0,0 +1,139 @@
+MODULE = KVIrc PACKAGE = KVIrc
+
+void echo(text,colorset = 0,windowid = 0)
+ char * text
+ int colorset
+ char * windowid
+ CODE:
+ if(g_pCurrentKvsContext && text)
+ {
+ KviWindow * pWnd;
+ if(windowid)
+ {
+ pWnd = g_pApp->findWindow(windowid);
+ if(!pWnd)pWnd = g_pCurrentKvsContext->window();
+ } else {
+ pWnd = g_pCurrentKvsContext->window();
+ }
+ pWnd->outputNoFmt(colorset,QString::fromUtf8(text));
+ }
+
+void say(text,windowid = 0)
+ char * text
+ char * windowid
+ CODE:
+ if(g_pCurrentKvsContext && text)
+ {
+ KviWindow * pWnd;
+ if(windowid)
+ {
+ pWnd = g_pApp->findWindow(windowid);
+ if(!pWnd)pWnd = g_pCurrentKvsContext->window();
+ } else {
+ pWnd = g_pCurrentKvsContext->window();
+ }
+ QString tmp = QString::fromUtf8(text);
+ KviUserInput::parse(tmp,pWnd);
+ }
+
+void warning(text)
+ char * text
+ CODE:
+ if((!g_bExecuteQuiet) && g_pCurrentKvsContext)
+ g_pCurrentKvsContext->warning(text);
+
+void internalWarning(text)
+ char * text
+ CODE:
+ if(!g_bExecuteQuiet)
+ g_lWarningList.append(QString(text));
+
+
+char * getLocal(varname)
+ char * varname
+ CODE:
+ QString tmp;
+ KviStr hack;
+ if(g_pCurrentKvsContext)
+ {
+ KviKvsVariant * pVar = g_pCurrentKvsContext->localVariables()->find(varname);
+ if(pVar)
+ {
+ pVar->asString(tmp);
+ hack = tmp;
+ RETVAL = hack.ptr();
+ } else RETVAL = "";
+ }
+ OUTPUT:
+ RETVAL
+
+void setLocal(varname,value)
+ char * varname
+ char * value
+ CODE:
+ if(g_pCurrentKvsContext)
+ {
+ if(value && *value)
+ {
+ KviKvsVariant * pVar = g_pCurrentKvsContext->localVariables()->get(varname);
+ pVar->setString(value);
+ } else {
+ g_pCurrentKvsContext->localVariables()->unset(varname);
+ }
+ }
+
+char * getGlobal(varname)
+ char * varname
+ CODE:
+ QString tmp;
+ KviStr hack;
+ if(g_pCurrentKvsContext)
+ {
+ KviKvsVariant * pVar = g_pCurrentKvsContext->globalVariables()->find(varname);
+ if(pVar)
+ {
+ pVar->asString(tmp);
+ hack = tmp;
+ RETVAL = hack.ptr();
+ } else RETVAL = "";
+ }
+ OUTPUT:
+ RETVAL
+
+void setGlobal(varname,value)
+ char * varname
+ char * value
+ CODE:
+ if(g_pCurrentKvsContext)
+ {
+ if(value && *value)
+ {
+ KviKvsVariant * pVar = g_pCurrentKvsContext->globalVariables()->get(varname);
+ pVar->setString(value);
+ } else {
+ g_pCurrentKvsContext->localVariables()->unset(varname);
+ }
+ }
+
+
+char * eval(code)
+ char * code
+ CODE:
+ if(g_pCurrentKvsContext && code)
+ {
+ KviKvsVariant ret;
+ if(KviKvsScript::run(QString::fromUtf8(code),g_pCurrentKvsContext->window(),0,&ret))
+ {
+ QString tmp;
+ ret.asString(tmp);
+ g_szLastReturnValue = tmp;
+ } else {
+ g_szLastReturnValue = "";
+ }
+ RETVAL = g_szLastReturnValue.ptr();
+ } else {
+ RETVAL = "";
+ }
+ OUTPUT:
+ RETVAL
+
diff --git a/src/modules/perlcore/Makefile.am b/src/modules/perlcore/Makefile.am
new file mode 100644
index 00000000..a153262c
--- /dev/null
+++ b/src/modules/perlcore/Makefile.am
@@ -0,0 +1,23 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\" $(SS_PERL_CCFLAGS)
+
+pluglib_LTLIBRARIES = libkviperlcore.la
+
+libkviperlcore_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS) $(SS_PERL_LDFLAGS)
+
+libkviperlcore_la_SOURCES = libkviperlcore.cpp
+libkviperlcore_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS = perlcoreinterface.h
+
+EXTRA_DIST = KVIrc.xs ppport.h xs.inc typemap
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+xs:
+ xsubpp -noversioncheck -C++ -noprototypes KVIrc.xs > xs.inc
diff --git a/src/modules/perlcore/libkviperlcore.cpp b/src/modules/perlcore/libkviperlcore.cpp
new file mode 100644
index 00000000..a9196219
--- /dev/null
+++ b/src/modules/perlcore/libkviperlcore.cpp
@@ -0,0 +1,414 @@
+//=============================================================================
+//
+// File : libkviperlcore.cpp
+// Creation date : Tue Jul 13 13:03:31 2004 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_module.h"
+#include "kvi_settings.h"
+#include "kvi_locale.h"
+#include "kvi_out.h"
+#include "kvi_window.h"
+#include "kvi_app.h"
+
+#include "kvi_kvs_script.h"
+#include "kvi_kvs_variant.h"
+#include "kvi_userinput.h"
+#include "kvi_qcstring.h"
+#include "kvi_pointerhashtable.h"
+
+#ifdef DEBUG
+ #undef DEBUG
+#endif
+
+// I MUST say that the perl embedding process is somewhat ugly :(
+// First of all the man pages are somewhat unreadable even
+// for a non-novice perl user. The writer of each page assumed
+// that you have already read each other page...
+// Also browsing the pages with "man" is obviously out of mind
+// but this can be solved by looking up some html docs on the net.
+// Embedding multiple interpreters isn't that hard (after you
+// have read perlembed) but to start passing parameters
+// around you have to read at least perlembed, perlguts, perlxs,..
+// take a look at the perlinternals and have a good trip
+// around the web to find some examples for the functions
+// that aren't explained enough in the pages.
+// It gets even more weird when you attempt to include
+// some XS functions... (what the heck is boot_DynaLoader ?).
+
+// ... and I'm still convinced that I'm leaking memory with
+// the perl values, but well ...
+
+// anyway, once you struggled for a couple of days with all that
+// stuff then you start getting things done... and it rox :)
+
+#ifdef COMPILE_PERL_SUPPORT
+ #include <EXTERN.h>
+ #include <perl.h>
+ #include <XSUB.h>
+
+ #include "ppport.h"
+
+ #include "kvi_kvs_runtimecontext.h"
+
+ static KviKvsRunTimeContext * g_pCurrentKvsContext = 0;
+ static bool g_bExecuteQuiet = false;
+ static KviStr g_szLastReturnValue("");
+ static QStringList g_lWarningList;
+
+ #include "xs.inc"
+#endif // COMPILE_PERL_SUPPORT
+
+// perl redefines bool :///
+#ifdef bool
+ #undef bool
+#endif
+
+#ifdef COMPILE_PERL_SUPPORT
+
+#include "perlcoreinterface.h"
+
+// people ... are you mad ? ... what the heck is "my_perl" ?
+#define my_perl m_pInterpreter
+
+class KviPerlInterpreter
+{
+public:
+ KviPerlInterpreter(const QString &szContextName);
+ ~KviPerlInterpreter();
+protected:
+ QString m_szContextName;
+ PerlInterpreter * m_pInterpreter;
+public:
+ bool init(); // if this fails then well.. :D
+ void done();
+ bool execute(const QString &szCode,QStringList &args,QString &szRetVal,QString &szError,QStringList &lWarnings);
+ const QString & contextName(){ return m_szContextName; };
+protected:
+ QString svToQString(SV * sv);
+};
+
+KviPerlInterpreter::KviPerlInterpreter(const QString &szContextName)
+{
+ m_szContextName = szContextName;
+ m_pInterpreter = 0;
+}
+
+KviPerlInterpreter::~KviPerlInterpreter()
+{
+ done();
+}
+
+// this kinda sux :(
+// It SHOULD be mentioned somewhere that
+// this function is in DynaLoader.a in the perl
+// distribution and you MUST link it statically.
+extern "C" void boot_DynaLoader(pTHX_ CV* cv);
+
+extern "C" void xs_init(pTHX)
+{
+ char *file = __FILE__;
+ // boot up the DynaLoader
+ newXS("DynaLoader::boot_DynaLoader",boot_DynaLoader,file);
+ // now bootstrap the KVIrc module
+ // This stuff is simply cutted and pasted from xs.inc
+ // since I don't really know if it's safe to call
+ // something like
+ // CV * dummy;
+ // boot_KVIrc(aTHX,dummy);
+ // ...
+ newXS("KVIrc::echo", XS_KVIrc_echo, file);
+ newXS("KVIrc::say", XS_KVIrc_say, file);
+ newXS("KVIrc::warning", XS_KVIrc_warning, file);
+ newXS("KVIrc::getLocal", XS_KVIrc_getLocal, file);
+ newXS("KVIrc::setLocal", XS_KVIrc_setLocal, file);
+ newXS("KVIrc::getGlobal", XS_KVIrc_getGlobal, file);
+ newXS("KVIrc::setGlobal", XS_KVIrc_setGlobal, file);
+ newXS("KVIrc::eval", XS_KVIrc_eval, file);
+ newXS("KVIrc::internalWarning", XS_KVIrc_internalWarning, file);
+}
+
+bool KviPerlInterpreter::init()
+{
+ if(m_pInterpreter)done();
+ m_pInterpreter = perl_alloc();
+ if(!m_pInterpreter)return false;
+ PERL_SET_CONTEXT(m_pInterpreter);
+ PL_perl_destruct_level = 1;
+ perl_construct(m_pInterpreter);
+ char * daArgs[] = { "yo", "-e", "0", "-w" };
+ perl_parse(m_pInterpreter,xs_init,4,daArgs,NULL);
+ QString szInitCode;
+
+ // this part of the code seems to be unnecessary
+ // even if it is created by the perl make process...
+ // "our %EXPORT_TAGS = ('all' => [qw(echo)]);\n"
+ // "our @EXPORT_OK = (qw(echo));\n"
+ // "our @EXPORT = qw();\n"
+ // This is probably needed only if perl has to load
+ // the XS through XSLoader ?
+ // Maybe also the remaining part of the package
+ // declaration could be dropped as well...
+ // I just haven't tried :D
+
+ KviQString::sprintf(
+ szInitCode,
+ "{\n" \
+ "package KVIrc;\n" \
+ "require Exporter;\n" \
+ "our @ISA = qw(Exporter);\n" \
+ "1;\n" \
+ "}\n" \
+ "$g_szContext = \"%Q\";\n" \
+ "$g_bExecuteQuiet = 0;\n" \
+ "$SIG{__WARN__} = sub\n" \
+ "{\n" \
+ " my($p,$f,$l,$x);\n" \
+ " ($p,$f,$l) = caller;\n" \
+ " KVIrc::internalWarning(\"At line \".$l.\" of perl code: \");\n" \
+ " KVIrc::internalWarning(join(' ',@_));\n" \
+ "}\n",
+ &m_szContextName);
+
+ eval_pv(szInitCode.utf8().data(),false);
+ return true;
+}
+
+void KviPerlInterpreter::done()
+{
+ if(!m_pInterpreter)return;
+ PERL_SET_CONTEXT(m_pInterpreter);
+ PL_perl_destruct_level = 1;
+ perl_destruct(m_pInterpreter);
+ perl_free(m_pInterpreter);
+ m_pInterpreter = 0;
+}
+
+QString KviPerlInterpreter::svToQString(SV * sv)
+{
+ QString ret = "";
+ if(!sv)return ret;
+ STRLEN len;
+ char * ptr = SvPV(sv,len);
+ if(ptr)ret = ptr;
+ return ret;
+}
+
+bool KviPerlInterpreter::execute(
+ const QString &szCode,
+ QStringList &args,
+ QString &szRetVal,
+ QString &szError,
+ QStringList &lWarnings)
+{
+ if(!m_pInterpreter)
+ {
+ szError = __tr2qs_ctx("Internal error: perl interpreter not initialized","perlcore");
+ return false;
+ }
+
+ g_lWarningList.clear();
+
+ KviQCString szUtf8 = szCode.utf8();
+ PERL_SET_CONTEXT(m_pInterpreter);
+
+ // clear the _ array
+ AV * pArgs = get_av("_",1);
+ SV * pArg = av_shift(pArgs);
+ while(SvOK(pArg))
+ {
+ SvREFCNT_dec(pArg);
+ pArg = av_shift(pArgs);
+ }
+
+ if(args.count() > 0)
+ {
+ // set the args in the _ arry
+ av_unshift(pArgs,(I32)args.count());
+ int idx = 0;
+ for(QStringList::Iterator it = args.begin();it != args.end();++it)
+ {
+ QString tmp = *it;
+ const char * val = tmp.utf8().data();
+ if(val)
+ {
+ pArg = newSVpv(val,tmp.length());
+ if(!av_store(pArgs,idx,pArg))
+ SvREFCNT_dec(pArg);
+ }
+ idx++;
+ }
+ }
+
+ // call the code
+ SV * pRet = eval_pv(szUtf8.data(),false);
+
+ // clear the _ array again
+ pArgs = get_av("_",1);
+ pArg = av_shift(pArgs);
+ while(SvOK(pArg))
+ {
+ SvREFCNT_dec(pArg);
+ pArg = av_shift(pArgs);
+ }
+ av_undef(pArgs);
+
+ // get the ret value
+ if(pRet)
+ {
+ if(SvOK(pRet))
+ szRetVal = svToQString(pRet);
+ }
+
+ if(!g_lWarningList.isEmpty())
+ lWarnings = g_lWarningList;
+
+ // and the eventual error string
+ pRet = get_sv("@",false);
+ if(pRet)
+ {
+ if(SvOK(pRet))
+ {
+ szError = svToQString(pRet);
+ if(!szError.isEmpty())return false;
+ }
+ }
+
+ return true;
+}
+
+static KviPointerHashTable<QString,KviPerlInterpreter> * g_pInterpreters = 0;
+
+static KviPerlInterpreter * perlcore_get_interpreter(const QString &szContextName)
+{
+ KviPerlInterpreter * i = g_pInterpreters->find(szContextName);
+ if(i)return i;
+ i = new KviPerlInterpreter(szContextName);
+ if(!i->init())
+ {
+ delete i;
+ return 0;
+ }
+ g_pInterpreters->replace(szContextName,i);
+ return i;
+}
+
+static void perlcore_destroy_interpreter(const QString &szContextName)
+{
+ KviPerlInterpreter * i = g_pInterpreters->find(szContextName);
+ if(!i)return;
+ g_pInterpreters->remove(szContextName);
+ i->done();
+ delete i;
+}
+
+static void perlcore_destroy_all_interpreters()
+{
+ KviPointerHashTableIterator<QString,KviPerlInterpreter> it(*g_pInterpreters);
+
+ while(it.current())
+ {
+ KviPerlInterpreter * i = it.current();
+ i->done();
+ delete i;
+ ++it;
+ }
+ g_pInterpreters->clear();
+}
+
+#endif // COMPILE_PERL_SUPPORT
+
+static bool perlcore_module_ctrl(KviModule * m,const char * cmd,void * param)
+{
+#ifdef COMPILE_PERL_SUPPORT
+ if(kvi_strEqualCS(cmd,KVI_PERLCORECTRLCOMMAND_EXECUTE))
+ {
+ KviPerlCoreCtrlCommand_execute * ex = (KviPerlCoreCtrlCommand_execute *)param;
+ if(ex->uSize != sizeof(KviPerlCoreCtrlCommand_execute))return false;
+ g_pCurrentKvsContext = ex->pKvsContext;
+ g_bExecuteQuiet = ex->bQuiet;
+ if(ex->szContext.isEmpty())
+ {
+ KviPerlInterpreter * m = new KviPerlInterpreter("temporary");
+ if(!m->init())
+ {
+ delete m;
+ return false;
+ }
+ ex->bExitOk = m->execute(ex->szCode,ex->lArgs,ex->szRetVal,ex->szError,ex->lWarnings);
+ m->done();
+ delete m;
+ } else {
+ KviPerlInterpreter * m = perlcore_get_interpreter(ex->szContext);
+ ex->bExitOk = m->execute(ex->szCode,ex->lArgs,ex->szRetVal,ex->szError,ex->lWarnings);
+ }
+ return true;
+ }
+ if(kvi_strEqualCS(cmd,KVI_PERLCORECTRLCOMMAND_DESTROY))
+ {
+ KviPerlCoreCtrlCommand_destroy * de = (KviPerlCoreCtrlCommand_destroy *)param;
+ if(de->uSize != sizeof(KviPerlCoreCtrlCommand_destroy))return false;
+ perlcore_destroy_interpreter(de->szContext);
+ return true;
+ }
+#endif // COMPILE_PERL_SUPPORT
+ return false;
+}
+
+static bool perlcore_module_init(KviModule * m)
+{
+#ifdef COMPILE_PERL_SUPPORT
+ g_pInterpreters = new KviPointerHashTable<QString,KviPerlInterpreter>(17,false);
+ g_pInterpreters->setAutoDelete(false);
+ return true;
+#else // !COMPILE_PERL_SUPPORT
+ return false;
+#endif // !COMPILE_PERL_SUPPORT
+}
+
+static bool perlcore_module_cleanup(KviModule *m)
+{
+#ifdef COMPILE_PERL_SUPPORT
+ perlcore_destroy_all_interpreters();
+ delete g_pInterpreters;
+ g_pInterpreters = 0;
+#endif // COMPILE_PERL_SUPPORT
+ return true;
+}
+
+static bool perlcore_module_can_unload(KviModule *m)
+{
+#ifdef COMPILE_PERL_SUPPORT
+ return (g_pInterpreters->count() == 0);
+#endif // COMPILE_PERL_SUPPORT
+ return true;
+}
+
+KVIRC_MODULE(
+ "Perl", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Perl scripting engine core",
+ perlcore_module_init,
+ perlcore_module_can_unload,
+ perlcore_module_ctrl,
+ perlcore_module_cleanup
+)
diff --git a/src/modules/perlcore/perlcoreinterface.h b/src/modules/perlcore/perlcoreinterface.h
new file mode 100644
index 00000000..a7ceb1fc
--- /dev/null
+++ b/src/modules/perlcore/perlcoreinterface.h
@@ -0,0 +1,59 @@
+#ifndef _PERLCOREINTERFACE_H_
+#define _PERLCOREINTERFACE_H_
+
+//=============================================================================
+//
+// File : perlcoreinterface.h
+// Creation date : Tue Jul 13 13:03:31 2004 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_settings.h"
+#include "kvi_qstring.h"
+#include "kvi_kvs_runtimecontext.h"
+
+#include <qstringlist.h>
+
+
+#define KVI_PERLCORECTRLCOMMAND_EXECUTE "execute"
+
+typedef struct _KviPerlCoreCtrlCommand_execute
+{
+ unsigned int uSize;
+ KviKvsRunTimeContext * pKvsContext;
+ QString szContext;
+ QString szCode;
+ bool bExitOk;
+ QString szRetVal;
+ QString szError;
+ QStringList lWarnings;
+ QStringList lArgs;
+ bool bQuiet;
+} KviPerlCoreCtrlCommand_execute;
+
+#define KVI_PERLCORECTRLCOMMAND_DESTROY "destroy"
+
+typedef struct _KviPerlCoreCtrlCommand_destroy
+{
+ unsigned int uSize;
+ QString szContext;
+} KviPerlCoreCtrlCommand_destroy;
+
+#endif // !_PERLCOREINTERFACE_H_
diff --git a/src/modules/perlcore/ppport.h b/src/modules/perlcore/ppport.h
new file mode 100644
index 00000000..2a802132
--- /dev/null
+++ b/src/modules/perlcore/ppport.h
@@ -0,0 +1,540 @@
+
+/* ppport.h -- Perl/Pollution/Portability Version 2.0002
+ *
+ * Automatically Created by Devel::PPPort on Tue Jul 13 13:16:39 2004
+ *
+ * Do NOT edit this file directly! -- Edit PPPort.pm instead.
+ *
+ * Version 2.x, Copyright (C) 2001, Paul Marquess.
+ * Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
+ * This code may be used and distributed under the same license as any
+ * version of Perl.
+ *
+ * This version of ppport.h is designed to support operation with Perl
+ * installations back to 5.004, and has been tested up to 5.8.0.
+ *
+ * If this version of ppport.h is failing during the compilation of this
+ * module, please check if a newer version of Devel::PPPort is available
+ * on CPAN before sending a bug report.
+ *
+ * If you are using the latest version of Devel::PPPort and it is failing
+ * during compilation of this module, please send a report to perlbug@perl.com
+ *
+ * Include all following information:
+ *
+ * 1. The complete output from running "perl -V"
+ *
+ * 2. This file.
+ *
+ * 3. The name & version of the module you were trying to build.
+ *
+ * 4. A full log of the build that failed.
+ *
+ * 5. Any other information that you think could be relevant.
+ *
+ *
+ * For the latest version of this code, please retreive the Devel::PPPort
+ * module from CPAN.
+ *
+ */
+
+/*
+ * In order for a Perl extension module to be as portable as possible
+ * across differing versions of Perl itself, certain steps need to be taken.
+ * Including this header is the first major one, then using dTHR is all the
+ * appropriate places and using a PL_ prefix to refer to global Perl
+ * variables is the second.
+ *
+ */
+
+
+/* If you use one of a few functions that were not present in earlier
+ * versions of Perl, please add a define before the inclusion of ppport.h
+ * for a static include, or use the GLOBAL request in a single module to
+ * produce a global definition that can be referenced from the other
+ * modules.
+ *
+ * Function: Static define: Extern define:
+ * newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL
+ *
+ */
+
+
+/* To verify whether ppport.h is needed for your module, and whether any
+ * special defines should be used, ppport.h can be run through Perl to check
+ * your source code. Simply say:
+ *
+ * perl -x ppport.h *.c *.h *.xs foo/bar*.c [etc]
+ *
+ * The result will be a list of patches suggesting changes that should at
+ * least be acceptable, if not necessarily the most efficient solution, or a
+ * fix for all possible problems. It won't catch where dTHR is needed, and
+ * doesn't attempt to account for global macro or function definitions,
+ * nested includes, typemaps, etc.
+ *
+ * In order to test for the need of dTHR, please try your module under a
+ * recent version of Perl that has threading compiled-in.
+ *
+ */
+
+
+/*
+#!/usr/bin/perl
+@ARGV = ("*.xs") if !@ARGV;
+%badmacros = %funcs = %macros = (); $replace = 0;
+foreach (<DATA>) {
+ $funcs{$1} = 1 if /Provide:\s+(\S+)/;
+ $macros{$1} = 1 if /^#\s*define\s+([a-zA-Z0-9_]+)/;
+ $replace = $1 if /Replace:\s+(\d+)/;
+ $badmacros{$2}=$1 if $replace and /^#\s*define\s+([a-zA-Z0-9_]+).*?\s+([a-zA-Z0-9_]+)/;
+ $badmacros{$1}=$2 if /Replace (\S+) with (\S+)/;
+}
+foreach $filename (map(glob($_),@ARGV)) {
+ unless (open(IN, "<$filename")) {
+ warn "Unable to read from $file: $!\n";
+ next;
+ }
+ print "Scanning $filename...\n";
+ $c = ""; while (<IN>) { $c .= $_; } close(IN);
+ $need_include = 0; %add_func = (); $changes = 0;
+ $has_include = ($c =~ /#.*include.*ppport/m);
+
+ foreach $func (keys %funcs) {
+ if ($c =~ /#.*define.*\bNEED_$func(_GLOBAL)?\b/m) {
+ if ($c !~ /\b$func\b/m) {
+ print "If $func isn't needed, you don't need to request it.\n" if
+ $changes += ($c =~ s/^.*#.*define.*\bNEED_$func\b.*\n//m);
+ } else {
+ print "Uses $func\n";
+ $need_include = 1;
+ }
+ } else {
+ if ($c =~ /\b$func\b/m) {
+ $add_func{$func} =1 ;
+ print "Uses $func\n";
+ $need_include = 1;
+ }
+ }
+ }
+
+ if (not $need_include) {
+ foreach $macro (keys %macros) {
+ if ($c =~ /\b$macro\b/m) {
+ print "Uses $macro\n";
+ $need_include = 1;
+ }
+ }
+ }
+
+ foreach $badmacro (keys %badmacros) {
+ if ($c =~ /\b$badmacro\b/m) {
+ $changes += ($c =~ s/\b$badmacro\b/$badmacros{$badmacro}/gm);
+ print "Uses $badmacros{$badmacro} (instead of $badmacro)\n";
+ $need_include = 1;
+ }
+ }
+
+ if (scalar(keys %add_func) or $need_include != $has_include) {
+ if (!$has_include) {
+ $inc = join('',map("#define NEED_$_\n", sort keys %add_func)).
+ "#include \"ppport.h\"\n";
+ $c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m;
+ } elsif (keys %add_func) {
+ $inc = join('',map("#define NEED_$_\n", sort keys %add_func));
+ $c = "$inc$c" unless $c =~ s/^.*#.*include.*ppport.*$/$inc$&/m;
+ }
+ if (!$need_include) {
+ print "Doesn't seem to need ppport.h.\n";
+ $c =~ s/^.*#.*include.*ppport.*\n//m;
+ }
+ $changes++;
+ }
+
+ if ($changes) {
+ open(OUT,">/tmp/ppport.h.$$");
+ print OUT $c;
+ close(OUT);
+ open(DIFF, "diff -u $filename /tmp/ppport.h.$$|");
+ while (<DIFF>) { s!/tmp/ppport\.h\.$$!$filename.patched!; print STDOUT; }
+ close(DIFF);
+ unlink("/tmp/ppport.h.$$");
+ } else {
+ print "Looks OK\n";
+ }
+}
+__DATA__
+*/
+
+#ifndef _P_P_PORTABILITY_H_
+#define _P_P_PORTABILITY_H_
+
+#ifndef PERL_REVISION
+# ifndef __PATCHLEVEL_H_INCLUDED__
+# include "patchlevel.h"
+# endif
+# ifndef PERL_REVISION
+# define PERL_REVISION (5)
+ /* Replace: 1 */
+# define PERL_VERSION PATCHLEVEL
+# define PERL_SUBVERSION SUBVERSION
+ /* Replace PERL_PATCHLEVEL with PERL_VERSION */
+ /* Replace: 0 */
+# endif
+#endif
+
+#define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION)
+
+/* It is very unlikely that anyone will try to use this with Perl 6
+ (or greater), but who knows.
+ */
+#if PERL_REVISION != 5
+# error ppport.h only works with Perl version 5
+#endif /* PERL_REVISION != 5 */
+
+#ifndef ERRSV
+# define ERRSV perl_get_sv("@",FALSE)
+#endif
+
+#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5))
+/* Replace: 1 */
+# define PL_Sv Sv
+# define PL_compiling compiling
+# define PL_copline copline
+# define PL_curcop curcop
+# define PL_curstash curstash
+# define PL_defgv defgv
+# define PL_dirty dirty
+# define PL_dowarn dowarn
+# define PL_hints hints
+# define PL_na na
+# define PL_perldb perldb
+# define PL_rsfp_filters rsfp_filters
+# define PL_rsfpv rsfp
+# define PL_stdingv stdingv
+# define PL_sv_no sv_no
+# define PL_sv_undef sv_undef
+# define PL_sv_yes sv_yes
+/* Replace: 0 */
+#endif
+
+#ifdef HASATTRIBUTE
+# if defined(__GNUC__) && defined(__cplusplus)
+# define PERL_UNUSED_DECL
+# else
+# define PERL_UNUSED_DECL __attribute__((unused))
+# endif
+#else
+# define PERL_UNUSED_DECL
+#endif
+
+#ifndef dNOOP
+# define NOOP (void)0
+# define dNOOP extern int Perl___notused PERL_UNUSED_DECL
+#endif
+
+#ifndef dTHR
+# define dTHR dNOOP
+#endif
+
+#ifndef dTHX
+# define dTHX dNOOP
+# define dTHXa(x) dNOOP
+# define dTHXoa(x) dNOOP
+#endif
+
+#ifndef pTHX
+# define pTHX void
+# define pTHX_
+# define aTHX
+# define aTHX_
+#endif
+
+#ifndef UVSIZE
+# define UVSIZE IVSIZE
+#endif
+
+#ifndef NVTYPE
+# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE)
+# define NVTYPE long double
+# else
+# define NVTYPE double
+# endif
+typedef NVTYPE NV;
+#endif
+
+#ifndef INT2PTR
+
+#if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE)
+# define PTRV UV
+# define INT2PTR(any,d) (any)(d)
+#else
+# if PTRSIZE == LONGSIZE
+# define PTRV unsigned long
+# else
+# define PTRV unsigned
+# endif
+# define INT2PTR(any,d) (any)(PTRV)(d)
+#endif
+#define NUM2PTR(any,d) (any)(PTRV)(d)
+#define PTR2IV(p) INT2PTR(IV,p)
+#define PTR2UV(p) INT2PTR(UV,p)
+#define PTR2NV(p) NUM2PTR(NV,p)
+#if PTRSIZE == LONGSIZE
+# define PTR2ul(p) (unsigned long)(p)
+#else
+# define PTR2ul(p) INT2PTR(unsigned long,p)
+#endif
+
+#endif /* !INT2PTR */
+
+#ifndef boolSV
+# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
+#endif
+
+#ifndef gv_stashpvn
+# define gv_stashpvn(str,len,flags) gv_stashpv(str,flags)
+#endif
+
+#ifndef newSVpvn
+# define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0))
+#endif
+
+#ifndef newRV_inc
+/* Replace: 1 */
+# define newRV_inc(sv) newRV(sv)
+/* Replace: 0 */
+#endif
+
+/* DEFSV appears first in 5.004_56 */
+#ifndef DEFSV
+# define DEFSV GvSV(PL_defgv)
+#endif
+
+#ifndef SAVE_DEFSV
+# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv))
+#endif
+
+#ifndef newRV_noinc
+# ifdef __GNUC__
+# define newRV_noinc(sv) \
+ ({ \
+ SV *nsv = (SV*)newRV(sv); \
+ SvREFCNT_dec(sv); \
+ nsv; \
+ })
+# else
+# if defined(USE_THREADS)
+static SV * newRV_noinc (SV * sv)
+{
+ SV *nsv = (SV*)newRV(sv);
+ SvREFCNT_dec(sv);
+ return nsv;
+}
+# else
+# define newRV_noinc(sv) \
+ (PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv)
+# endif
+# endif
+#endif
+
+/* Provide: newCONSTSUB */
+
+/* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */
+#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION < 63))
+
+#if defined(NEED_newCONSTSUB)
+static
+#else
+extern void newCONSTSUB(HV * stash, char * name, SV *sv);
+#endif
+
+#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL)
+void
+newCONSTSUB(stash,name,sv)
+HV *stash;
+char *name;
+SV *sv;
+{
+ U32 oldhints = PL_hints;
+ HV *old_cop_stash = PL_curcop->cop_stash;
+ HV *old_curstash = PL_curstash;
+ line_t oldline = PL_curcop->cop_line;
+ PL_curcop->cop_line = PL_copline;
+
+ PL_hints &= ~HINT_BLOCK_SCOPE;
+ if (stash)
+ PL_curstash = PL_curcop->cop_stash = stash;
+
+ newSUB(
+
+#if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22))
+ /* before 5.003_22 */
+ start_subparse(),
+#else
+# if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22)
+ /* 5.003_22 */
+ start_subparse(0),
+# else
+ /* 5.003_23 onwards */
+ start_subparse(FALSE, 0),
+# endif
+#endif
+
+ newSVOP(OP_CONST, 0, newSVpv(name,0)),
+ newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */
+ newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
+ );
+
+ PL_hints = oldhints;
+ PL_curcop->cop_stash = old_cop_stash;
+ PL_curstash = old_curstash;
+ PL_curcop->cop_line = oldline;
+}
+#endif
+
+#endif /* newCONSTSUB */
+
+#ifndef START_MY_CXT
+
+/*
+ * Boilerplate macros for initializing and accessing interpreter-local
+ * data from C. All statics in extensions should be reworked to use
+ * this, if you want to make the extension thread-safe. See ext/re/re.xs
+ * for an example of the use of these macros.
+ *
+ * Code that uses these macros is responsible for the following:
+ * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts"
+ * 2. Declare a typedef named my_cxt_t that is a structure that contains
+ * all the data that needs to be interpreter-local.
+ * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t.
+ * 4. Use the MY_CXT_INIT macro such that it is called exactly once
+ * (typically put in the BOOT: section).
+ * 5. Use the members of the my_cxt_t structure everywhere as
+ * MY_CXT.member.
+ * 6. Use the dMY_CXT macro (a declaration) in all the functions that
+ * access MY_CXT.
+ */
+
+#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \
+ defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT)
+
+/* This must appear in all extensions that define a my_cxt_t structure,
+ * right after the definition (i.e. at file scope). The non-threads
+ * case below uses it to declare the data as static. */
+#define START_MY_CXT
+
+#if (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION < 68 ))
+/* Fetches the SV that keeps the per-interpreter data. */
+#define dMY_CXT_SV \
+ SV *my_cxt_sv = perl_get_sv(MY_CXT_KEY, FALSE)
+#else /* >= perl5.004_68 */
+#define dMY_CXT_SV \
+ SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \
+ sizeof(MY_CXT_KEY)-1, TRUE)
+#endif /* < perl5.004_68 */
+
+/* This declaration should be used within all functions that use the
+ * interpreter-local data. */
+#define dMY_CXT \
+ dMY_CXT_SV; \
+ my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv))
+
+/* Creates and zeroes the per-interpreter data.
+ * (We allocate my_cxtp in a Perl SV so that it will be released when
+ * the interpreter goes away.) */
+#define MY_CXT_INIT \
+ dMY_CXT_SV; \
+ /* newSV() allocates one more than needed */ \
+ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
+ Zero(my_cxtp, 1, my_cxt_t); \
+ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
+
+/* This macro must be used to access members of the my_cxt_t structure.
+ * e.g. MYCXT.some_data */
+#define MY_CXT (*my_cxtp)
+
+/* Judicious use of these macros can reduce the number of times dMY_CXT
+ * is used. Use is similar to pTHX, aTHX etc. */
+#define pMY_CXT my_cxt_t *my_cxtp
+#define pMY_CXT_ pMY_CXT,
+#define _pMY_CXT ,pMY_CXT
+#define aMY_CXT my_cxtp
+#define aMY_CXT_ aMY_CXT,
+#define _aMY_CXT ,aMY_CXT
+
+#else /* single interpreter */
+
+
+#define START_MY_CXT static my_cxt_t my_cxt;
+#define dMY_CXT_SV dNOOP
+#define dMY_CXT dNOOP
+#define MY_CXT_INIT NOOP
+#define MY_CXT my_cxt
+
+#define pMY_CXT void
+#define pMY_CXT_
+#define _pMY_CXT
+#define aMY_CXT
+#define aMY_CXT_
+#define _aMY_CXT
+
+#endif
+
+#endif /* START_MY_CXT */
+
+#ifndef IVdf
+# if IVSIZE == LONGSIZE
+# define IVdf "ld"
+# define UVuf "lu"
+# define UVof "lo"
+# define UVxf "lx"
+# define UVXf "lX"
+# else
+# if IVSIZE == INTSIZE
+# define IVdf "d"
+# define UVuf "u"
+# define UVof "o"
+# define UVxf "x"
+# define UVXf "X"
+# endif
+# endif
+#endif
+
+#ifndef NVef
+# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \
+ defined(PERL_PRIfldbl) /* Not very likely, but let's try anyway. */
+# define NVef PERL_PRIeldbl
+# define NVff PERL_PRIfldbl
+# define NVgf PERL_PRIgldbl
+# else
+# define NVef "e"
+# define NVff "f"
+# define NVgf "g"
+# endif
+#endif
+
+#ifndef AvFILLp /* Older perls (<=5.003) lack AvFILLp */
+# define AvFILLp AvFILL
+#endif
+
+#ifdef SvPVbyte
+# if PERL_REVISION == 5 && PERL_VERSION < 7
+ /* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */
+# undef SvPVbyte
+# define SvPVbyte(sv, lp) \
+ ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \
+ ? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp))
+ static char *
+ my_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *lp)
+ {
+ sv_utf8_downgrade(sv,0);
+ return SvPV(sv,*lp);
+ }
+# endif
+#else
+# define SvPVbyte SvPV
+#endif
+
+#endif /* _P_P_PORTABILITY_H_ */
+
+/* End of File ppport.h */
diff --git a/src/modules/perlcore/typemap b/src/modules/perlcore/typemap
new file mode 100644
index 00000000..1124eb64
--- /dev/null
+++ b/src/modules/perlcore/typemap
@@ -0,0 +1,313 @@
+# basic C types
+int T_IV
+unsigned T_UV
+unsigned int T_UV
+long T_IV
+unsigned long T_UV
+short T_IV
+unsigned short T_UV
+char T_CHAR
+unsigned char T_U_CHAR
+char * T_PV
+unsigned char * T_PV
+const char * T_PV
+caddr_t T_PV
+wchar_t * T_PV
+wchar_t T_IV
+bool_t T_IV
+size_t T_UV
+ssize_t T_IV
+time_t T_NV
+unsigned long * T_OPAQUEPTR
+char ** T_PACKEDARRAY
+void * T_PTR
+Time_t * T_PV
+SV * T_SV
+SVREF T_SVREF
+AV * T_AVREF
+HV * T_HVREF
+CV * T_CVREF
+
+IV T_IV
+UV T_UV
+NV T_NV
+I32 T_IV
+I16 T_IV
+I8 T_IV
+STRLEN T_UV
+U32 T_U_LONG
+U16 T_U_SHORT
+U8 T_UV
+Result T_U_CHAR
+Boolean T_BOOL
+float T_FLOAT
+double T_DOUBLE
+SysRet T_SYSRET
+SysRetLong T_SYSRET
+FILE * T_STDIO
+PerlIO * T_INOUT
+FileHandle T_PTROBJ
+InputStream T_IN
+InOutStream T_INOUT
+OutputStream T_OUT
+bool T_BOOL
+
+#############################################################################
+INPUT
+T_SV
+ $var = $arg
+T_SVREF
+ if (SvROK($arg))
+ $var = (SV*)SvRV($arg);
+ else
+ Perl_croak(aTHX_ \"$var is not a reference\")
+T_AVREF
+ if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV)
+ $var = (AV*)SvRV($arg);
+ else
+ Perl_croak(aTHX_ \"$var is not an array reference\")
+T_HVREF
+ if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVHV)
+ $var = (HV*)SvRV($arg);
+ else
+ Perl_croak(aTHX_ \"$var is not a hash reference\")
+T_CVREF
+ if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVCV)
+ $var = (CV*)SvRV($arg);
+ else
+ Perl_croak(aTHX_ \"$var is not a code reference\")
+T_SYSRET
+ $var NOT IMPLEMENTED
+T_UV
+ $var = ($type)SvUV($arg)
+T_IV
+ $var = ($type)SvIV($arg)
+T_INT
+ $var = (int)SvIV($arg)
+T_ENUM
+ $var = ($type)SvIV($arg)
+T_BOOL
+ $var = (bool)SvTRUE($arg)
+T_U_INT
+ $var = (unsigned int)SvUV($arg)
+T_SHORT
+ $var = (short)SvIV($arg)
+T_U_SHORT
+ $var = (unsigned short)SvUV($arg)
+T_LONG
+ $var = (long)SvIV($arg)
+T_U_LONG
+ $var = (unsigned long)SvUV($arg)
+T_CHAR
+ $var = (char)*SvPV_nolen($arg)
+T_U_CHAR
+ $var = (unsigned char)SvUV($arg)
+T_FLOAT
+ $var = (float)SvNV($arg)
+T_NV
+ $var = ($type)SvNV($arg)
+T_DOUBLE
+ $var = (double)SvNV($arg)
+T_PV
+ $var = ($type)SvPV_nolen($arg)
+T_PTR
+ $var = INT2PTR($type,SvIV($arg))
+T_PTRREF
+ if (SvROK($arg)) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ $var = INT2PTR($type,tmp);
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not a reference\")
+T_REF_IV_REF
+ if (sv_isa($arg, \"${ntype}\")) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ $var = *INT2PTR($type *, tmp);
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not of type ${ntype}\")
+T_REF_IV_PTR
+ if (sv_isa($arg, \"${ntype}\")) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ $var = INT2PTR($type, tmp);
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not of type ${ntype}\")
+T_PTROBJ
+ if (sv_derived_from($arg, \"${ntype}\")) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ $var = INT2PTR($type,tmp);
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not of type ${ntype}\")
+T_PTRDESC
+ if (sv_isa($arg, \"${ntype}\")) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ ${type}_desc = (\U${type}_DESC\E*) tmp;
+ $var = ${type}_desc->ptr;
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not of type ${ntype}\")
+T_REFREF
+ if (SvROK($arg)) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ $var = *INT2PTR($type,tmp);
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not a reference\")
+T_REFOBJ
+ if (sv_isa($arg, \"${ntype}\")) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ $var = *INT2PTR($type,tmp);
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not of type ${ntype}\")
+T_OPAQUE
+ $var = *($type *)SvPV_nolen($arg)
+T_OPAQUEPTR
+ $var = ($type)SvPV_nolen($arg)
+T_PACKED
+ $var = XS_unpack_$ntype($arg)
+T_PACKEDARRAY
+ $var = XS_unpack_$ntype($arg)
+T_CALLBACK
+ $var = make_perl_cb_$type($arg)
+T_ARRAY
+ U32 ix_$var = $argoff;
+ $var = $ntype(items -= $argoff);
+ while (items--) {
+ DO_ARRAY_ELEM;
+ ix_$var++;
+ }
+ /* this is the number of elements in the array */
+ ix_$var -= $argoff
+T_STDIO
+ $var = PerlIO_findFILE(IoIFP(sv_2io($arg)))
+T_IN
+ $var = IoIFP(sv_2io($arg))
+T_INOUT
+ $var = IoIFP(sv_2io($arg))
+T_OUT
+ $var = IoOFP(sv_2io($arg))
+#############################################################################
+OUTPUT
+T_SV
+ $arg = $var;
+T_SVREF
+ $arg = newRV((SV*)$var);
+T_AVREF
+ $arg = newRV((SV*)$var);
+T_HVREF
+ $arg = newRV((SV*)$var);
+T_CVREF
+ $arg = newRV((SV*)$var);
+T_IV
+ sv_setiv($arg, (IV)$var);
+T_UV
+ sv_setuv($arg, (UV)$var);
+T_INT
+ sv_setiv($arg, (IV)$var);
+T_SYSRET
+ if ($var != -1) {
+ if ($var == 0)
+ sv_setpvn($arg, "0 but true", 10);
+ else
+ sv_setiv($arg, (IV)$var);
+ }
+T_ENUM
+ sv_setiv($arg, (IV)$var);
+T_BOOL
+ $arg = boolSV($var);
+T_U_INT
+ sv_setuv($arg, (UV)$var);
+T_SHORT
+ sv_setiv($arg, (IV)$var);
+T_U_SHORT
+ sv_setuv($arg, (UV)$var);
+T_LONG
+ sv_setiv($arg, (IV)$var);
+T_U_LONG
+ sv_setuv($arg, (UV)$var);
+T_CHAR
+ sv_setpvn($arg, (char *)&$var, 1);
+T_U_CHAR
+ sv_setuv($arg, (UV)$var);
+T_FLOAT
+ sv_setnv($arg, (double)$var);
+T_NV
+ sv_setnv($arg, (NV)$var);
+T_DOUBLE
+ sv_setnv($arg, (double)$var);
+T_PV
+ sv_setpv((SV*)$arg, $var);
+T_PTR
+ sv_setiv($arg, PTR2IV($var));
+T_PTRREF
+ sv_setref_pv($arg, Nullch, (void*)$var);
+T_REF_IV_REF
+ sv_setref_pv($arg, \"${ntype}\", (void*)new $ntype($var));
+T_REF_IV_PTR
+ sv_setref_pv($arg, \"${ntype}\", (void*)$var);
+T_PTROBJ
+ sv_setref_pv($arg, \"${ntype}\", (void*)$var);
+T_PTRDESC
+ sv_setref_pv($arg, \"${ntype}\", (void*)new\U${type}_DESC\E($var));
+T_REFREF
+ NOT_IMPLEMENTED
+T_REFOBJ
+ NOT IMPLEMENTED
+T_OPAQUE
+ sv_setpvn($arg, (char *)&$var, sizeof($var));
+T_OPAQUEPTR
+ sv_setpvn($arg, (char *)$var, sizeof(*$var));
+T_PACKED
+ XS_pack_$ntype($arg, $var);
+T_PACKEDARRAY
+ XS_pack_$ntype($arg, $var, count_$ntype);
+T_DATAUNIT
+ sv_setpvn($arg, $var.chp(), $var.size());
+T_CALLBACK
+ sv_setpvn($arg, $var.context.value().chp(),
+ $var.context.value().size());
+T_ARRAY
+ {
+ U32 ix_$var;
+ EXTEND(SP,size_$var);
+ for (ix_$var = 0; ix_$var < size_$var; ix_$var++) {
+ ST(ix_$var) = sv_newmortal();
+ DO_ARRAY_ELEM
+ }
+ }
+T_STDIO
+ {
+ GV *gv = newGVgen("$Package");
+ PerlIO *fp = PerlIO_importFILE($var,0);
+ if ( fp && do_open(gv, "+<&", 3, FALSE, 0, 0, fp) )
+ sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1)));
+ else
+ $arg = &PL_sv_undef;
+ }
+T_IN
+ {
+ GV *gv = newGVgen("$Package");
+ if ( do_open(gv, "<&", 2, FALSE, 0, 0, $var) )
+ sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1)));
+ else
+ $arg = &PL_sv_undef;
+ }
+T_INOUT
+ {
+ GV *gv = newGVgen("$Package");
+ if ( do_open(gv, "+<&", 3, FALSE, 0, 0, $var) )
+ sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1)));
+ else
+ $arg = &PL_sv_undef;
+ }
+T_OUT
+ {
+ GV *gv = newGVgen("$Package");
+ if ( do_open(gv, "+>&", 3, FALSE, 0, 0, $var) )
+ sv_setsv($arg, sv_bless(newRV((SV*)gv), gv_stashpv("$Package",1)));
+ else
+ $arg = &PL_sv_undef;
+ }
diff --git a/src/modules/perlcore/xs.inc b/src/modules/perlcore/xs.inc
new file mode 100644
index 00000000..5c31cb19
--- /dev/null
+++ b/src/modules/perlcore/xs.inc
@@ -0,0 +1,277 @@
+/*
+ * This file was generated automatically by xsubpp version 1.9508 from the
+ * contents of KVIrc.xs. Do not edit this file, edit KVIrc.xs instead.
+ *
+ * ANY CHANGES MADE HERE WILL BE LOST!
+ *
+ */
+
+#line 1 "KVIrc.xs"
+#line 11 "KVIrc.c"
+XS(XS_KVIrc_echo); /* prototype to pass -Wmissing-prototypes */
+XS(XS_KVIrc_echo)
+{
+ dXSARGS;
+ if (items < 1 || items > 3)
+ Perl_croak(aTHX_ "Usage: KVIrc::echo(text, colorset = 0, windowid = 0)");
+ {
+ char * text = (char *)SvPV_nolen(ST(0));
+ int colorset;
+ char * windowid;
+
+ if (items < 2)
+ colorset = 0;
+ else {
+ colorset = (int)SvIV(ST(1));
+ }
+
+ if (items < 3)
+ windowid = 0;
+ else {
+ windowid = (char *)SvPV_nolen(ST(2));
+ }
+#line 8 "KVIrc.xs"
+ if(g_pCurrentKvsContext && text)
+ {
+ KviWindow * pWnd;
+ if(windowid)
+ {
+ pWnd = g_pApp->findWindow(windowid);
+ if(!pWnd)pWnd = g_pCurrentKvsContext->window();
+ } else {
+ pWnd = g_pCurrentKvsContext->window();
+ }
+ pWnd->outputNoFmt(colorset,QString::fromUtf8(text));
+ }
+#line 47 "KVIrc.c"
+ }
+ XSRETURN_EMPTY;
+}
+
+XS(XS_KVIrc_say); /* prototype to pass -Wmissing-prototypes */
+XS(XS_KVIrc_say)
+{
+ dXSARGS;
+ if (items < 1 || items > 2)
+ Perl_croak(aTHX_ "Usage: KVIrc::say(text, windowid = 0)");
+ {
+ char * text = (char *)SvPV_nolen(ST(0));
+ char * windowid;
+
+ if (items < 2)
+ windowid = 0;
+ else {
+ windowid = (char *)SvPV_nolen(ST(1));
+ }
+#line 25 "KVIrc.xs"
+ if(g_pCurrentKvsContext && text)
+ {
+ KviWindow * pWnd;
+ if(windowid)
+ {
+ pWnd = g_pApp->findWindow(windowid);
+ if(!pWnd)pWnd = g_pCurrentKvsContext->window();
+ } else {
+ pWnd = g_pCurrentKvsContext->window();
+ }
+ QString tmp = QString::fromUtf8(text);
+ KviUserInput::parse(tmp,pWnd);
+ }
+#line 81 "KVIrc.c"
+ }
+ XSRETURN_EMPTY;
+}
+
+XS(XS_KVIrc_warning); /* prototype to pass -Wmissing-prototypes */
+XS(XS_KVIrc_warning)
+{
+ dXSARGS;
+ if (items != 1)
+ Perl_croak(aTHX_ "Usage: KVIrc::warning(text)");
+ {
+ char * text = (char *)SvPV_nolen(ST(0));
+#line 42 "KVIrc.xs"
+ if((!g_bExecuteQuiet) && g_pCurrentKvsContext)
+ g_pCurrentKvsContext->warning(text);
+#line 97 "KVIrc.c"
+ }
+ XSRETURN_EMPTY;
+}
+
+XS(XS_KVIrc_internalWarning); /* prototype to pass -Wmissing-prototypes */
+XS(XS_KVIrc_internalWarning)
+{
+ dXSARGS;
+ if (items != 1)
+ Perl_croak(aTHX_ "Usage: KVIrc::internalWarning(text)");
+ {
+ char * text = (char *)SvPV_nolen(ST(0));
+#line 48 "KVIrc.xs"
+ if(!g_bExecuteQuiet)
+ g_lWarningList.append(QString(text));
+#line 113 "KVIrc.c"
+ }
+ XSRETURN_EMPTY;
+}
+
+XS(XS_KVIrc_getLocal); /* prototype to pass -Wmissing-prototypes */
+XS(XS_KVIrc_getLocal)
+{
+ dXSARGS;
+ if (items != 1)
+ Perl_croak(aTHX_ "Usage: KVIrc::getLocal(varname)");
+ {
+ char * varname = (char *)SvPV_nolen(ST(0));
+ char * RETVAL;
+ dXSTARG;
+#line 55 "KVIrc.xs"
+ QString tmp;
+ KviStr hack;
+ if(g_pCurrentKvsContext)
+ {
+ KviKvsVariant * pVar = g_pCurrentKvsContext->localVariables()->find(varname);
+ if(pVar)
+ {
+ pVar->asString(tmp);
+ hack = tmp;
+ RETVAL = hack.ptr();
+ } else RETVAL = "";
+ }
+#line 141 "KVIrc.c"
+ sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
+ }
+ XSRETURN(1);
+}
+
+XS(XS_KVIrc_setLocal); /* prototype to pass -Wmissing-prototypes */
+XS(XS_KVIrc_setLocal)
+{
+ dXSARGS;
+ if (items != 2)
+ Perl_croak(aTHX_ "Usage: KVIrc::setLocal(varname, value)");
+ {
+ char * varname = (char *)SvPV_nolen(ST(0));
+ char * value = (char *)SvPV_nolen(ST(1));
+#line 74 "KVIrc.xs"
+ if(g_pCurrentKvsContext)
+ {
+ if(value && *value)
+ {
+ KviKvsVariant * pVar = g_pCurrentKvsContext->localVariables()->get(varname);
+ pVar->setString(value);
+ } else {
+ g_pCurrentKvsContext->localVariables()->unset(varname);
+ }
+ }
+#line 167 "KVIrc.c"
+ }
+ XSRETURN_EMPTY;
+}
+
+XS(XS_KVIrc_getGlobal); /* prototype to pass -Wmissing-prototypes */
+XS(XS_KVIrc_getGlobal)
+{
+ dXSARGS;
+ if (items != 1)
+ Perl_croak(aTHX_ "Usage: KVIrc::getGlobal(varname)");
+ {
+ char * varname = (char *)SvPV_nolen(ST(0));
+ char * RETVAL;
+ dXSTARG;
+#line 88 "KVIrc.xs"
+ QString tmp;
+ KviStr hack;
+ if(g_pCurrentKvsContext)
+ {
+ KviKvsVariant * pVar = g_pCurrentKvsContext->globalVariables()->find(varname);
+ if(pVar)
+ {
+ pVar->asString(tmp);
+ hack = tmp;
+ RETVAL = hack.ptr();
+ } else RETVAL = "";
+ }
+#line 195 "KVIrc.c"
+ sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
+ }
+ XSRETURN(1);
+}
+
+XS(XS_KVIrc_setGlobal); /* prototype to pass -Wmissing-prototypes */
+XS(XS_KVIrc_setGlobal)
+{
+ dXSARGS;
+ if (items != 2)
+ Perl_croak(aTHX_ "Usage: KVIrc::setGlobal(varname, value)");
+ {
+ char * varname = (char *)SvPV_nolen(ST(0));
+ char * value = (char *)SvPV_nolen(ST(1));
+#line 107 "KVIrc.xs"
+ if(g_pCurrentKvsContext)
+ {
+ if(value && *value)
+ {
+ KviKvsVariant * pVar = g_pCurrentKvsContext->globalVariables()->get(varname);
+ pVar->setString(value);
+ } else {
+ g_pCurrentKvsContext->localVariables()->unset(varname);
+ }
+ }
+#line 221 "KVIrc.c"
+ }
+ XSRETURN_EMPTY;
+}
+
+XS(XS_KVIrc_eval); /* prototype to pass -Wmissing-prototypes */
+XS(XS_KVIrc_eval)
+{
+ dXSARGS;
+ if (items != 1)
+ Perl_croak(aTHX_ "Usage: KVIrc::eval(code)");
+ {
+ char * code = (char *)SvPV_nolen(ST(0));
+ char * RETVAL;
+ dXSTARG;
+#line 122 "KVIrc.xs"
+ if(g_pCurrentKvsContext && code)
+ {
+ KviKvsVariant ret;
+ if(KviKvsScript::run(QString::fromUtf8(code),g_pCurrentKvsContext->window(),0,&ret))
+ {
+ QString tmp;
+ ret.asString(tmp);
+ g_szLastReturnValue = tmp;
+ } else {
+ g_szLastReturnValue = "";
+ }
+ RETVAL = g_szLastReturnValue.ptr();
+ } else {
+ RETVAL = "";
+ }
+#line 252 "KVIrc.c"
+ sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
+ }
+ XSRETURN(1);
+}
+
+#ifdef __cplusplus
+extern "C"
+#endif
+XS(boot_KVIrc); /* prototype to pass -Wmissing-prototypes */
+XS(boot_KVIrc)
+{
+ dXSARGS;
+ char* file = __FILE__;
+
+ newXS("KVIrc::echo", XS_KVIrc_echo, file);
+ newXS("KVIrc::say", XS_KVIrc_say, file);
+ newXS("KVIrc::warning", XS_KVIrc_warning, file);
+ newXS("KVIrc::internalWarning", XS_KVIrc_internalWarning, file);
+ newXS("KVIrc::getLocal", XS_KVIrc_getLocal, file);
+ newXS("KVIrc::setLocal", XS_KVIrc_setLocal, file);
+ newXS("KVIrc::getGlobal", XS_KVIrc_getGlobal, file);
+ newXS("KVIrc::setGlobal", XS_KVIrc_setGlobal, file);
+ newXS("KVIrc::eval", XS_KVIrc_eval, file);
+ XSRETURN_YES;
+}
+
diff --git a/src/modules/popupeditor/Makefile.am b/src/modules/popupeditor/Makefile.am
new file mode 100644
index 00000000..a9e2f1d7
--- /dev/null
+++ b/src/modules/popupeditor/Makefile.am
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvipopupeditor.la
+
+libkvipopupeditor_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvipopupeditor_la_SOURCES = libkvipopupeditor.cpp popupeditor.cpp
+nodist_libkvipopupeditor_la_SOURCES = moc_popupeditor.cpp
+
+noinst_HEADERS = popupeditor.h
+libkvipopupeditor_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+moc_popupeditor.cpp: popupeditor.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/popupeditor/libkvipopupeditor.cpp b/src/modules/popupeditor/libkvipopupeditor.cpp
new file mode 100644
index 00000000..a223a1e7
--- /dev/null
+++ b/src/modules/popupeditor/libkvipopupeditor.cpp
@@ -0,0 +1,88 @@
+//
+// File : libkvipopupeditor.cpp
+// Creation date : Mon 23 Dec 2002 20:23:59 2002 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2002 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_module.h"
+
+#include "kvi_locale.h"
+
+#include "kvi_frame.h"
+
+#include "popupeditor.h"
+
+KviPopupEditorWindow * g_pPopupEditorWindow = 0;
+
+
+/*
+ @doc: popupeditor.open
+ @type:
+ command
+ @title:
+ popupeditor.open
+ @short:
+ Shows the popup editor
+ @syntax:
+ toolbareditor.open
+ @description:
+ Opens the script popup editor dialog.
+*/
+
+static bool popupeditor_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ if(!g_pPopupEditorWindow)
+ {
+ g_pPopupEditorWindow = new KviPopupEditorWindow(c->window()->frame());
+ c->window()->frame()->addWindow(g_pPopupEditorWindow);
+ }
+
+ g_pPopupEditorWindow->setFocus();
+ return true;
+}
+
+static bool popupeditor_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",popupeditor_kvs_cmd_open);
+ g_pPopupEditorWindow = 0;
+ return true;
+}
+
+static bool popupeditor_module_can_unload(KviModule * m)
+{
+ return (g_pPopupEditorWindow == 0);
+}
+
+static bool popupeditor_module_cleanup(KviModule *m)
+{
+ if(g_pPopupEditorWindow)delete g_pPopupEditorWindow;
+ g_pPopupEditorWindow = 0;
+ return true;
+}
+
+KVIRC_MODULE(
+ "PopupEditor", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Editor for the script popups",
+ popupeditor_module_init,
+ popupeditor_module_can_unload,
+ 0,
+ popupeditor_module_cleanup
+)
diff --git a/src/modules/popupeditor/popupeditor.cpp b/src/modules/popupeditor/popupeditor.cpp
new file mode 100644
index 00000000..942b5b2f
--- /dev/null
+++ b/src/modules/popupeditor/popupeditor.cpp
@@ -0,0 +1,1433 @@
+//=============================================================================
+//
+// File : popupeditor.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 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 "popupeditor.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_imagedialog.h"
+#include "kvi_config.h"
+#include "kvi_filedialog.h"
+#include "kvi_fileutils.h"
+#include "kvi_scripteditor.h"
+#include "kvi_debug.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_kvs_popupmanager.h"
+#include "kvi_kvs_popupmenu.h"
+#include "kvi_kvs_variantlist.h"
+//#include "kvi_parameterlist.h"
+
+#include <qmessagebox.h>
+#include <qdir.h>
+#include <qsplitter.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qtooltip.h>
+#include "kvi_pointerhashtable.h"
+#include <qpushbutton.h>
+#include "kvi_tal_vbox.h"
+
+extern KviPopupEditorWindow * g_pPopupEditorWindow;
+
+
+
+//KviPopupEntryItem
+KviPopupListViewItem::KviPopupListViewItem(KviTalListView * pListView,KviPopupListViewItem * after,Type t)
+: KviTalListViewItem(pListView,after)
+{
+ m_type = t;
+ init();
+}
+
+KviPopupListViewItem::KviPopupListViewItem(KviPopupListViewItem * parent,KviPopupListViewItem * after,Type t)
+: KviTalListViewItem(parent,after)
+{
+ m_type = t;
+ init();
+}
+
+void KviPopupListViewItem::init()
+{
+ switch(m_type)
+ {
+ case Item:
+ setText(1,__tr2qs("Item"));
+ break;
+ case Menu:
+ setText(1,__tr2qs("Submenu"));
+ break;
+ case ExtMenu:
+ setText(1,__tr2qs("External Menu"));
+ break;
+ case Separator:
+ setText(0,"-----------------------");
+ setText(1,__tr2qs("Separator"));
+ break;
+ case Label:
+ setText(1,__tr2qs("Label"));
+ break;
+ case Epilogue:
+ setText(0,__tr2qs("### Epilogue ###"));
+ setText(1,__tr2qs("Epilogue"));
+ break;
+ case Prologue:
+ setText(0,__tr2qs("### Prologue ###"));
+ setText(1,__tr2qs("Prologue"));
+ break;
+ default:
+ break;
+ }
+}
+
+void KviPopupListViewItem::setItemText(const QString & szText)
+{
+ switch(m_type)
+ {
+ case Item:
+ case Menu:
+ case Label:
+ case ExtMenu:
+ m_szText = szText;
+ setText(0,szText);
+ break;
+ default:
+ break;
+ }
+}
+
+void KviPopupListViewItem::setCondition(const QString & szCondition)
+{
+ switch(m_type)
+ {
+ case Item:
+ case Menu:
+ case Label:
+ case ExtMenu:
+ m_szCondition = szCondition;
+ break;
+ default:
+ break;
+ }
+}
+
+void KviPopupListViewItem::setCode(const QString & szCode)
+{
+ switch(m_type)
+ {
+ case Item:
+ case Epilogue:
+ case Prologue:
+ case ExtMenu:
+ m_szCode = szCode;
+ break;
+ default:
+ break;
+ }
+}
+
+void KviPopupListViewItem::setId(const QString & szId)
+{
+ m_szId = szId;
+}
+
+void KviPopupListViewItem::setIcon(const QString & szIcon)
+{
+ switch(m_type)
+ {
+ case Item:
+ case Menu:
+ case Label:
+ case ExtMenu:
+ m_szIcon = szIcon;
+ {
+ QPixmap * pix = g_pIconManager->getImage(szIcon);
+ if(pix)setPixmap(0,*pix);
+ else setPixmap(0,QPixmap());
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+KviSinglePopupEditor::KviSinglePopupEditor(QWidget * par)
+: QWidget(par)
+{
+ m_pLastSelectedItem = 0;
+ m_pContextPopup = new KviTalPopupMenu(this);
+ m_pClipboard = 0;
+ m_pTestPopup = 0;
+
+ QGridLayout * g = new QGridLayout(this,7,3,2,2);
+
+ m_pNameEditor = new QLineEdit(this);
+ QToolTip::add(m_pNameEditor,__tr2qs("Popup name"));
+
+ g->addMultiCellWidget(m_pNameEditor,0,0,0,1);
+
+ m_pMenuButton = new QPushButton(__tr2qs("Test"),this);
+ g->addWidget(m_pMenuButton,0,2);
+ connect(m_pMenuButton,SIGNAL(clicked()),this,SLOT(testPopup()));
+#ifdef COMPILE_USE_QT4
+ QSplitter * spl = new QSplitter(Qt::Vertical,this,"popupeditor");
+ spl->setOpaqueResize(false);
+#else
+ QSplitter * spl = new QSplitter(QSplitter::Vertical,this);
+#endif
+
+ m_pListView = new KviTalListView(spl);
+ m_pListView->addColumn(__tr2qs("Item"));
+ m_pListView->addColumn(__tr2qs("Type"));
+ m_pListView->setMultiSelection(false);
+ m_pListView->setAllColumnsShowFocus(true);
+ m_pListView->setRootIsDecorated(true);
+ m_pListView->setShowSortIndicator(false);
+ m_pListView->setSorting(-1);
+
+
+ connect(m_pListView,SIGNAL(selectionChanged(KviTalListViewItem *)),this,SLOT(selectionChanged(KviTalListViewItem *)));
+ connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),
+ this,SLOT(itemPressed(KviTalListViewItem *,const QPoint &,int)));
+
+ m_pEditor = KviScriptEditor::createInstance(spl);
+
+ g->addMultiCellWidget(spl,1,1,0,2);
+
+ QLabel * l = new QLabel(__tr2qs("Text:"),this);
+ l->setMargin(2);
+ g->addWidget(l,2,0);
+
+ m_pTextEditor = new QLineEdit(this);
+ QToolTip::add(m_pTextEditor,
+ __tr2qs("<center><b>Visible text</b><br>May contain identifiers that will be evaluated at popup call time.<br>For labels, this text can contain also limited HTML tags.</center>"));
+ g->addMultiCellWidget(m_pTextEditor,2,2,1,2);
+
+ l = new QLabel(__tr2qs("Condition:"),this);
+ l->setMargin(2);
+ g->addWidget(l,3,0);
+
+ m_pConditionEditor = new QLineEdit(this);
+ QToolTip::add(m_pConditionEditor,
+ __tr2qs("<center><b>Boolean condition</b><br>Will be evaluated at popup call time in order to decide if this entry has to be shown.<br>An empty condition evaluates to true.</center>"));
+ g->addMultiCellWidget(m_pConditionEditor,3,3,1,2);
+
+ l = new QLabel(__tr2qs("Icon:"),this);
+ l->setMargin(2);
+ g->addWidget(l,4,0);
+
+ m_pIconEditor = new QLineEdit(this);
+ QToolTip::add(m_pIconEditor,
+ __tr2qs("<center><b>Icon identifier</b><br>May be an internal icon ID, an absolute path or a relative path.<br>Portable scripts should never use absolute paths.</center>"));
+ g->addMultiCellWidget(m_pIconEditor,4,4,1,2);
+
+ l = new QLabel(__tr2qs("External menu:"),this);
+ l->setMargin(2);
+ g->addWidget(l,5,0);
+
+ m_pExtNameEditor = new QLineEdit(this);
+ QToolTip::add(m_pExtNameEditor,
+ __tr2qs("<center><b>External menu name</b><br>This allows to nest externally defined popup menus. The popup menu with the specified name will be looked up at menu setup time.</center>"));
+ g->addMultiCellWidget(m_pExtNameEditor,5,5,1,2);
+
+ l = new QLabel(__tr2qs("Item Id:"),this);
+ l->setMargin(2);
+ g->addWidget(l,6,0);
+
+
+ m_pIdEditor = new QLineEdit(this);
+ QToolTip::add(m_pIdEditor,
+ __tr2qs("<center><b>Item id</b><br>This will allow you to use delpopupitem later.</center>"));
+ g->addMultiCellWidget(m_pIdEditor,6,6,1,2);
+
+
+ g->setColStretch(1,1);
+ g->setRowStretch(1,1);
+
+}
+
+KviSinglePopupEditor::~KviSinglePopupEditor()
+{
+ if(m_pClipboard)delete m_pClipboard;
+ if(m_pTestPopup)delete m_pTestPopup;
+ KviScriptEditor::destroyInstance(m_pEditor);
+}
+
+void KviSinglePopupEditor::testPopup()
+{
+
+ if(m_pTestPopup)delete m_pTestPopup;
+ m_pTestPopup = getMenu();
+ if(!m_pTestPopup)return;
+ connect(m_pTestPopup,SIGNAL(testModeItemClicked(KviKvsPopupMenuItem *)),this,SLOT(testModeMenuItemClicked(KviKvsPopupMenuItem *)));
+ QPoint pnt = m_pMenuButton->mapToGlobal(QPoint(0,m_pMenuButton->height()));
+ KviKvsVariantList * parms = new KviKvsVariantList();
+ parms->append(new KviKvsVariant(QString("test1")));
+ parms->append(new KviKvsVariant(QString("test2")));
+ parms->append(new KviKvsVariant(QString("test3")));
+ parms->append(new KviKvsVariant(QString("test4")));
+ m_pTestPopup->doPopup(pnt,g_pActiveWindow,parms,true);
+}
+
+KviPopupListViewItem * KviSinglePopupEditor::findMatchingItem(KviKvsPopupMenuItem * it,KviPopupListViewItem * item)
+{
+
+ if(it->type() != KviKvsPopupMenuItem::Item)goto not_this_one;
+ if(item->m_type != KviPopupListViewItem::Item)goto not_this_one;
+ if(it->name() != item->m_szId)goto not_this_one;
+ if(it->kvsText())
+ {
+ if(it->kvsText()->code() != item->m_szText)goto not_this_one;
+ } else {
+ if(!item->m_szText.isEmpty())goto not_this_one;
+ }
+ if(it->kvsCode())
+ {
+ if(it->kvsCode()->code() != item->m_szCode)goto not_this_one;
+ } else {
+ if(!item->m_szCode.isEmpty())goto not_this_one;
+ }
+ if(it->kvsIcon())
+ {
+ if(it->kvsIcon()->code() != item->m_szIcon)goto not_this_one;
+ } else {
+ if(!item->m_szIcon.isEmpty())goto not_this_one;
+ }
+ if(it->kvsCondition())
+ {
+ if(it->kvsCondition()->code() != item->m_szCondition)goto not_this_one;
+ } else {
+ if(!item->m_szCondition.isEmpty())goto not_this_one;
+ }
+
+ return item;
+
+not_this_one:
+ item = (KviPopupListViewItem *)item->firstChild();
+ while(item)
+ {
+ KviPopupListViewItem * found = findMatchingItem(it,item);
+ if(found)return found;
+ item = (KviPopupListViewItem *)item->nextSibling();
+ }
+
+ return 0;
+}
+
+void KviSinglePopupEditor::testModeMenuItemClicked(KviKvsPopupMenuItem * it)
+{
+
+ saveLastSelectedItem(); // that's the first thingie
+ // find the matching item and set it as current
+ KviPopupListViewItem * item = (KviPopupListViewItem *)m_pListView->firstChild();
+ while(item)
+ {
+ KviPopupListViewItem * found = findMatchingItem(it,item);
+ if(found)
+ {
+ // set the item as current
+ m_pListView->ensureItemVisible(found);
+ m_pListView->setCurrentItem(found);
+ selectionChanged(found);
+ return;
+ }
+ item = (KviPopupListViewItem *)item->nextSibling();
+ }
+
+}
+
+
+void KviSinglePopupEditor::itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ m_pContextPopup->clear();
+
+ KviPopupListViewItem * parentMenu = 0;
+ bool bIsMenu = false;
+
+ if(it)
+ {
+ parentMenu = (KviPopupListViewItem *) (((KviPopupListViewItem *)it)->parent());
+ bIsMenu = ((KviPopupListViewItem *)it)->m_type == KviPopupListViewItem::Menu;
+ }
+
+ m_pContextPopup->insertItem(__tr2qs("New Separator Below"),this,SLOT(contextNewSeparatorBelow()));
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New Separator Above"),this,SLOT(contextNewSeparatorAbove())),
+ it);
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New Separator Inside"),this,SLOT(contextNewSeparatorInside())),
+ it && bIsMenu);
+
+ m_pContextPopup->insertSeparator();
+
+ m_pContextPopup->insertItem(__tr2qs("New Label Below"),this,SLOT(contextNewLabelBelow()));
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New Label Above"),this,SLOT(contextNewLabelAbove())),
+ it);
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New Label Inside"),this,SLOT(contextNewLabelInside())),
+ it && bIsMenu);
+
+ m_pContextPopup->insertSeparator();
+
+ m_pContextPopup->insertItem(__tr2qs("New Item Below"),this,SLOT(contextNewItemBelow()));
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New Item Above"),this,SLOT(contextNewItemAbove())),
+ it);
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New Item Inside"),this,SLOT(contextNewItemInside())),
+ it && bIsMenu);
+
+ m_pContextPopup->insertSeparator();
+
+ m_pContextPopup->insertItem(__tr2qs("New Menu Below"),this,SLOT(contextNewMenuBelow()));
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New Menu Above"),this,SLOT(contextNewMenuAbove())),
+ it);
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New Menu Inside"),this,SLOT(contextNewMenuInside())),
+ it && bIsMenu);
+
+ m_pContextPopup->insertSeparator();
+
+ m_pContextPopup->insertItem(__tr2qs("New External Menu Below"),this,SLOT(contextNewExtMenuBelow()));
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New External Menu Above"),this,SLOT(contextNewExtMenuAbove())),
+ it);
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(__tr2qs("New External Menu Inside"),this,SLOT(contextNewExtMenuInside())),
+ it && bIsMenu);
+
+ m_pContextPopup->insertSeparator();
+
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_CUT)),
+ __tr2qs("Cu&t"),
+ this,SLOT(contextCut())),
+ it);
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_COPY)),
+ __tr2qs("&Copy"),
+ this,SLOT(contextCopy())),
+ it);
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_PASTE)),
+ __tr2qs("&Paste Below"),this,SLOT(contextPasteBelow())),
+ m_pClipboard);
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_PASTE)),
+ __tr2qs("Paste Above"),this,SLOT(contextPasteAbove())),
+ it && m_pClipboard);
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_PASTE)),
+ __tr2qs("Paste Inside"),this,SLOT(contextPasteInside())),
+ it && bIsMenu && m_pClipboard);
+
+
+ bool bSeparatorInserted = false;
+
+// if(!findPrologue(parentMenu))
+// {
+ m_pContextPopup->insertSeparator();
+ bSeparatorInserted = true;
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_PROLOGUE)),
+ __tr2qs("New Menu Prologue"),this,SLOT(contextNewPrologue()));
+// }
+
+// if(!findEpilogue(parentMenu))
+// {
+ if(!bSeparatorInserted)m_pContextPopup->insertSeparator();
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_EPILOGUE)),
+ __tr2qs("New Menu Epilogue"),this,SLOT(contextNewEpilogue()));
+// }
+
+ m_pContextPopup->popup(pnt);
+}
+
+void KviSinglePopupEditor::createNewItemAboveLastSelected(KviPopupListViewItem::Type t)
+{
+ m_pListView->setCurrentItem(newItemAbove(m_pLastSelectedItem,t));
+}
+
+void KviSinglePopupEditor::createNewItemBelowLastSelected(KviPopupListViewItem::Type t)
+{
+ m_pListView->setCurrentItem(newItemBelow(m_pLastSelectedItem,t));
+}
+
+void KviSinglePopupEditor::createNewItemInsideLastSelected(KviPopupListViewItem::Type t)
+{
+ if(m_pLastSelectedItem)m_pLastSelectedItem->setOpen(true);
+ m_pListView->setCurrentItem(newItemInside(m_pLastSelectedItem,t));
+}
+
+void KviSinglePopupEditor::contextNewSeparatorAbove()
+{
+ createNewItemAboveLastSelected(KviPopupListViewItem::Separator);
+}
+
+void KviSinglePopupEditor::contextNewSeparatorBelow()
+{
+ createNewItemBelowLastSelected(KviPopupListViewItem::Separator);
+}
+
+void KviSinglePopupEditor::contextNewSeparatorInside()
+{
+ createNewItemInsideLastSelected(KviPopupListViewItem::Separator);
+}
+
+void KviSinglePopupEditor::contextNewItemBelow()
+{
+ createNewItemBelowLastSelected(KviPopupListViewItem::Item);
+}
+
+void KviSinglePopupEditor::contextNewItemAbove()
+{
+ createNewItemAboveLastSelected(KviPopupListViewItem::Item);
+}
+
+void KviSinglePopupEditor::contextNewItemInside()
+{
+ createNewItemInsideLastSelected(KviPopupListViewItem::Item);
+}
+
+void KviSinglePopupEditor::contextNewMenuBelow()
+{
+ createNewItemBelowLastSelected(KviPopupListViewItem::Menu);
+}
+
+void KviSinglePopupEditor::contextNewMenuAbove()
+{
+ createNewItemAboveLastSelected(KviPopupListViewItem::Menu);
+}
+
+void KviSinglePopupEditor::contextNewMenuInside()
+{
+ createNewItemInsideLastSelected(KviPopupListViewItem::Menu);
+}
+
+void KviSinglePopupEditor::contextNewExtMenuBelow()
+{
+ createNewItemBelowLastSelected(KviPopupListViewItem::ExtMenu);
+}
+
+void KviSinglePopupEditor::contextNewExtMenuAbove()
+{
+ createNewItemAboveLastSelected(KviPopupListViewItem::ExtMenu);
+}
+void KviSinglePopupEditor::contextNewExtMenuInside()
+{
+ createNewItemInsideLastSelected(KviPopupListViewItem::ExtMenu);
+}
+
+
+void KviSinglePopupEditor::contextNewLabelBelow()
+{
+ createNewItemBelowLastSelected(KviPopupListViewItem::Label);
+}
+
+void KviSinglePopupEditor::contextNewLabelAbove()
+{
+ createNewItemAboveLastSelected(KviPopupListViewItem::Label);
+}
+
+void KviSinglePopupEditor::contextNewLabelInside()
+{
+ createNewItemInsideLastSelected(KviPopupListViewItem::Label);
+}
+
+KviPopupListViewItem * KviSinglePopupEditor::newItem(KviPopupListViewItem * par,KviPopupListViewItem * after,KviPopupListViewItem::Type t)
+{
+ if(par)return new KviPopupListViewItem(par,after,t);
+ return new KviPopupListViewItem(m_pListView,after,t);
+}
+
+KviPopupListViewItem * KviSinglePopupEditor::newItemBelow(KviPopupListViewItem * it,KviPopupListViewItem::Type t)
+{
+ if(!it)return newItem(0,0,t);
+ return newItem((KviPopupListViewItem *)it->parent(),it,t);
+}
+
+KviPopupListViewItem * KviSinglePopupEditor::newItemAbove(KviPopupListViewItem * it,KviPopupListViewItem::Type t)
+{
+ if(!it)return newItem(0,0,t);
+ return newItem((KviPopupListViewItem *)it->parent(),(KviPopupListViewItem *)it->itemAbove(),t);
+}
+
+KviPopupListViewItem * KviSinglePopupEditor::newItemInside(KviPopupListViewItem * it,KviPopupListViewItem::Type t)
+{
+ if(it)
+ {
+ if(it->m_type != KviPopupListViewItem::Menu)
+ {
+ return newItemBelow(it,t);
+ }
+ }
+ return newItem(it,it,t);
+}
+
+void KviSinglePopupEditor::contextNewPrologue()
+{
+ KviPopupListViewItem * it = m_pLastSelectedItem ? (KviPopupListViewItem *)m_pLastSelectedItem->parent() : 0;
+// if(!findPrologue(it))
+// {
+ m_pListView->setCurrentItem(newItem(it,it,KviPopupListViewItem::Prologue));
+// }
+}
+
+void KviSinglePopupEditor::contextNewEpilogue()
+{
+ KviPopupListViewItem * it = m_pLastSelectedItem ? (KviPopupListViewItem *)m_pLastSelectedItem->parent() : 0;
+// if(!findEpilogue(it))
+// {
+ KviPopupListViewItem * after = it ? (KviPopupListViewItem *)it->firstChild() : (KviPopupListViewItem *)m_pListView->firstChild();
+ if(after)
+ {
+ while(after->nextSibling())after = (KviPopupListViewItem *)after->nextSibling();
+ } else {
+ after = it;
+ }
+ m_pListView->setCurrentItem(newItem(it,after,KviPopupListViewItem::Epilogue));
+// }
+}
+
+void KviSinglePopupEditor::contextCopy()
+{
+ if(!m_pLastSelectedItem)return;
+ if(m_pClipboard)delete m_pClipboard;
+ m_pClipboard = new KviKvsPopupMenu("clipboard");
+ addItemToMenu(m_pClipboard,m_pLastSelectedItem);
+}
+
+void KviSinglePopupEditor::contextCut()
+{
+ if(!m_pLastSelectedItem)return;
+ contextCopy();
+
+ KviPopupListViewItem * it = m_pLastSelectedItem;
+ m_pLastSelectedItem = 0;
+ delete it;
+ if(!m_pLastSelectedItem)selectionChanged(0);
+}
+
+
+void KviSinglePopupEditor::contextPasteBelow()
+{
+ if(!m_pClipboard)return;
+ KviPopupListViewItem * par = m_pLastSelectedItem ? (KviPopupListViewItem *)m_pLastSelectedItem->parent() : 0;
+ populateMenu(m_pClipboard,par,m_pLastSelectedItem);
+}
+
+void KviSinglePopupEditor::contextPasteAbove()
+{
+ if(!m_pClipboard)return;
+ KviPopupListViewItem * par = m_pLastSelectedItem ? (KviPopupListViewItem *)m_pLastSelectedItem->parent() : 0;
+ KviPopupListViewItem * above = m_pLastSelectedItem ? (KviPopupListViewItem *)m_pLastSelectedItem->itemAbove() : 0;
+ populateMenu(m_pClipboard,par,above);
+
+}
+
+void KviSinglePopupEditor::contextPasteInside()
+{
+ if(!m_pClipboard)return;
+ if(m_pLastSelectedItem)
+ {
+ if(m_pLastSelectedItem->m_type != KviPopupListViewItem::Menu)
+ {
+ contextPasteBelow();
+ return;
+ }
+ m_pLastSelectedItem->setOpen(true);
+ }
+ populateMenu(m_pClipboard,m_pLastSelectedItem,0);
+}
+
+void KviSinglePopupEditor::saveLastSelectedItem()
+{
+ if(!m_pLastSelectedItem)return;
+
+ QString tmp;
+
+ switch(m_pLastSelectedItem->m_type)
+ {
+ case KviPopupListViewItem::Prologue:
+ case KviPopupListViewItem::Epilogue:
+ case KviPopupListViewItem::Item:
+ {
+ QString tmpx;
+ m_pEditor->getText(tmpx);
+ m_pLastSelectedItem->setCode(tmpx);
+ }
+ break;
+ default:
+ break;
+ }
+
+ m_pLastSelectedItem->setId(m_pIdEditor->text());
+
+ switch(m_pLastSelectedItem->m_type)
+ {
+ case KviPopupListViewItem::Menu:
+ case KviPopupListViewItem::ExtMenu:
+ case KviPopupListViewItem::Item:
+ m_pLastSelectedItem->setIcon(m_pIconEditor->text());
+ break;
+ default:
+ break;
+ }
+
+ switch(m_pLastSelectedItem->m_type)
+ {
+ case KviPopupListViewItem::Menu:
+ case KviPopupListViewItem::Item:
+ case KviPopupListViewItem::Label:
+ case KviPopupListViewItem::ExtMenu:
+ m_pLastSelectedItem->setItemText(m_pTextEditor->text());
+ m_pLastSelectedItem->setCondition(m_pConditionEditor->text());
+ break;
+ default:
+ break;
+ }
+
+ if(m_pLastSelectedItem->m_type == KviPopupListViewItem::ExtMenu)
+ {
+ m_pLastSelectedItem->setCode(m_pExtNameEditor->text());
+ }
+}
+
+void KviSinglePopupEditor::addItemToMenu(KviKvsPopupMenu * p,KviPopupListViewItem *it)
+{
+ it->m_szId.stripWhiteSpace();
+ switch(it->m_type)
+ {
+ case KviPopupListViewItem::Prologue:
+ it->m_szCode.stripWhiteSpace();
+ p->addPrologue(it->m_szId,it->m_szCode);
+ break;
+ case KviPopupListViewItem::Epilogue:
+ it->m_szCode.stripWhiteSpace();
+ p->addEpilogue(it->m_szId,it->m_szCode);
+ break;
+ case KviPopupListViewItem::Separator:
+ it->m_szCondition.stripWhiteSpace();
+ p->addSeparator(it->m_szId,it->m_szCondition);
+ break;
+ case KviPopupListViewItem::Label:
+ it->m_szText.stripWhiteSpace();
+ it->m_szCondition.stripWhiteSpace();
+ it->m_szIcon.stripWhiteSpace();
+ p->addLabel(it->m_szId,it->m_szText,it->m_szIcon,it->m_szCondition);
+ break;
+ case KviPopupListViewItem::Item:
+ it->m_szText.stripWhiteSpace();
+ it->m_szIcon.stripWhiteSpace();
+ it->m_szCondition.stripWhiteSpace();
+ it->m_szCode.stripWhiteSpace();
+ p->addItem(it->m_szId,it->m_szCode,it->m_szText,it->m_szIcon,it->m_szCondition);
+ break;
+ case KviPopupListViewItem::ExtMenu:
+ it->m_szText.stripWhiteSpace();
+ it->m_szIcon.stripWhiteSpace();
+ it->m_szCondition.stripWhiteSpace();
+ it->m_szCode.stripWhiteSpace();// <-- this is the ext name in fact
+ p->addExtPopup(it->m_szId,it->m_szCode,it->m_szText,it->m_szIcon,it->m_szCondition);
+ break;
+ case KviPopupListViewItem::Menu:
+ {
+ it->m_szText.stripWhiteSpace();
+ it->m_szIcon.stripWhiteSpace();
+ it->m_szCondition.stripWhiteSpace();
+ KviKvsPopupMenu * menu = p->addPopup(it->m_szId,it->m_szText,it->m_szIcon,it->m_szCondition);
+ for(KviPopupListViewItem * item = (KviPopupListViewItem *)it->firstChild();item;item = (KviPopupListViewItem *)item->nextSibling())
+ {
+ addItemToMenu(menu,item);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+KviKvsPopupMenu * KviSinglePopupEditor::getMenu()
+{
+ saveLastSelectedItem();
+
+ QString tmp = m_pNameEditor->text();
+ tmp.stripWhiteSpace();
+
+ KviKvsPopupMenu * p = new KviKvsPopupMenu(tmp);
+ for(KviPopupListViewItem * it = (KviPopupListViewItem *)m_pListView->firstChild();it;it = (KviPopupListViewItem *)it->nextSibling())
+ {
+ addItemToMenu(p,it);
+ }
+ return p;
+}
+
+void KviSinglePopupEditor::selectionChanged(KviTalListViewItem * it)
+{
+ saveLastSelectedItem();
+
+ bool bEditorEnabled = false;
+ bool bIconEditorEnabled = false;
+ bool bConditionEditorEnabled = false;
+ bool bTextEditorEnabled = false;
+ bool bNameEditorEnabled = false;
+
+ if(it)
+ {
+ m_pIdEditor->setText(((KviPopupListViewItem *)it)->m_szId);
+
+ switch(((KviPopupListViewItem *)it)->m_type)
+ {
+ case KviPopupListViewItem::Prologue:
+ case KviPopupListViewItem::Epilogue:
+ case KviPopupListViewItem::Item:
+ m_pEditor->setText(((KviPopupListViewItem *)it)->m_szCode);
+ bEditorEnabled = true;
+ break;
+ default:
+ break;
+ }
+
+ switch(((KviPopupListViewItem *)it)->m_type)
+ {
+ case KviPopupListViewItem::Menu:
+ case KviPopupListViewItem::Item:
+ case KviPopupListViewItem::Label:
+ case KviPopupListViewItem::ExtMenu:
+ m_pIconEditor->setText(((KviPopupListViewItem *)it)->m_szIcon);
+ bIconEditorEnabled = true;
+ break;
+ default:
+ break; }
+
+ switch(((KviPopupListViewItem *)it)->m_type)
+ {
+ case KviPopupListViewItem::Menu:
+ case KviPopupListViewItem::Item:
+ case KviPopupListViewItem::Label:
+ case KviPopupListViewItem::ExtMenu:
+ m_pConditionEditor->setText(((KviPopupListViewItem *)it)->m_szCondition);
+ bConditionEditorEnabled = true;
+ m_pTextEditor->setText(((KviPopupListViewItem *)it)->m_szText);
+ bTextEditorEnabled = true;
+ break;
+ default:
+ break;
+ }
+
+ if(((KviPopupListViewItem *)it)->m_type == KviPopupListViewItem::ExtMenu)
+ {
+ m_pExtNameEditor->setText(((KviPopupListViewItem *)it)->m_szCode);
+ bNameEditorEnabled =true;
+ }
+ }
+
+ m_pLastSelectedItem = (KviPopupListViewItem *)it;
+
+ if(!bEditorEnabled)m_pEditor->setText("");
+ m_pEditor->setEnabled(bEditorEnabled);
+ if(!bIconEditorEnabled)m_pIconEditor->setText("");
+ m_pIconEditor->setEnabled(bIconEditorEnabled);
+ if(!bConditionEditorEnabled)m_pConditionEditor->setText("");
+ m_pConditionEditor->setEnabled(bConditionEditorEnabled);
+ if(!bTextEditorEnabled)m_pTextEditor->setText("");
+ m_pTextEditor->setEnabled(bTextEditorEnabled);
+ m_pExtNameEditor->setEnabled(bNameEditorEnabled);
+ if(!bNameEditorEnabled)m_pExtNameEditor->setText("");
+ if(!it)m_pIdEditor->setText("");
+ m_pIdEditor->setEnabled(it);
+}
+
+void KviSinglePopupEditor::populateMenu(KviKvsPopupMenu * pop,KviPopupListViewItem * par,KviPopupListViewItem * theItem)
+{
+ if(!pop)return;
+
+ for(KviKvsScript * sp = pop->prologues()->first();sp;sp = pop->prologues()->next())
+ {
+ if(par)theItem = new KviPopupListViewItem(par,theItem,KviPopupListViewItem::Prologue);
+ else theItem = new KviPopupListViewItem(m_pListView,theItem,KviPopupListViewItem::Prologue);
+ theItem->setCode(sp->code());
+ theItem->setId(sp->name());
+ }
+
+ for(KviKvsPopupMenuItem * item = pop->m_pItemList->first();item;item = pop->m_pItemList->next())
+ {
+ switch(item->type())
+ {
+ case KviKvsPopupMenuItem::Item:
+ if(par)theItem = new KviPopupListViewItem(par,theItem,KviPopupListViewItem::Item);
+ else theItem = new KviPopupListViewItem(m_pListView,theItem,KviPopupListViewItem::Item);
+ theItem->setIcon(item->kvsIcon() ? item->kvsIcon()->code() : QString::null);
+ theItem->setItemText(item->kvsText() ? item->kvsText()->code() : QString::null);
+ theItem->setCondition(item->kvsCondition() ? item->kvsCondition()->code() : QString::null);
+ theItem->setCode(item->kvsCode() ? item->kvsCode()->code() : QString::null);
+ theItem->setId(item->name());
+ break;
+ case KviKvsPopupMenuItem::ExtMenu:
+ if(par)theItem = new KviPopupListViewItem(par,theItem,KviPopupListViewItem::ExtMenu);
+ else theItem = new KviPopupListViewItem(m_pListView,theItem,KviPopupListViewItem::ExtMenu);
+ theItem->setIcon(item->kvsIcon() ? item->kvsIcon()->code() : QString::null);
+ theItem->setItemText(item->kvsText() ? item->kvsText()->code() : QString::null);
+ theItem->setCondition(item->kvsCondition() ? item->kvsCondition()->code() : QString::null);
+ theItem->setCode(((KviKvsPopupMenuItemExtMenu *)item)->extName());
+ theItem->setId(item->name());
+ break;
+ case KviKvsPopupMenuItem::Label:
+ if(par)theItem = new KviPopupListViewItem(par,theItem,KviPopupListViewItem::Label);
+ else theItem = new KviPopupListViewItem(m_pListView,theItem,KviPopupListViewItem::Label);
+ theItem->setIcon(item->kvsIcon() ? item->kvsIcon()->code() : QString::null);
+ theItem->setItemText(item->kvsText() ? item->kvsText()->code() : QString::null);
+ theItem->setCondition(item->kvsCondition() ? item->kvsCondition()->code() : QString::null);
+ theItem->setId(item->name());
+ break;
+ case KviKvsPopupMenuItem::Separator:
+ if(par)theItem = new KviPopupListViewItem(par,theItem,KviPopupListViewItem::Separator);
+ else theItem = new KviPopupListViewItem(m_pListView,theItem,KviPopupListViewItem::Separator);
+ theItem->setId(item->name());
+ break;
+ case KviKvsPopupMenuItem::Menu:
+ if(par)theItem = new KviPopupListViewItem(par,theItem,KviPopupListViewItem::Menu);
+ else theItem = new KviPopupListViewItem(m_pListView,theItem,KviPopupListViewItem::Menu);
+ theItem->setIcon(item->kvsIcon() ? item->kvsIcon()->code() : QString::null);
+ theItem->setItemText(item->kvsText() ? item->kvsText()->code() : QString::null);
+ theItem->setCondition(item->kvsCondition() ? item->kvsCondition()->code() : QString::null);
+ theItem->setId(item->name());
+ populateMenu(((KviKvsPopupMenuItemMenu *)item)->menu(),theItem,0);
+ break;
+ default:
+ break;
+ }
+ }
+
+ for(KviKvsScript * se = pop->epilogues()->first();se;se = pop->epilogues()->next())
+ {
+ if(par)theItem = new KviPopupListViewItem(par,theItem,KviPopupListViewItem::Epilogue);
+ else theItem = new KviPopupListViewItem(m_pListView,theItem,KviPopupListViewItem::Epilogue);
+ theItem->setCode(se->code());
+ theItem->setId(se->name());
+ }
+}
+
+
+
+void KviSinglePopupEditor::edit(KviMenuListViewItem * it)
+{
+ saveLastSelectedItem();
+
+ m_pLastSelectedItem = 0;
+
+ m_pListView->clear();
+
+ selectionChanged(0);
+
+ if(it)
+ {
+ m_pNameEditor->setText(it->m_pPopup->popupName());
+
+ populateMenu(it->m_pPopup,0,0);
+
+ } else {
+ m_pIconEditor->setText("");
+ m_pIconEditor->setEnabled(false);
+ m_pIdEditor->setText("");
+ m_pIdEditor->setEnabled(false);
+ m_pConditionEditor->setText("");
+ m_pConditionEditor->setEnabled(false);
+ m_pTextEditor->setText("");
+ m_pTextEditor->setEnabled(false);
+ m_pEditor->setText("");
+ m_pEditor->setEnabled(false);
+ m_pNameEditor->setText("");
+ m_pExtNameEditor->setText("");
+ m_pExtNameEditor->setEnabled(false);
+ }
+ m_pListView->setEnabled(it);
+ m_pNameEditor->setEnabled(it);
+ m_pMenuButton->setEnabled(it);
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+KviMenuListViewItem::KviMenuListViewItem(KviTalListView * par,KviKvsPopupMenu * popup)
+: KviTalListViewItem(par)
+{
+ setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_POPUP)));
+ setText(0,popup->name());
+ m_pPopup = popup;
+}
+
+KviMenuListViewItem::~KviMenuListViewItem()
+{
+ delete m_pPopup;
+}
+
+void KviMenuListViewItem::replacePopup(KviKvsPopupMenu * popup)
+{
+ delete m_pPopup;
+ m_pPopup = popup;
+}
+
+
+KviPopupEditor::KviPopupEditor(QWidget * par)
+: QWidget(par)
+{
+ QGridLayout * l = new QGridLayout(this,1,1,0,2);
+#ifdef COMPILE_USE_QT4
+ QSplitter * spl = new QSplitter(Qt::Horizontal,this,"popupeditor");
+ spl->setOpaqueResize(false);
+#else
+ QSplitter * spl = new QSplitter(QSplitter::Horizontal,this);
+#endif
+ l->addWidget(spl,0,0);
+
+ KviTalVBox * box = new KviTalVBox(spl);
+
+ m_pListView = new KviTalListView(box);
+ m_pListView->addColumn(__tr2qs("Popup"));
+ m_pListView->setSelectionMode(KviTalListView::Extended);
+ m_pListView->setShowSortIndicator(true);
+
+ QPushButton * pb = new QPushButton(__tr2qs("&Export All To..."),box);
+ connect(pb,SIGNAL(clicked()),this,SLOT(exportAll()));
+ QPushButton * gn = new QPushButton(__tr2qs("&Export selected To..."),box);
+ connect(gn,SIGNAL(clicked()),this,SLOT(exportSelected()));
+
+ m_pEditor = new KviSinglePopupEditor(spl);
+
+ m_bOneTimeSetupDone = false;
+ m_pLastEditedItem = 0;
+
+ m_pContextPopup = new KviTalPopupMenu(this);
+
+ currentItemChanged(0);
+}
+
+KviPopupEditor::~KviPopupEditor()
+{
+}
+
+void KviPopupEditor::oneTimeSetup()
+{
+ if(m_bOneTimeSetupDone)return;
+ m_bOneTimeSetupDone = true;
+
+ const KviPointerHashTable<QString,KviKvsPopupMenu> * a = KviKvsPopupManager::instance()->popupDict();
+ if(!a)return;
+
+ KviPointerHashTableIterator<QString,KviKvsPopupMenu> it(*a);
+
+ KviMenuListViewItem * item;
+
+ while(it.current())
+ {
+ KviKvsPopupMenu * popup = it.current();
+ KviKvsPopupMenu * copy = new KviKvsPopupMenu(popup->popupName());
+ copy->copyFrom(popup);
+ item = new KviMenuListViewItem(m_pListView,copy);
+ ++it;
+ }
+
+ connect(m_pListView,SIGNAL(currentChanged(KviTalListViewItem *)),this,SLOT(currentItemChanged(KviTalListViewItem *)));
+ connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),
+ this,SLOT(itemPressed(KviTalListViewItem *,const QPoint &,int)));
+
+}
+
+void KviPopupEditor::itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ __range_valid(m_bOneTimeSetupDone);
+ m_pContextPopup->clear();
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_POPUP)),
+ __tr2qs("&New Popup"),
+ this,SLOT(newPopup()));
+
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),
+ __tr2qs("Re&move Popup"),
+ this,SLOT(removeCurrentPopup())),
+ it);
+
+ m_pContextPopup->setItemEnabled(
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)),
+ __tr2qs("&Export Popup To..."),
+ this,SLOT(exportCurrentPopup())),
+ it);
+
+ m_pContextPopup->popup(pnt);
+}
+
+
+void KviPopupEditor::exportCurrentPopup()
+{
+ if(!m_pLastEditedItem)return;
+ saveLastEditedItem();
+ if(!m_pLastEditedItem)return;
+
+ QString szName = QDir::homeDirPath();
+ if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR;
+ szName += m_pLastEditedItem->popup()->name();
+ szName += ".kvs";
+
+ QString szFile;
+
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose a Filename - KVIrc"),szName,"*.kvs",true,true,true))return;
+
+ QString szOut;
+ m_pLastEditedItem->popup()->generateDefPopup(szOut);
+
+ if(!KviFileUtils::writeFile(szFile,szOut))
+ {
+ QMessageBox::warning(this,__tr2qs("Write Failed - KVIrc"),__tr2qs("Unable to write to the popup file."),__tr2qs("Ok"));
+ }
+}
+
+void KviPopupEditor::exportAll()
+{
+ bool bSelectedOnly=true;
+ exportPopups(bSelectedOnly);
+}
+
+void KviPopupEditor::exportSelected()
+{
+ bool bSelectedOnly=false;
+ exportPopups(bSelectedOnly);
+}
+
+void KviPopupEditor::exportPopups(bool bSelectedOnly)
+{
+ saveLastEditedItem();
+
+ KviMenuListViewItem * it = (KviMenuListViewItem *)m_pListView->firstChild();
+
+ QString out;
+
+ int count=0;
+ KviTalListViewItemIterator itv( m_pListView );
+ while( itv.current() )
+ {
+ if ( (itv.current()->isSelected()) || (bSelectedOnly == true) )
+ {
+ count ++;
+ QString tmp;
+ it->popup()->generateDefPopup(tmp);
+ out += tmp;
+ out += "\n";
+ }
+ it = (KviMenuListViewItem *)it->nextSibling();
+ ++itv;
+ }
+ if (!count && bSelectedOnly==false) return;
+
+ QString szName = QDir::homeDirPath();
+ if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR;
+ szName += "popups.kvs";
+
+ QString szFile;
+
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose a Filename - KVIrc"),szName,"*.kvs",true,true,true))return;
+
+ if(!KviFileUtils::writeFile(szFile,out))
+ {
+ QMessageBox::warning(this,__tr2qs("Write Failed - KVIrc"),__tr2qs("Unable to write to the alias file."),__tr2qs("Ok"));
+ }
+}
+
+
+void KviPopupEditor::removeCurrentPopup()
+{
+ if(m_pLastEditedItem)
+ {
+ KviMenuListViewItem * it = m_pLastEditedItem;
+ m_pLastEditedItem = 0;
+ delete it;
+ if(!m_pLastEditedItem)currentItemChanged(0);
+ }
+}
+
+void KviPopupEditor::newPopup()
+{
+ QString newName;
+ getUniquePopupName(0,newName);
+ KviMenuListViewItem * it = new KviMenuListViewItem(m_pListView,new KviKvsPopupMenu(newName));
+ m_pListView->setCurrentItem(it);
+}
+
+void KviPopupEditor::saveLastEditedItem()
+{
+ if(m_pLastEditedItem == 0)return;
+
+ KviKvsPopupMenu * m = m_pEditor->getMenu();
+ QString tmp = m->popupName();
+ QString old = m_pLastEditedItem->m_pPopup->popupName();
+ if(!KviQString::equalCI(tmp,old))
+ {
+ getUniquePopupName(m_pLastEditedItem,tmp);
+ m->setPopupName(tmp);
+ }
+
+ m_pLastEditedItem->replacePopup(m);
+ m_pLastEditedItem->setText(0,m->popupName());
+}
+
+void KviPopupEditor::currentItemChanged(KviTalListViewItem *it)
+{
+ saveLastEditedItem();
+
+ m_pLastEditedItem = (KviMenuListViewItem *)it;
+
+ m_pEditor->edit(m_pLastEditedItem);
+}
+
+void KviPopupEditor::showEvent(QShowEvent *e)
+{
+ oneTimeSetup();
+ QWidget::showEvent(e);
+}
+
+void KviPopupEditor::commit()
+{
+ if(!m_bOneTimeSetupDone)return;
+
+ saveLastEditedItem();
+
+ //KviKvsPopupManager::instance()->clear();
+
+ KviMenuListViewItem * it = (KviMenuListViewItem *)m_pListView->firstChild();
+
+ // Copy the original popup dict
+ KviPointerHashTable<QString,KviKvsPopupMenu> copy(*(KviKvsPopupManager::instance()->popupDict()));
+ copy.setAutoDelete(false);
+
+ while(it)
+ {
+ KviKvsPopupMenu * p = KviKvsPopupManager::instance()->get(it->m_pPopup->popupName());
+ p->doClear();
+ p->copyFrom(it->m_pPopup);
+ it = (KviMenuListViewItem *)it->nextSibling();
+ // remove it from the original copy
+ copy.remove(p->popupName());
+ }
+
+ // the remaining elements in the copy need to be removed from
+ // the "new" dictionary (they are no longer used)
+ KviPointerHashTableIterator<QString,KviKvsPopupMenu> iter(copy);
+
+ while(iter.current())
+ {
+ KviKvsPopupManager::instance()->remove(iter.currentKey());
+ ++iter;
+ }
+
+
+ g_pApp->savePopups();
+}
+
+
+void KviPopupEditor::getUniquePopupName(KviMenuListViewItem *item,QString &buffer)
+{
+ __range_valid(m_bOneTimeSetupDone);
+
+ if(buffer.isEmpty())buffer = __tr2qs("unnamed");
+ QString newName = buffer;
+
+ bool bFound = true;
+ int idx = 1;
+
+ while(bFound)
+ {
+ bFound = false;
+
+ for(KviMenuListViewItem * ch = (KviMenuListViewItem *)(m_pListView->firstChild());ch;ch = (KviMenuListViewItem *)ch->nextSibling())
+ {
+ if(KviQString::equalCI(newName,ch->m_pPopup->popupName()) && (ch != item))
+ {
+ bFound = true;
+ KviQString::sprintf(newName,"%Q.%d",&buffer,idx);
+ idx++;
+ break;
+ }
+ }
+
+ }
+
+ buffer = newName;
+}
+
+
+
+KviPopupEditorWindow::KviPopupEditorWindow(KviFrame * lpFrm)
+: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"popupeditor",0)
+{
+ g_pPopupEditorWindow = this;
+
+ m_pEditor = new KviPopupEditor(this);
+
+ m_pBase = new QWidget(this);
+ QGridLayout * g = new QGridLayout(m_pBase,1,4,4,4);
+
+ QPushButton * btn = new QPushButton(__tr2qs("&OK"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(okClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,1);
+
+ btn = new QPushButton(__tr2qs("&Apply"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,2);
+
+ btn = new QPushButton(__tr2qs("Cancel"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ g->addWidget(btn,0,3);
+
+ g->setColStretch(0,1);
+}
+
+KviPopupEditorWindow::~KviPopupEditorWindow()
+{
+ g_pPopupEditorWindow = 0;
+}
+
+void KviPopupEditorWindow::okClicked()
+{
+ m_pEditor->commit();
+ close();
+}
+
+void KviPopupEditorWindow::applyClicked()
+{
+ m_pEditor->commit();
+}
+
+void KviPopupEditorWindow::cancelClicked()
+{
+ close();
+}
+
+
+QPixmap * KviPopupEditorWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_POPUP);
+}
+
+void KviPopupEditorWindow::resizeEvent(QResizeEvent *e)
+{
+ int hght = m_pBase->sizeHint().height();
+ m_pEditor->setGeometry(0,0,width(),height()- hght);
+ m_pBase->setGeometry(0,height() - hght,width(),hght);
+}
+
+void KviPopupEditorWindow::fillCaptionBuffers()
+{
+ m_szPlainTextCaption = __tr2qs("Popup Editor");
+
+ static QString p1("<nobr><font color=\"");
+ static QString p2("\"><b>");
+ static QString p3("</b></font></nobr>");
+
+ m_szHtmlActiveCaption = p1;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += p2;
+ m_szHtmlActiveCaption += m_szPlainTextCaption;
+ m_szHtmlActiveCaption += p3;
+
+ m_szHtmlInactiveCaption = p1;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += p2;
+ m_szHtmlInactiveCaption += m_szPlainTextCaption;
+ m_szHtmlInactiveCaption += p3;
+
+}
+
+
+void KviPopupEditorWindow::getConfigGroupName(KviStr &szName)
+{
+ szName = "popupeditor";
+}
+
+
+void KviPopupEditorWindow::saveProperties(KviConfig *cfg)
+{
+/*
+#ifdef COMPILE_SCRIPTTOOLBAR
+ cfg->writeEntry("Sizes",m_pEditor->sizes());
+ cfg->writeEntry("LastPopup",m_pEditor->lastEditedPopup().ptr());
+ //debug("LAST EDITED=%s",m_pEditor->lastEditedPopup().ptr());
+#endif // COMPILE_SCRIPTTOOLBAR
+*/
+}
+
+void KviPopupEditorWindow::loadProperties(KviConfig *cfg)
+{
+/*
+#ifdef COMPILE_SCRIPTTOOLBAR
+ QValueList<int> def;
+ def.append(20);
+ def.append(80);
+ m_pEditor->setSizes(cfg->readIntListEntry("Sizes",def));
+ KviStr tmp = cfg->readEntry("LastPopup","");
+ m_pEditor->editPopup(tmp);
+ //debug("LAST EDITED WAS %s",tmp.ptr());
+#endif // COMPILE_SCRIPTTOOLBAR
+*/
+}
diff --git a/src/modules/popupeditor/popupeditor.h b/src/modules/popupeditor/popupeditor.h
new file mode 100644
index 00000000..3560ffa7
--- /dev/null
+++ b/src/modules/popupeditor/popupeditor.h
@@ -0,0 +1,206 @@
+#ifndef _POPUPEDITOR_H_
+#define _POPUPEDITOR_H_
+//
+// File : popupeditor.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 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 "kvi_window.h"
+#include "kvi_string.h"
+
+
+#include <qwidget.h>
+#include "kvi_tal_listview.h"
+#include <qlineedit.h>
+#include "kvi_tal_popupmenu.h"
+#include <qpushbutton.h>
+
+class KviKvsPopupMenu;
+class KviKvsPopupMenuItem;
+
+// KviPopupListViewItem
+class KviPopupListViewItem : public KviTalListViewItem
+{
+public:
+ enum Type { Item , Menu , Separator , Label , Epilogue , Prologue , ExtMenu };
+public:
+ KviPopupListViewItem(KviTalListView * pListView,KviPopupListViewItem * after,Type t);
+ KviPopupListViewItem(KviPopupListViewItem * parent,KviPopupListViewItem * after,Type t);
+public:
+ Type m_type;
+ QString m_szText;
+ QString m_szCondition;
+ QString m_szIcon;
+ QString m_szCode;
+ QString m_szId;
+private:
+ void init();
+public:
+ void setItemText(const QString & szText);
+ void setCondition(const QString & szCondition);
+ void setIcon(const QString & szIcon);
+ void setCode(const QString & szCode);
+ void setId(const QString & szId);
+};
+
+
+
+class KviScriptEditor;
+
+class KviMenuListViewItem;
+
+class KviSinglePopupEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ KviSinglePopupEditor(QWidget * par);
+ ~KviSinglePopupEditor();
+protected:
+ QPushButton * m_pMenuButton;
+ KviKvsPopupMenu * m_pClipboard;
+ KviKvsPopupMenu * m_pTestPopup;
+ KviPopupListViewItem * m_pLastSelectedItem;
+ KviTalListView * m_pListView;
+ QLineEdit * m_pNameEditor;
+ KviScriptEditor * m_pEditor;
+ QLineEdit * m_pTextEditor;
+ QLineEdit * m_pIdEditor;
+ QLineEdit * m_pIconEditor;
+ QLineEdit * m_pConditionEditor;
+ QLineEdit * m_pExtNameEditor;
+ KviTalPopupMenu * m_pContextPopup;
+public:
+ void edit(KviMenuListViewItem * it);
+ KviKvsPopupMenu * getMenu();
+protected:
+ // theItem is the item above the first item that has to be inserted
+ void populateMenu(KviKvsPopupMenu * pop,KviPopupListViewItem * par,KviPopupListViewItem * theItem = 0);
+ void saveLastSelectedItem();
+ void addItemToMenu(KviKvsPopupMenu * pop,KviPopupListViewItem * par);
+ KviPopupListViewItem * newItem(KviPopupListViewItem * par,KviPopupListViewItem * after,KviPopupListViewItem::Type t);
+ KviPopupListViewItem * newItemBelow(KviPopupListViewItem * it,KviPopupListViewItem::Type t);
+ KviPopupListViewItem * newItemAbove(KviPopupListViewItem * it,KviPopupListViewItem::Type t);
+ KviPopupListViewItem * newItemInside(KviPopupListViewItem * it,KviPopupListViewItem::Type t);
+ void createNewItemAboveLastSelected(KviPopupListViewItem::Type t);
+ void createNewItemBelowLastSelected(KviPopupListViewItem::Type t);
+ void createNewItemInsideLastSelected(KviPopupListViewItem::Type t);
+ KviPopupListViewItem * findMatchingItem(KviKvsPopupMenuItem * it,KviPopupListViewItem * item);
+protected slots:
+ void contextCut();
+ void contextCopy();
+ void contextPasteBelow();
+ void contextPasteAbove();
+ void contextPasteInside();
+ void contextNewSeparatorBelow();
+ void contextNewSeparatorAbove();
+ void contextNewSeparatorInside();
+ void contextNewItemBelow();
+ void contextNewItemAbove();
+ void contextNewItemInside();
+ void contextNewMenuBelow();
+ void contextNewMenuAbove();
+ void contextNewMenuInside();
+ void contextNewExtMenuBelow();
+ void contextNewExtMenuAbove();
+ void contextNewExtMenuInside();
+ void contextNewLabelBelow();
+ void contextNewLabelAbove();
+ void contextNewLabelInside();
+ void contextNewPrologue();
+ void contextNewEpilogue();
+ void selectionChanged(KviTalListViewItem * it);
+ void itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col);
+ void testPopup();
+ void testModeMenuItemClicked(KviKvsPopupMenuItem * it);
+};
+
+
+
+class KviMenuListViewItem : public KviTalListViewItem
+{
+public:
+ KviMenuListViewItem(KviTalListView * par,KviKvsPopupMenu * popup);
+ ~KviMenuListViewItem();
+public:
+ KviKvsPopupMenu * m_pPopup;
+public:
+ KviKvsPopupMenu * popup(){ return m_pPopup; };
+public:
+ void replacePopup(KviKvsPopupMenu * popup);
+};
+
+
+class KviPopupEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ KviPopupEditor(QWidget * par);
+ ~KviPopupEditor();
+public:
+ KviSinglePopupEditor * m_pEditor;
+ KviTalListView * m_pListView;
+ KviMenuListViewItem * m_pLastEditedItem;
+ bool m_bOneTimeSetupDone;
+ KviTalPopupMenu * m_pContextPopup;
+public:
+ void commit();
+ void exportPopups(bool);
+protected slots:
+ void currentItemChanged(KviTalListViewItem *it);
+ void newPopup();
+ void exportAll();
+ void exportSelected();
+ void exportCurrentPopup();
+ void removeCurrentPopup();
+ void itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col);
+protected:
+ void showEvent(QShowEvent *e);
+ void getExportPopupBuffer(QString &buffer,KviMenuListViewItem * it);
+private:
+ void oneTimeSetup();
+ void saveLastEditedItem();
+ void getUniquePopupName(KviMenuListViewItem * it,QString &buffer);
+};
+
+
+
+class KviPopupEditorWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviPopupEditorWindow(KviFrame * lpFrm);
+ ~KviPopupEditorWindow();
+protected:
+ KviPopupEditor * m_pEditor;
+ QWidget * m_pBase;
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void getConfigGroupName(KviStr &szName);
+ virtual void saveProperties(KviConfig *);
+ virtual void loadProperties(KviConfig *);
+protected slots:
+ void cancelClicked();
+ void okClicked();
+ void applyClicked();
+};
+
+#endif //_POPUPEDITOR_H_
diff --git a/src/modules/raweditor/Makefile.am b/src/modules/raweditor/Makefile.am
new file mode 100644
index 00000000..74c64e9b
--- /dev/null
+++ b/src/modules/raweditor/Makefile.am
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviraweditor.la
+
+libkviraweditor_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviraweditor_la_SOURCES = libkviraweditor.cpp raweditor.cpp
+nodist_libkviraweditor_la_SOURCES = moc_raweditor.cpp
+
+noinst_HEADERS = raweditor.h
+libkviraweditor_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+moc_raweditor.cpp: raweditor.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/raweditor/libkviraweditor.cpp b/src/modules/raweditor/libkviraweditor.cpp
new file mode 100644
index 00000000..9f6975f5
--- /dev/null
+++ b/src/modules/raweditor/libkviraweditor.cpp
@@ -0,0 +1,87 @@
+//
+// File : libkviraweditor.cpp
+// Creation date : Mon 23 Dec 2002 20:23:59 2002 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2002 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_module.h"
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+
+#include "raweditor.h"
+
+KviRawEditorWindow * g_pRawEditorWindow = 0;
+
+
+/*
+ @doc: raweditor.open
+ @type:
+ command
+ @title:
+ raweditor.open
+ @short:
+ Shows the raw events editor
+ @syntax:
+ toolbareditor.open
+ @description:
+ Opens the script raw events editor dialog.
+*/
+
+static bool raweditor_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ if(!g_pRawEditorWindow)
+ {
+ g_pRawEditorWindow = new KviRawEditorWindow(c->window()->frame());
+ c->window()->frame()->addWindow(g_pRawEditorWindow);
+ }
+ g_pRawEditorWindow->setFocus();
+ return true;
+}
+
+
+static bool raweditor_module_init(KviModule * m)
+{
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",raweditor_kvs_cmd_open);
+ g_pRawEditorWindow = 0;
+ return true;
+}
+
+static bool raweditor_module_can_unload(KviModule * m)
+{
+ return (g_pRawEditorWindow == 0);
+}
+
+static bool raweditor_module_cleanup(KviModule *m)
+{
+ if(g_pRawEditorWindow)delete g_pRawEditorWindow;
+ g_pRawEditorWindow = 0;
+ return true;
+}
+
+KVIRC_MODULE(
+ "RawEditor", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Editor for the script raw events",
+ raweditor_module_init,
+ raweditor_module_can_unload,
+ 0,
+ raweditor_module_cleanup
+)
diff --git a/src/modules/raweditor/raweditor.cpp b/src/modules/raweditor/raweditor.cpp
new file mode 100644
index 00000000..72b3888b
--- /dev/null
+++ b/src/modules/raweditor/raweditor.cpp
@@ -0,0 +1,563 @@
+//
+// File : raweditor.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 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 "raweditor.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_imagedialog.h"
+#include "kvi_config.h"
+#include "kvi_filedialog.h"
+#include "kvi_fileutils.h"
+#include "kvi_scripteditor.h"
+#include "kvi_debug.h"
+//#include "kvi_event.h"
+#include "kvi_app.h"
+#include "kvi_cmdformatter.h"
+#include "kvi_kvs_eventmanager.h"
+#include "kvi_kvs_eventhandler.h"
+
+#include <qmessagebox.h>
+#include <qsplitter.h>
+#include <qlayout.h>
+#include "kvi_tal_vbox.h"
+#include "kvi_tal_popupmenu.h"
+#include <qtooltip.h>
+#include <qinputdialog.h>
+#include <qpushbutton.h>
+
+extern KviRawEditorWindow * g_pRawEditorWindow;
+
+
+
+KviRawListViewItem::KviRawListViewItem(KviTalListView *par,int idx)
+: KviTalListViewItem(par)
+{
+ m_iIdx = idx;
+ m_szName.setNum(idx);
+ if(idx < 100)m_szName.prepend('0');
+ if(idx < 10)m_szName.prepend('0');
+};
+
+const QPixmap * KviRawListViewItem::pixmap(int col) const
+{
+ return g_pIconManager->getSmallIcon(firstChild() ? KVI_SMALLICON_RAWEVENT : KVI_SMALLICON_RAWEVENTNOHANDLERS);
+}
+
+const QPixmap * KviRawHandlerListViewItem::pixmap(int col) const
+{
+ return g_pIconManager->getSmallIcon(m_bEnabled ? KVI_SMALLICON_HANDLER : KVI_SMALLICON_HANDLERDISABLED);
+}
+
+
+
+KviRawEditor::KviRawEditor(QWidget * par)
+: QWidget(par,"raw_event_editor")
+{
+ QGridLayout * l = new QGridLayout(this,1,1,2,2);
+#ifdef COMPILE_USE_QT4
+ QSplitter * spl = new QSplitter(Qt::Horizontal,this,"raweditorv");
+ spl->setOpaqueResize(false);
+#else
+ QSplitter * spl = new QSplitter(QSplitter::Horizontal,this);
+#endif
+ l->addWidget(spl,0,0);
+
+ KviTalVBox * boxi = new KviTalVBox(spl);
+ m_pListView = new KviTalListView(boxi);
+ m_pListView->addColumn(__tr2qs("Raw Event"));
+ m_pListView->setMultiSelection(false);
+ m_pListView->setShowSortIndicator(true);
+ m_pListView->setRootIsDecorated(true);
+
+ QPushButton * pb = new QPushButton(__tr2qs("&Export All To..."),boxi);
+ connect(pb,SIGNAL(clicked()),this,SLOT(exportAllEvents()));
+
+ KviTalVBox * box = new KviTalVBox(spl);
+ m_pNameEditor = new QLineEdit(box);
+ QToolTip::add(m_pNameEditor,__tr2qs("Edit the raw event handler name."));
+ m_pEditor = KviScriptEditor::createInstance(box);
+
+ m_bOneTimeSetupDone = false;
+ m_pLastEditedItem = 0;
+}
+
+KviRawEditor::~KviRawEditor()
+{
+ KviScriptEditor::destroyInstance(m_pEditor);
+}
+
+void KviRawEditor::oneTimeSetup()
+{
+ if(m_bOneTimeSetupDone)return;
+ m_bOneTimeSetupDone = true;
+
+ KviRawListViewItem * it;
+ KviRawHandlerListViewItem * ch;
+
+ for(unsigned int i = 0;i < 999;i++)
+ {
+ KviPointerList<KviKvsEventHandler> * l = KviKvsEventManager::instance()->rawHandlers(i);
+ if(l)
+ {
+ it = new KviRawListViewItem(m_pListView,i);
+ for(KviKvsEventHandler * s = l->first();s;s = l->next())
+ {
+ if(s->type() == KviKvsEventHandler::Script)
+ {
+ ch = new KviRawHandlerListViewItem(it,((KviKvsScriptEventHandler *)s)->name(),
+ ((KviKvsScriptEventHandler *)s)->code(),((KviKvsScriptEventHandler *)s)->isEnabled());
+ }
+ }
+ it->setOpen(true);
+ }
+ }
+
+
+ m_pContextPopup = new KviTalPopupMenu(this);
+
+ connect(m_pListView,SIGNAL(selectionChanged(KviTalListViewItem *)),this,SLOT(selectionChanged(KviTalListViewItem *)));
+ connect(m_pListView,SIGNAL(rightButtonPressed(KviTalListViewItem *,const QPoint &,int)),
+ this,SLOT(itemPressed(KviTalListViewItem *,const QPoint &,int)));
+}
+
+void KviRawEditor::itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ __range_valid(m_bOneTimeSetupDone);
+ m_pContextPopup->clear();
+ if(it)
+ {
+ if(it->parent())
+ {
+ if(!(((KviRawHandlerListViewItem *)it)->m_bEnabled))
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLER)),
+ __tr2qs("&Enable Handler"),this,SLOT(toggleCurrentHandlerEnabled()));
+ else
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLERDISABLED)),
+ __tr2qs("&Disable Handler"),this,SLOT(toggleCurrentHandlerEnabled()));
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),
+ __tr2qs("Re&move Handler"),
+ this,SLOT(removeCurrentHandler()));
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)),
+ __tr2qs("&Export Handler To..."),
+ this,SLOT(exportCurrentHandler()));
+ } else {
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLER)),
+ __tr2qs("&New Handler"),
+ this,SLOT(addHandlerForCurrentRaw()));
+ }
+ }
+
+ m_pContextPopup->insertSeparator();
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_RAWEVENT)),
+ __tr2qs("&Add Raw Event..."),
+ this,SLOT(addRaw()));
+
+ m_pContextPopup->popup(pnt);
+}
+
+void KviRawEditor::getUniqueHandlerName(KviRawListViewItem *it,QString &buffer)
+{
+ __range_valid(m_bOneTimeSetupDone);
+
+ QString newName = buffer;
+ if(newName.isEmpty())newName = __tr2qs("unnamed");
+
+ bool bFound = true;
+ int idx = 1;
+
+ while(bFound)
+ {
+ bFound = false;
+
+ for(KviRawHandlerListViewItem * ch = (KviRawHandlerListViewItem *)(it->firstChild());ch;ch = (KviRawHandlerListViewItem *)ch->nextSibling())
+ {
+ if(KviQString::equalCI(newName,ch->m_szName))
+ {
+ bFound = true;
+ KviQString::sprintf(newName,"%Q_%d",&buffer,idx);
+ idx++;
+ break;
+ }
+ }
+
+ }
+
+ buffer = newName;
+}
+
+void KviRawEditor::addRaw()
+{
+ bool bOk = false;
+
+ int iIdx = QInputDialog::getInteger(__tr2qs("New Raw Event"),__tr2qs("Enter the numeric code of the message (0-999)"),0,0,999,1,&bOk,this);
+
+ if(!bOk)return;
+
+ KviRawListViewItem * it;
+ for(it = (KviRawListViewItem *)m_pListView->firstChild();it;it = (KviRawListViewItem *)it->nextSibling())
+ {
+ if(it->m_iIdx == iIdx)
+ {
+ m_pListView->setSelected(it,true);
+ goto add_handler;
+ }
+ }
+
+ it = new KviRawListViewItem(m_pListView,iIdx);
+ m_pListView->setSelected(it,true);
+
+add_handler:
+ addHandlerForCurrentRaw();
+
+}
+
+void KviRawEditor::addHandlerForCurrentRaw()
+{
+ __range_valid(m_pOneTimeSetupDone);
+
+ KviTalListViewItem * it = m_pListView->selectedItem();
+ if(it)
+ {
+ if(it->parent() == 0)
+ {
+ QString buffer = __tr2qs("default");
+ getUniqueHandlerName((KviRawListViewItem *)it,buffer);
+ KviTalListViewItem * ch = new KviRawHandlerListViewItem(it,buffer,"",true);
+ it->setOpen(true);
+ m_pListView->setSelected(ch,true);
+ }
+ }
+}
+
+void KviRawEditor::removeCurrentHandler()
+{
+ __range_valid(m_pOneTimeSetupDone);
+ if(m_pLastEditedItem)
+ {
+ KviTalListViewItem * it = m_pLastEditedItem;
+ m_pLastEditedItem = 0;
+ delete it;
+ m_pEditor->setEnabled(false);
+ m_pNameEditor->setEnabled(false);
+ }
+}
+
+void KviRawEditor::toggleCurrentHandlerEnabled()
+{
+ __range_valid(m_pOneTimeSetupDone);
+ if(m_pLastEditedItem)
+ {
+ m_pLastEditedItem->m_bEnabled = !(m_pLastEditedItem->m_bEnabled);
+ m_pListView->repaintItem(m_pLastEditedItem);
+ selectionChanged(m_pLastEditedItem);
+ }
+}
+
+void KviRawEditor::commit()
+{
+ if(!m_bOneTimeSetupDone)return; // nothing to commit
+
+ saveLastEditedItem();
+ KviKvsEventManager::instance()->removeAllScriptRawHandlers();
+ for(KviTalListViewItem * it = m_pListView->firstChild();it;it = it->nextSibling())
+ {
+ if(it->firstChild())
+ {
+ QString szContext;
+ for(KviTalListViewItem * ch = it->firstChild();ch;ch = ch->nextSibling())
+ {
+
+ KviQString::sprintf(szContext,"RawEvent%d::%Q",&(((KviRawListViewItem *)it)->m_iIdx),&(((KviRawHandlerListViewItem *)ch)->m_szName));
+ KviKvsScriptEventHandler * s = new KviKvsScriptEventHandler(
+ ((KviRawHandlerListViewItem *)ch)->m_szName,
+ szContext,
+ ((KviRawHandlerListViewItem *)ch)->m_szBuffer,
+ ((KviRawHandlerListViewItem *)ch)->m_bEnabled
+ );
+
+ KviKvsEventManager::instance()->addRawHandler(((KviRawListViewItem *)it)->m_iIdx,s);
+ }
+ }
+ }
+
+ g_pApp->saveRawEvents(); // otherwise this page has never been shown
+}
+
+void KviRawEditor::saveLastEditedItem()
+{
+ __range_valid(m_bOneTimeSetupDone);
+ if(!m_pLastEditedItem)return;
+
+ QString buffer = m_pNameEditor->text();
+ if(!KviQString::equalCI(buffer,m_pLastEditedItem->m_szName))
+ {
+ getUniqueHandlerName((KviRawListViewItem *)(m_pLastEditedItem->parent()),buffer);
+ }
+
+ m_pLastEditedItem->m_szName = buffer;
+ QString tmp;
+ m_pEditor->getText(tmp);
+
+ m_pLastEditedItem->m_szBuffer = tmp;
+}
+
+void KviRawEditor::selectionChanged(KviTalListViewItem * it)
+{
+ __range_valid(m_bOneTimeSetupDone);
+ saveLastEditedItem();
+ if(it->parent())
+ {
+ m_pLastEditedItem = (KviRawHandlerListViewItem *)it;
+ m_pNameEditor->setEnabled(true);
+ m_pNameEditor->setText(it->text(0));
+ m_pEditor->setEnabled(true);
+ m_pEditor->setText(((KviRawHandlerListViewItem *)it)->m_szBuffer);
+ } else {
+ m_pLastEditedItem = 0;
+ m_pNameEditor->setEnabled(false);
+ m_pNameEditor->setText("");
+ m_pEditor->setEnabled(false);
+ }
+}
+
+void KviRawEditor::showEvent(QShowEvent *e)
+{
+ oneTimeSetup();
+ QWidget::showEvent(e);
+}
+
+void KviRawEditor::getExportEventBuffer(QString &buffer,KviRawHandlerListViewItem * it)
+{
+ if(!it->parent())return;
+
+ QString szBuf = it->m_szBuffer;
+
+ KviCommandFormatter::blockFromBuffer(szBuf);
+
+ buffer = "event(";
+ buffer += ((KviRawListViewItem *)(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 += ((KviRawListViewItem *)(it->parent()))->m_szName;
+ buffer += " ";
+ buffer += it->m_szName;
+ }
+}
+
+void KviRawEditor::exportCurrentHandler()
+{
+ if(!m_pLastEditedItem)return;
+ saveLastEditedItem();
+ if(!m_pLastEditedItem)return;
+
+ QString szName = QDir::homeDirPath();
+ if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR;
+ szName += "raw";
+ szName += ((KviRawListViewItem *)(m_pLastEditedItem->parent()))->m_szName;
+ szName += ".";
+ szName += m_pLastEditedItem->m_szName;
+ szName += ".kvs";
+
+ QString szFile;
+
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose a Filename - KVIrc"),szName,"*.kvs",true,true,true))return;
+
+ QString szOut;
+ getExportEventBuffer(szOut,m_pLastEditedItem);
+
+ if(!KviFileUtils::writeFile(szFile,szOut))
+ {
+ QMessageBox::warning(this,__tr2qs("Write Failed - KVIrc"),__tr2qs("Unable to write to the raw event file."),__tr2qs("&OK"));
+ }
+}
+
+void KviRawEditor::exportAllEvents()
+{
+ saveLastEditedItem();
+
+ KviRawListViewItem * it = (KviRawListViewItem *)m_pListView->firstChild();
+
+ QString out;
+
+ while(it)
+ {
+ KviRawHandlerListViewItem * item = (KviRawHandlerListViewItem *)it->firstChild();
+ while(item)
+ {
+ QString tmp;
+ getExportEventBuffer(tmp,item);
+ out += tmp;
+ out += "\n";
+ item = (KviRawHandlerListViewItem *)item->nextSibling();
+ }
+ it = (KviRawListViewItem *)it->nextSibling();
+ }
+
+ QString szName = QDir::homeDirPath();
+ if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR;
+ szName += "rawevents.kvs";
+
+ QString szFile;
+
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose a Filename - KVIrc"),szName,"*.kvs",true,true,true))return;
+
+ if(!KviFileUtils::writeFile(szFile,out))
+ {
+ QMessageBox::warning(this,__tr2qs("Write Failed - KVIrc"),__tr2qs("Unable to write to the raw events file."),__tr2qs("Ok"));
+ }
+}
+
+
+
+
+KviRawEditorWindow::KviRawEditorWindow(KviFrame * lpFrm)
+: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"raweditor",0)
+{
+ g_pRawEditorWindow = this;
+
+ m_pEditor = new KviRawEditor(this);
+
+ m_pBase = new QWidget(this);
+ QGridLayout * g = new QGridLayout(m_pBase,1,4,4,4);
+
+ QPushButton * btn = new QPushButton(__tr2qs("&OK"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(okClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,1);
+
+ btn = new QPushButton(__tr2qs("&Apply"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(btn,0,2);
+
+ btn = new QPushButton(__tr2qs("Cancel"),m_pBase);
+ connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ btn->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ g->addWidget(btn,0,3);
+
+ g->setColStretch(0,1);
+}
+
+KviRawEditorWindow::~KviRawEditorWindow()
+{
+ g_pRawEditorWindow = 0;
+}
+
+void KviRawEditorWindow::okClicked()
+{
+ m_pEditor->commit();
+ close();
+}
+
+void KviRawEditorWindow::applyClicked()
+{
+ m_pEditor->commit();
+}
+
+void KviRawEditorWindow::cancelClicked()
+{
+ close();
+}
+
+
+QPixmap * KviRawEditorWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_RAWEVENT);
+}
+
+void KviRawEditorWindow::resizeEvent(QResizeEvent *e)
+{
+ int hght = m_pBase->sizeHint().height();
+ m_pEditor->setGeometry(0,0,width(),height()- hght);
+ m_pBase->setGeometry(0,height() - hght,width(),hght);
+}
+
+void KviRawEditorWindow::fillCaptionBuffers()
+{
+ m_szPlainTextCaption = __tr2qs("Raw Editor");
+
+ static QString p1("<nobr><font color=\"");
+ static QString p2("\"><b>");
+ static QString p3("</b></font></nobr>");
+
+ m_szHtmlActiveCaption = p1;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += p2;
+ m_szHtmlActiveCaption += m_szPlainTextCaption;
+ m_szHtmlActiveCaption += p3;
+
+ m_szHtmlInactiveCaption = p1;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += p2;
+ m_szHtmlInactiveCaption += m_szPlainTextCaption;
+ m_szHtmlInactiveCaption += p3;
+
+}
+
+
+void KviRawEditorWindow::getConfigGroupName(KviStr &szName)
+{
+ szName = "raweditor";
+}
+
+
+void KviRawEditorWindow::saveProperties(KviConfig *cfg)
+{
+/*
+#ifdef COMPILE_SCRIPTTOOLBAR
+ cfg->writeEntry("Sizes",m_pEditor->sizes());
+ cfg->writeEntry("LastRaw",m_pEditor->lastEditedRaw().ptr());
+ //debug("LAST EDITED=%s",m_pEditor->lastEditedRaw().ptr());
+#endif // COMPILE_SCRIPTTOOLBAR
+*/
+}
+
+void KviRawEditorWindow::loadProperties(KviConfig *cfg)
+{
+/*
+#ifdef COMPILE_SCRIPTTOOLBAR
+ QValueList<int> def;
+ def.append(20);
+ def.append(80);
+ m_pEditor->setSizes(cfg->readIntListEntry("Sizes",def));
+ KviStr tmp = cfg->readEntry("LastRaw","");
+ m_pEditor->editRaw(tmp);
+ //debug("LAST EDITED WAS %s",tmp.ptr());
+#endif // COMPILE_SCRIPTTOOLBAR
+*/
+}
diff --git a/src/modules/raweditor/raweditor.h b/src/modules/raweditor/raweditor.h
new file mode 100644
index 00000000..7adf2213
--- /dev/null
+++ b/src/modules/raweditor/raweditor.h
@@ -0,0 +1,118 @@
+#ifndef _RAWEDITOR_H_
+#define _RAWEDITOR_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 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 "kvi_window.h"
+#include "kvi_qstring.h"
+
+#include <qwidget.h>
+#include "kvi_tal_listview.h"
+#include <qlineedit.h>
+
+class KviScriptEditor;
+
+class KviRawListViewItem : public KviTalListViewItem
+{
+public:
+ int m_iIdx;
+ QString m_szName;
+public:
+ KviRawListViewItem(KviTalListView * par,int idx);
+ ~KviRawListViewItem() {};
+public:
+ virtual QString text(int col) const { return m_szName; };
+ virtual const QPixmap * pixmap(int col) const;
+};
+
+class KviRawHandlerListViewItem : public KviTalListViewItem
+{
+public:
+ KviRawHandlerListViewItem(KviTalListViewItem * par,const QString & name,const QString & buffer,bool bEnabled)
+ : KviTalListViewItem(par), m_szName(name) , m_szBuffer(buffer) , m_bEnabled(bEnabled) {};
+ ~KviRawHandlerListViewItem() {};
+public:
+ QString m_szName;
+ QString m_szBuffer;
+ bool m_bEnabled;
+ virtual QString text(int col) const { return m_szName; };
+ virtual const QPixmap * pixmap(int col) const;
+};
+
+class KviTalPopupMenu;
+
+class KviRawEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ KviRawEditor(QWidget * par);
+ ~KviRawEditor();
+public:
+ KviScriptEditor * m_pEditor;
+ KviTalListView * m_pListView;
+ QLineEdit * m_pNameEditor;
+ KviTalPopupMenu * m_pContextPopup;
+ KviRawHandlerListViewItem * m_pLastEditedItem;
+ bool m_bOneTimeSetupDone;
+public:
+ void commit();
+ void saveLastEditedItem();
+ void getUniqueHandlerName(KviRawListViewItem *it,QString &buffer);
+ void getExportEventBuffer(QString &szBuffer,KviRawHandlerListViewItem * it);
+protected slots:
+ void selectionChanged(KviTalListViewItem *it);
+ void itemPressed(KviTalListViewItem *it,const QPoint &pnt,int col);
+ void toggleCurrentHandlerEnabled();
+ void removeCurrentHandler();
+ void addHandlerForCurrentRaw();
+ void addRaw();
+ void exportAllEvents();
+ void exportCurrentHandler();
+protected:
+ void showEvent(QShowEvent *e);
+private:
+ void oneTimeSetup();
+};
+
+class KviRawEditorWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviRawEditorWindow(KviFrame * lpFrm);
+ ~KviRawEditorWindow();
+protected:
+ KviRawEditor * m_pEditor;
+ QWidget * m_pBase;
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void getConfigGroupName(KviStr &szName);
+ virtual void saveProperties(KviConfig *);
+ virtual void loadProperties(KviConfig *);
+protected slots:
+ void cancelClicked();
+ void okClicked();
+ void applyClicked();
+};
+
+#endif //_RAWEDITOR_H_
diff --git a/src/modules/regchan/Makefile.am b/src/modules/regchan/Makefile.am
new file mode 100644
index 00000000..c46f64aa
--- /dev/null
+++ b/src/modules/regchan/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviregchan.la
+
+libkviregchan_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviregchan_la_SOURCES = libkviregchan.cpp
+libkviregchan_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+#noinst_HEADERS= edituser.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/regchan/libkviregchan.cpp b/src/modules/regchan/libkviregchan.cpp
new file mode 100644
index 00000000..eaa53268
--- /dev/null
+++ b/src/modules/regchan/libkviregchan.cpp
@@ -0,0 +1,426 @@
+//======================================================================================
+//
+// File : libkviregchan.cpp
+// Creation date : Sat Jun 29 02:55:18 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2004 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.
+//
+//======================================================================================
+// incomplete
+#include "kvi_module.h"
+
+
+#include "kvi_regchan.h"
+#include "kvi_locale.h"
+#include "kvi_out.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_window.h"
+
+
+// kvi_app.cpp
+extern KVIRC_API KviRegisteredChannelDataBase * g_pRegisteredChannelDataBase;
+
+/*
+ @doc: regchan.add
+ @type:
+ command
+ @title:
+ regchan.add
+ @keyterms:
+ registering channels
+ @short:
+ Registers a channel
+ @syntax:
+ regchan.add <channel:string> [netmask:string]
+ @description:
+ Registers the <channel> with the specified [netmask].
+ [netmask] can be a full network name or a wildcard string
+ tht will be matched against network names.
+ For example, if you want to register #kvirc on IRCNet
+ you can use regchan.add #kvirc IRCNet.
+ If you want to handle #kvirc on all the IRC networks then
+ you can use regchan.add #kvirc *[br]
+ Obviously if you register both #kvirc/IRCNet and #kvirc/*
+ then #kvirc/IRCNet will be looked first.
+ If netmask is not passed a netmask of * is assumed.[br]
+ @examples:
+ [example]
+ regchan.add #kvirc openprojects
+ [/example]
+ @seealso:
+*/
+
+static bool regchan_kvs_cmd_add(KviKvsModuleCommandCall * c)
+{
+ QString szChan,szNetmask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("channel name",KVS_PT_NONEMPTYSTRING,0,szChan)
+ KVSM_PARAMETER("netmask",KVS_PT_STRING,KVS_PF_OPTIONAL,szNetmask)
+ KVSM_PARAMETERS_END(c)
+ if(szNetmask.isEmpty())szNetmask="*";
+ g_pRegisteredChannelDataBase->add(new KviRegisteredChannel(szChan,szNetmask));
+ return true;
+}
+
+/*
+ @doc: regchan.remove
+ @type:
+ command
+ @title:
+ regchan.remove
+ @keyterms:
+ unregistering channels
+ @short:
+ Unregisters a channel
+ @syntax:
+ regchan.remove [-q|--quiet] [-e|--exactly] <channel:string> <network:string>
+ @description:
+ Unregisters the channel named <channel> that best matches <network>
+ with its netmask.[br]
+ If no match for <channel>/<network> is found in the database then
+ a warning is printed unless -q is used.[br]
+ If -e is specified then <network> is not matched against the
+ netmasks in the database but is compared directly. This means
+ that <network> must be exactly the netmask used to register a channel.
+ @examples:
+ [example]
+ regchan.remove #kvirc openprojects
+ [/example]
+ @seealso:
+ [cmd]regchan.add[/cmd]
+*/
+static bool regchan_kvs_cmd_remove(KviKvsModuleCommandCall * c)
+{
+ QString szChan,szNetwork;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("channel name",KVS_PT_NONEMPTYSTRING,0,szChan)
+ KVSM_PARAMETER("network",KVS_PT_NONEMPTYSTRING,0,szNetwork)
+ KVSM_PARAMETERS_END(c)
+ KviRegisteredChannel * ch;
+ if(c->hasSwitch('e',"exactly"))ch = g_pRegisteredChannelDataBase->findExact(szChan,szNetwork);
+ else ch = g_pRegisteredChannelDataBase->find(szChan,szNetwork);
+ if(ch)
+ {
+ g_pRegisteredChannelDataBase->remove(ch);
+ } else {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("No such channel/netmask entry in the database"));
+ }
+ return true;
+}
+
+/*
+ @doc: regchan.setproperty
+ @type:
+ command
+ @title:
+ regchan.setproperty
+ @short:
+ Sets a property for a registered channel
+ @syntax:
+ regchan.setproperty [-e|--exactly] [-q|--quiet] <channel:string> <network:string> <property:string> <value:string>
+ @description:
+ Sets the <property> for the registered <channel> that best
+ matches <network> to <value>.[br]
+ If <value> is an empty string the <property> is removed.[br]
+ If no match for <channel>/<network> is found in the database then
+ a warning is printed unless -q is used.[br]
+ @switches:
+ !fn: -q|--quiet
+ No warning on screen.
+ !fn: -e|--exactly
+ If -e is specified then <network> is not matched against the
+ netmasks in the database but is compared directly. This means
+ that <network> must be exactly the netmask used to register a channel.
+ @examples:
+ [example]
+ regchan.setproperty #kvirc openprojects autojoin true
+ [/example]
+ @seealso:
+ [cmd]regchan.add[/cmd]
+*/
+
+static bool regchan_kvs_cmd_setProperty(KviKvsModuleCommandCall * c)
+{
+ QString szChan,szNetwork,szProperty,szValue;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("channel name",KVS_PT_NONEMPTYSTRING,0,szChan)
+ KVSM_PARAMETER("network",KVS_PT_NONEMPTYSTRING,0,szNetwork)
+ KVSM_PARAMETER("property name",KVS_PT_NONEMPTYSTRING,0,szProperty)
+ KVSM_PARAMETER("value",KVS_PT_STRING,0,szValue)
+ KVSM_PARAMETERS_END(c)
+ KviRegisteredChannel * ch;
+ if(c->hasSwitch('e',"exactly"))ch = g_pRegisteredChannelDataBase->findExact(szChan,szNetwork);
+ else ch = g_pRegisteredChannelDataBase->find(szChan,szNetwork);
+ if(ch)
+ {
+ if(!szValue.isEmpty())
+ {
+ ch->setProperty(szProperty.utf8().data(),new KviStr(szValue));
+ } else {
+ ch->removeProperty(szProperty);
+ }
+ } else {
+ if(!c->hasSwitch('q',"quiet")) c->warning(__tr2qs("No such channel/netmask entry in the database"));
+ }
+ return true;
+}
+/*
+ @doc: regchan.showlist
+ @type:
+ command
+ @title:
+ regchan.showlist
+ @short:
+ Lists the registered channels
+ @syntax:
+ regchan.showlist
+ @description:
+ Lists the registered channels with their description
+*/
+
+static bool regchan_kvs_cmd_showlist(KviKvsModuleCommandCall * c)
+{
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Registered channel list:"));
+
+ int tot = 0;
+
+ KviPointerHashTableIterator<const char *,KviRegisteredChannelList> it(*(g_pRegisteredChannelDataBase->channelDict()));
+ while(KviRegisteredChannelList * l = it.current())
+ {
+ for(KviRegisteredChannel * ch = l->first();ch;ch = l->next())
+ {
+ tot++;
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Channel: %c%s@%s"),
+ KVI_TEXT_BOLD,ch->name().ptr(),ch->netMask().ptr());
+ KviPointerHashTableIterator<const char *,KviStr> pit(*(ch->propertyDict()));
+ while(KviStr * s = pit.current())
+ {
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs(" Property: %s=%s"),pit.currentKey(),s->ptr());
+ ++pit;
+ }
+ }
+ ++it;
+ }
+
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Total %d channels"),tot);
+ return true;
+}
+
+/*
+ @doc: regchan.list
+ @type:
+ function
+ @title:
+ $regchan.list
+ @short:
+ Get a list of registered channels
+ @syntax:
+ <array> $regchan.list([<channel_mask:string>],[<network_mask:string>])
+ @description:
+ Returns an array of the channel@netmask entries in the registered
+ channels database.[br]
+ Please note that <network_mask> is a wildcard string that will match
+ wildcard strings.[br]
+ @examples:
+ [example]
+ echo $regchan.list(#kvirc*,[fnc]$my.network[/fnc])
+ [/example]
+*/
+
+static bool regchan_kvs_fnc_list(KviKvsModuleFunctionCall * c)
+{
+ QString szChan,szNetmask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("channel name",KVS_PT_STRING,KVS_PF_OPTIONAL,szChan)
+ KVSM_PARAMETER("netmask",KVS_PT_STRING,KVS_PF_OPTIONAL,szNetmask)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray* pArray = new KviKvsArray();
+// KviKvsArray* pArrayCN = new KviKvsArray();
+// pArrayCN->set(0,new KviKvsVariant(QString("")));
+// pArrayCN->set(1,new KviKvsVariant(QString("")));
+ int aid=0;
+
+ if(szChan.isEmpty())szChan="*";
+ if(szNetmask.isEmpty())szNetmask="*";
+
+ KviPointerHashTable<const char *,KviRegisteredChannelList> * d = g_pRegisteredChannelDataBase->channelDict();
+ KviPointerHashTableIterator<const char *,KviRegisteredChannelList> it(*d);
+
+ while(KviRegisteredChannelList * l = it.current())
+ {
+ for(KviRegisteredChannel * ch = l->first();ch;ch = l->next())
+ if(KviQString::matchWildExpressionsCI(ch->name().ptr(),szChan) &&
+ KviQString::matchWildExpressionsCI(ch->netMask().ptr(),szNetmask))
+ {
+// FIXME: WE NEED TO RETURN AN ARRAY OF 2-ELEMENT ARRAYS (chan name, netmask)
+ pArray->set(aid,new KviKvsVariant(QString(ch->name()+"@"+ch->netMask())));
+// pArray->set(aid,new KviKvsVariant(QString(ch->name()));
+// pArrayCN->set(0,new KviKvsVariant(QString(ch->name())));
+// pArrayCN->set(1,new KviKvsVariant(QString(ch->netMask())));
+// pArray->set(aid,new KviKvsVariant(pArrayCN));
+ aid++;
+ }
+ ++it;
+ }
+ c->returnValue()->setArray(pArray);
+ return true;
+}
+
+/*
+ @doc: regchan.property
+ @type:
+ function
+ @title:
+ $regchan.property
+ @short:
+ Returns a property of an entry in the registered channels database
+ @syntax:
+ <string> $regchan.property(<channel_name:string>,<network:string>,<property_name:string>)
+ @description:
+ Returns the value of the property identified by <property_name> and
+ bound to the channel identified by <channel_name> and best
+ matched by <network>.[br]
+ If the property is not set or if there is no matching channel entry an empty string is returned.[br]
+ @examples:
+ [example]
+ echo $regchan.property(#kvirc,[fnc]$my.network[/fnc],autojoin)
+ [/example]
+*/
+
+static bool regchan_kvs_fnc_property(KviKvsModuleFunctionCall * c)
+{
+ QString szChan,szNetwork,szPropertyName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("channel name",KVS_PT_STRING,0,szChan)
+ KVSM_PARAMETER("network",KVS_PT_STRING,0,szNetwork)
+ KVSM_PARAMETER("property name",KVS_PT_NONEMPTYSTRING,0,szPropertyName)
+ KVSM_PARAMETERS_END(c)
+ KviRegisteredChannel * ch = g_pRegisteredChannelDataBase->find(szChan,szNetwork);
+ if(ch)
+ {
+ KviStr * p = ch->property(szPropertyName);
+ if(p)c->returnValue()->setString(p->ptr());
+ } //else c->warning(__tr("User %s not found"),parms->safeFirstParam());
+ return true;
+}
+/*
+ @doc: regchan.match
+ @type:
+ function
+ @title:
+ $regchan.match
+ @short:
+ Checks if a channel is registered
+ @syntax:
+ <boolean> $regchan.match(<channel_name:string>,<network:string>)
+ @description:
+ Returns 1 if <channel_name> and <network> match a registered channel entry
+ and 0 otherwise.
+ @examples:
+ [example]
+ echo $regchan.match(#kvirc,IRCNet)
+ echo $regchan.match(#kvirc,$my.network)
+ [/example]
+ @seealso:
+ [fnc]$regchan.find[/fnc]
+*/
+
+
+static bool regchan_kvs_fnc_match(KviKvsModuleFunctionCall * c)
+{
+ QString szChan,szNetwork;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("channel name",KVS_PT_STRING,0,szChan)
+ KVSM_PARAMETER("network",KVS_PT_STRING,0,szNetwork)
+ KVSM_PARAMETERS_END(c)
+ KviRegisteredChannel * ch = g_pRegisteredChannelDataBase->find(szChan,szNetwork);
+ c->returnValue()->setBoolean(ch);
+ return true;
+}
+
+/*
+ @doc: regchan.find
+ @type:
+ function
+ @title:
+ $regchan.find
+ @short:
+ Checks if a channel is registered
+ @syntax:
+ <boolean> $regchan.find(<channel_name:string>,<netmask:string>)
+ @description:
+ Returns 1 if the channel identified by <channel_name> and <netmask>
+ is registered and 0 otherwise. This function is similar to $regchan.match
+ but for $regchan.find the second parameter is the exact netmask
+ of the registered channel entry.
+ @examples:
+ [example]
+ echo $regchan.find(#kvirc,IRCNet)
+ echo $regchan.find(#kvirc,*)
+ [/example]
+ @seealso:
+ [fnc]$regchan.match[/fnc]
+*/
+
+static bool regchan_kvs_fnc_find(KviKvsModuleFunctionCall * c)
+{
+ QString szChan,szNetmask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("channel name",KVS_PT_STRING,0,szChan)
+ KVSM_PARAMETER("netmask",KVS_PT_STRING,0,szNetmask)
+ KVSM_PARAMETERS_END(c)
+ KviRegisteredChannel * ch = g_pRegisteredChannelDataBase->find(szChan,szNetmask);
+ c->returnValue()->setBoolean(ch);
+ return true;
+}
+
+static bool regchan_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"add",regchan_kvs_cmd_add);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"showlist",regchan_kvs_cmd_showlist);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"remove",regchan_kvs_cmd_remove);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setProperty",regchan_kvs_cmd_setProperty);
+ KVSM_REGISTER_FUNCTION(m,"property",regchan_kvs_fnc_property);
+ KVSM_REGISTER_FUNCTION(m,"match",regchan_kvs_fnc_match);
+ KVSM_REGISTER_FUNCTION(m,"find",regchan_kvs_fnc_find);
+ KVSM_REGISTER_FUNCTION(m,"list",regchan_kvs_fnc_list);
+
+ return true;
+}
+
+static bool regchan_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+static bool regchan_module_can_unload(KviModule *)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "RegChan", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Script interface to the registered channels database",
+ regchan_module_init,
+ regchan_module_can_unload,
+ 0,
+ regchan_module_cleanup
+)
diff --git a/src/modules/reguser/Makefile.am b/src/modules/reguser/Makefile.am
new file mode 100644
index 00000000..93aea872
--- /dev/null
+++ b/src/modules/reguser/Makefile.am
@@ -0,0 +1,25 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvireguser.la
+
+libkvireguser_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvireguser_la_SOURCES = libkvireguser.cpp edituser.cpp wizard.cpp dialog.cpp
+libkvireguser_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= edituser.h wizard.h dialog.h
+nodist_libkvireguser_la_SOURCES = moc_dialog.cpp
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+moc_dialog.cpp: dialog.h
+ $(SS_QT_MOC) $< -o $@
+
+edituser.cpp: edituser.moc
+wizard.cpp: wizard.moc
diff --git a/src/modules/reguser/dialog.cpp b/src/modules/reguser/dialog.cpp
new file mode 100644
index 00000000..b8d02fe2
--- /dev/null
+++ b/src/modules/reguser/dialog.cpp
@@ -0,0 +1,903 @@
+//=============================================================================
+//
+// File : edituser.cpp
+// Creation date : Tue Dec 26 2000 12:24:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 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 _WANT_OPTION_FLAGS_
+
+#include "edituser.h"
+#include "kvi_regusersdb.h"
+
+#include "kvi_locale.h"
+#include "kvi_ircmask.h"
+#include "kvi_debug.h"
+#include "kvi_iconmanager.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_file.h"
+#include "kvi_filedialog.h"
+#include "kvi_msgbox.h"
+#include "kvi_fileutils.h"
+#include "kvi_settings.h"
+#include "kvi_stringconversion.h"
+#include "kvi_options.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+#ifdef COMPILE_USE_QT4
+#include <q3header.h>
+#include <qevent.h>
+#include <QImageWriter>
+#include <QImageReader>
+
+#else
+#include <qheader.h>
+#endif
+#include "kvi_pointerhashtable.h"
+#include <qimage.h>
+#include <qstring.h>
+#include <qcombobox.h>
+
+
+#include <qstyle.h>
+#include <qpainter.h>
+#include "kvi_tal_hbox.h"
+#include "kvi_tal_vbox.h"
+#include <qinputdialog.h>
+
+#include "wizard.h"
+#include "dialog.h"
+
+
+#ifdef COMPILE_INFO_TIPS
+ #include <qtooltip.h>
+#endif // COMPILE_INFO_TIPS
+
+
+#define LVI_ICON_SIZE 32
+#define LVI_BORDER 4
+#define LVI_SPACING 8
+#define LVI_MINIMUM_TEXT_WIDTH 300
+#define LVI_MINIMUM_CELL_WIDTH (LVI_MINIMUM_TEXT_WIDTH + LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER)
+
+
+extern KviRegisteredUsersDialog * g_pRegisteredUsersDialog;
+
+KviRegisteredUsersDialogItem::KviRegisteredUsersDialogItem(KviTalListViewItem * par,KviRegisteredUser * u)
+: KviRegisteredUsersDialogItemBase(User,par), m_pUser(u)
+{
+ QString szTmp;
+ QString t = "<nobr><b>";
+ t += u->name();
+ t += "</b> [";
+ szTmp = m_pUser->getProperty("notify");
+ if(szTmp.isEmpty())
+ {
+ t += __tr2qs("Notify disabled");
+ } else {
+ t += __tr2qs("Notify as: ");
+ t += szTmp;
+
+ }
+ t += "]</nobr>";
+ t += "<br><nobr><font size=\"-1\">";
+ szTmp = m_pUser->getProperty("comment");
+ if(szTmp.isEmpty())
+ {
+ t += __tr2qs("No comment set");
+ } else {
+ t += __tr2qs("Comment: ");
+ t += m_pUser->getProperty("comment");
+ }
+ t += "</font></nobr>";
+ m_pText = new QSimpleRichText(t,listView()->font());
+
+ //setText(0,u->name());
+}
+
+KviRegisteredUsersDialogItem::~KviRegisteredUsersDialogItem()
+{
+ delete m_pText;
+}
+
+QString KviRegisteredUsersDialogItem::key(int,bool) const
+{
+ return m_pUser->name();
+}
+
+void KviRegisteredUsersDialogItem::paintCell(QPainter * p,const QColorGroup &cg,int column,int width,int align)
+{
+ KviTalListViewItem::paintCell(p,cg,column,width,align);
+ if(column==0)
+ {
+ p->drawPixmap(LVI_BORDER,LVI_BORDER, *(g_pIconManager->getBigIcon(QString(KVI_BIGICON_REGUSERS))) );
+ int afterIcon = LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING;
+ int www = listView()->visibleWidth() - (afterIcon + LVI_BORDER);
+ m_pText->setWidth(www);
+ if(isSelected())
+ {
+ QColorGroup cg2(cg);
+ cg2.setColor(QColorGroup::HighlightedText,cg.text());
+ m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,height() - (LVI_BORDER * 2)),cg2);
+ } else {
+ m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,height() - (LVI_BORDER * 2)),cg);
+ }
+ } else {
+ if(m_pUser)
+ {
+ if(!m_pUser->getProperty("notify").isEmpty())
+ p->drawPixmap(LVI_BORDER,LVI_BORDER,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NOTIFYONLINE)));
+ if(m_pUser->ignoreEnagled())
+ p->drawPixmap(LVI_BORDER,2*LVI_BORDER+16,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_IGNORE)));
+ }
+ }
+}
+
+void KviRegisteredUsersDialogItem::setup()
+{
+ KviTalListViewItem::setup();
+ int iWidth = listView()->visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ iWidth -= LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER;
+ m_pText->setWidth(iWidth);
+ int iHeight = m_pText->height() + (2 * LVI_BORDER);
+ if(iHeight < (LVI_ICON_SIZE + (2 * LVI_BORDER)))iHeight = LVI_ICON_SIZE + (2 * LVI_BORDER);
+ setHeight(iHeight);
+}
+
+
+KviRegisteredUsersDialog::KviRegisteredUsersDialog(QWidget * par)
+: QWidget(par)
+{
+ g_pRegisteredUsersDialog = this;
+
+ g_pLocalRegisteredUserDataBase = new KviRegisteredUserDataBase();
+ g_pLocalRegisteredUserDataBase->copyFrom(g_pRegisteredUserDataBase);
+
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_REGUSERS)));
+ setCaption(__tr2qs("Registered Users - KVIrc"));
+
+ QGridLayout * g = new QGridLayout(this,4,3,4,4);
+
+
+ m_pListView = new KviTalListView(this);
+
+ m_pListView->addColumn(__tr2qs("Name"),200);
+ m_pListView->addColumn(__tr2qs("Flags"),20);
+
+ m_pListView->setAllColumnsShowFocus(true);
+
+ m_pListView->setSelectionMode(KviTalListView::Extended);
+ m_pListView->setRootIsDecorated(TRUE);
+
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pListView,__tr2qs("<center>This is the list of registered users. " \
+ "KVIrc can automatically recognize and associate properties to them.<br>" \
+ "Use the buttons on the right to add, edit and remove entries. " \
+ "The \"notify\" column allows you to quickly add users to the notify list. " \
+ "Notify list fine-tuning can be performed by editing the entry properties.</center>"));
+#endif // COMPILE_INFO_TIPS
+
+ connect(m_pListView,SIGNAL(pressed(KviTalListViewItem *,const QPoint &,int)),this,SLOT(itemPressed(KviTalListViewItem *,const QPoint &,int)));
+ connect(m_pListView,SIGNAL(doubleClicked(KviTalListViewItem *)),this,SLOT(itemDoubleClicked(KviTalListViewItem *)));
+
+ g->addMultiCellWidget(m_pListView,0,1,0,1);
+
+ KviTalVBox * vbox = new KviTalVBox(this);
+ vbox->setSpacing(4);
+ g->addWidget(vbox,0,2);
+
+ m_pWizardAddButton = new QPushButton(__tr2qs("Add (Wizard)..."),vbox);
+ connect(m_pWizardAddButton,SIGNAL(clicked()),this,SLOT(addWizardClicked()));
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pWizardAddButton,__tr2qs("Add a registered user by means of a user-friendly wizard."));
+#endif // COMPILE_INFO_TIPS
+ m_pWizardAddButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NEWITEMBYWIZARD)));
+
+
+ m_pAddButton = new QPushButton(__tr2qs("&Add..."),vbox);
+ connect(m_pAddButton,SIGNAL(clicked()),this,SLOT(addClicked()));
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pAddButton,__tr2qs("Open the edit dialog to create a new user entry."));
+#endif // COMPILE_INFO_TIPS
+ m_pAddButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NEWITEM)));
+
+ m_pAddGroupButton = new QPushButton(__tr2qs("&Add Group..."),vbox);
+ connect(m_pAddGroupButton,SIGNAL(clicked()),this,SLOT(addGroupClicked()));
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pAddGroupButton,__tr2qs("Adds a new group"));
+#endif // COMPILE_INFO_TIPS
+ m_pAddGroupButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NEWITEM)));
+
+ m_pRemoveButton = new QPushButton(__tr2qs("Re&move"),vbox);
+ connect(m_pRemoveButton,SIGNAL(clicked()),this,SLOT(removeClicked()));
+ m_pRemoveButton->setEnabled(false);
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pRemoveButton,__tr2qs("Remove the currently selected entries."));
+#endif // COMPILE_INFO_TIPS
+ m_pRemoveButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DELETEITEM)));
+
+
+ m_pEditButton = new QPushButton(__tr2qs("&Edit..."),vbox);
+ connect(m_pEditButton,SIGNAL(clicked()),this,SLOT(editClicked()));
+ m_pEditButton->setEnabled(false);
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pEditButton,__tr2qs("Edit the first selected entry."));
+#endif // COMPILE_INFO_TIPS
+ m_pEditButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_EDITITEM)));
+
+ QFrame * f = new QFrame(vbox);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+
+ m_pExportButton = new QPushButton(__tr("Export To..."),vbox);
+ m_pExportButton->setEnabled(false);
+ connect(m_pExportButton,SIGNAL(clicked()),this,SLOT(exportClicked()));
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pExportButton,__tr2qs("Export the selected entries to a file.<br>All the data associated with the selected registered users will be exported.<br>You (or anyone else) can later import the entries by using the \"Import\" button."));
+#endif // COMPILE_INFO_TIPS
+ m_pExportButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_FLOPPY)));
+
+
+ m_pImportButton = new QPushButton(__tr("Import From..."),vbox);
+ connect(m_pImportButton,SIGNAL(clicked()),this,SLOT(importClicked()));
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pImportButton,__tr2qs("Import entries from a file exported earlier by the \"export\" function of this dialog."));
+#endif // COMPILE_INFO_TIPS
+ m_pImportButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)));
+
+
+ KviTalHBox * hbox = new KviTalHBox(this);
+ hbox->setSpacing(4);
+ g->addMultiCellWidget(hbox,3,3,1,2);
+
+ QPushButton * b;
+
+
+ b = new QPushButton(__tr2qs("&OK"),hbox);
+ connect(b,SIGNAL(clicked()),this,SLOT(okClicked()));
+ b->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ //b->setMinimumWidth(120);
+
+ b = new QPushButton(__tr2qs("Cancel"),hbox);
+ connect(b,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ b->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ //b->setMinimumWidth(120);
+
+
+ g->addRowSpacing(2,15);
+
+ g->setColStretch(0,1);
+ g->setRowStretch(1,1);
+
+ connect(m_pListView,SIGNAL(selectionChanged()),this,SLOT(selectionChanged()));
+ connect(m_pListView,SIGNAL(rightButtonClicked ( KviTalListViewItem *, const QPoint &, int ) ),this,SLOT(listViewRightButtonClicked ( KviTalListViewItem *, const QPoint &, int )));
+
+ fillList();
+
+ if(!parent())
+ {
+ if(KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry).y() < 5)
+ {
+ KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry).setY(5);
+ }
+ //setGeometry(KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry));
+ resize(KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry).width(),
+ KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry).height());
+ move(KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry).x(),
+ KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry).y());
+ }
+}
+
+KviRegisteredUsersDialog::~KviRegisteredUsersDialog()
+{
+#ifndef Q_OS_MACX
+ if(!parent())KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry) = QRect(pos().x(),pos().y(),
+ size().width(),size().height());
+#else
+ if(!parent())KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry) = geometry();
+#endif
+
+ g_pRegisteredUsersDialog = 0;
+
+ delete g_pLocalRegisteredUserDataBase;
+ g_pLocalRegisteredUserDataBase = 0;
+}
+
+void KviRegisteredUsersDialog::itemPressed(KviTalListViewItem *it,const QPoint &pnt,int c)
+{
+ if(!it)return;
+ KviRegisteredUsersDialogItemBase* b=(KviRegisteredUsersDialogItemBase*)it;
+ if(b->type()==KviRegisteredUsersDialogItemBase::User)
+ {
+ KviRegisteredUsersDialogItem *i = (KviRegisteredUsersDialogItem *)it;
+
+ QRect r = m_pListView->itemRect(i);
+ int daw = m_pListView->columnWidth(0);
+
+ QPoint ppp = m_pListView->mapFromGlobal(pnt);
+
+ if((c == 1) && (ppp.x() < (r.height() + 5 + daw)))
+ {
+ // notify list toggle
+ if(i->user()->getProperty("notify").isEmpty())
+ {
+ i->user()->setProperty("notify",""); // kill that
+ } else {
+ // try to find the nicknames to be notified
+ QString szMask;
+
+ for(KviIrcMask * m = i->user()->maskList()->first();m;m = i->user()->maskList()->next())
+ {
+ QString tmp = m->nick();
+ if((tmp.find('*') == -1) && (tmp.find('?') == -1) && (!tmp.isEmpty()))
+ {
+ if(!szMask.isEmpty())szMask.append(' ');
+ szMask.append(tmp);
+ }
+ }
+ // if the nickname list is still empty , build a dummy nick to notify
+ szMask = i->user()->name();
+ szMask.replace(" ","");
+ szMask.replace("'","");
+ szMask.replace("&","");
+ szMask.replace(",","");
+
+ i->user()->setProperty("notify",szMask);
+ }
+ m_pListView->update();
+ }
+ }
+}
+
+void KviRegisteredUsersDialog::itemDoubleClicked(KviTalListViewItem *it)
+{
+ if(!it)return;
+ KviRegisteredUsersDialogItemBase* b=(KviRegisteredUsersDialogItemBase*)it;
+ if(b->type()==KviRegisteredUsersDialogItemBase::User)
+ {
+ editItem((KviRegisteredUsersDialogItem *)it);
+ } else {
+ KviRegisteredUsersGroupItem *i = (KviRegisteredUsersGroupItem *)b;
+ editGroup(i->group());
+ }
+}
+
+void KviRegisteredUsersDialog::addGroupClicked()
+{
+ bool ok;
+ QString text = QInputDialog::getText(
+ "KVIrc", __tr("Group name:"), QLineEdit::Normal,
+ QString::null, &ok, this );
+ if ( ok && !text.isEmpty() ) {
+ g_pLocalRegisteredUserDataBase->addGroup(text);
+ fillList();
+ }
+}
+void KviRegisteredUsersDialog::editGroup(KviRegisteredUserGroup* group)
+{
+ bool ok;
+
+ QString text = QInputDialog::getText(
+ "KVIrc", __tr("Group name:"), QLineEdit::Normal,
+ group->name(), &ok, this );
+ if ( ok && !text.isEmpty() ) {
+ QString szOldGroup=group->name();
+ g_pLocalRegisteredUserDataBase->groupDict()->setAutoDelete(0);
+ g_pLocalRegisteredUserDataBase->groupDict()->remove(szOldGroup);
+ g_pLocalRegisteredUserDataBase->groupDict()->setAutoDelete(1);
+ group->setName(text);
+ g_pLocalRegisteredUserDataBase->groupDict()->insert(text,group);
+
+ KviPointerHashTable<QString,KviRegisteredUser> * d = g_pLocalRegisteredUserDataBase->userDict();
+
+ for(KviRegisteredUser * u = d->first();u;u = d->next())
+ {
+ if(u->group()==szOldGroup)
+ u->setGroup(text);
+ }
+
+
+ fillList();
+ }
+}
+
+void KviRegisteredUsersDialog::listViewRightButtonClicked ( KviTalListViewItem * pItem, const QPoint & point, int )
+{
+ if(pItem)
+ {
+ KviRegisteredUsersDialogItemBase* b=(KviRegisteredUsersDialogItemBase*)pItem;
+ if(b->type()==KviRegisteredUsersDialogItemBase::User)
+ {
+ KviTalPopupMenu *groups = new KviTalPopupMenu;
+
+ KviPointerHashTable<QString,KviRegisteredUserGroup> * pGroups = g_pLocalRegisteredUserDataBase->groupDict();
+ m_TmpDict.clear();
+ for(KviPointerHashTableEntry<QString,KviRegisteredUserGroup> * g = pGroups->firstEntry();g;g = pGroups->nextEntry())
+ {
+ int id=groups->insertItem(g->key());
+ m_TmpDict.replace(id,g->data());
+ }
+
+ connect(groups,SIGNAL(activated ( int )),this,SLOT(moveToGroupMenuClicked(int)));
+
+ KviTalPopupMenu *mainPopup = new KviTalPopupMenu;
+ mainPopup->insertItem(__tr("Move to group"),groups);
+ mainPopup->exec(point);
+ }
+ }
+}
+
+void KviRegisteredUsersDialog::moveToGroupMenuClicked(int id)
+{
+ QString szGroup=m_TmpDict.find(id)->name();
+ KviTalListViewItemIterator it( m_pListView, KviTalListViewItemIterator::Selected );
+ while ( it.current() ) {
+ KviRegisteredUsersDialogItemBase* b=(KviRegisteredUsersDialogItemBase*)(it.current());
+ if(b->type()==KviRegisteredUsersDialogItemBase::User)
+ {
+ ((KviRegisteredUsersDialogItem *)(it.current()))->user()->setGroup(szGroup);
+ }
+ ++it;
+ }
+ fillList();
+}
+
+void KviRegisteredUsersDialog::fillList()
+{
+ m_pListView->clear();
+ KviPointerHashTable<QString,KviRegisteredUsersGroupItem> groupItems(5,false);
+ groupItems.setAutoDelete(false);
+
+ KviPointerHashTable<QString,KviRegisteredUserGroup> * pGroups = g_pLocalRegisteredUserDataBase->groupDict();
+ for(KviRegisteredUserGroup * g = pGroups->first();g;g = pGroups->next())
+ {
+ KviRegisteredUsersGroupItem* pCur = new KviRegisteredUsersGroupItem(m_pListView,g);
+ groupItems.insert(g->name(),pCur);
+ pCur->setOpen(TRUE);
+ }
+
+ KviPointerHashTable<QString,KviRegisteredUser> * d = g_pLocalRegisteredUserDataBase->userDict();
+ KviRegisteredUsersDialogItem * item;
+
+ for(KviRegisteredUser * u = d->first();u;u = d->next())
+ {
+ if(u->group().isEmpty())
+ u->setGroup(__tr("Default"));
+ if(groupItems.find(u->group()))
+ item = new KviRegisteredUsersDialogItem(groupItems.find(u->group()),u);
+ else if(groupItems.find(__tr("Default")))
+ item = new KviRegisteredUsersDialogItem(groupItems.find(__tr("Default")),u);
+ else { //should never be called
+ KviRegisteredUserGroup* pGroup = g_pLocalRegisteredUserDataBase->addGroup(__tr("Default"));
+ KviRegisteredUsersGroupItem* pCur = new KviRegisteredUsersGroupItem(m_pListView,pGroup);
+ groupItems.insert(__tr("Default"),pCur);
+ item = new KviRegisteredUsersDialogItem(pCur,u);
+ }
+ }
+ if(m_pListView->firstChild())
+ {
+ m_pListView->setSelected(m_pListView->firstChild(),true);
+ m_pListView->setCurrentItem(m_pListView->firstChild());
+ }
+}
+
+void KviRegisteredUsersDialog::closeEvent(QCloseEvent *e)
+{
+ m_pListView->clear();
+ e->accept();
+ okClicked();
+ //delete this;
+}
+
+void KviRegisteredUsersDialog::okClicked()
+{
+ m_pListView->clear();
+ g_pRegisteredUserDataBase->copyFrom(g_pLocalRegisteredUserDataBase);
+ g_pApp->restartNotifyLists();
+ delete this;
+}
+
+void KviRegisteredUsersDialog::cancelClicked()
+{
+ m_pListView->clear();
+ delete this;
+}
+
+void KviRegisteredUsersDialog::addClicked()
+{
+ KviRegisteredUserEntryDialog * dlg = new KviRegisteredUserEntryDialog(this,0);
+ int ret = dlg->exec();
+ delete dlg;
+
+ if(!g_pRegisteredUsersDialog)return; // we have been deleted!
+
+ if(ret == QDialog::Accepted)
+ {
+ fillList();
+ }
+}
+
+void KviRegisteredUsersDialog::addWizardClicked()
+{
+ KviRegistrationWizard * w = new KviRegistrationWizard("",g_pLocalRegisteredUserDataBase,this,true);
+ int ret = w->exec();
+ delete w;
+ if(!g_pRegisteredUsersDialog)return; // we have been deleted!
+ if(ret == QDialog::Accepted)
+ {
+ fillList();
+ }
+}
+
+void KviRegisteredUsersDialog::removeClicked()
+{
+ KviTalListViewItemIterator it( m_pListView, KviTalListViewItemIterator::Selected );
+ while ( it.current() ) {
+ KviRegisteredUsersDialogItemBase* b=(KviRegisteredUsersDialogItemBase*)(it.current());
+ if(b->type()==KviRegisteredUsersDialogItemBase::User)
+ {
+ g_pLocalRegisteredUserDataBase->removeUser(((KviRegisteredUsersDialogItem *)(it.current()))->user()->name());
+ } else {
+ g_pLocalRegisteredUserDataBase->removeGroup(((KviRegisteredUsersGroupItem *)(it.current()))->group()->name());
+ }
+ ++it;
+ }
+ fillList();
+// KviRegisteredUsersDialogItem *it = (KviRegisteredUsersDialogItem *)m_pListView->firstChild();
+// KviRegisteredUsersDialogItemBase* b=(KviRegisteredUsersDialogItemBase*)it;
+// if(b->type()==KviRegisteredUsersDialogItemBase::User)
+// {
+// KviPointerList<KviRegisteredUsersDialogItem> l;
+// l.setAutoDelete(false);
+// while(it)
+// {
+// if(it->isSelected())l.append(it);
+// it = (KviRegisteredUsersDialogItem *)it->nextSibling();
+// }
+//
+// for(KviRegisteredUsersDialogItem * i = l.first();i;i = l.next())
+// {
+// //g_pLocalRegisteredUserDataBase->removeUser(i->user()->name());
+// delete i;
+// }
+// } else {
+//
+// }
+}
+
+void KviRegisteredUsersDialog::editClicked()
+{
+ KviRegisteredUsersDialogItemBase* b=(KviRegisteredUsersDialogItemBase*)(m_pListView->currentItem());
+ if(!b)return;
+ if(b->type()==KviRegisteredUsersDialogItemBase::User)
+ {
+ KviRegisteredUsersDialogItem *i = (KviRegisteredUsersDialogItem *)b;
+ editItem(i);
+ } else {
+ KviRegisteredUsersGroupItem *i = (KviRegisteredUsersGroupItem *)b;
+ editGroup(i->group());
+ }
+}
+
+void KviRegisteredUsersDialog::editItem(KviRegisteredUsersDialogItem * i)
+{
+ KviRegisteredUser * u = i->user();
+
+ i->setUser(0);
+
+ QString szName = u->name();
+
+ KviRegisteredUserEntryDialog * dlg = new KviRegisteredUserEntryDialog(this,u);
+ int res = dlg->exec();
+ delete dlg;
+
+ if(!g_pRegisteredUsersDialog)return; // we have been deleted!
+
+ if(res == QDialog::Accepted)
+ {
+ fillList();
+
+ // select the last edited item
+ KviTalListViewItem * i = m_pListView->firstChild();
+ while(i)
+ {
+ QString szTmp = i->text(0);
+ if(KviQString::equalCI(szTmp,szName))
+ {
+ m_pListView->setSelected(i,true);
+ m_pListView->setCurrentItem(i);
+ break;
+ }
+ i = i->nextSibling();
+ }
+
+ return;
+ }
+
+ i->setUser(u);
+ m_pListView->update();
+}
+
+
+void KviRegisteredUsersDialog::selectionChanged()
+{
+ bool bHaveSelected = !m_pListView->selectedItem();
+
+ m_pEditButton->setEnabled(bHaveSelected);
+ m_pRemoveButton->setEnabled(bHaveSelected);
+ m_pExportButton->setEnabled(bHaveSelected);
+}
+
+
+#define KVI_REGUSER_DB_FILE_MAGIC 0x5334DBDB
+#define KVI_REGUSER_DB_FILE_VERSION 1
+
+typedef struct _KviReguserDbFileHeader
+{
+ unsigned int magic;
+ unsigned int version;
+ unsigned int nentries;
+} KviReguserDbFileHeader;
+
+void KviRegisteredUsersDialog::exportClicked()
+{
+ unsigned int nEntries = 0;
+
+ KviTalListViewItemIterator it( m_pListView, KviTalListViewItemIterator::Selected );
+ KviTalListViewItemIterator cit( m_pListView, KviTalListViewItemIterator::Selected );
+ while ( cit.current() ) {
+ if(((KviRegisteredUsersDialogItemBase *)(cit.current()))->type() == KviRegisteredUsersDialogItemBase::User)
+ nEntries++;
+ ++cit;
+ }
+
+ if(nEntries < 1)
+ {
+ KviMessageBox::warning(__tr("No entries selected."));
+ return;
+ }
+
+ QString buffer;
+
+ if(!KviFileDialog::askForSaveFileName(buffer,__tr("Choose a Filename - KVIrc"),0,0,true,true))return;
+
+ if(!g_pRegisteredUsersDialog)return; // we have been deleted!
+
+ KviFile f(buffer);
+ if(!f.open(IO_WriteOnly | IO_Truncate))
+ {
+ KviMessageBox::warning(__tr("Can't open file %Q for writing."),&buffer);
+ return;
+ }
+
+ KviReguserDbFileHeader hf;
+ hf.magic = KVI_REGUSER_DB_FILE_MAGIC;
+ hf.version = KVI_REGUSER_DB_FILE_VERSION;
+ hf.nentries = nEntries;
+
+ if(f.writeBlock((const char *)&hf,sizeof(KviReguserDbFileHeader)) != sizeof(KviReguserDbFileHeader))goto write_error;
+
+ while ( it.current() ) {
+ KviRegisteredUsersDialogItemBase *pBase = (KviRegisteredUsersDialogItemBase *)(it.current());
+ if(pBase->type()!=KviRegisteredUsersDialogItemBase::User) continue;
+ QString szName = it.current()->text(0);
+ KviRegisteredUser * u = ((KviRegisteredUsersDialogItem *)(it.current()))->user();
+ if(u)
+ {
+ if(!f.save(szName))goto write_error;
+ KviPointerHashTable<QString,QString> * pd = u->propertyDict();
+ if(pd)
+ {
+ if(!f.save(pd->count()))goto write_error;
+ for(KviPointerHashTableEntry<QString,QString> * pCur = pd->firstEntry();pCur;pCur = pd->nextEntry())
+ {
+ QString key = pCur->key();
+ if(!f.save(key))goto write_error;
+ if(!f.save(*(pCur->data())))goto write_error;
+ }
+ } else {
+ if(!f.save(0))goto write_error;
+ }
+
+ KviPointerList<KviIrcMask> * ml = u->maskList();
+ if(ml)
+ {
+ if(!f.save(ml->count()))goto write_error;
+ for(KviIrcMask * m = ml->first();m;m = ml->next())
+ {
+ QString fullMask;
+ m->mask(fullMask,KviIrcMask::NickUserHost);
+ if(!f.save(fullMask))goto write_error;
+ }
+ } else {
+ if(!f.save(0))goto write_error;
+ }
+
+ QString avatar;
+ if(u->getProperty("avatar",avatar))
+ {
+ KviAvatar * av = g_pIconManager->getAvatar(QString::null,avatar);
+ if(av)
+ {
+ if(!av->pixmap()->isNull())
+ {
+ if(!f.save(1))goto write_error;
+#ifdef COMPILE_USE_QT4
+ QImageWriter io;
+ io.setDevice(&f);
+ io.setFormat("PNG");
+ if(!io.write(av->pixmap()->convertToImage()))goto write_error;
+#else
+ QImageIO io;
+ io.setImage(av->pixmap()->convertToImage());
+ io.setIODevice(&f);
+ io.setFormat("PNG");
+ if(!io.write())goto write_error;
+#endif
+ } else {
+ if(!f.save(0))goto write_error;
+ }
+ } else {
+ if(!f.save(0))goto write_error;
+ }
+ } else {
+ if(!f.save(0))goto write_error;
+ }
+ }
+ ++it;
+ }
+
+ goto succesfull_export;
+
+
+write_error:
+ KviMessageBox::warning(__tr("Can't export the registered users database: Write error."));
+ f.close();
+ return;
+
+succesfull_export:
+
+ f.close();
+}
+
+void KviRegisteredUsersDialog::importClicked()
+{
+ //KviStr buffer;
+ QString buffer;
+
+ if(!KviFileDialog::askForOpenFileName(buffer,__tr("Choose a Filename - KVIrc")))return;
+
+ if(!g_pRegisteredUsersDialog)return; // we have been deleted!
+
+ KviFile f(buffer);
+ if(!f.open(IO_ReadOnly))
+ {
+ KviMessageBox::warning(__tr2qs("Can't open file %s for reading."),&buffer);
+ return;
+ }
+
+ KviReguserDbFileHeader hf;
+ unsigned int idx;
+
+ if(f.readBlock((char *)&hf,sizeof(KviReguserDbFileHeader)) != sizeof(KviReguserDbFileHeader))goto read_error;
+
+ if(hf.magic != KVI_REGUSER_DB_FILE_MAGIC)
+ {
+ KviMessageBox::warning(__tr2qs("The file %s doesn't appear to be a valid registered users database."),&buffer);
+ f.close();
+ return;
+ }
+
+ if(hf.version != KVI_REGUSER_DB_FILE_VERSION)
+ {
+ KviMessageBox::warning(__tr2qs("The file %s contains an invalid registered users database version."),&buffer);
+ f.close();
+ return;
+ }
+
+
+
+ for(idx = 0;idx < hf.nentries;idx++)
+ {
+ QString szName;
+ if(!f.load(szName))goto read_error;
+ KviRegisteredUser * u = g_pLocalRegisteredUserDataBase->getUser(szName);
+ unsigned int count = 0;
+ if(!f.load(count))goto read_error;
+ for(unsigned int up = 0;up < count;up++)
+ {
+ QString szKey,szValue;
+ if(!f.load(szKey))goto read_error;
+ if(!f.load(szValue))goto read_error;
+ u->setProperty(szKey,szValue);
+ }
+ if(!f.load(count))goto read_error;
+ for(unsigned int um = 0;um < count;um++)
+ {
+ QString szMask;
+ if(!f.load(szMask))goto read_error;
+ if(!szMask.isEmpty())
+ {
+ KviIrcMask * m = new KviIrcMask(szMask);
+ g_pLocalRegisteredUserDataBase->addMask(u,m);
+ }
+ }
+ if(!f.load(count))goto read_error;
+ if(count)
+ {
+ // there is an avatar
+ QImage img;
+#ifdef COMPILE_USE_QT4
+ QImageReader io;
+ io.setDevice(&f);
+ io.setFormat("PNG");
+ img=io.read();
+// if(io.read())goto read_error;
+
+#else
+ QImageIO io;
+ io.setImage(img);
+ io.setIODevice(&f);
+ io.setFormat("PNG");
+
+ if(!io.read())goto read_error;
+
+ img = io.image();
+#endif
+ if(img.isNull())debug("Ops.. readed a null image ?");
+
+ KviStr fName = u->name();
+ kvi_encodeFileName(fName);
+
+ KviStr fPath;
+ int rnm = 0 ;
+ do
+ {
+ g_pApp->getLocalKvircDirectory(fPath,KviApp::Avatars,fName.ptr());
+ fPath.append(KviStr::Format,"%d.png",rnm);
+ rnm++;
+ } while(KviFileUtils::fileExists(fPath.ptr()));
+
+ if(!img.save(fPath.ptr(),"PNG"))
+ {
+ debug("Can't save image %s",fPath.ptr());
+ } else {
+ u->setProperty("avatar",fPath.ptr());
+ }
+ }
+ }
+
+ goto succesfull_import;
+
+
+read_error:
+ KviMessageBox::warning(__tr("Can't import the registered users database: Read error."));
+ f.close();
+ return;
+
+succesfull_import:
+
+ f.close();
+ fillList();
+}
+#if defined(COMPILE_USE_QT4) && defined(COMPILE_ON_WINDOWS)
+#include "dialog.moc"
+#endif
diff --git a/src/modules/reguser/dialog.h b/src/modules/reguser/dialog.h
new file mode 100644
index 00000000..c292adc4
--- /dev/null
+++ b/src/modules/reguser/dialog.h
@@ -0,0 +1,148 @@
+#ifndef _DIALOG_H_
+#define _DIALOG_H_
+//=============================================================================
+//
+// File : edituser.h
+// Creation date : Sun Dec 24 2000 15:16:17 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 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_string.h"
+#include "kvi_regusersdb.h"
+#include "kvi_selectors.h"
+
+#include <qwidget.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include "kvi_tal_listview.h"
+#include "kvi_tal_listbox.h"
+#include "kvi_pointerhashtable.h"
+#include "kvi_tal_popupmenu.h"
+#ifdef COMPILE_USE_QT4
+ #include <q3intdict.h>
+ #include <q3simplerichtext.h>
+ #define QSimpleRichText Q3SimpleRichText
+#else
+ #include <qsimplerichtext.h>
+ #include <qintdict.h>
+
+
+#endif
+
+class KviRegisteredUsersDialogItemBase : public KviTalListViewItem
+{
+public:
+ enum Types { User,Group };
+protected:
+ KviRegisteredUsersDialogItemBase(Types type,KviTalListView * par)
+ :KviTalListViewItem(par),m_iType(type)
+ {
+ };
+ KviRegisteredUsersDialogItemBase(Types type,KviTalListViewItem * par)
+ :KviTalListViewItem(par),m_iType(type)
+ {
+ };
+ ~KviRegisteredUsersDialogItemBase()
+ {
+ };
+
+private:
+ KviRegisteredUsersDialogItemBase::Types m_iType;
+public:
+ KviRegisteredUsersDialogItemBase::Types type() { return m_iType; };
+};
+
+class KviRegisteredUsersGroupItem : public KviRegisteredUsersDialogItemBase
+{
+protected:
+ KviRegisteredUserGroup * m_pGroup;
+public:
+ KviRegisteredUsersGroupItem(KviTalListView * par,KviRegisteredUserGroup * g)
+ :KviRegisteredUsersDialogItemBase(Group,par), m_pGroup(g)
+ {
+ setText(0,m_pGroup->name());
+ }
+ ~KviRegisteredUsersGroupItem()
+ {
+ }
+ KviRegisteredUserGroup * group() { return m_pGroup; };
+};
+
+class KviRegisteredUsersDialogItem : public KviRegisteredUsersDialogItemBase
+{
+protected:
+ KviRegisteredUser * m_pUser;
+ QSimpleRichText * m_pText;
+public:
+ KviRegisteredUsersDialogItem(KviTalListViewItem * par,KviRegisteredUser * u);
+ ~KviRegisteredUsersDialogItem();
+public:
+ KviRegisteredUser * user(){ return m_pUser; };
+ void setUser(KviRegisteredUser * u){ m_pUser = u; };
+ virtual void paintCell(QPainter * p,const QColorGroup &cg,int column,int width,int align);
+ virtual void setup();
+ virtual QString key(int,bool) const;
+};
+
+class KviRegisteredUsersDialog : public QWidget
+{
+ Q_OBJECT
+public:
+ KviRegisteredUsersDialog(QWidget * par = 0);
+ ~KviRegisteredUsersDialog();
+public:
+ KviTalListView * m_pListView;
+ QPushButton * m_pAddButton;
+ QPushButton * m_pWizardAddButton;
+ QPushButton * m_pRemoveButton;
+ QPushButton * m_pEditButton;
+ QPushButton * m_pImportButton;
+ QPushButton * m_pExportButton;
+ QPushButton * m_pAddGroupButton;
+#ifdef COMPILE_USE_QT4
+ Q3IntDict<KviRegisteredUserGroup> m_TmpDict;
+#else
+ QIntDict<KviRegisteredUserGroup> m_TmpDict;
+#endif
+
+ protected slots:
+ void itemPressed(KviTalListViewItem *it,const QPoint &pnt,int c);
+ void itemDoubleClicked(KviTalListViewItem *it);
+protected:
+ void fillList();
+protected:
+ virtual void closeEvent(QCloseEvent *);
+ void editItem(KviRegisteredUsersDialogItem * i);
+ void editGroup(KviRegisteredUserGroup* group);
+protected slots:
+ void cancelClicked();
+ void okClicked();
+ void addClicked();
+ void removeClicked();
+ void editClicked();
+ void selectionChanged();
+ void importClicked();
+ void exportClicked();
+ void addWizardClicked();
+ void addGroupClicked();
+ void listViewRightButtonClicked ( KviTalListViewItem *, const QPoint &, int );
+ void moveToGroupMenuClicked(int);
+};
+
+#endif
diff --git a/src/modules/reguser/edituser.cpp b/src/modules/reguser/edituser.cpp
new file mode 100644
index 00000000..f0d6d6b9
--- /dev/null
+++ b/src/modules/reguser/edituser.cpp
@@ -0,0 +1,781 @@
+//=============================================================================
+//
+// File : edituser.cpp
+// Creation date : Tue Dec 26 2000 12:24:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 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 _WANT_OPTION_FLAGS_
+#define _EDITUSER_CPP_
+
+#include "edituser.h"
+#include "kvi_regusersdb.h"
+
+#include "kvi_locale.h"
+#include "kvi_ircmask.h"
+#include "kvi_debug.h"
+#include "kvi_iconmanager.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_file.h"
+#include "kvi_filedialog.h"
+#include "kvi_msgbox.h"
+#include "kvi_fileutils.h"
+#include "kvi_settings.h"
+#include "kvi_stringconversion.h"
+#include "kvi_options.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qgroupbox.h>
+#ifdef COMPILE_USE_QT4
+#include <qevent.h>
+#include <q3header.h>
+#include <q3vbox.h>
+#else
+#include <qheader.h>
+#endif
+#include "kvi_pointerhashtable.h"
+#include <qimage.h>
+#include <qstring.h>
+#include <qcombobox.h>
+
+
+#include <qstyle.h>
+#include <qpainter.h>
+#include "kvi_tal_hbox.h"
+#include "kvi_tal_vbox.h"
+#include <qinputdialog.h>
+
+#include "wizard.h"
+#include "dialog.h"
+
+
+#ifdef COMPILE_INFO_TIPS
+ #include <qtooltip.h>
+#endif // COMPILE_INFO_TIPS
+
+// kvi_app.cpp
+extern KviRegisteredUsersDialog * g_pRegisteredUsersDialog;
+
+KviRegisteredUserDataBase * g_pLocalRegisteredUserDataBase; // local copy!
+
+
+
+KviReguserPropertiesDialog::KviReguserPropertiesDialog(QWidget * p,KviPointerHashTable<QString,QString> * dict)
+: QDialog(p,"property_editor",true)
+{
+ m_pPropertyDict = dict;
+
+ setCaption(__tr2qs("Property Editor"));
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LINUX)));
+
+ QGridLayout * g = new QGridLayout(this,3,3,4,4);
+
+#ifdef COMPILE_USE_QT4
+ m_pTable = new Q3Table(this);
+#else
+ m_pTable = new QTable(this);
+#endif
+ g->addMultiCellWidget(m_pTable,0,1,0,1);
+
+ m_pTable->setNumCols(2);
+ m_pTable->setSelectionMode(Kvi_Tal_Table::NoSelection);
+
+ m_pTable->horizontalHeader()->setLabel(0,__tr2qs("Property"));
+ m_pTable->horizontalHeader()->setLabel(1,__tr2qs("Value"));
+
+ m_pTable->setMinimumSize(250,250);
+ //connect(m_pTable,SIGNAL(valueChanged(int,int)),this,SLOT(propertyValueChanged(int,int)));
+
+ KviTalVBox * vb = new KviTalVBox(this);
+ vb->setSpacing(4);
+ g->addWidget(vb,0,2);
+
+ m_pAddButton = new QPushButton(__tr2qs("&New"),vb);
+ connect(m_pAddButton,SIGNAL(clicked()),this,SLOT(addClicked()));
+ m_pAddButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NEWITEM)));
+
+ m_pDelButton = new QPushButton(__tr2qs("&Remove"),vb);
+ connect(m_pDelButton,SIGNAL(clicked()),this,SLOT(delClicked()));
+ m_pDelButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DELETEITEM)));
+
+ KviTalHBox * b = new KviTalHBox(this);
+ b->setSpacing(4);
+ g->addMultiCellWidget(b,2,2,1,2);
+
+ QPushButton * pb = new QPushButton(__tr2qs("&OK"),b);
+ connect(pb,SIGNAL(clicked()),this,SLOT(okClicked()));
+ pb->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+
+
+ pb = new QPushButton(__tr2qs("Cancel"),b);
+ connect(pb,SIGNAL(clicked()),this,SLOT(reject()));
+ pb->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+
+ g->setRowStretch(1,1);
+ g->setColStretch(0,1);
+
+ fillData();
+}
+
+KviReguserPropertiesDialog::~KviReguserPropertiesDialog()
+{
+}
+
+void KviReguserPropertiesDialog::closeEvent(QCloseEvent *e)
+{
+ e->accept();
+ //delete this;
+}
+
+void KviReguserPropertiesDialog::fillData()
+{
+ m_pTable->setNumRows(m_pPropertyDict->count());
+ KviPointerHashTableIterator<QString,QString> it(*m_pPropertyDict);
+ int row = 0;
+ while(it.current())
+ {
+ m_pTable->setItem(row,0,new Kvi_Tal_TableItem(m_pTable,Kvi_Tal_TableItem::OnTyping,it.currentKey()));
+ m_pTable->setItem(row,1,new Kvi_Tal_TableItem(m_pTable,Kvi_Tal_TableItem::OnTyping,*(it.current())));
+ ++row;
+ ++it;
+ }
+ if(m_pTable->numRows() == 0)m_pDelButton->setEnabled(false);
+}
+
+void KviReguserPropertiesDialog::okClicked()
+{
+ m_pPropertyDict->clear();
+
+ int n = m_pTable->numRows();
+ for(int i=0;i<n;i++)
+ {
+ QString szName = m_pTable->text(i,0);
+ QString szValue = m_pTable->text(i,1);
+ if((!szName.isEmpty()) && (!szValue.isEmpty()))
+ {
+ m_pPropertyDict->replace(szName,new QString(szValue));
+ }
+ }
+
+ accept();
+}
+
+
+void KviReguserPropertiesDialog::addClicked()
+{
+ m_pTable->setNumRows(m_pTable->numRows() + 1);
+ m_pTable->setItem(m_pTable->numRows() - 1,0,new Kvi_Tal_TableItem(m_pTable,Kvi_Tal_TableItem::OnTyping,""));
+ m_pTable->setItem(m_pTable->numRows() - 1,1,new Kvi_Tal_TableItem(m_pTable,Kvi_Tal_TableItem::OnTyping,""));
+ m_pDelButton->setEnabled(true);
+}
+
+void KviReguserPropertiesDialog::delClicked()
+{
+ int i = m_pTable->currentRow();
+
+ if((i > -1) && (i < m_pTable->numRows()))
+ {
+ // remove row i
+ m_pTable->clearCell(i,0);
+ m_pTable->clearCell(i,1);
+
+ for(;i < (m_pTable->numRows() - 1);i++)
+ {
+ m_pTable->swapRows(i,i+1);
+ }
+ m_pTable->setNumRows(m_pTable->numRows() - 1);
+ if(m_pTable->numRows() == 0)m_pDelButton->setEnabled(false);
+ }
+}
+
+
+KviReguserMaskDialog::KviReguserMaskDialog(QWidget * p,KviIrcMask * m)
+: QDialog(p,"reguser_mask_editor",true)
+{
+ m_pMask = m;
+
+ setCaption(__tr2qs("Mask Editor"));
+
+ QGridLayout * g = new QGridLayout(this,3,2,4,4);
+
+ QLabel * l = new QLabel(__tr2qs("Insert a mask for this user.<br>It can contain the wildcard characters '*' and '?'."),this);
+ //l->setAlignment(Qt::AlignCenter);
+ g->addMultiCellWidget(l,0,0,0,1);
+
+ KviTalHBox * b = new KviTalHBox(this);
+ g->addMultiCellWidget(b,1,1,0,1);
+
+ m_pNickEdit = new QLineEdit(b);
+ //m_pNickEdit->setMinimumWidth(120);
+ m_pNickEdit->setAlignment(Qt::AlignRight);
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pNickEdit,__tr2qs("<center>This the <b>nickname</b> that will match this user, default value is the registered name.</center>"));
+#endif
+
+ l = new QLabel("<center><b>!</b></center>",b);
+ l->setAlignment(Qt::AlignCenter);
+ //l->setMinimumWidth(40);
+
+ m_pUserEdit = new QLineEdit(b);
+ //m_pUserEdit->setMinimumWidth(120);
+ m_pUserEdit->setAlignment(Qt::AlignCenter);
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pUserEdit,__tr2qs("<center>This the <b>username</b> that will match this user. <b>*</b> will match any username.</center>"));
+#endif
+
+ l = new QLabel("<center><b>@</b></center>",b);
+ l->setAlignment(Qt::AlignCenter);
+ //l->setMinimumWidth(40);
+
+ m_pHostEdit = new QLineEdit(b);
+ //m_pHostEdit->setMinimumWidth(120);
+ m_pHostEdit->setAlignment(Qt::AlignLeft);
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pHostEdit,__tr2qs("<center>This the <b>hostname</b> that will match this user. <b>*</b> will match any hostname.</center>"));
+#endif
+
+ // just a spacer
+// l = new QLabel("<nobr>&nbsp;<nobr>",this);
+// g->addMultiCellWidget(l,2,2,0,1);
+
+// QFrame * f = new QFrame(this);
+// f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+// g->addMultiCellWidget(f,3,3,0,1);
+
+ b = new KviTalHBox(this);
+ b->setSpacing(4);
+ g->addWidget(b,2,1);
+
+ QPushButton * pb = new QPushButton(__tr2qs("&OK"),b);
+ connect(pb,SIGNAL(clicked()),this,SLOT(okClicked()));
+ //pb->setMinimumWidth(120);
+
+ pb = new QPushButton(__tr2qs("Cancel"),b);
+ connect(pb,SIGNAL(clicked()),this,SLOT(reject()));
+ //pb->setMinimumWidth(120);
+
+
+
+ g->setColStretch(0,1);
+ g->setRowStretch(0,1);
+
+ m_pNickEdit->setText(m->nick());
+ m_pUserEdit->setText(m->user());
+ m_pHostEdit->setText(m->host());
+}
+
+KviReguserMaskDialog::~KviReguserMaskDialog()
+{
+}
+
+void KviReguserMaskDialog::closeEvent(QCloseEvent *e)
+{
+ e->accept();
+ //delete this;
+}
+
+void KviReguserMaskDialog::okClicked()
+{
+ KviStr szTmp = m_pNickEdit->text();
+ if(szTmp.isEmpty())szTmp = "*";
+ m_pMask->setNick(szTmp.ptr());
+
+ szTmp = m_pUserEdit->text();
+ if(szTmp.isEmpty())szTmp = "*";
+ m_pMask->setUsername(szTmp.ptr());
+
+ szTmp = m_pHostEdit->text();
+ if(szTmp.isEmpty())szTmp = "*";
+ m_pMask->setHost(szTmp.ptr());
+
+ accept();
+}
+
+
+
+
+KviRegisteredUserEntryDialog::KviRegisteredUserEntryDialog(QWidget *p,KviRegisteredUser * r,bool bModal)
+: KviTalTabDialog(p,"reguser_entry_editor",bModal)
+{
+ m_pUser = r;
+ m_pCustomColor = new QColor();
+
+ if(r)
+ {
+ QString col=r->getProperty("customColor");
+ KviStringConversion::fromString(col,(*m_pCustomColor));
+ }
+
+ m_pPropertyDict = new KviPointerHashTable<QString,QString>(17,false);
+ m_pPropertyDict->setAutoDelete(true);
+
+ //setMinimumSize(400,450);
+
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LINUX)));
+ setCaption(__tr2qs("Registered User Entry"));
+
+ QWidget * p1 = new QWidget(this);
+
+ QGridLayout * g = new QGridLayout(p1,6,2,4,4);
+
+ QLabel * l = new QLabel(__tr2qs("Name:"),p1);
+ g->addWidget(l,0,0);
+
+ m_pNameEdit = new QLineEdit(p1);
+ g->addWidget(m_pNameEdit,0,1);
+
+ l = new QLabel(__tr2qs("Comment:"),p1);
+ g->addWidget(l,1,0);
+
+ m_pCommentEdit = new QLineEdit(p1);
+ g->addWidget(m_pCommentEdit,1,1);
+
+ QFrame * f = new QFrame(p1);
+ g->addMultiCellWidget(f,2,2,0,1);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+
+ l = new QLabel(__tr2qs("Masks:"),p1);
+ g->addMultiCellWidget(l,3,3,0,1);
+
+ m_pMaskListBox = new KviTalListBox(p1);
+ connect(m_pMaskListBox,SIGNAL(currentChanged(KviTalListBoxItem *)),this,SLOT(maskCurrentChanged(KviTalListBoxItem *)));
+ m_pMaskListBox->setMinimumSize(300,200);
+
+ g->addMultiCellWidget(m_pMaskListBox,4,4,0,1);
+
+ KviTalHBox * b = new KviTalHBox(p1);
+ g->addMultiCellWidget(b,5,5,0,1);
+ b->setSpacing(4);
+
+ m_pAddMaskButton = new QPushButton(__tr2qs("&Add..."),b);
+ connect(m_pAddMaskButton,SIGNAL(clicked()),this,SLOT(addMaskClicked()));
+ m_pAddMaskButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NEWITEM)));
+
+ m_pDelMaskButton = new QPushButton(__tr2qs("Re&move"),b);
+ m_pDelMaskButton->setEnabled(false);
+ connect(m_pDelMaskButton,SIGNAL(clicked()),this,SLOT(delMaskClicked()));
+ m_pDelMaskButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DELETEITEM)));
+
+ m_pEditMaskButton = new QPushButton(__tr2qs("&Edit"),b);
+ m_pEditMaskButton->setEnabled(false);
+ connect(m_pEditMaskButton,SIGNAL(clicked()),this,SLOT(editMaskClicked()));
+ m_pEditMaskButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_EDITITEM)));
+
+ g->setRowStretch(4,1);
+ g->setColStretch(1,1);
+
+ addTab(p1,__tr2qs("Identity"));
+
+
+
+ QWidget * p2 = new QWidget(this);
+
+ g = new QGridLayout(p2,6,3,5,2);
+
+ m_pNotifyCheck = new KviStyledCheckBox(__tr2qs("Notify when user is online"),p2);
+ g->addMultiCellWidget(m_pNotifyCheck,0,0,0,2);
+
+ l = new QLabel(__tr2qs("Notify nicknames:"),p2);
+ l->setEnabled(m_pNotifyCheck->isChecked());
+ g->addWidget(l,1,0);
+ connect(m_pNotifyCheck,SIGNAL(toggled(bool)),l,SLOT(setEnabled(bool)));
+#ifdef COMPILE_INFO_TIPS
+ QToolTip::add(m_pNotifyCheck,__tr2qs("<center>You can enter a space separated list of nicknames.</center>"));
+#endif
+
+
+ m_pNotifyNick = new QLineEdit(p2);
+ m_pNotifyNick->setEnabled(false);
+ g->addMultiCellWidget(m_pNotifyNick,1,1,1,2);
+ connect(m_pNotifyCheck,SIGNAL(toggled(bool)),m_pNotifyNick,SLOT(setEnabled(bool)));
+
+
+ f = new QFrame(p2);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ g->addMultiCellWidget(f,2,2,0,2);
+
+ m_pAvatar = 0;
+ if(r)
+ {
+ const char * av = r->getProperty("avatar");
+ if(av)
+ {
+ m_pAvatar = new KviPixmap(av);
+ }
+ }
+ if(!m_pAvatar)m_pAvatar = new KviPixmap();
+
+ m_pAvatarSelector = new KviPixmapSelector(p2,__tr2qs("Avatar"),m_pAvatar,true);
+ g->addMultiCellWidget(m_pAvatarSelector,3,3,0,2);
+
+ f = new QFrame(p2);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ g->addMultiCellWidget(f,4,4,0,2);
+
+ m_pCustomColorCheck = new KviStyledCheckBox(__tr2qs("Use custom color in userlist"),p2);
+ if(r)
+ m_pCustomColorCheck->setChecked(r->getBoolProperty("useCustomColor"));
+ g->addMultiCellWidget(m_pCustomColorCheck,5,5,0,1);
+
+ m_pCustomColorSelector = new KviColorSelector(p2,QString::null,m_pCustomColor,1);
+ g->addWidget(m_pCustomColorSelector,5,2);
+
+ QPushButton * pb = new QPushButton(__tr2qs("All Properties..."),p2);
+ connect(pb,SIGNAL(clicked()),this,SLOT(editAllPropertiesClicked()));
+ g->addWidget(pb,6,2);
+
+ g->setColStretch(1,1);
+ g->setRowStretch(3,1);
+
+ addTab(p2,__tr2qs("Properties"));
+
+ // Ignore TAB
+#ifdef COMPILE_USE_QT4
+ Q3VBox * vb = new Q3VBox(this);
+#else
+ QVBox * vb = new QVBox(this);
+#endif
+ vb->setMargin(10);
+
+ m_pIgnoreEnabled = new KviStyledCheckBox(__tr2qs("Enable ignore for this user"),vb);
+
+ QGroupBox * gb = new QGroupBox(__tr2qs("Ignore features"),vb);
+ connect(m_pIgnoreEnabled,SIGNAL(toggled(bool)),gb,SLOT(setEnabled(bool)));
+
+ QVBoxLayout * layout = new QVBoxLayout(gb,20,3);
+
+ m_pIgnoreQuery = new KviStyledCheckBox(__tr2qs("Ignore query-messages"),gb);
+ layout->addWidget(m_pIgnoreQuery);
+
+ m_pIgnoreChannel = new KviStyledCheckBox(__tr2qs("Ignore channel-messages"),gb);
+ layout->addWidget(m_pIgnoreChannel);
+
+ m_pIgnoreNotice = new KviStyledCheckBox(__tr2qs("Ignore notice-messages"),gb);
+ layout->addWidget(m_pIgnoreNotice);
+
+ m_pIgnoreCtcp = new KviStyledCheckBox(__tr2qs("Ignore ctcp-messages"),gb);
+ layout->addWidget(m_pIgnoreCtcp);
+
+ m_pIgnoreInvite = new KviStyledCheckBox(__tr2qs("Ignore invites"),gb);
+ layout->addWidget(m_pIgnoreInvite);
+
+ m_pIgnoreDcc = new KviStyledCheckBox(__tr2qs("Ignore DCCs"),gb);
+ layout->addWidget(m_pIgnoreDcc);
+
+ QWidget *w = new QWidget(vb);
+ w->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
+
+ addTab(vb,__tr2qs("Ignore"));
+
+ setCancelButton(__tr2qs("Cancel"));
+ setOkButton(__tr2qs("&OK"));
+ connect(this,SIGNAL(applyButtonPressed()),this,SLOT(okClicked()));
+ connect(this,SIGNAL(cancelButtonPressed()),this,SLOT(reject()));
+
+ if(r)
+ {
+ m_pNameEdit->setText(r->name());
+ m_pCommentEdit->setText(r->getProperty("comment"));
+ for(KviIrcMask * m = r->maskList()->first();m;m = r->maskList()->next())
+ {
+ QString mk = m->nick();
+ mk += QChar('!');
+ mk += m->user();
+ mk += QChar('@');
+ mk += m->host();
+ m_pMaskListBox->insertItem(mk);
+ }
+
+ QString szNotifyNicks = r->getProperty("notify");
+ if(!szNotifyNicks.isEmpty())
+ {
+ m_pNotifyCheck->setChecked(true);
+ m_pNotifyNick->setText(szNotifyNicks);
+ m_pNotifyNick->setEnabled(true);
+ }
+
+ if(r->propertyDict())
+ {
+ KviPointerHashTableIterator<QString,QString> it(*(r->propertyDict()));
+ while(QString *s = it.current())
+ {
+ m_pPropertyDict->insert(it.currentKey(),new QString(*s));
+ ++it;
+ }
+ }
+
+ m_pIgnoreEnabled->setChecked(r->ignoreEnagled());
+
+ gb->setEnabled(r->ignoreEnagled());
+
+ m_pIgnoreQuery->setChecked(r->ignoreFlags() & KviRegisteredUser::Query);
+ m_pIgnoreChannel->setChecked(r->ignoreFlags() & KviRegisteredUser::Channel);
+ m_pIgnoreNotice->setChecked(r->ignoreFlags() & KviRegisteredUser::Notice);
+ m_pIgnoreCtcp->setChecked(r->ignoreFlags() & KviRegisteredUser::Ctcp);
+ m_pIgnoreInvite->setChecked(r->ignoreFlags() & KviRegisteredUser::Invite);
+ m_pIgnoreDcc->setChecked(r->ignoreFlags() & KviRegisteredUser::Dcc);
+ } else {
+ // default values
+ if(!m_pIgnoreEnabled->isChecked())
+ {
+ gb->setEnabled(false);
+ }
+ }
+}
+
+void KviRegisteredUserEntryDialog::closeEvent(QCloseEvent *e)
+{
+ e->accept();
+ okClicked();
+ //delete this;
+}
+
+KviRegisteredUserEntryDialog::~KviRegisteredUserEntryDialog()
+{
+ delete m_pAvatar;
+ delete m_pPropertyDict;
+ delete m_pCustomColor;
+}
+
+void KviRegisteredUserEntryDialog::maskCurrentChanged(KviTalListBoxItem *it)
+{
+ m_pDelMaskButton->setEnabled(it);
+ m_pEditMaskButton->setEnabled(it);
+}
+
+void KviRegisteredUserEntryDialog::okClicked()
+{
+ QString szGroup;
+ if(m_pUser)
+ {
+ szGroup=m_pUser->group();
+ g_pLocalRegisteredUserDataBase->removeUser(m_pUser->name());
+ }
+
+ QString name = m_pNameEdit->text();
+
+ if(name.isEmpty())name = "user";
+
+ KviRegisteredUser * u;
+
+ QString szNameOk = name;
+
+ int idx = 1;
+
+ do {
+ u = g_pLocalRegisteredUserDataBase->findUserByName(szNameOk);
+ if(u)
+ {
+ KviQString::sprintf(szNameOk,"%Q%d",&name,idx);
+ idx++;
+ }
+ } while(u);
+
+
+ u = g_pLocalRegisteredUserDataBase->addUser(szNameOk);
+ u->setGroup(szGroup);
+
+ if(!u)
+ {
+ // ops... no way
+ // FIXME: spit an error message ?
+ debug("Ops.. something wrong with the regusers db");
+ accept();
+ return;
+ }
+
+ int cnt = m_pMaskListBox->count();
+ idx = 0;
+ while(cnt > 0)
+ {
+ QString mask = m_pMaskListBox->text(idx);
+ KviIrcMask * mk = new KviIrcMask(mask);
+ g_pLocalRegisteredUserDataBase->removeMask(*mk);
+ g_pLocalRegisteredUserDataBase->addMask(u,mk);
+ cnt--;
+ idx++;
+ }
+ u->setProperty("comment",m_pCommentEdit->text());
+
+ m_pAvatarSelector->commit();
+
+ if(!m_pAvatar->isNull())
+ {
+ QString szPath = m_pAvatar->path();
+ u->setProperty("avatar",szPath);
+ }
+
+ if(m_pNotifyCheck->isChecked())
+ {
+ QString szNicks = m_pNotifyNick->text();
+
+ if(!szNicks.isEmpty())
+ {
+ u->setProperty("notify",szNicks);
+ }
+ }
+
+ m_pPropertyDict->remove("notify");
+ m_pPropertyDict->remove("avatar");
+
+ KviPointerHashTableIterator<QString,QString> it(*m_pPropertyDict);
+ while(QString *s = it.current())
+ {
+ u->setProperty(it.currentKey(),*s);
+ ++it;
+ }
+
+ u->setProperty("useCustomColor",m_pCustomColorCheck->isChecked());
+
+ QString col;
+ KviStringConversion::toString(m_pCustomColorSelector->getColor(),col);
+ u->setProperty("customColor",col);
+
+
+ int iIgnoreFlags=0;
+ u->setIgnoreEnabled(m_pIgnoreEnabled->isChecked());
+ if(m_pIgnoreQuery->isChecked())
+ iIgnoreFlags |= KviRegisteredUser::Query;
+ if(m_pIgnoreChannel->isChecked())
+ iIgnoreFlags |= KviRegisteredUser::Channel;
+ if(m_pIgnoreNotice->isChecked())
+ iIgnoreFlags |= KviRegisteredUser::Notice;
+ if(m_pIgnoreCtcp->isChecked())
+ iIgnoreFlags |= KviRegisteredUser::Ctcp;
+ if(m_pIgnoreInvite->isChecked())
+ iIgnoreFlags |= KviRegisteredUser::Invite;
+ if(m_pIgnoreDcc->isChecked())
+ iIgnoreFlags |= KviRegisteredUser::Dcc;
+
+ u->setIgnoreFlags(iIgnoreFlags);
+ accept();
+ g_pApp->optionResetUpdate(KviOption_resetUpdateGui);
+}
+
+
+void KviRegisteredUserEntryDialog::addMaskClicked()
+{
+ KviIrcMask mk;
+ KviReguserMaskDialog * dlg = new KviReguserMaskDialog(this,&mk);
+ if(dlg->exec() == QDialog::Accepted)
+ {
+ QString m = mk.nick();
+ m += QChar('!');
+ m += mk.user();
+ m += QChar('@');
+ m += mk.host();
+ m_pMaskListBox->insertItem(m);
+ }
+ delete dlg;
+}
+
+void KviRegisteredUserEntryDialog::delMaskClicked()
+{
+ int idx = m_pMaskListBox->currentItem();
+ if(idx == -1)return;
+ m_pMaskListBox->removeItem(idx);
+}
+
+void KviRegisteredUserEntryDialog::editMaskClicked()
+{
+ int idx = m_pMaskListBox->currentItem();
+ if(idx == -1)return;
+ KviStr szM = m_pMaskListBox->text(idx);
+ if(szM.isEmpty())return;
+
+ KviIrcMask mk(szM.ptr());
+ KviReguserMaskDialog * dlg = new KviReguserMaskDialog(this,&mk);
+ if(dlg->exec() == QDialog::Accepted)
+ {
+ QString m = mk.nick();
+ m += QChar('!');
+ m += mk.user();
+ m += QChar('@');
+ m += mk.host();
+ m_pMaskListBox->changeItem(m,idx);
+ }
+ delete dlg;
+}
+
+void KviRegisteredUserEntryDialog::editAllPropertiesClicked()
+{
+ m_pAvatarSelector->commit();
+
+ if(m_pAvatar->isNull())
+ {
+ m_pPropertyDict->remove("avatar");
+ } else {
+ KviStr szPath = m_pAvatar->path();
+ if(szPath.isEmpty())m_pPropertyDict->remove("avatar");
+ else m_pPropertyDict->replace("avatar",new QString(szPath));
+ }
+
+ if(m_pNotifyCheck->isChecked())
+ {
+ QString szNicks = m_pNotifyNick->text();
+
+ if(!szNicks.isEmpty())
+ {
+ m_pPropertyDict->replace("notify",new QString(szNicks));
+ } else {
+ m_pPropertyDict->remove("notify");
+ }
+ } else {
+ m_pPropertyDict->remove("notify");
+ }
+
+
+ KviReguserPropertiesDialog * dlg = new KviReguserPropertiesDialog(this,m_pPropertyDict);
+ if(dlg->exec() != QDialog::Accepted)
+ {
+ delete dlg;
+ return;
+ }
+ delete dlg;
+
+ QString * notify = m_pPropertyDict->find("notify");
+ bool bGotIt = false;
+ if(notify)
+ {
+ if(!notify->isEmpty())
+ {
+ bGotIt = true;
+ m_pNotifyNick->setText(*notify);
+ }
+ }
+ m_pNotifyCheck->setChecked(bGotIt);
+ m_pNotifyNick->setEnabled(bGotIt);
+ if(!bGotIt)m_pNotifyNick->setText("");
+
+ QString * avatar = m_pPropertyDict->find("avatar");
+ bGotIt = false;
+ if(avatar)
+ {
+ if(!avatar->isEmpty())
+ m_pAvatarSelector->setImagePath(*avatar);
+ }
+
+}
+
+
+
+
+#include "edituser.moc"
diff --git a/src/modules/reguser/edituser.h b/src/modules/reguser/edituser.h
new file mode 100644
index 00000000..fecbbf09
--- /dev/null
+++ b/src/modules/reguser/edituser.h
@@ -0,0 +1,152 @@
+#ifndef _EDITUSER_H_
+#define _EDITUSER_H_
+//=============================================================================
+//
+// File : edituser.h
+// Creation date : Sun Dec 24 2000 15:16:17 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 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_string.h"
+#include "kvi_regusersdb.h"
+#include "kvi_selectors.h"
+
+#include <qwidget.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include "kvi_tal_listview.h"
+#include "kvi_tal_listbox.h"
+#include "kvi_pointerhashtable.h"
+#include <kvi_tal_tabdialog.h>
+#ifdef COMPILE_USE_QT4
+#include <q3table.h>
+#define Kvi_Tal_Table Q3Table
+#define Kvi_Tal_TableItem Q3TableItem
+
+#else
+#include <qtable.h>
+#define Kvi_Tal_Table QTable
+#define Kvi_Tal_TableItem QTableItem
+
+#endif
+#include "kvi_tal_popupmenu.h"
+
+#ifndef _EDITUSER_CPP_
+ extern KviRegisteredUserDataBase * g_pLocalRegisteredUserDataBase;
+#endif
+
+class KviRegisteredUser;
+
+class KviReguserPropertiesDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviReguserPropertiesDialog(QWidget *p,KviPointerHashTable<QString,QString> * dict);
+ ~KviReguserPropertiesDialog();
+protected:
+#ifdef COMPILE_USE_QT4
+ Q3Table *m_pTable;
+#else
+ QTable * m_pTable;
+#endif
+ KviPointerHashTable<QString,QString> * m_pPropertyDict;
+ QPushButton * m_pDelButton;
+ QPushButton * m_pAddButton;
+protected:
+ void fillData();
+ virtual void closeEvent(QCloseEvent *);
+protected slots:
+ void okClicked();
+ void addClicked();
+ void delClicked();
+};
+
+
+class KviReguserMaskDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviReguserMaskDialog(QWidget * p,KviIrcMask * m);
+ ~KviReguserMaskDialog();
+protected:
+ KviIrcMask * m_pMask;
+
+ QLineEdit * m_pNickEdit;
+ QLineEdit * m_pUserEdit;
+ QLineEdit * m_pHostEdit;
+
+ virtual void closeEvent(QCloseEvent *);
+protected slots:
+ void okClicked();
+};
+
+
+class KviRegisteredUserEntryDialog : public KviTalTabDialog
+{
+ Q_OBJECT
+public:
+ KviRegisteredUserEntryDialog(QWidget * p,KviRegisteredUser * r,bool bModal = true);
+ virtual ~KviRegisteredUserEntryDialog();
+protected:
+ KviRegisteredUser * m_pUser;
+
+ QLineEdit * m_pNameEdit;
+ QLineEdit * m_pCommentEdit;
+
+ KviTalListBox * m_pMaskListBox;
+
+ QPushButton * m_pDelMaskButton;
+ QPushButton * m_pEditMaskButton;
+ QPushButton * m_pAddMaskButton;
+
+ QCheckBox * m_pNotifyCheck;
+ QLineEdit * m_pNotifyNick;
+
+ KviPixmap * m_pAvatar;
+ KviPixmapSelector * m_pAvatarSelector;
+
+ KviPointerHashTable<QString,QString> * m_pPropertyDict;
+
+ QCheckBox * m_pCustomColorCheck;
+ QColor * m_pCustomColor;
+ KviColorSelector * m_pCustomColorSelector;
+
+ //Ignore TAB
+ QCheckBox * m_pIgnoreEnabled;
+ QCheckBox * m_pIgnoreQuery;
+ QCheckBox * m_pIgnoreChannel;
+ QCheckBox * m_pIgnoreNotice;
+ QCheckBox * m_pIgnoreCtcp;
+ QCheckBox * m_pIgnoreInvite;
+ QCheckBox * m_pIgnoreDcc;
+
+ virtual void closeEvent(QCloseEvent *);
+protected slots:
+ void okClicked();
+ void addMaskClicked();
+ void delMaskClicked();
+ void editMaskClicked();
+ void editAllPropertiesClicked();
+ void maskCurrentChanged(KviTalListBoxItem *it);
+};
+
+
+
+#endif //_EDITUSER_H_
diff --git a/src/modules/reguser/libkvireguser.cpp b/src/modules/reguser/libkvireguser.cpp
new file mode 100644
index 00000000..49e4a204
--- /dev/null
+++ b/src/modules/reguser/libkvireguser.cpp
@@ -0,0 +1,1239 @@
+//=============================================================================
+//
+// File : libkvireguser.cpp
+// Creation date : Fri Dec 01 2000 14:53:10 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 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_module.h"
+
+#include "kvi_regusersdb.h"
+#include "kvi_ircuserdb.h"
+#include "kvi_out.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_window.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_window.h"
+#include "kvi_frame.h"
+
+#include "edituser.h"
+#include "wizard.h"
+#include "kvi_ircconnection.h"
+#include "dialog.h"
+
+#include "kvi_pointerlist.h"
+#include <qsplitter.h> // FIXME: REmove this!
+
+//#warning "$reguser.matches..."
+//#warning "$reguser.clear"
+
+//#warning "THIS MODULE HAS TO BE REVISED (notify list consistency!!!)"
+
+// kvi_app.cpp
+
+
+extern KVIRC_API KviRegisteredUserDataBase * g_pRegisteredUserDataBase;
+
+KviPointerList<KviRegistrationWizard> * g_pRegistrationWizardList = 0;
+
+KviRegisteredUsersDialog * g_pRegisteredUsersDialog = 0;
+
+/*
+ @doc: reguser
+ @type:
+ module
+ @short:
+ Interface to the registered users database
+ @title:
+ The reguser module
+ @body:
+ The reguser module is the scripting interface to the [doc:registered_users]registered users database[/doc].[br]
+ It provides the following set of commands:[br]
+ [cmd]reguser.add[/cmd]: adds an user entry to the database[br]
+ [cmd]reguser.addmask[/cmd]: adds an user's mask to the database[br]
+ [cmd]reguser.remove[/cmd]: removes an user entry from the database[br]
+ [fnc]$reguser.list[/fnc]: lists the entries[br]
+ [cmd]reguser.setproperty[/cmd]: sets a property associated to an entry[br]
+ [cmd]reguser.edit[/cmd]: shows an editor for an user entry
+ [fnc]$reguser.match[/fnc](): finds an entry by matching masks[br]
+ [fnc]$reguser.exactMatch[/fnc](): finds an entry by comparing masks[br]
+ [fnc]$reguser.property[/fnc](): finds a property associated to an entry[br]
+ [fnc]$reguser.matchProperty[/fnc](): shortcut for [fnc]$reguser.property[/fnc]([fnc]$reguser.match[/fnc]())[br]
+ [fnc]$reguser.mask[/fnc](): returns the registration masks for an entry
+*/
+
+/*
+ @doc: reguser.edit
+ @type:
+ command
+ @title:
+ reguser.edit
+ @keyterms:
+ registering users
+ @short:
+ Opens the registeredusers dialog
+ @syntax:
+ reguser.edit [-t]
+ @switches:
+ !sw: -t | --toplevel
+ the editor is created as a toplevel window (dialog)
+ @description:
+ Shows the registered user database editor.[br]
+ If the [-t] switch is passed, the editor is created as a toplevel window (dialog), otherwise
+ it is created as part of the current main window.[br]
+ @examples:
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [fnc]$reguser.list[/fnc]
+*/
+
+static bool reguser_kvs_cmd_edit(KviKvsModuleCommandCall * c)
+{
+ if(g_pRegisteredUsersDialog)
+ {
+ if(c->hasSwitch('t',"toplevel"))
+ {
+ if(g_pRegisteredUsersDialog->parent())
+ {
+ g_pRegisteredUsersDialog->reparent(0,QPoint(0,0),true);
+ }
+ } else {
+ if(g_pRegisteredUsersDialog->parent() != c->window()->frame()->splitter())
+ {
+ g_pRegisteredUsersDialog->reparent(c->window()->frame()->splitter(),QPoint(0,0),true);
+ }
+ }
+ } else {
+ if(c->hasSwitch('t',"toplevel"))
+ {
+ g_pRegisteredUsersDialog = new KviRegisteredUsersDialog(0);
+ } else {
+ g_pRegisteredUsersDialog = new KviRegisteredUsersDialog(c->window()->frame()->splitter());
+ }
+ }
+ g_pRegisteredUsersDialog->show();
+ g_pRegisteredUsersDialog->raise();
+ g_pRegisteredUsersDialog->setFocus();
+ return true;
+}
+
+/*
+ @doc: reguser.add
+ @type:
+ command
+ @title:
+ reguser.add
+ @keyterms:
+ registering users
+ @short:
+ Registers an user
+ @syntax:
+ reguser.add [-r] [-f] [-q] [-g=group] <name> [mask]
+ @description:
+ Adds a new entry with the specified <name> to the database.[br]
+ If the database contains an entry with the same <name>, this command just prints
+ a warning and returns.[br]
+ If no [mask] is given the new entry has no registration masks: so it can't be "matched" yet. You have to add
+ at least one mask with [cmd]reguser.addmask[/cmd].
+ If [mask] is given, then it is added to the entry mask list.[br]
+ The <name> parameter may contain any character: even spaces are allowed (obviously you have to
+ use quotes in that case).[br]
+ If the '-r' switch is given , the new entry replaces any previous one with the same <name> (the old entry is removed).[br]
+ If the '-f' switch is given , and there is an existing entry with the same name , no warning is printed
+ and the old entry is treated just like it has been just added (thus the [mask] is eventually added to its mask list).[br]
+ The '-q' switch causes the command to run in "quiet" mode and print no warning.[br]
+ @examples:
+ [example]
+ reguser.add Pragma
+ [/example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [fnc]$reguser.list[/fnc]
+*/
+
+static bool reguser_kvs_cmd_add(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ QString szMask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,szMask)
+ KVSM_PARAMETERS_END(c)
+ if(szName.isEmpty())
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("No name specified"));
+ return true;
+ }
+
+ if(c->hasSwitch('r',"replace"))g_pRegisteredUserDataBase->removeUser(szName);
+
+
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->addUser(szName);
+ QString group;
+ if(c->hasSwitch('g',"group"))
+ {
+ c->switches()->getAsStringIfExisting('g',"group",group);
+ u->setGroup(group);
+ }
+ if(u == 0)
+ {
+ if(c->hasSwitch('f',"force"))
+ {
+ u = g_pRegisteredUserDataBase->findUserByName(szName);
+ } else {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("User already registered: found exact name match"));
+ }
+ }
+
+
+ if(u)
+ {
+ if(!szMask.isEmpty())
+ {
+ KviIrcMask * m = new KviIrcMask(szMask);
+ u = g_pRegisteredUserDataBase->addMask(u,m);
+ if(u != 0)
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("Mask %Q is already used to identify user %s"),&szMask,u->name().utf8().data());
+ }
+ }
+ }
+ return true;
+}
+
+/*
+ @doc: reguser.remove
+ @type:
+ command
+ @title:
+ reguser.remove
+ @keyterms:
+ unregistering users
+ @short:
+ Removes an entry from the regusers database
+ @syntax:
+ reguser.remove [-q] [-n] <name>
+ @description:
+ Removes the regusers database entry with the specified <name>.[br]
+ If the -n switch is given, and there is a removed entry,
+ this command will restart all the running "notify lists".
+ If the -q switch is used , no warning is printed if the <name>
+ does not identify an existing entry.
+ @examples:
+ [example]
+ [cmd]reguser.add[/cmd] Pragma
+ reguser.remove Pragma
+ [example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [fnc]$reguser.list[/fnc]
+*/
+
+static bool reguser_kvs_cmd_remove(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ if(szName.isEmpty())
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("No name specified"));
+ return true;
+ }
+
+ if(!(g_pRegisteredUserDataBase->removeUser(szName)))
+ {
+ c->warning(__tr2qs("User not found (%Q)"),&szName);
+ } else {
+ if(c->hasSwitch('n',"restartnotifylists"))g_pApp->restartNotifyLists();
+ }
+ return true;
+}
+
+/*
+ @doc: reguser.addmask
+ @type:
+ command
+ @title:
+ reguser.addmask
+ @keyterms:
+ registering users
+ @short:
+ Adds a mask to a registered user
+ @syntax:
+ reguser.addmask [-f] <name> <mask>
+ @description:
+ Adds a registration mask to the database entry with name <name>.[br]
+ The <mask> has the common [doc:irc_masks]irc mask[/doc] format.[br]
+ The only restriction on the <mask> is that it must be unique inside the
+ regusers database: you can't match two users with the same mask (it would
+ have rather undefined results).[br]
+ If -f is used , KVIrc ensures that the mask is unique in the database
+ and associates is to THIS registered user (breaking the previous associations).<br>
+ Once at least one mask has been added, the user can be "matched"
+ by using the [fnc]$reguser.match[/fnc]() function.[br]
+ Each database entry can have an unlimited number of masks.[br]
+ @examples:
+ [example]
+ [cmd]reguser.add[/cmd] "Szymon Stefanek"
+ reguser.addmask "Szymon Stefanek" Pragma!*@*.it
+ [/example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.delmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.match[/fnc],
+ [fnc]$reguser.exactMatch[/fnc]
+*/
+
+static bool reguser_kvs_cmd_addmask(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ QString szMask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,szMask)
+ KVSM_PARAMETERS_END(c)
+
+ if(szName.isEmpty())
+ {
+ c->warning(__tr2qs("No name specified"));
+ return true;
+ }
+
+ if(szMask.isEmpty())
+ {
+ c->warning(__tr2qs("No mask specified"));
+ return true;
+ }
+
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findUserByName(szName);
+ if(!u)
+ {
+ c->warning(__tr2qs("User %Q not found"),&szName);
+ return true;
+ }
+
+ KviIrcMask * mk = new KviIrcMask(szMask);
+
+ if(c->hasSwitch('f',"force"))g_pRegisteredUserDataBase->removeMask(*mk);
+
+ u = g_pRegisteredUserDataBase->addMask(u,mk);
+
+ if(u != 0)c->warning(__tr2qs("Mask %Q already used to identify user %Q"),&szMask,&(u->name()));
+ return true;
+}
+
+/*
+ @doc: reguser.delmask
+ @type:
+ command
+ @title:
+ reguser.delmask
+ @keyterms:
+ registering users
+ @short:
+ Removes a mask from the regusers database
+ @syntax:
+ reguser.delmask <mask>
+ @description:
+ Removes a mask from the regusers database.[br]
+ Since masks are unique in the database , you don't need to pass
+ an <user> parameter: if an <user> entry has the <mask>, removing that <mask>
+ will surely remove it from that <user> entry. (contorsions ?)[br]
+ @examples:
+ [example]
+ [cmd]reguser.add[/cmd] "Szymon Stefanek"
+ [cmd]reguser.addmask[/cmd] "Szymon Stefanek" Pragma!*@*.it
+ reguser.delmask Pragma!*@*.it
+ [fnc]$reguser.list[/fnc]
+ [/example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.match[/fnc],
+ [fnc]$reguser.exactMatch[/fnc]
+*/
+
+static bool reguser_kvs_cmd_delmask(KviKvsModuleCommandCall * c)
+{
+ QString szMask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,szMask)
+ KVSM_PARAMETERS_END(c)
+
+ if(szMask.isEmpty())
+ {
+ c->warning(__tr2qs("No mask specified"));
+ return true;
+ }
+
+ KviIrcMask mk(szMask);
+ if(!g_pRegisteredUserDataBase->removeMask(mk))
+ {
+ c->warning(__tr2qs("Mask %Q not found"),&szMask);
+ }
+
+ return true;
+}
+
+/*
+ @doc: reguser.setIgnoreEnabled
+ @type:
+ command
+ @title:
+ reguser.setIgnoreEnabled
+ @keyterms:
+ enable/disable ignoring of this user
+ @short:
+ Enable/disable ignoring of this user
+ @syntax:
+ reguser.setIgnoreEnabled [-q] <name:string> <isEnabled:bool>
+ @description:
+
+ @examples:
+ [example]
+ reguser.setproperty "Alexey" $true
+ [/example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [fnc]$reguser.matchProperty[/fnc],
+ [fnc]$reguser.property[/fnc]
+*/
+
+static bool reguser_kvs_cmd_setIgnoreEnabled(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ bool bEnabled;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETER("isEnabled",KVS_PT_BOOL,0,bEnabled)
+ KVSM_PARAMETERS_END(c)
+
+ if(szName.isEmpty())
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("No name specified"));
+ return true;
+ }
+
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findUserByName(szName);
+ if(!u)
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("User %Q not found"),&szName);
+ } else {
+ u->setIgnoreEnabled(bEnabled);
+ }
+ return true;
+}
+
+
+/*
+ @doc: reguser.setIgnoreFlags
+ @type:
+ command
+ @title:
+ reguser.setIgnoreFlags
+ @keyterms:
+ Sets ignore flags for registered user
+ @short:
+ Sets ignore flags for registered user
+ @syntax:
+ reguser.setIgnoreFlags [-p|--query] [-c|--channel] [-n|--notice] [-t|--ctcp] [-i|--invite] [-d|--dcc] [-q] <name:string>
+ @switches:
+ !sw: -q | --quiet
+ Don't warn if the specified user doesn't exist. Just continue silently.
+ !sw: -p | --query
+ Sets ignore for query messages and actions
+ !sw: -c | --channel
+ Sets ignore for channel messages and actions
+ !sw: -n | --notice
+ Sets ignore for notices
+ !sw: -t | --ctcp
+ Sets ignore for CTCP's
+ !sw: -i | --invite
+ Sets ignore for invites
+ !sw: -d | --dcc
+ Sets ignore for DCC's
+
+ @description:
+ Sets ignore flags for registered user
+ @examples:
+ [example]
+ reguser.setproperty "Alexey" $true
+ [/example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [fnc]$reguser.matchProperty[/fnc],
+ [fnc]$reguser.property[/fnc]
+*/
+
+static bool reguser_kvs_cmd_setIgnoreFlags(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ if(szName.isEmpty())
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("No name specified"));
+ return true;
+ }
+
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findUserByName(szName);
+ if(!u)
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("User %Q not found"),&szName);
+ } else {
+ int iIgnoreFlags=0;
+ if(c->hasSwitch('p',"query"))
+ iIgnoreFlags |= KviRegisteredUser::Query;
+ if(c->hasSwitch('c',"channel"))
+ iIgnoreFlags |= KviRegisteredUser::Channel;
+ if(c->hasSwitch('n',"notice"))
+ iIgnoreFlags |= KviRegisteredUser::Notice;
+ if(c->hasSwitch('t',"ctcp"))
+ iIgnoreFlags |= KviRegisteredUser::Ctcp;
+ if(c->hasSwitch('i',"invite"))
+ iIgnoreFlags |= KviRegisteredUser::Invite;
+ if(c->hasSwitch('d',"dcc"))
+ iIgnoreFlags |= KviRegisteredUser::Dcc;
+ u->setIgnoreFlags(iIgnoreFlags);
+ }
+ return true;
+}
+
+/*
+ @doc: reguser.getIgnoreFlags
+ @type:
+ function
+ @title:
+ $reguser.getIgnoreFlags
+ @short:
+ Returns ignore flags for registered user
+ @syntax:
+ $reguser.getIgnoreFlags(<name:string>)
+ @description:
+ Returns the ignore flags for registered user. Flags are string of letters:[br]
+ p - query ignore[br]
+ c - channel ignore[br]
+ t - ctcp ignore[br]
+ n - notice ignore[br]
+ d - dcc ignore[br]
+ i - invite ignore[br]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [cmd]reguser.delmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.match[/fnc],
+ [fnc]$reguser.matchProperty[/fnc]
+*/
+
+static bool reguser_kvs_fnc_getIgnoreFlags(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ QString szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray* pArray = new KviKvsArray();
+ int aid=0;
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findUserByName(szName);
+ if(u)
+ {
+ if(u->ignoreFlags() & KviRegisteredUser::Query)
+ szFlags+='q';
+ if(u->ignoreFlags() & KviRegisteredUser::Channel)
+ szFlags+='c';
+ if(u->ignoreFlags() & KviRegisteredUser::Notice)
+ szFlags+='n';
+ if(u->ignoreFlags() & KviRegisteredUser::Ctcp)
+ szFlags+='t';
+ if(u->ignoreFlags() & KviRegisteredUser::Invite)
+ szFlags+='i';
+ if(u->ignoreFlags() & KviRegisteredUser::Dcc)
+ szFlags+='d';
+ c->returnValue()->setString(szFlags);
+
+ }
+ return true;
+}
+
+/*
+ @doc: reguser.isIgnoreEnabled
+ @type:
+ function
+ @title:
+ $reguser.isIgnoreEnabled
+ @short:
+ Returns if ignore enabled registered user
+ @syntax:
+ $reguser.isIgnoreEnabled(<name:string>)
+ @description:
+ Returns if ignore enabled registered user
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [cmd]reguser.delmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.match[/fnc],
+ [fnc]$reguser.matchProperty[/fnc]
+*/
+
+static bool reguser_kvs_fnc_isIgnoreEnabled(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray* pArray = new KviKvsArray();
+ int aid=0;
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findUserByName(szName);
+ if(u)
+ {
+ c->returnValue()->setBoolean(u->ignoreEnagled());
+
+ }
+ return true;
+}
+
+/*
+ @doc: reguser.setproperty
+ @type:
+ command
+ @title:
+ reguser.setproperty
+ @keyterms:
+ setting user properties
+ @short:
+ Sets a property of a registered user
+ @syntax:
+ reguser.setproperty [-n] [-a] [-q] <name> <property> [value]
+ @description:
+ Adds a property to the registered users database entry with name <name>.[br]
+ The property <property> is set to the specified <value> or is unset if <value>
+ is not given (or is an empty string).[br]
+ If the '-n' switch is used , and the user entry has been found in the database,
+ all the [doc:notify_list]notify lists[/doc] are restarted.[br]
+ If the '-a' switch is used , and there are users on IRC currently matched
+ by this reguser entry then their avatar is reset.
+ This is useful when you're changing someone's notify property.[br]
+ If the -q switch is used , the command runs in "quiet" mode and prints no warnings.[br]
+ @examples:
+ [example]
+ [cmd]reguser.add[/cmd] "Szymon Stefanek"
+ reguser.setproperty -n "Szymon Stefanek" notify Pragma
+ [fnc]$reguser.list[/fnc]
+ [/example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [fnc]$reguser.matchProperty[/fnc],
+ [fnc]$reguser.property[/fnc]
+*/
+
+static bool reguser_kvs_cmd_setproperty(KviKvsModuleCommandCall * c)
+{
+ QString szName;
+ QString szProperty;
+ QString szValue;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETER("property",KVS_PT_STRING,0,szProperty)
+ KVSM_PARAMETER("value",KVS_PT_STRING,KVS_PF_OPTIONAL,szValue)
+ KVSM_PARAMETERS_END(c)
+
+ if(szName.isEmpty())
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("No name specified"));
+ return true;
+ }
+
+ if(szProperty.isEmpty())
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("No property specified"));
+ return true;
+ }
+
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findUserByName(szName);
+ if(!u)
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("User %Q not found"),&szName);
+ } else {
+ u->setProperty(szProperty,szValue);
+ if(c->hasSwitch('n',"restartnotifylists"))g_pApp->restartNotifyLists();
+ if(c->hasSwitch('a',"resetavatar"))g_pApp->resetAvatarForMatchingUsers(u);
+ }
+ return true;
+}
+/*
+ @doc: reguser.list
+ @type:
+ function
+ @title:
+ $reguser.list
+ @short:
+ Get a list of registered user masks
+ @syntax:
+ $reguser.list([mask])
+ @description:
+ Returns an array of the entries in the registered users database.[br]
+ If <mask> is specified, only entries matching the <mask>
+ and the entries with no registration masks are listed.[br]
+ Please note that <mask> is a wildcard string that will match
+ wildcard strings... don't get messed with that :D[br]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.exactMatch[/fnc]
+*/
+
+static bool reguser_kvs_fnc_list(KviKvsModuleFunctionCall * c)
+{
+ QString szMask;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("user_mask",KVS_PT_STRING,KVS_PF_OPTIONAL,szMask)
+ KVSM_PARAMETERS_END(c)
+
+ KviIrcMask mask(szMask);
+ KviKvsArray* pArray = new KviKvsArray();
+ int aid=0;
+
+ int cnt = 0;
+
+ KviPointerHashTable<QString,KviRegisteredUser> * d = g_pRegisteredUserDataBase->userDict();
+ KviPointerHashTableIterator<QString,KviRegisteredUser> it(*d);
+
+ while(KviRegisteredUser * u = it.current())
+ {
+ KviPointerList<KviIrcMask> * ml = u->maskList();
+ if(u->matches(mask) || (ml->count() == 0))
+ {
+ pArray->set(aid,new KviKvsVariant(u->name()));
+ aid++;
+ }
+ ++it;
+ }
+ c->returnValue()->setArray(pArray);
+ return true;
+}
+
+/*
+ @doc: reguser.showlist
+ @type:
+ command
+ @title:
+ reguser.showlist
+ @keyterms:
+ registered users
+ @short:
+ Lists the registered users
+ @syntax:
+ reguser.showlist [mask]
+ @description:
+ Lists the entries in the registered users database.[br]
+ If <mask> is specified, only entries matching the <mask>
+ and the entries with no registration masks are listed.[br]
+ Please note that <mask> is a wildcard string that will match
+ wildcard strings... don't get messed with that :D[br]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [fnc]$reguser.match[/fnc],
+ [fnc]$reguser.exactMatch[/fnc]
+*/
+
+static bool reguser_kvs_cmd_showlist(KviKvsModuleCommandCall * c)
+{
+ QString szMask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,KVS_PF_OPTIONAL,szMask)
+ KVSM_PARAMETERS_END(c)
+
+ KviIrcMask mask(szMask);
+ c->window()->outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Registered users database dump:"));
+
+ int count = 0;
+
+ KviPointerHashTable<QString,KviRegisteredUser> * d = g_pRegisteredUserDataBase->userDict();
+ KviPointerHashTableIterator<QString,KviRegisteredUser> it(*d);
+ while(KviRegisteredUser * u = it.current())
+ {
+ KviPointerList<KviIrcMask> * ml = u->maskList();
+ if(u->matches(mask) || (ml->count() == 0))
+ {
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs(" User: %c%Q"),KVI_TEXT_BOLD,&(u->name()));
+
+ if(ml->count() == 0)
+ {
+ c->window()->output(KVI_OUT_SYSTEMWARNING,__tr2qs(" Warning: this user has no registration masks"));
+ } else {
+ for(KviIrcMask * m = ml->first();m;m = ml->next())
+ {
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs(" Mask: %Q!%Q@%Q"),&(m->nick()),&(m->user()),&(m->host()));
+ }
+ }
+
+ KviPointerHashTable<QString,QString> * pd = u->propertyDict();
+ if(pd)
+ {
+ KviPointerHashTableIterator<QString,QString> pdit(*pd);
+ while(pdit.current())
+ {
+ QString key = pdit.currentKey();
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs(" Property: %Q=%Q"),&(key),pdit.current());
+ ++pdit;
+ }
+ } else c->window()->outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs(" No properties"));
+ count++;
+ }
+ ++it;
+ }
+
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Total: %d matching users (of %d in the database)"),count,d->count());
+ return true;
+}
+
+
+
+/*
+ @doc: reguser.match
+ @type:
+ function
+ @title:
+ $reguser.match
+ @short:
+ Returns an entry in the registered user database
+ @syntax:
+ $reguser.match(<user_mask>)
+ @description:
+ Returns the name of the first entry matching <user_mask> in the registered user database.[br]
+ The <user_mask> has the common [doc:irc_masks]irc mask[/doc] format but can't contain wildcards.[br]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.exactMatch[/fnc]
+*/
+
+static bool reguser_kvs_fnc_match(KviKvsModuleFunctionCall * c)
+{
+ QString szMask;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("user_mask",KVS_PT_STRING,0,szMask)
+ KVSM_PARAMETERS_END(c)
+ KviIrcMask mask(szMask);
+//FIXME: it crashes kvirc KviRegisteredUser * u = c->context()->connection()->userDataBase()->registeredUser(mask.nick(),mask.user(),mask.host());
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findMatchingUser(mask.nick(),mask.user(),mask.host());
+ if(u) c->returnValue()->setString(u->name());
+ return true;
+}
+
+/*
+ @doc: reguser.exactmatch
+ @type:
+ function
+ @title:
+ $reguser.exactMatch
+ @short:
+ Returns an entry in the registered user database
+ @syntax:
+ $reguser.exactMatch(<user_mask>)
+ @description:
+ Returns the name of the registered user database entry that has <user_mask> in its registration mask list.[br]
+ The <user_mask> has the common [doc:irc_masks]wild irc mask[/doc] format and can contain wildcards.[br]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.match[/fnc]
+*/
+
+static bool reguser_kvs_fnc_exactMatch(KviKvsModuleFunctionCall * c)
+{
+ QString szMask;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("user_mask",KVS_PT_STRING,0,szMask)
+ KVSM_PARAMETERS_END(c)
+ KviIrcMask mask(szMask);
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findUserWithMask(mask);
+ if(u) c->returnValue()->setString(u->name());
+ return true;
+}
+
+///*
+// @doc: reguser.matches
+// @type:
+// function
+// @title:
+// $reguser.matches
+// @short:
+// Returns entries in the registered user database
+// @syntax:
+// $reguser.matches(<user_mask>)
+// @description:
+// Returns a comma separated list of registered user masks that match <user_mask>.[br]
+// User mask must be in the format <nick>!<user>@<host> , where <user> and
+// <host> may contain '*' wildcards.[br]
+// If no registered mask matches the <user_mask> an empty string is returned.[br]
+// @seealso:
+// [module:reguser]reguser module documentation[/module]
+//*/
+
+//static void search_reguser_list(KviRegisteredUserList * l,KviWindow * w,const char * mask,KviStr & buffer)
+//{
+// for(KviRegisteredUser * u = l->first();u;u = l->next())
+// {
+// if(u->matches(mask))
+// {
+// if(buffer.hasData())buffer.append(',');
+// buffer.append(u->mask());
+// }
+// }
+//}
+
+//static bool reguser_module_fnc_matches(KviModule *m,KviCommand *c,KviParameterList * parms,KviStr &buffer)
+//{
+// ENTER_STACK_FRAME(c,"reguser.matches");
+//
+// KviStr list;
+//
+// const KviPointerHashTable<const char *,KviRegisteredUserList> * d = g_pRegisteredUserDataBase->nickDict();
+// KviPointerHashTableIterator<const char *,KviRegisteredUserList> it(*d);
+// while(KviRegisteredUserList * l = it.current())
+// {
+// search_reguser_list(l,c->window(),parms->safeFirstParam(),list);
+// ++it;
+// }
+//
+// search_reguser_list(g_pRegisteredUserDataBase->wildList(),c->window(),parms->safeFirstParam(),list);
+//
+// buffer.append(list);
+//
+// return c->leaveStackFrame();
+//}
+
+
+/*
+ @doc: reguser.mask
+ @type:
+ function
+ @title:
+ $reguser.mask
+ @short:
+ Returns the registration masks for a db entry
+ @syntax:
+ $reguser.mask(<name>[,<N>])
+ @description:
+ Returns the <N>th registration mask for the registered user database record identified
+ by <name>. If <N> is not given , returns an array of registration masks for that entry.[br]
+ If <name> does not identify a valid entry an empty string is returned;
+ if <N> is out of range (or there are no masks at all) , an empty string is returned.[br]
+ <N> is a ZERO BASED index.[br]
+ @examples:
+ [example]
+ [cmd]reguser.add[/cmd] Pragma
+ [cmd]reguser.addmask[/cmd] Pragma Pragma!*@*.it
+ [cmd]echo[/cmd] $reguser.mask(Pragma,0)
+ [/example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [cmd]reguser.delmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.match[/fnc],
+ [fnc]$reguser.matchProperty[/fnc]
+*/
+
+static bool reguser_kvs_fnc_mask(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ QString szN;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("name",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETER("N",KVS_PT_STRING,KVS_PF_OPTIONAL,szN)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray* pArray = new KviKvsArray();
+ int aid=0;
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findUserByName(szName);
+ if(u)
+ {
+ KviStr n = szName;
+ if(n.hasData() && n.isUnsignedNum())
+ {
+ KviIrcMask * m = u->maskList()->at(n.toInt());
+ if(m) c->returnValue()->setString(m->nick()+"!"+m->user()+"@"+m->host());
+ } else {
+ int id=0;
+ for(KviIrcMask * m = u->maskList()->first();m;m = u->maskList()->next())
+ {
+ pArray->set(aid,new KviKvsVariant(QString(m->nick()+"!"+m->user()+"@"+m->host())));
+ aid++;
+ }
+ c->returnValue()->setArray(pArray);
+ }
+ }
+ return true;
+}
+/*
+ @doc: reguser.property
+ @type:
+ function
+ @title:
+ $reguser.property
+ @short:
+ Returns a property of an entry in the registered user database
+ @syntax:
+ $reguser.property(<user_name>,<property_name>)
+ @description:
+ Returns the value of the property identified by <property_name> and
+ bound to the entry identified by <user_name>.[br]
+ If the property is not set or if there is no entry with <user_name> an empty string is returned.[br]
+ @examples:
+ [example]
+ [cmd]reguser.add[/cmd] Pragma
+ [cmd]reguser.addmask[/cmd] Pragma Pragma!*@*.it
+ [cmd]reguser.setproperty[/cmd] Pragma isDev 1
+ [cmd]echo[/cmd] $reguser.property(Pragma,isDev)
+ [/example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.match[/fnc],
+ [fnc]$reguser.matchProperty[/fnc]
+*/
+
+static bool reguser_kvs_fnc_property(KviKvsModuleFunctionCall * c)
+{
+ QString szName;
+ QString szProperty;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("user_name",KVS_PT_STRING,0,szName)
+ KVSM_PARAMETER("property_name",KVS_PT_STRING,KVS_PF_OPTIONAL,szProperty)
+ KVSM_PARAMETERS_END(c)
+
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findUserByName(szName);
+ if(u)
+ {
+ QString tmp;
+ u->getProperty(szProperty,tmp);
+ c->returnValue()->setString(tmp);
+ }
+ return true;
+}
+/*
+ @doc: reguser.matchproperty
+ @type:
+ function
+ @title:
+ $reguser.matchProperty
+ @short:
+ Returns a property of an entry in the registered user database
+ @syntax:
+ $reguser.matchProperty(<user_mask>,<property_name>)
+ @description:
+ Returns the value of the property identified by <property_name> and
+ bound to the first entry matched by by <user_mask>.[br]
+ If the property is not set, an empty string is returned.[br]
+ If no entry matches <user_mask> this function returns an empty string
+ and does not print any error.[br]
+ [example]
+ %property = $reguser.matchProperty(<user_mask>,<property_name>)
+ [/example]
+ Is actually a shortcut for:[br]
+ [example]
+ %tmp = [fnc]$reguser.match[/fnc](<user_mask>)
+ if("%tmp" != "")%property = $reguser.property(%tmp,<property_name>)
+ [/example]
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+ [cmd]reguser.remove[/cmd],
+ [cmd]reguser.addmask[/cmd],
+ [fnc]$reguser.list[/fnc],
+ [fnc]$reguser.match[/fnc],
+ [fnc]$reguser.property[/fnc]
+*/
+
+static bool reguser_kvs_fnc_matchProperty(KviKvsModuleFunctionCall * c)
+{
+ QString szMask;
+ QString szProperty;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("user_mask",KVS_PT_STRING,0,szMask)
+ KVSM_PARAMETER("property_name",KVS_PT_STRING,KVS_PF_OPTIONAL,szProperty)
+ KVSM_PARAMETERS_END(c)
+
+ KviIrcMask mask(szMask);
+//FIXME: it crashes kvirc KviRegisteredUser * u = c->context()->connection()->userDataBase()->registeredUser(mask.nick(),mask.user(),mask.host());
+ KviRegisteredUser * u = g_pRegisteredUserDataBase->findMatchingUser(mask.nick(),mask.user(),mask.host());
+ if(u)
+ {
+ QString tmp;
+ u->getProperty(szProperty,tmp);
+ c->returnValue()->setString(tmp);
+ }
+ return true;
+}
+
+/*
+ @doc: reguser.wizard
+ @type:
+ command
+ @title:
+ reguser.wizard
+ @keyterms:
+ registering users, registration wizard
+ @short:
+ Shows a registration wizard dialog
+ @syntax:
+ reguser.wizard [mask]
+ @description:
+ Allows registering an user with an intuitive and easy to use interface.
+ If [mask] is specified , it is used as inital mask in the dialog.
+ @seealso:
+ [module:reguser]Registered users database interface[/module],
+ [doc:registered_users]Registered users database[/doc],
+ [cmd]reguser.add[/cmd],
+*/
+
+static bool reguser_kvs_cmd_wizard(KviKvsModuleCommandCall * c)
+{
+ QString szMask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("mask",KVS_PT_STRING,KVS_PF_OPTIONAL,szMask)
+ KVSM_PARAMETERS_END(c)
+
+ KviRegistrationWizard * w = new KviRegistrationWizard(szMask);
+ w->show();
+ return true;
+}
+
+static bool reguser_module_init(KviModule * m)
+{
+ g_pLocalRegisteredUserDataBase = 0;
+ g_pRegistrationWizardList = new KviPointerList<KviRegistrationWizard>;
+ g_pRegistrationWizardList->setAutoDelete(true);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"add",reguser_kvs_cmd_add);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"remove",reguser_kvs_cmd_remove);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"addmask",reguser_kvs_cmd_addmask);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"delmask",reguser_kvs_cmd_delmask);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"edit",reguser_kvs_cmd_edit);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"showlist",reguser_kvs_cmd_showlist);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setproperty",reguser_kvs_cmd_setproperty);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"wizard",reguser_kvs_cmd_wizard);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setIgnoreEnabled",reguser_kvs_cmd_setIgnoreEnabled);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setIgnoreFlags",reguser_kvs_cmd_setIgnoreFlags);
+
+ KVSM_REGISTER_FUNCTION(m,"match",reguser_kvs_fnc_match);
+ KVSM_REGISTER_FUNCTION(m,"list",reguser_kvs_fnc_list);
+ KVSM_REGISTER_FUNCTION(m,"exactMatch",reguser_kvs_fnc_exactMatch);
+ KVSM_REGISTER_FUNCTION(m,"mask",reguser_kvs_fnc_mask);
+ KVSM_REGISTER_FUNCTION(m,"property",reguser_kvs_fnc_property);
+ KVSM_REGISTER_FUNCTION(m,"matchProperty",reguser_kvs_fnc_matchProperty);
+ KVSM_REGISTER_FUNCTION(m,"getIgnoreFlags",reguser_kvs_fnc_getIgnoreFlags);
+ KVSM_REGISTER_FUNCTION(m,"isIgnoreEnabled",reguser_kvs_fnc_isIgnoreEnabled);
+
+ return true;
+}
+
+static bool reguser_module_cleanup(KviModule *m)
+{
+ if(g_pRegisteredUsersDialog)delete g_pRegisteredUsersDialog;
+ g_pRegisteredUsersDialog = 0;
+
+ while(KviRegistrationWizard * w = g_pRegistrationWizardList->first())delete w;
+ delete g_pRegistrationWizardList;
+ g_pRegistrationWizardList = 0;
+
+ // FIXME: UNREGISTER THE METAOBJECTS
+ return true;
+}
+
+static bool reguser_module_can_unload(KviModule *)
+{
+ return ((g_pRegistrationWizardList->isEmpty()) && (g_pRegisteredUsersDialog == 0));
+}
+
+KVIRC_MODULE(
+ "Reguser", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Script interface to the registered users database",
+ reguser_module_init,
+ reguser_module_can_unload,
+ 0,
+ reguser_module_cleanup
+)
diff --git a/src/modules/reguser/wizard.cpp b/src/modules/reguser/wizard.cpp
new file mode 100644
index 00000000..1777621d
--- /dev/null
+++ b/src/modules/reguser/wizard.cpp
@@ -0,0 +1,464 @@
+//
+// File : wizard.cpp
+// Creation date : Fri Jun 26 2002 21:21:21 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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 "wizard.h"
+
+#include "kvi_locale.h"
+#include "kvi_pointerlist.h"
+#include "kvi_app.h"
+#include "kvi_ircmask.h"
+#include "kvi_selectors.h"
+#include "kvi_pixmap.h"
+#include "kvi_regusersdb.h"
+#include "kvi_iconmanager.h"
+#ifdef COMPILE_USE_QT4
+#include <QDesktopWidget>
+#endif
+
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qvariant.h>
+#include <qframe.h>
+
+
+extern KVIRC_API KviRegisteredUserDataBase * g_pRegisteredUserDataBase;
+extern KviPointerList<KviRegistrationWizard> * g_pRegistrationWizardList;
+
+KviRegistrationWizard::KviRegistrationWizard(const char * startMask,KviRegisteredUserDataBase * db,QWidget * par,bool bModal)
+: KviTalWizard(par)
+{
+ m_pDb = db;
+
+ setModal(bModal);
+
+ m_bModal = bModal;
+
+ KviIrcMask mask(startMask ? startMask : "*!*@*");
+
+ g_pRegistrationWizardList->append(this);
+
+ QGridLayout* m_pPage1Layout;
+ QGridLayout* m_pPage2Layout;
+ QGridLayout* m_pPage3Layout;
+ QGridLayout* m_pPage4Layout;
+ QGridLayout* m_pPage5Layout;
+
+ QLabel* TextLabel10_2;
+ QLabel* TextLabel10;
+ QLabel* TextLabel10_3;
+ QLabel* TextLabel10_3_2;
+
+ QFrame * f;
+
+// resize( 490, 456 );
+ setCaption(__tr2qs("User Registration Wizard - KVIrc"));
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LINUX)));
+
+ setSizeGripEnabled( TRUE );
+
+ m_pPage1 = new QWidget(this);
+ m_pPage1Layout = new QGridLayout(m_pPage1);
+ m_pPage1Layout->setSpacing(4);
+ m_pPage1Layout->setMargin(8);
+
+ m_pLabel1 = new QLabel(m_pPage1);
+ m_pLabel1->setText(__tr2qs("<p>Welcome to the user registration wizard.<br>This process allows you to add an IRC user to the database and set properties for that user. KVIrc will be (hopefully) able to recognize the user, add him to the notify list, and display the associated avatar.<br><br>First of all, you must insert an <b>entry name or real name</b> for the user you're going to register. The name will be used to identify the database entry and has no specific requirements, it can be a given name, nickname, or just some text to remind you of the real person.<br>Examples: \"George W Bush\", \"Dubya\".\n</p>" ));
+
+ m_pPage1Layout->addWidget(m_pLabel1, 0, 0);
+
+ m_pEditRealName = new QLineEdit(m_pPage1);
+ //m_pEditRealName->setAlignment(int(QLineEdit::AlignHCenter));
+
+ m_pPage1Layout->addWidget(m_pEditRealName,1,0);
+ addPage( m_pPage1,__tr2qs("Step 1: Entry Name"));
+
+ if(mask.nick() != "*")m_pEditRealName->setText(mask.nick());
+
+ connect(m_pEditRealName,SIGNAL(textChanged(const QString &)),this,SLOT(realNameChanged(const QString &)));
+
+ // PAGE 2
+
+
+ m_pPage2 = new QWidget(this);
+ m_pPage2Layout = new QGridLayout( m_pPage2 );
+ m_pPage2Layout->setSpacing( 4 );
+ m_pPage2Layout->setMargin( 8 );
+
+ m_pLabel2 = new QLabel( m_pPage2);
+ m_pLabel2->setText(__tr2qs("<p>A registered user is identified by one or more <b>IRC masks</b>.<br>A mask must be in the following form:<br><b>nickname!username@hostname</b><br>and can contain wildcard characters '*' and '?'. Be careful in choosing the masks, as they are the only way to verify the identity of a registered user.<br><br>You can enter at most two masks here, if you wish to add more masks, use the \"<b>Edit</b>\" button in the Registered Users dialog. You must enter at least one mask.</p>"));
+
+ m_pPage2Layout->addMultiCellWidget(m_pLabel2,0,0,0,4);
+
+ //KviStr szMask;
+
+ //mask.mask(szMask,11);
+
+ //KviIrcMask masktempl(szMask.ptr());
+
+ m_pNicknameEdit1 = new QLineEdit(m_pPage2);
+ m_pNicknameEdit1->setAlignment(Qt::AlignRight);
+ if(mask.nick() != "*")m_pNicknameEdit1->setText(mask.nick());
+ connect(m_pNicknameEdit1,SIGNAL(textChanged(const QString &)),this,SLOT(maskChanged(const QString &)));
+ m_pPage2Layout->addWidget( m_pNicknameEdit1, 1, 0 );
+
+ m_pUsernameEdit1 = new QLineEdit(m_pPage2);
+ m_pUsernameEdit1->setAlignment(Qt::AlignHCenter);
+ if(mask.hasUser())m_pUsernameEdit1->setText(mask.user());
+ connect(m_pUsernameEdit1,SIGNAL(textChanged(const QString &)),this,SLOT(maskChanged(const QString &)));
+ m_pPage2Layout->addWidget(m_pUsernameEdit1,1,2);
+
+ m_pHostEdit1 = new QLineEdit(m_pPage2);
+ if(mask.hasHost())m_pHostEdit1->setText(mask.host());
+ connect(m_pHostEdit1,SIGNAL(textChanged(const QString &)),this,SLOT(maskChanged(const QString &)));
+ m_pPage2Layout->addWidget(m_pHostEdit1,1,4);
+
+ m_pNicknameEdit2 = new QLineEdit(m_pPage2);
+ m_pNicknameEdit2->setAlignment(Qt::AlignRight);
+ m_pPage2Layout->addWidget(m_pNicknameEdit2,2,0);
+
+ m_pUsernameEdit2 = new QLineEdit(m_pPage2);
+ m_pUsernameEdit2->setAlignment(Qt::AlignHCenter);
+ m_pPage2Layout->addWidget(m_pUsernameEdit2,2,2);
+
+ m_pHostEdit2 = new QLineEdit(m_pPage2);
+ m_pPage2Layout->addWidget(m_pHostEdit2,2,4);
+
+ TextLabel10_2 = new QLabel(m_pPage2);
+ TextLabel10_2->setText("<center><b>!</b></center>");
+ TextLabel10_2->setAlignment(int(Qt::AlignCenter));
+ m_pPage2Layout->addWidget(TextLabel10_2,2,1);
+
+ TextLabel10 = new QLabel(m_pPage2);
+ TextLabel10->setText("<center><b>!</b></center>");
+ TextLabel10->setAlignment(int(Qt::AlignCenter));
+ m_pPage2Layout->addWidget(TextLabel10,1,1);
+
+ TextLabel10_3 = new QLabel(m_pPage2);
+ TextLabel10_3->setText("<center><b>@</b></center>");
+ TextLabel10_3->setAlignment(int(Qt::AlignCenter));
+ m_pPage2Layout->addWidget(TextLabel10_3,1,3);
+
+ TextLabel10_3_2 = new QLabel(m_pPage2);
+ TextLabel10_3_2->setText("<center><b>@</b></center>");
+ TextLabel10_3_2->setAlignment(int(Qt::AlignCenter));
+ m_pPage2Layout->addWidget(TextLabel10_3_2,2,3);
+
+ addPage(m_pPage2,__tr2qs("Step 2: Mask Selection"));
+
+
+
+
+
+ m_pPage3 = new QWidget(this);
+ m_pPage3Layout = new QGridLayout(m_pPage3);
+ m_pPage3Layout->setSpacing(4);
+ m_pPage3Layout->setMargin(8);
+
+ m_pLabel3 = new QLabel(m_pPage3);
+ m_pLabel3->setText(__tr2qs("<p>If you want to store an avatar image for this user, you can set it here. KVIrc will show the avatar in the userlist next to the user's nickname.<br>An avatar can be in any supported image format (PNG is recommended). Keep in mind that KVIrc stores avatars in memory and has to resize them to fit in the userlist, thus it's better to use small, low-resolution images.</p>"));
+ m_pPage3Layout->addWidget(m_pLabel3,0,0);
+
+ f = new QFrame(m_pPage3);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ m_pPage3Layout->addWidget(f,1,0);
+
+ m_pAvatar = new KviPixmap();
+ m_pAvatarSelector = new KviPixmapSelector(m_pPage3,__tr2qs("Store an avatar for this user"),m_pAvatar,true);
+ m_pPage3Layout->addWidget(m_pAvatarSelector,2,0);
+
+ m_pPage3Layout->setRowStretch(0,1);
+
+ addPage(m_pPage3,__tr2qs( "Step 3: Avatar Selection"));
+
+
+
+
+ m_pPage4 = new QWidget(this);
+ m_pPage4Layout = new QGridLayout(m_pPage4);
+ m_pPage4Layout->setSpacing(4);
+ m_pPage4Layout->setMargin(8);
+
+ m_pLabel4 = new QLabel(m_pPage4);
+ m_pLabel4->setText(__tr2qs("<p>If you want to be notified when this user is online or goes offline, you must specify the list of nicknames that KVIrc will look for.<br><br>You can enter at most two nicknames here, if you wish to add more nicknames, use the \"<b>Edit</b>\" button in the Registered Users dialog.</p>"));
+ m_pPage4Layout->addMultiCellWidget(m_pLabel4,0,0,0,1);
+
+
+ f = new QFrame(m_pPage4);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ m_pPage4Layout->addMultiCellWidget(f,1,1,0,1);
+
+ m_pNotifyCheck = new QCheckBox(m_pPage4);
+ m_pNotifyCheck->setText(__tr2qs("Add this user to the notify list"));
+ m_pNotifyCheck->setChecked(false);
+ connect(m_pNotifyCheck,SIGNAL(toggled(bool)),this,SLOT(notifyCheckToggled(bool)));
+ m_pPage4Layout->addMultiCellWidget(m_pNotifyCheck,2,2,0,1);
+
+ m_pNotifyNickLabel1 = new QLabel(m_pPage4);
+ m_pNotifyNickLabel1->setText(__tr2qs("Nickname:"));
+ m_pPage4Layout->addWidget(m_pNotifyNickLabel1,3,0);
+
+ m_pNotifyNickLabel2 = new QLabel(m_pPage4);
+ m_pNotifyNickLabel2->setText(__tr2qs("Nickname 2:"));
+ m_pPage4Layout->addWidget(m_pNotifyNickLabel2,4,0);
+
+ m_pNotifyNickEdit1 = new QLineEdit(m_pPage4);
+ if(mask.nick() != "*")m_pNotifyNickEdit1->setText(mask.nick());
+ connect(m_pNotifyNickEdit1,SIGNAL(textChanged(const QString &)),this,SLOT(notifyNickChanged(const QString &)));
+ m_pPage4Layout->addWidget(m_pNotifyNickEdit1,3,1);
+
+ m_pNotifyNickEdit2 = new QLineEdit(m_pPage4);
+ connect(m_pNotifyNickEdit2,SIGNAL(textChanged(const QString &)),this,SLOT(notifyNickChanged(const QString &)));
+ m_pPage4Layout->addWidget(m_pNotifyNickEdit2,4,1);
+
+ m_pPage4Layout->setRowStretch(0,1);
+
+ addPage(m_pPage4,__tr2qs("Step 4: Notify List"));
+
+
+
+
+
+ m_pPage5 = new QWidget(this);
+ m_pPage5Layout = new QGridLayout(m_pPage5);
+ m_pPage5Layout->setSpacing(4);
+ m_pPage5Layout->setMargin(8);
+
+ m_pTextLabel5 = new QLabel(m_pPage5);
+ m_pTextLabel5->setText(__tr2qs("<p>That's it. The user registration has been completed.<br><br>Click \"<b>Finish</b>\" to close this dialog.</p>"));
+ m_pPage5Layout->addWidget(m_pTextLabel5,0,0);
+
+ addPage(m_pPage5,__tr2qs("Registration Complete"));
+
+ setFinishEnabled(m_pPage5,true);
+ QString dummy;
+ maskChanged(dummy);
+ realNameChanged(dummy);
+ notifyCheckToggled(false);
+
+ setMinimumSize(QSize(350,420));
+
+ // signals and slots connections
+}
+
+KviRegistrationWizard::~KviRegistrationWizard()
+{
+ delete m_pAvatar;
+ g_pRegistrationWizardList->setAutoDelete(false);
+ g_pRegistrationWizardList->removeRef(this);
+ g_pRegistrationWizardList->setAutoDelete(true);
+}
+
+void KviRegistrationWizard::reject()
+{
+ KviTalWizard::reject();
+ if(!m_bModal)delete this;
+// hide();
+// g_pApp->collectGarbage(this);
+}
+
+void KviRegistrationWizard::accept()
+{
+ bool bLocalDb = true;
+ if(!m_pDb)
+ {
+ bLocalDb = false;
+ m_pDb = g_pRegisteredUserDataBase;
+ }
+
+ QString szName = m_pEditRealName->text();
+ KviRegisteredUser * u;
+
+
+ if(bLocalDb)
+ {
+ if(szName.isEmpty()) szName = "user";
+
+ QString szNameOk = szName;
+
+ int idx = 1;
+
+ do {
+ u = m_pDb->findUserByName(szNameOk);
+ if(u)
+ {
+ KviQString::sprintf(szNameOk,"%Q%d",&szNameOk,idx);
+ idx++;
+ }
+ } while(u);
+
+ u = m_pDb->addUser(szNameOk);
+
+ } else {
+ u = m_pDb->findUserByName(szName);
+ if(!u)u = m_pDb->addUser(szName);
+ }
+
+ if(!u)
+ {
+ // ops... no way
+ // FIXME: spit an error message ?
+ debug("Ops.. something wrong with the regusers db");
+ //delete this;
+ return;
+ }
+
+ QString m1 = m_pNicknameEdit1->text();
+ QString m2 = m_pUsernameEdit1->text();
+ QString m3 = m_pHostEdit1->text();
+ KviIrcMask * mk = new KviIrcMask(m1,m2,m3);
+ m_pDb->removeMask(*mk);
+ m_pDb->addMask(u,mk);
+
+
+ m1 = m_pNicknameEdit2->text();
+ m2 = m_pUsernameEdit2->text();
+ if(m2.isEmpty())m2 = "*";
+ if(m3.isEmpty())m3 = "*";
+ m3 = m_pHostEdit2->text();
+ mk = new KviIrcMask(m1,m2,m3);
+
+ m_pDb->removeMask(*mk);
+ m_pDb->addMask(u,mk);
+
+ m_pAvatarSelector->commit();
+
+ bool bSetAvatar = false;
+
+ if(!m_pAvatar->isNull())
+ {
+ QString szPath = m_pAvatar->path();
+ u->setProperty("avatar",szPath);
+ bSetAvatar = true;
+ }
+
+ if(m_pNotifyCheck->isChecked())
+ {
+ m1 = m_pNotifyNickEdit1->text();
+ m2 = m_pNotifyNickEdit2->text();
+ if(!m2.isEmpty())
+ {
+ if(!m1.isEmpty())
+ m1.append(' ');
+ m1.append(m2);
+ }
+
+ if(!m1.isEmpty())
+ {
+ u->setProperty("notify",m1);
+ if(!bLocalDb)g_pApp->restartNotifyLists();
+ }
+ }
+
+ if(bSetAvatar && !bLocalDb)
+ g_pApp->resetAvatarForMatchingUsers(u);
+
+ KviTalWizard::accept();
+
+// if(!m_bModal)delete this;
+// hide();
+// g_pApp->collectGarbage(this);
+}
+
+
+void KviRegistrationWizard::showEvent(QShowEvent *e)
+{
+ if(height() < 420)resize(width(),420);
+ move((g_pApp->desktop()->width() - width())/2,(g_pApp->desktop()->height() - height())/2);
+ KviTalWizard::showEvent(e);
+}
+
+void KviRegistrationWizard::maskChanged(const QString &)
+{
+ KviStr tmp1 = m_pNicknameEdit1->text();
+ KviStr tmp2 = m_pUsernameEdit1->text();
+ KviStr tmp3 = m_pHostEdit1->text();
+
+ if(tmp1.isEmpty())
+ {
+ setNextEnabled(m_pPage2,false);
+ return;
+ }
+
+ if(tmp2.isEmpty())
+ {
+ setNextEnabled(m_pPage2,false);
+ return;
+ }
+
+ if(tmp3.isEmpty())
+ {
+ setNextEnabled(m_pPage2,false);
+ return;
+ }
+
+ KviStr mask(KviStr::Format,"%s!%s@%s",tmp1.ptr(),tmp2.ptr(),tmp3.ptr());
+
+ //KviIrcMask m(mask.ptr());
+
+ setNextEnabled(m_pPage2,mask!="*!*@*");
+}
+
+void KviRegistrationWizard::realNameChanged(const QString &)
+{
+ QString tmp = m_pEditRealName->text();
+ setNextEnabled(m_pPage1,!(tmp.isEmpty() || tmp.isNull()));
+}
+
+void KviRegistrationWizard::notifyNickChanged(const QString &)
+{
+ bool bYes = !m_pNotifyCheck->isChecked();
+
+ if(!bYes)
+ {
+ // we need at least one nickname then :)
+ KviStr tmp = m_pNotifyNickEdit1->text();
+ if(tmp.hasData())
+ {
+ bYes = true;
+ } else {
+ tmp = m_pNotifyNickEdit2->text();
+ if(tmp.hasData())bYes = true;
+ }
+ }
+
+ setNextEnabled(m_pPage4,bYes);
+}
+
+void KviRegistrationWizard::notifyCheckToggled(bool)
+{
+ bool bYes = m_pNotifyCheck->isChecked();
+
+ m_pNotifyNickEdit1->setEnabled(bYes);
+ m_pNotifyNickEdit2->setEnabled(bYes);
+ m_pNotifyNickLabel1->setEnabled(bYes);
+ m_pNotifyNickLabel2->setEnabled(bYes);
+
+ QString dummy;
+ notifyNickChanged(dummy);
+}
+
+#include "wizard.moc"
diff --git a/src/modules/reguser/wizard.h b/src/modules/reguser/wizard.h
new file mode 100644
index 00000000..f1446ec6
--- /dev/null
+++ b/src/modules/reguser/wizard.h
@@ -0,0 +1,89 @@
+#ifndef _WIZARD_H_
+#define _WIZARD_H_
+//
+// File : wizard.h
+// Creation date : Fri Jun 26 2002 21:21:21 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 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_string.h"
+
+#include <kvi_tal_wizard.h>
+
+class KviPixmap;
+class KviPixmapSelector;
+class KviTalVBoxLayout;
+class KviTalHBoxLayout;
+class QGridLayout;
+class QCheckBox;
+class QLabel;
+class QLineEdit;
+class QWidget;
+class KviRegisteredUserDataBase;
+
+class KviRegistrationWizard : public KviTalWizard
+{
+ Q_OBJECT
+public:
+ KviRegistrationWizard(const char * startMask,KviRegisteredUserDataBase * db = 0,QWidget * par = 0,bool bModal = false);
+ ~KviRegistrationWizard();
+
+ KviRegisteredUserDataBase * m_pDb;
+
+ KviStr m_szStartMask;
+
+ bool m_bModal;
+
+ QWidget* m_pPage1;
+ QLabel* m_pLabel1;
+ QLineEdit* m_pEditRealName;
+ QWidget* m_pPage2;
+ QLabel* m_pLabel2;
+ QLineEdit* m_pNicknameEdit1;
+ QLineEdit* m_pNicknameEdit2;
+ QLineEdit* m_pHostEdit1;
+ QLineEdit* m_pHostEdit2;
+ QLineEdit* m_pUsernameEdit1;
+ QLineEdit* m_pUsernameEdit2;
+ QWidget* m_pPage3;
+ QLabel* m_pLabel3;
+ KviPixmapSelector * m_pAvatarSelector;
+ QWidget* m_pPage4;
+ QCheckBox* m_pNotifyCheck;
+ QLabel* m_pNotifyNickLabel1;
+ QLabel* m_pNotifyNickLabel2;
+ QLabel* m_pLabel4;
+ QLineEdit* m_pNotifyNickEdit1;
+ QLineEdit* m_pNotifyNickEdit2;
+ QWidget* m_pPage5;
+ QLabel* m_pTextLabel5;
+
+ KviPixmap * m_pAvatar;
+protected:
+ virtual void showEvent(QShowEvent *e);
+ virtual void accept();
+ virtual void reject();
+protected slots:
+ void realNameChanged(const QString &str);
+ void maskChanged(const QString &str);
+ void notifyNickChanged(const QString &);
+ void notifyCheckToggled(bool);
+};
+
+#endif // _WIZARD_H_
diff --git a/src/modules/rijndael/Makefile.am b/src/modules/rijndael/Makefile.am
new file mode 100644
index 00000000..69b2fe01
--- /dev/null
+++ b/src/modules/rijndael/Makefile.am
@@ -0,0 +1,23 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+SUBDIRS = caps
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvirijndael.la
+
+libkvirijndael_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvirijndael_la_SOURCES = libkvirijndael.cpp rijndael.cpp ablowfish.cpp
+libkvirijndael_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= libkvirijndael.h rijndael.h ablowfish.h
+
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkvirijndael.cpp: libkvirijndael.moc
diff --git a/src/modules/rijndael/ablowfish.cpp b/src/modules/rijndael/ablowfish.cpp
new file mode 100644
index 00000000..c56ff36a
--- /dev/null
+++ b/src/modules/rijndael/ablowfish.cpp
@@ -0,0 +1,632 @@
+//
+// File : ablowfish.cpp
+// Creation date : Wed Jan 13 2005 02:04:10 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2005 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 "ablowfish.h"
+#include "kvi_memmove.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+
+//Initialization with a fixed string which consists of the hexadecimal digits of PI (less the initial 3)
+//P-array, 18 32-bit subkeys
+const unsigned int BlowFish::scm_auiInitP[18] = {
+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+ 0x9216d5d9, 0x8979fb1b
+};
+
+//Four 32-bit S-boxes with 256 entries each
+const unsigned int BlowFish::scm_auiInitS[4][256] = {
+ //0
+ {0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
+
+ //1
+ {0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
+
+ //2
+ {0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
+
+ //3
+ {0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
+};
+
+//Constructor - Initialize the P and S boxes for a given Key
+BlowFish::BlowFish(unsigned char* ucKey, unsigned int keysize, const SBlock& roChain) : m_oChain0(roChain), m_oChain(roChain)
+{
+ if(keysize<1)
+ // throw exception("Incorrect key length");
+ return;
+
+
+ //Check the Key - the key length should be between 1 and 56 bytes
+ if(keysize>56)
+ keysize = 56;
+ unsigned char aucLocalKey[56];
+ unsigned int i, j;
+ kvi_fastmove(aucLocalKey, ucKey, keysize);
+ //Reflexive Initialization of the Blowfish.
+ //Generating the Subkeys from the Key flood P and S boxes with PI
+ kvi_fastmove(m_auiP, scm_auiInitP, sizeof(m_auiP));
+ kvi_fastmove(m_auiS, scm_auiInitS, sizeof(m_auiS));
+ //Load P boxes with key bytes
+ const unsigned char* p = aucLocalKey;
+ unsigned int x=0;
+ //Repeatedly cycle through the key bits until the entire P array has been XORed with key bits
+ int iCount = 0;
+ for(i=0; i<18; i++)
+ {
+ x=0;
+ for(int n=4; n--; )
+ {
+ x <<= 8;
+ x |= *(p++);
+ iCount++;
+ if(iCount == ((int)keysize))
+ {
+ //All bytes used, so recycle bytes
+ iCount = 0;
+ p = aucLocalKey;
+ }
+ }
+ m_auiP[i] ^= x;
+ }
+ //Reflect P and S boxes through the evolving Blowfish
+ SBlock block(0UL,0UL); //all-zero block
+ for(i=0; i<18; )
+ Encrypt(block), m_auiP[i++] = block.m_uil, m_auiP[i++] = block.m_uir;
+ for(j=0; j<4; j++)
+ for(int k=0; k<256; )
+ Encrypt(block), m_auiS[j][k++] = block.m_uil, m_auiS[j][k++] = block.m_uir;
+}
+
+//Sixteen Round Encipher of Block
+void BlowFish::Encrypt(SBlock& block)
+{
+ unsigned int uiLeft = block.m_uil;
+ unsigned int uiRight = block.m_uir;
+ uiLeft ^= m_auiP[0];
+ uiRight ^= F(uiLeft)^m_auiP[1]; uiLeft ^= F(uiRight)^m_auiP[2];
+ uiRight ^= F(uiLeft)^m_auiP[3]; uiLeft ^= F(uiRight)^m_auiP[4];
+ uiRight ^= F(uiLeft)^m_auiP[5]; uiLeft ^= F(uiRight)^m_auiP[6];
+ uiRight ^= F(uiLeft)^m_auiP[7]; uiLeft ^= F(uiRight)^m_auiP[8];
+ uiRight ^= F(uiLeft)^m_auiP[9]; uiLeft ^= F(uiRight)^m_auiP[10];
+ uiRight ^= F(uiLeft)^m_auiP[11]; uiLeft ^= F(uiRight)^m_auiP[12];
+ uiRight ^= F(uiLeft)^m_auiP[13]; uiLeft ^= F(uiRight)^m_auiP[14];
+ uiRight ^= F(uiLeft)^m_auiP[15]; uiLeft ^= F(uiRight)^m_auiP[16];
+ uiRight ^= m_auiP[17];
+ block.m_uil = uiRight;
+ block.m_uir = uiLeft;
+}
+
+//Sixteen Round Decipher of SBlock
+void BlowFish::Decrypt(SBlock& block)
+{
+ unsigned int uiLeft = block.m_uil;
+ unsigned int uiRight = block.m_uir;
+ uiLeft ^= m_auiP[17];
+ uiRight ^= F(uiLeft)^m_auiP[16]; uiLeft ^= F(uiRight)^m_auiP[15];
+ uiRight ^= F(uiLeft)^m_auiP[14]; uiLeft ^= F(uiRight)^m_auiP[13];
+ uiRight ^= F(uiLeft)^m_auiP[12]; uiLeft ^= F(uiRight)^m_auiP[11];
+ uiRight ^= F(uiLeft)^m_auiP[10]; uiLeft ^= F(uiRight)^m_auiP[9];
+ uiRight ^= F(uiLeft)^m_auiP[8]; uiLeft ^= F(uiRight)^m_auiP[7];
+ uiRight ^= F(uiLeft)^m_auiP[6]; uiLeft ^= F(uiRight)^m_auiP[5];
+ uiRight ^= F(uiLeft)^m_auiP[4]; uiLeft ^= F(uiRight)^m_auiP[3];
+ uiRight ^= F(uiLeft)^m_auiP[2]; uiLeft ^= F(uiRight)^m_auiP[1];
+ uiRight ^= m_auiP[0];
+ block.m_uil = uiRight;
+ block.m_uir = uiLeft;
+}
+
+//Semi-Portable Byte Shuffling
+inline void BytesToBlock(unsigned char const* p, SBlock& b)
+{
+ unsigned int y;
+ //Left
+ b.m_uil = 0;
+ y = *p++;
+ y <<= 24;
+ b.m_uil |= y;
+ y = *p++;
+ y <<= 16;
+ b.m_uil |= y;
+ y = *p++;
+ y <<= 8;
+ b.m_uil |= y;
+ y = *p++;
+ b.m_uil |= y;
+ //Right
+ b.m_uir = 0;
+ y = *p++;
+ y <<= 24;
+ b.m_uir |= y;
+ y = *p++;
+ y <<= 16;
+ b.m_uir |= y;
+ y = *p++;
+ y <<= 8;
+ b.m_uir |= y;
+ y = *p++;
+ b.m_uir |= y;
+}
+
+inline void BlockToBytes(SBlock const& b, unsigned char* p)
+{
+ unsigned int y;
+ //Right
+ y = b.m_uir;
+ *--p = Byte(y);
+ y = b.m_uir >> 8;
+ *--p = Byte(y);
+ y = b.m_uir >> 16;
+ *--p = Byte(y);
+ y = b.m_uir >> 24;
+ *--p = Byte(y);
+ //Left
+ y = b.m_uil;
+ *--p = Byte(y);
+ y = b.m_uil >> 8;
+ *--p = Byte(y);
+ y = b.m_uil >> 16;
+ *--p = Byte(y);
+ y = b.m_uil >> 24;
+ *--p = Byte(y);
+}
+
+//Encrypt Buffer in Place
+//Returns false if n is multiple of 8
+void BlowFish::Encrypt(unsigned char* buf, unsigned int n, int iMode)
+{
+ //Check the buffer's length - should be > 0 and multiple of 8
+ if((n==0)||(n%8!=0))
+ //throw exception("Incorrect buffer length");
+ return;
+
+ SBlock work;
+ if(iMode == CBC) //CBC mode, using the Chain
+ {
+ SBlock chain(m_oChain);
+ for(; n >= 8; n -= 8)
+ {
+ BytesToBlock(buf, work);
+ work ^= chain;
+ Encrypt(work);
+ chain = work;
+ BlockToBytes(work, buf+=8);
+ }
+ }
+ else if(iMode == CFB) //CFB mode, using the Chain
+ {
+ SBlock chain(m_oChain);
+ for(; n >= 8; n -= 8)
+ {
+ Encrypt(chain);
+ BytesToBlock(buf, work);
+ work ^= chain;
+ chain = work;
+ BlockToBytes(work, buf+=8);
+ }
+ }
+ else //ECB mode, not using the Chain
+ {
+ for(; n >= 8; n -= 8)
+ {
+ BytesToBlock(buf, work);
+ Encrypt(work);
+ BlockToBytes(work, buf+=8);
+ }
+ }
+}
+
+//Decrypt Buffer in Place
+//Returns false if n is multiple of 8
+void BlowFish::Decrypt(unsigned char* buf, unsigned int n, int iMode)
+{
+ //Check the buffer's length - should be > 0 and multiple of 8
+ if((n==0)||(n%8!=0))
+ //throw exception("Incorrect buffer length");
+ return;
+
+ SBlock work;
+ if(iMode == CBC) //CBC mode, using the Chain
+ {
+ SBlock crypt, chain(m_oChain);
+ for(; n >= 8; n -= 8)
+ {
+ BytesToBlock(buf, work);
+ crypt = work;
+ Decrypt(work);
+ work ^= chain;
+ chain = crypt;
+ BlockToBytes(work, buf+=8);
+ }
+ }
+ else if(iMode == CFB) //CFB mode, using the Chain, not using Decrypt()
+ {
+ SBlock crypt, chain(m_oChain);
+ for(; n >= 8; n -= 8)
+ {
+ BytesToBlock(buf, work);
+ Encrypt(chain);
+ crypt = work;
+ work ^= chain;
+ chain = crypt;
+ BlockToBytes(work, buf+=8);
+ }
+ }
+ else //ECB mode, not using the Chain
+ {
+ for(; n >= 8; n -= 8)
+ {
+ BytesToBlock(buf, work);
+ Decrypt(work);
+ BlockToBytes(work, buf+=8);
+ }
+ }
+}
+
+//Encrypt from Input Buffer to Output Buffer
+//Returns false if n is multiple of 8
+void BlowFish::Encrypt(const unsigned char* in, unsigned char* out, unsigned int n, int iMode)
+{
+ //Check the buffer's length - should be > 0 and multiple of 8
+ if((n==0)||(n%8!=0))
+ //throw exception("Incorrect buffer length");
+ return;
+
+ SBlock work;
+ if(iMode == CBC) //CBC mode, using the Chain
+ {
+ SBlock chain(m_oChain);
+ for(; n >= 8; n -= 8, in += 8)
+ {
+ BytesToBlock(in, work);
+ work ^= chain;
+ Encrypt(work);
+ chain = work;
+ BlockToBytes(work, out+=8);
+ }
+ }
+ else if(iMode == CFB) //CFB mode, using the Chain
+ {
+ SBlock chain(m_oChain);
+ for(; n >= 8; n -= 8, in += 8)
+ {
+ Encrypt(chain);
+ BytesToBlock(in, work);
+ work ^= chain;
+ chain = work;
+ BlockToBytes(work, out+=8);
+ }
+ }
+ else //ECB mode, not using the Chain
+ {
+ for(; n >= 8; n -= 8, in += 8)
+ {
+ BytesToBlock(in, work);
+ Encrypt(work);
+ BlockToBytes(work, out+=8);
+ }
+ }
+}
+
+//Decrypt from Input Buffer to Output Buffer
+//Returns false if n is multiple of 8
+void BlowFish::Decrypt(const unsigned char* in, unsigned char* out, unsigned int n, int iMode)
+{
+ //Check the buffer's length - should be > 0 and multiple of 8
+ if((n==0)||(n%8!=0))
+ //throw exception("Incorrect buffer length");
+ return;
+
+ SBlock work;
+ if(iMode == CBC) //CBC mode, using the Chain
+ {
+ SBlock crypt, chain(m_oChain);
+ for(; n >= 8; n -= 8, in += 8)
+ {
+ BytesToBlock(in, work);
+ crypt = work;
+ Decrypt(work);
+ work ^= chain;
+ chain = crypt;
+ BlockToBytes(work, out+=8);
+ }
+ }
+ else if(iMode == CFB) //CFB mode, using the Chain, not using Decrypt()
+ {
+ SBlock crypt, chain(m_oChain);
+ for(; n >= 8; n -= 8, in += 8)
+ {
+ BytesToBlock(in, work);
+ Encrypt(chain);
+ crypt = work;
+ work ^= chain;
+ chain = crypt;
+ BlockToBytes(work, out+=8);
+ }
+ }
+ else //ECB mode, not using the Chain
+ {
+ for(; n >= 8; n -= 8, in += 8)
+ {
+ BytesToBlock(in, work);
+ Decrypt(work);
+ BlockToBytes(work, out+=8);
+ }
+ }
+}
+
+#endif //COMPILE_CRYPT_SUPPORT
diff --git a/src/modules/rijndael/ablowfish.h b/src/modules/rijndael/ablowfish.h
new file mode 100644
index 00000000..862477dc
--- /dev/null
+++ b/src/modules/rijndael/ablowfish.h
@@ -0,0 +1,141 @@
+#ifndef _BLOWFISH_H_
+#define _BLOWFISH_H_
+//=============================================================================
+//
+// File : ablowfish.h
+// Creation date : Wed Jan 13 2005 02:04:10 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2005 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.
+//
+//=============================================================================
+
+//
+// This code is adapted from the MircCryption engine suite by Dark Raichu
+// Original comments follow.
+//
+
+//---------------------------------------------------------------------------
+// The implementation of blowfish for CBC mode is from
+// http://www.thecodeproject.com/cpp/blowfish.asp by George Anescu
+// I removed exception handling, so it is callers responsibility to insure
+// that strings are length multiples of 8 bytes
+// -mouser 1/08/05
+//---------------------------------------------------------------------------
+
+
+//
+// BLOWFISH ENCRYPTION ALGORITHM
+//
+// Implementation of Bruce Schneier's BLOWFISH algorithm from "Applied
+// Cryptography", Second Edition.
+//
+// Encryption and Decryption of Byte Strings using the Blowfish Encryption Algorithm.
+// Blowfish is a block cipher that encrypts data in 8-byte blocks. The algorithm consists
+// of two parts: a key-expansion part and a data-ancryption part. Key expansion converts a
+// variable key of at least 1 and at most 56 bytes into several subkey arrays totaling
+// 4168 bytes. Blowfish has 16 rounds. Each round consists of a key-dependent permutation,
+// and a key and data-dependent substitution. All operations are XORs and additions on 32-bit words.
+// The only additional operations are four indexed array data lookups per round.
+// Blowfish uses a large number of subkeys. These keys must be precomputed before any data
+// encryption or decryption. The P-array consists of 18 32-bit subkeys: P0, P1,...,P17.
+// There are also four 32-bit S-boxes with 256 entries each: S0,0, S0,1,...,S0,255;
+// S1,0, S1,1,...,S1,255; S2,0, S2,1,...,S2,255; S3,0, S3,1,...,S3,255;
+//
+// The Electronic Code Book (ECB), Cipher Block Chaining (CBC) and Cipher Feedback modes
+// are used:
+//
+// In ECB mode if the same block is encrypted twice with the same key, the resulting
+// ciphertext blocks are the same.
+//
+// In CBC Mode a ciphertext block is obtained by first xoring the
+// plaintext block with the previous ciphertext block, and encrypting the resulting value.
+//
+// In CFB mode a ciphertext block is obtained by encrypting the previous ciphertext block
+// and xoring the resulting value with the plaintext
+//
+// The previous ciphertext block is usually stored in an Initialization Vector (IV).
+// An Initialization Vector of zero is commonly used for the first block, though other
+// arrangements are also in use.
+//
+
+#include "kvi_settings.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+
+//Block Structure
+struct SBlock
+{
+ //Constructors
+ SBlock(unsigned int l=0, unsigned int r=0) : m_uil(l), m_uir(r) {}
+ //Copy Constructor
+ SBlock(const SBlock& roBlock) : m_uil(roBlock.m_uil), m_uir(roBlock.m_uir) {}
+ SBlock& operator^=(SBlock& b) { m_uil ^= b.m_uil; m_uir ^= b.m_uir; return *this; }
+ unsigned int m_uil, m_uir;
+};
+
+class BlowFish
+{
+public:
+ enum { ECB=0, CBC=1, CFB=2 };
+
+ //Constructor - Initialize the P and S boxes for a given Key
+ BlowFish(unsigned char* ucKey, unsigned int n, const SBlock& roChain = SBlock(0UL,0UL));
+
+ //Resetting the chaining block
+ void ResetChain() { m_oChain = m_oChain0; }
+
+ // Encrypt/Decrypt Buffer in Place
+ void Encrypt(unsigned char* buf, unsigned int n, int iMode=ECB);
+ void Decrypt(unsigned char* buf, unsigned int n, int iMode=ECB);
+
+ // Encrypt/Decrypt from Input Buffer to Output Buffer
+ void Encrypt(const unsigned char* in, unsigned char* out, unsigned int n, int iMode=ECB);
+ void Decrypt(const unsigned char* in, unsigned char* out, unsigned int n, int iMode=ECB);
+
+//Private Functions
+private:
+ unsigned int F(unsigned int ui);
+ void Encrypt(SBlock&);
+ void Decrypt(SBlock&);
+
+private:
+ //The Initialization Vector, by default {0, 0}
+ SBlock m_oChain0;
+ SBlock m_oChain;
+ unsigned int m_auiP[18];
+ unsigned int m_auiS[4][256];
+ static const unsigned int scm_auiInitP[18];
+ static const unsigned int scm_auiInitS[4][256];
+};
+
+//Extract low order byte
+inline unsigned char Byte(unsigned int ui)
+{
+ return (unsigned char)(ui & 0xff);
+}
+
+//Function F
+inline unsigned int BlowFish::F(unsigned int ui)
+{
+ return ((m_auiS[0][Byte(ui>>24)] + m_auiS[1][Byte(ui>>16)]) ^ m_auiS[2][Byte(ui>>8)]) + m_auiS[3][Byte(ui)];
+}
+
+#endif //COMPILE_CRYPT_SUPPORT
+
+#endif //!_BLOWFISH_H_
diff --git a/src/modules/rijndael/caps/Makefile.am b/src/modules/rijndael/caps/Makefile.am
new file mode 100644
index 00000000..663f77a8
--- /dev/null
+++ b/src/modules/rijndael/caps/Makefile.am
@@ -0,0 +1,9 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir = $(pluglibdir)/caps/crypt/
+
+tmp_DATA= rijndael
+
+EXTRA_DIST = $(tmp_DATA)
diff --git a/src/modules/rijndael/caps/rijndael b/src/modules/rijndael/caps/rijndael
new file mode 100644
index 00000000..9788f702
--- /dev/null
+++ b/src/modules/rijndael/caps/rijndael
@@ -0,0 +1 @@
+timestamp
diff --git a/src/modules/rijndael/libkvirijndael.cpp b/src/modules/rijndael/libkvirijndael.cpp
new file mode 100644
index 00000000..0a678437
--- /dev/null
+++ b/src/modules/rijndael/libkvirijndael.cpp
@@ -0,0 +1,853 @@
+//
+// File : libkvirijndael.cpp
+// Creation date : Sat Now 4 2000 15:33:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Till Bush (buti@geocities.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 "libkvirijndael.h"
+
+#include "rijndael.h"
+
+#include "kvi_module.h"
+#include "kvi_debug.h"
+#include "kvi_locale.h"
+
+#include "kvi_mirccntrl.h"
+#include "kvi_time.h"
+
+//#warning "Other engines: mircStrip koi2win colorizer lamerizer etc.."
+
+/*
+ @doc: rijndael
+ @type:
+ module
+ @short:
+ The Rijndael cryptographic engines
+ @title:
+ The rijndael module
+ @body:
+ The rijndael module exports six [doc:crypt_engines]cryptographic engines[/doc] based
+ on the Advanced Encryptiong Standard algorithm called Rijndael. Rijndael was
+ originally written by Joan Daemen and Vincent Rijmen. The original Rijndael
+ description is available at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/.[br]
+ It is a private key block cipher that has been designed to replace
+ the widely used DES, and it should provide at leas a decent security agains
+ common attacks. Theoretically the best attack that one can perform on this cipher
+ is the "brute force" attack that requires a really massive parallel computation:
+ actually out of the possibilities of a common "hacker".[br]
+ My implementation allows the usage of 128, 192 and 256 bit keys
+ on 128 bit data blocks. The encrypted binary data buffer is then converted
+ into an ascii-string by using the base64 conversion or hex-digit-string rappresentation.
+ The six engines are the six possible combinations of the key lengths and ascii-string
+ conversions.
+*/
+
+
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+ #include "kvi_memmove.h"
+ #include "kvi_malloc.h"
+
+ #include "kvi_pointerlist.h"
+
+ static KviPointerList<KviCryptEngine> * g_pEngineList = 0;
+
+
+
+
+ KviRijndaelEngine::KviRijndaelEngine()
+ : KviCryptEngine()
+ {
+ g_pEngineList->append(this);
+ m_pEncryptCipher = 0;
+ m_pDecryptCipher = 0;
+ }
+
+ KviRijndaelEngine::~KviRijndaelEngine()
+ {
+ g_pEngineList->removeRef(this);
+ if(m_pEncryptCipher)delete m_pEncryptCipher;
+ if(m_pDecryptCipher)delete m_pDecryptCipher;
+ }
+
+ bool KviRijndaelEngine::init(const char *encKey,int encKeyLen,const char *decKey,int decKeyLen)
+ {
+ if(m_pEncryptCipher)
+ {
+ delete m_pEncryptCipher;
+ m_pEncryptCipher = 0;
+ }
+ if(m_pDecryptCipher)
+ {
+ delete m_pDecryptCipher;
+ m_pDecryptCipher = 0;
+ }
+
+ if(encKey && (encKeyLen > 0))
+ {
+ if(!(decKey && (decKeyLen > 0)))
+ {
+ decKey = encKey;
+ decKeyLen = encKeyLen;
+ } // else all
+ } else {
+ // no encrypt key specified...
+ if(decKey && decKeyLen)
+ {
+ encKey = decKey;
+ encKeyLen = decKeyLen;
+ } else {
+ // both keys missing
+ setLastError(__tr("Missing both encrypt and decrypt key: at least one is needed"));
+ return false;
+ }
+ }
+
+ int defLen = getKeyLen();
+
+ char * encryptKey = (char *)kvi_malloc(defLen);
+ char * decryptKey = (char *)kvi_malloc(defLen);
+
+ if(encKeyLen > defLen)encKeyLen = defLen;
+ kvi_memmove(encryptKey,encKey,encKeyLen);
+ if(encKeyLen < defLen)kvi_memset(encryptKey + encKeyLen,'0',defLen - encKeyLen);
+
+ if(decKeyLen > defLen)decKeyLen = defLen;
+ kvi_memmove(decryptKey,decKey,decKeyLen);
+ if(decKeyLen < defLen)kvi_memset(decryptKey + decKeyLen,'0',defLen - decKeyLen);
+
+ m_pEncryptCipher = new Rijndael();
+ int retVal = m_pEncryptCipher->init(Rijndael::CBC,Rijndael::Encrypt,(unsigned char *)encryptKey,getKeyLenId());
+ kvi_free(encryptKey);
+ if(retVal != RIJNDAEL_SUCCESS)
+ {
+ kvi_free(decryptKey);
+ delete m_pEncryptCipher;
+ m_pEncryptCipher = 0;
+ setLastErrorFromRijndaelErrorCode(retVal);
+ return false;
+ }
+
+ m_pDecryptCipher = new Rijndael();
+ retVal = m_pDecryptCipher->init(Rijndael::CBC,Rijndael::Decrypt,(unsigned char *)decryptKey,getKeyLenId());
+ kvi_free(decryptKey);
+ if(retVal != RIJNDAEL_SUCCESS)
+ {
+ delete m_pEncryptCipher;
+ m_pEncryptCipher = 0;
+ delete m_pDecryptCipher;
+ m_pDecryptCipher = 0;
+ setLastErrorFromRijndaelErrorCode(retVal);
+ return false;
+ }
+
+ return true;
+ }
+
+ void KviRijndaelEngine::setLastErrorFromRijndaelErrorCode(int errCode)
+ {
+ switch(errCode)
+ {
+ case RIJNDAEL_SUCCESS: setLastError(__tr("Error 0: Success ?")); break;
+ case RIJNDAEL_UNSUPPORTED_MODE: setLastError(__tr("Unsupported crypt mode")); break;
+ case RIJNDAEL_UNSUPPORTED_DIRECTION: setLastError(__tr("Unsupported direction")); break;
+ case RIJNDAEL_UNSUPPORTED_KEY_LENGTH: setLastError(__tr("Unsupported key length")); break;
+ case RIJNDAEL_BAD_KEY: setLastError(__tr("Bad key data")); break;
+ case RIJNDAEL_NOT_INITIALIZED: setLastError(__tr("Engine not initialized")); break;
+ case RIJNDAEL_BAD_DIRECTION: setLastError(__tr("Invalid direction for this engine")); break;
+ case RIJNDAEL_CORRUPTED_DATA: setLastError(__tr("Corrupted message data or invalid decrypt key")); break;
+ default: setLastError(__tr("Unknown error")); break;
+ }
+ }
+
+ KviCryptEngine::EncryptResult KviRijndaelEngine::encrypt(const char * plainText,KviStr &outBuffer)
+ {
+ if(!m_pEncryptCipher)
+ {
+ setLastError(__tr("Ops...encrypt cipher not initialized"));
+ return KviCryptEngine::EncryptError;
+ }
+ int len = (int)kvi_strLen(plainText);
+ char * buf = (char *)kvi_malloc(len + 16);
+
+ int retVal = m_pEncryptCipher->padEncrypt((const unsigned char *)plainText,len,(unsigned char *)buf);
+ if(retVal < 0)
+ {
+ kvi_free(buf);
+ setLastErrorFromRijndaelErrorCode(retVal);
+ return KviCryptEngine::EncryptError;
+ }
+
+ if(!binaryToAscii(buf,retVal,outBuffer))
+ {
+ kvi_free(buf);
+ return KviCryptEngine::EncryptError;
+ }
+ kvi_free(buf);
+
+ if(outBuffer.len() > maxEncryptLen())
+ {
+ if(maxEncryptLen() > 0)
+ {
+ setLastError(__tr("Data buffer too long"));
+ return KviCryptEngine::EncryptError;
+ }
+ }
+ outBuffer.prepend(KVI_TEXT_CRYPTESCAPE);
+ return KviCryptEngine::Encrypted;
+ }
+
+ KviCryptEngine::DecryptResult KviRijndaelEngine::decrypt(const char * inBuffer,KviStr &plainText)
+ {
+ if(!m_pDecryptCipher)
+ {
+ setLastError(__tr("Ops...decrypt cipher not initialized"));
+ return KviCryptEngine::DecryptError;
+ }
+
+ if(*inBuffer != KVI_TEXT_CRYPTESCAPE)
+ {
+ plainText = inBuffer;
+ return KviCryptEngine::DecryptOkWasPlainText;
+ }
+
+ inBuffer++;
+
+ if(!*inBuffer)
+ {
+ plainText = inBuffer;
+ return KviCryptEngine::DecryptOkWasPlainText; // empty buffer
+ }
+
+ int len;
+ char * binary;
+
+ if(!asciiToBinary(inBuffer,&len,&binary))return KviCryptEngine::DecryptError;
+
+ char * buf = (char *)kvi_malloc(len + 1);
+
+ int retVal = m_pDecryptCipher->padDecrypt((const unsigned char *)binary,len,(unsigned char *)buf);
+ kvi_free(binary);
+
+ if(retVal < 0)
+ {
+ kvi_free(buf);
+ setLastErrorFromRijndaelErrorCode(retVal);
+ return KviCryptEngine::DecryptError;
+ }
+
+ buf[retVal] = '\0';
+
+ plainText = buf;
+
+ kvi_free(buf);
+ return KviCryptEngine::DecryptOkWasEncrypted;
+ }
+
+ bool KviRijndaelHexEngine::binaryToAscii(const char * inBuffer,int len,KviStr &outBuffer)
+ {
+ outBuffer.bufferToHex(inBuffer,len);
+ return true;
+ }
+
+ bool KviRijndaelHexEngine::asciiToBinary(const char * inBuffer,int * len,char ** outBuffer)
+ {
+ KviStr hex(inBuffer);
+ char * tmpBuf;
+ *len = hex.hexToBuffer(&tmpBuf,false);
+ if(*len < 0)
+ {
+ setLastError(__tr("The message is not a hexadecimal string: this is not my stuff"));
+ return false;
+ } else {
+ if(len > 0)
+ {
+ *outBuffer = (char *)kvi_malloc(*len);
+ kvi_memmove(*outBuffer,tmpBuf,*len);
+ KviStr::freeBuffer(tmpBuf);
+ }
+ }
+ return true;
+ }
+
+ bool KviRijndaelBase64Engine::binaryToAscii(const char * inBuffer,int len,KviStr &outBuffer)
+ {
+ outBuffer.bufferToBase64(inBuffer,len);
+ return true;
+ }
+
+ bool KviRijndaelBase64Engine::asciiToBinary(const char * inBuffer,int * len,char ** outBuffer)
+ {
+ KviStr base64(inBuffer);
+ char * tmpBuf;
+ *len = base64.base64ToBuffer(&tmpBuf,false);
+ if(*len < 0)
+ {
+ setLastError(__tr("The message is not a base64 string: this is not my stuff"));
+ return false;
+ } else {
+ if(len > 0)
+ {
+ *outBuffer = (char *)kvi_malloc(*len);
+ kvi_memmove(*outBuffer,tmpBuf,*len);
+ KviStr::freeBuffer(tmpBuf);
+ }
+ }
+ return true;
+ }
+
+ static KviCryptEngine * allocRijndael128HexEngine()
+ {
+ return new KviRijndael128HexEngine();
+ }
+
+ static KviCryptEngine * allocRijndael192HexEngine()
+ {
+ return new KviRijndael192HexEngine();
+ }
+
+ static KviCryptEngine * allocRijndael256HexEngine()
+ {
+ return new KviRijndael256HexEngine();
+ }
+
+ static KviCryptEngine * allocRijndael128Base64Engine()
+ {
+ return new KviRijndael128Base64Engine();
+ }
+
+ static KviCryptEngine * allocRijndael192Base64Engine()
+ {
+ return new KviRijndael192Base64Engine();
+ }
+
+ static KviCryptEngine * allocRijndael256Base64Engine()
+ {
+ return new KviRijndael256Base64Engine();
+ }
+
+ static void deallocRijndaelCryptEngine(KviCryptEngine * e)
+ {
+ delete e;
+ }
+
+
+
+
+
+ // Mircryption stuff
+
+ #include "ablowfish.h"
+
+ KviMircryptionEngine::KviMircryptionEngine()
+ : KviCryptEngine()
+ {
+ g_pEngineList->append(this);
+ }
+
+ KviMircryptionEngine::~KviMircryptionEngine()
+ {
+ g_pEngineList->removeRef(this);
+ }
+
+ bool KviMircryptionEngine::init(const char * encKey,int encKeyLen,const char * decKey,int decKeyLen)
+ {
+ if(encKey && (encKeyLen > 0))
+ {
+ if(!(decKey && (decKeyLen > 0)))
+ {
+ decKey = encKey;
+ decKeyLen = encKeyLen;
+ } // else all
+ } else {
+ // no encrypt key specified...
+ if(decKey && decKeyLen)
+ {
+ encKey = decKey;
+ encKeyLen = decKeyLen;
+ } else {
+ // both keys missing
+ setLastError(__tr("Missing both encrypt and decrypt key: at least one is needed"));
+ return false;
+ }
+ }
+ m_szEncryptKey = KviStr(encKey,encKeyLen);
+ m_szDecryptKey = KviStr(decKey,decKeyLen);
+ if(kvi_strEqualCIN("cbc:",m_szEncryptKey.ptr(),4) && (m_szEncryptKey.len() > 4))
+ m_szEncryptKey.cutLeft(4);
+ else
+ m_bEncryptCBC = false;
+ if(kvi_strEqualCIN("cbc:",m_szDecryptKey.ptr(),4) && (m_szDecryptKey.len() > 4))
+ m_szDecryptKey.cutLeft(4);
+ else
+ m_bDecryptCBC = false;
+ return true;
+ }
+
+ KviCryptEngine::EncryptResult KviMircryptionEngine::encrypt(const char * plainText,KviStr &outBuffer)
+ {
+ KviStr szPlain = plainText;
+ outBuffer = "";
+ if(m_bEncryptCBC)
+ {
+ if(!doEncryptCBC(szPlain,outBuffer))return KviCryptEngine::EncryptError;
+ } else {
+ if(!doEncryptECB(szPlain,outBuffer))return KviCryptEngine::EncryptError;
+ }
+ outBuffer.prepend("+OK ");
+
+ if(outBuffer.len() > maxEncryptLen())
+ {
+ if(maxEncryptLen() > 0)
+ {
+ setLastError(__tr("Data buffer too long"));
+ return KviCryptEngine::EncryptError;
+ }
+ }
+
+ //outBuffer = MCPS2_STARTTAG;
+ //outBuffer += MCPS2_ENDTAG;
+ return KviCryptEngine::Encrypted;
+ }
+
+ KviCryptEngine::DecryptResult KviMircryptionEngine::decrypt(const char * inBuffer,KviStr &plainText)
+ {
+ plainText = "";
+ KviStr szIn = inBuffer;
+ // various old versions
+ if(kvi_strEqualCSN(inBuffer,"mcps ",5))
+ szIn.cutLeft(5);
+ else if(kvi_strEqualCSN(inBuffer,"+OK ",4))
+ szIn.cutLeft(4);
+ else {
+ plainText = szIn;
+ return KviCryptEngine::DecryptOkWasPlainText;
+ }
+
+ if(m_bDecryptCBC)return doDecryptCBC(szIn,plainText) ? KviCryptEngine::DecryptOkWasEncrypted : KviCryptEngine::DecryptError;
+ return doDecryptECB(szIn,plainText) ? KviCryptEngine::DecryptOkWasEncrypted : KviCryptEngine::DecryptError;
+
+ /*
+ int len1 = kvi_strLen(MCPS2_STARTTAG);
+ int len2 = kvi_strLen(MCPS2_ENDTAG);
+ while(szIn.len() > 0)
+ {
+ int idx = szIn.findFirstIdx(MCPS2_STARTTAG);
+ if(idx == -1)
+ {
+ // no more encrypted stuff
+ plainText += szIn;
+ return true;
+ }
+ if(idx > 0) // a non encrypted block
+ plainText += szIn.left(idx);
+ szIn.cutLeft(idx + len1);
+
+ idx = szIn.findFirstIdx(MCPS2_ENDTAG);
+ if(idx != -1)
+ {
+ KviStr toDecrypt = szIn.left(idx);
+ if(!doDecrypt(toDecrypt,plainText))return false;
+ }
+ szIn.cutLeft(idx + len2);
+ }
+ */
+ }
+
+ static unsigned char fake_base64[]="./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ unsigned int fake_base64dec(unsigned char c)
+ {
+ static char base64unmap[255];
+ static bool didinit=false;
+ int i;
+
+ if(!didinit)
+ {
+ // initialize base64unmap
+ for (i=0;i<255;++i)base64unmap[i]=0;
+ for (i=0;i<64;++i)base64unmap[fake_base64[i]]=i;
+ didinit=true;
+ }
+
+ return base64unmap[c];
+ }
+
+ static void byteswap_buffer(unsigned char * p,int len)
+ {
+ while(len > 0)
+ {
+ unsigned char aux = p[0];
+ p[0] = p[3];
+ p[3] = aux;
+ aux = p[1];
+ p[1] = p[2];
+ p[2] = aux;
+ p += 4;
+ len -= 4;
+ }
+ }
+
+ bool KviMircryptionEngine::doEncryptECB(KviStr &plain,KviStr &encoded)
+ {
+ // make sure it is a multiple of 8 bytes (eventually pad with zeroes)
+ if(plain.len() % 8)
+ {
+ int oldL = plain.len();
+ plain.setLength(plain.len() + (8 - (plain.len() % 8)));
+ char * padB = plain.ptr() + oldL;
+ char * padE = plain.ptr() + plain.len();
+ while(padB < padE)*padB++ = 0;
+ }
+
+ //byteswap_buffer((unsigned char *)plain.ptr(),plain.len());
+
+ unsigned char * out =(unsigned char *)kvi_malloc(plain.len()); // we use this to avoid endiannes problems
+
+ BlowFish bf((unsigned char *)m_szEncryptKey.ptr(),m_szEncryptKey.len());
+ bf.ResetChain();
+ bf.Encrypt((unsigned char *)plain.ptr(),out,plain.len(),BlowFish::ECB);
+
+ // FIXME: this is probably needed only on LittleEndian machines!
+ byteswap_buffer((unsigned char *)out,plain.len());
+
+ // da uglybase64 encoding
+ unsigned char * outb = out;
+ unsigned char * oute = out + plain.len();
+
+ int ll = (plain.len() * 3) / 2;
+ encoded.setLength(ll);
+
+ unsigned char * p = (unsigned char *)encoded.ptr();
+ while(outb < oute)
+ {
+ Q_UINT32 * dd1 = (Q_UINT32 *)outb;
+ outb += 4;
+ Q_UINT32 * dd2 = (Q_UINT32 *)outb;
+ outb += 4;
+ *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
+ *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
+ *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
+ *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
+ *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
+ *p++ = fake_base64[*dd2 & 0x3f];
+
+ *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
+ *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
+ *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
+ *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
+ *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
+ *p++ = fake_base64[*dd1 & 0x3f];
+ }
+
+ kvi_free(out);
+ return true;
+ }
+
+ bool KviMircryptionEngine::doDecryptECB(KviStr &encoded,KviStr &plain)
+ {
+ // encoded is in this strange base64...
+ // make sure its length is multiple of 12 (eventually pad with zeroes)
+ if(encoded.len() % 12)
+ {
+ int oldL = encoded.len();
+ encoded.setLength(encoded.len() + (12 - (encoded.len() % 12)));
+ char * padB = encoded.ptr() + oldL;
+ char * padE = encoded.ptr() + encoded.len();
+ while(padB < padE)*padB++ = 0;
+ }
+
+ // a fake base64 decoding algo, use a different character set
+ // and stuff 6 bytes at a time into a 32 bit long...
+ int ll = (encoded.len() * 2) / 3;
+
+ unsigned char * buf = (unsigned char *)kvi_malloc(ll);
+ unsigned char * p = (unsigned char *)encoded.ptr();
+ unsigned char * e = p + encoded.len();
+ int i;
+ unsigned char * bufp = buf;
+ while(p < e)
+ {
+ Q_UINT32 * dw1 = (Q_UINT32 *)bufp;
+ bufp += 4;
+ Q_UINT32 * dw2 = (Q_UINT32 *)bufp;
+ bufp += 4;
+ *dw2 = 0;
+ for(i=0;i < 6;i++)*dw2 |= (fake_base64dec(*p++)) << (i * 6);
+ *dw1 = 0;
+ for(i=0;i < 6;i++)*dw1 |= (fake_base64dec(*p++)) << (i * 6);
+ }
+
+ // FIXME: this is probably needed only on LittleEndian machines!
+ byteswap_buffer((unsigned char *)buf,ll);
+
+ plain.setLength(ll);
+ BlowFish bf((unsigned char *)m_szDecryptKey.ptr(),m_szDecryptKey.len());
+ bf.ResetChain();
+ bf.Decrypt(buf,(unsigned char *)plain.ptr(),ll,BlowFish::ECB);
+
+ //byteswap_buffer((unsigned char *)plain.ptr(),ll);
+
+ kvi_free(buf);
+
+ return true;
+ }
+
+ bool KviMircryptionEngine::doEncryptCBC(KviStr &plain,KviStr &encoded)
+ {
+ // make sure it is a multiple of 8 bytes (eventually pad with zeroes)
+ if(plain.len() % 8)
+ {
+ int oldL = plain.len();
+ plain.setLength(plain.len() + (8 - (plain.len() % 8)));
+ char * padB = plain.ptr() + oldL;
+ char * padE = plain.ptr() + plain.len();
+ while(padB < padE)*padB++ = 0;
+ }
+
+ int ll = plain.len() + 8;
+ unsigned char * in = (unsigned char *)kvi_malloc(ll);
+
+ // choose an IV
+ static bool bDidInit = false;
+
+ int t = (int)kvi_unixTime();
+
+ if(!bDidInit)
+ {
+ srand(t);
+ bDidInit = true;
+ }
+
+ for(int i=0;i<8;i++)in[i] = (unsigned char)(rand() % 256);
+
+ kvi_fastmove(in+8,plain.ptr(),plain.len());
+
+ // encrypt
+ unsigned char * out = (unsigned char *)kvi_malloc(ll);
+ BlowFish bf((unsigned char *)m_szEncryptKey.ptr(),m_szEncryptKey.len());
+ bf.ResetChain();
+ bf.Encrypt(in,out,ll,BlowFish::CBC);
+ kvi_free(in);
+
+ encoded.bufferToBase64((const char *)out,ll);
+ kvi_free(out);
+
+ encoded.prepend('*'); // prepend the signature
+
+ return true;
+ }
+
+ bool KviMircryptionEngine::doDecryptCBC(KviStr &encoded,KviStr &plain)
+ {
+ if(*(encoded.ptr()) != '*')
+ {
+ debug("WARNING: Specified a CBC key but the incoming message doesn't seem to be a CBC one");
+ return doDecryptECB(encoded,plain);
+ }
+ encoded.cutLeft(1);
+
+ char * tmpBuf;
+ int len = encoded.base64ToBuffer(&tmpBuf,false);
+ if(len < 0)
+ {
+ setLastError(__tr("The message is not a base64 string: this is not my stuff"));
+ return false;
+ }
+ if((len < 8) || (len % 8))
+ {
+ setLastError(__tr("The message doesn't seem to be encoded with CBC Mircryption"));
+ if(len > 0)KviStr::freeBuffer(tmpBuf);
+ return false;
+ }
+
+ plain.setLength(len);
+ BlowFish bf((unsigned char *)m_szDecryptKey.ptr(),m_szDecryptKey.len());
+ bf.ResetChain();
+ bf.Decrypt((unsigned char *)tmpBuf,(unsigned char *)plain.ptr(),len,BlowFish::CBC);
+
+ // kill the first 8 bytes (random IV)
+ plain.cutLeft(8);
+
+ KviStr::freeBuffer(tmpBuf);
+
+ return true;
+ }
+
+
+ static KviCryptEngine * allocMircryptionEngine()
+ {
+ return new KviMircryptionEngine();
+ }
+
+#endif
+
+
+// =======================================
+// module routines
+// =======================================
+static bool rijndael_module_init(KviModule * m)
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ g_pEngineList = new KviPointerList<KviCryptEngine>;
+ g_pEngineList->setAutoDelete(false);
+
+ KviStr format = __tr("Cryptographic engine based on the\n" \
+ "Advanced Encryption Standard (AES)\n" \
+ "algorithm called Rijndael.\n" \
+ "The text is first encrypted with rijndael\n" \
+ "and then converted to %s notation.\n" \
+ "The keys used are %d bit long and will be padded\n" \
+ "with zeros if you provide shorter ones.\n" \
+ "If only one key is provided, this engine\n" \
+ "will use it for both encrypting and decrypting.\n" \
+ "See the rijndael module documentation\n" \
+ "for more info on the algorithm used.\n");
+
+ // FIXME: Maybe convert this repeated code to a function eh ?
+
+ KviCryptEngineDescription * d = new KviCryptEngineDescription;
+ d->szName = "Rijndael128Hex";
+ d->szAuthor = "Szymon Stefanek";
+ d->szDescription.sprintf(format.ptr(),__tr("hexadecimal"),128);
+ d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
+ KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
+ d->allocFunc = allocRijndael128HexEngine;
+ d->deallocFunc = deallocRijndaelCryptEngine;
+ m->registerCryptEngine(d);
+
+ d = new KviCryptEngineDescription;
+ d->szName = "Rijndael192Hex";
+ d->szAuthor = "Szymon Stefanek";
+ d->szDescription.sprintf(format.ptr(),__tr("hexadecimal"),192);
+ d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
+ KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
+ d->allocFunc = allocRijndael192HexEngine;
+ d->deallocFunc = deallocRijndaelCryptEngine;
+ m->registerCryptEngine(d);
+
+ d = new KviCryptEngineDescription;
+ d->szName = "Rijndael256Hex";
+ d->szAuthor = "Szymon Stefanek";
+ d->szDescription.sprintf(format.ptr(),__tr("hexadecimal"),256);
+ d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
+ KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
+ d->allocFunc = allocRijndael256HexEngine;
+ d->deallocFunc = deallocRijndaelCryptEngine;
+ m->registerCryptEngine(d);
+
+ d = new KviCryptEngineDescription;
+ d->szName = "Rijndael128Base64";
+ d->szAuthor = "Szymon Stefanek";
+ d->szDescription.sprintf(format.ptr(),__tr("base64"),128);
+ d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
+ KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
+ d->allocFunc = allocRijndael128Base64Engine;
+ d->deallocFunc = deallocRijndaelCryptEngine;
+ m->registerCryptEngine(d);
+
+ d = new KviCryptEngineDescription;
+ d->szName = "Rijndael192Base64";
+ d->szAuthor = "Szymon Stefanek";
+ d->szDescription.sprintf(format.ptr(),__tr("base64"),192);
+ d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
+ KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
+ d->allocFunc = allocRijndael192Base64Engine;
+ d->deallocFunc = deallocRijndaelCryptEngine;
+ m->registerCryptEngine(d);
+
+ d = new KviCryptEngineDescription;
+ d->szName = "Rijndael256Base64";
+ d->szAuthor = "Szymon Stefanek";
+ d->szDescription.sprintf(format.ptr(),__tr("base64"),256);
+ d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
+ KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
+ d->allocFunc = allocRijndael256Base64Engine;
+ d->deallocFunc = deallocRijndaelCryptEngine;
+ m->registerCryptEngine(d);
+
+
+ d = new KviCryptEngineDescription;
+ d->szName = "Mircryption";
+ d->szAuthor = "Szymon Stefanek";
+ d->szDescription = __tr("Popular cryptographic engine based on the\n" \
+ "old Blowfish encryption algorithm.\n" \
+ "The text is first encrypted with Blowfish \n" \
+ "and then converted to base64 notation.\n" \
+ "The keys used have variable length and\n" \
+ "are specified as character strings.\n" \
+ "You can specify keys long up to 56 bytes (448 bits).\n" \
+ "If only one key is provided, this engine\n" \
+ "will use it for both encrypting and decrypting.\n" \
+ "This engine works in ECB mode by default:\n" \
+ "if you want to use CBC mode you must prefix\n" \
+ "your key(s) with \"cbc:\".\n");
+ d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
+ KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
+ d->allocFunc = allocMircryptionEngine;
+ d->deallocFunc = deallocRijndaelCryptEngine;
+ m->registerCryptEngine(d);
+
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+static bool rijndael_module_cleanup(KviModule *m)
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ while(g_pEngineList->first())delete g_pEngineList->first();
+ delete g_pEngineList;
+ g_pEngineList = 0;
+ m->unregisterCryptEngines();
+ return true;
+#else
+ return false;
+#endif
+}
+
+static bool rijndael_module_can_unload(KviModule *)
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ return g_pEngineList->isEmpty();
+#else
+ return true;
+#endif
+}
+
+// =======================================
+// plugin definition structure
+// =======================================
+KVIRC_MODULE(
+ "Rijndael crypt engine",
+ "1.0.0",
+ "Szymon Stefanek <pragma at kvirc dot net>" ,
+ "Exports the rijndael crypt engine",
+ rijndael_module_init ,
+ rijndael_module_can_unload,
+ 0,
+ rijndael_module_cleanup
+)
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ #include "libkvirijndael.moc"
+#endif
diff --git a/src/modules/rijndael/libkvirijndael.h b/src/modules/rijndael/libkvirijndael.h
new file mode 100644
index 00000000..900ff252
--- /dev/null
+++ b/src/modules/rijndael/libkvirijndael.h
@@ -0,0 +1,169 @@
+#ifndef _LIBKVIRIJNDAEL_H_
+#define _LIBKVIRIJNDAEL_H_
+//
+// File : libkvirijndael.h
+// Creation date : Sat Now 4 2000 15:41:41 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Till Bush (buti@geocities.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_settings.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+ #include "kvi_crypt.h"
+ #include "rijndael.h"
+
+ class KviRijndaelEngine : public KviCryptEngine
+ {
+ Q_OBJECT
+ public:
+ KviRijndaelEngine();
+ virtual ~KviRijndaelEngine();
+ private:
+ Rijndael * m_pEncryptCipher;
+ Rijndael * m_pDecryptCipher;
+ public:
+ virtual bool init(const char *encKey,int encKeyLen,const char *decKey,int decKeyLen);
+ virtual KviCryptEngine::EncryptResult encrypt(const char * plainText,KviStr &outBuffer);
+ virtual KviCryptEngine::DecryptResult decrypt(const char * inBuffer,KviStr &plainText);
+ protected:
+ virtual bool binaryToAscii(const char * inBuffer,int len,KviStr &outBuffer){ return false; };
+ virtual bool asciiToBinary(const char * inBuffer,int * len,char ** outBuffer){ return false; };
+ virtual int getKeyLen(){ return 32; };
+ virtual Rijndael::KeyLength getKeyLenId(){ return Rijndael::Key32Bytes; };
+ private:
+ void setLastErrorFromRijndaelErrorCode(int errCode);
+ };
+
+ class KviRijndaelHexEngine : public KviRijndaelEngine
+ {
+ Q_OBJECT
+ public:
+ KviRijndaelHexEngine() : KviRijndaelEngine() {};
+ virtual ~KviRijndaelHexEngine(){};
+ protected:
+ virtual bool binaryToAscii(const char * inBuffer,int len,KviStr &outBuffer);
+ virtual bool asciiToBinary(const char * inBuffer,int * len,char ** outBuffer);
+ };
+
+ class KviRijndael128HexEngine : public KviRijndaelHexEngine
+ {
+ Q_OBJECT
+ public:
+ KviRijndael128HexEngine() : KviRijndaelHexEngine() {};
+ virtual ~KviRijndael128HexEngine(){};
+ protected:
+ virtual int getKenLen(){ return 16; };
+ virtual Rijndael::KeyLength getKeyLenId(){ return Rijndael::Key16Bytes; };
+ };
+
+ class KviRijndael192HexEngine : public KviRijndaelHexEngine
+ {
+ Q_OBJECT
+ public:
+ KviRijndael192HexEngine() : KviRijndaelHexEngine() {};
+ virtual ~KviRijndael192HexEngine(){};
+ protected:
+ virtual int getKenLen(){ return 24; };
+ virtual Rijndael::KeyLength getKeyLenId(){ return Rijndael::Key24Bytes; };
+ };
+
+ class KviRijndael256HexEngine : public KviRijndaelHexEngine
+ {
+ Q_OBJECT
+ public:
+ KviRijndael256HexEngine() : KviRijndaelHexEngine() {};
+ virtual ~KviRijndael256HexEngine(){};
+ protected:
+ virtual int getKenLen(){ return 32; };
+ };
+
+ class KviRijndaelBase64Engine : public KviRijndaelEngine
+ {
+ Q_OBJECT
+ public:
+ KviRijndaelBase64Engine() : KviRijndaelEngine() {};
+ virtual ~KviRijndaelBase64Engine(){};
+ protected:
+ virtual bool binaryToAscii(const char * inBuffer,int len,KviStr &outBuffer);
+ virtual bool asciiToBinary(const char * inBuffer,int * len,char ** outBuffer);
+ };
+
+ class KviRijndael128Base64Engine : public KviRijndaelBase64Engine
+ {
+ Q_OBJECT
+ public:
+ KviRijndael128Base64Engine() : KviRijndaelBase64Engine() {};
+ virtual ~KviRijndael128Base64Engine(){};
+ protected:
+ virtual int getKenLen(){ return 16; };
+ virtual Rijndael::KeyLength getKeyLenId(){ return Rijndael::Key16Bytes; };
+ };
+
+ class KviRijndael192Base64Engine : public KviRijndaelBase64Engine
+ {
+ Q_OBJECT
+ public:
+ KviRijndael192Base64Engine() : KviRijndaelBase64Engine() {};
+ virtual ~KviRijndael192Base64Engine(){};
+ protected:
+ virtual int getKenLen(){ return 24; };
+ virtual Rijndael::KeyLength getKeyLenId(){ return Rijndael::Key24Bytes; };
+ };
+
+ class KviRijndael256Base64Engine : public KviRijndaelBase64Engine
+ {
+ Q_OBJECT
+ public:
+ KviRijndael256Base64Engine() : KviRijndaelBase64Engine() {};
+ virtual ~KviRijndael256Base64Engine(){};
+ protected:
+ virtual int getKenLen(){ return 32; };
+ };
+
+ // Mircyption stuff
+ #define MCPS2_STARTTAG "\xABm\xAB"
+ #define MCPS2_ENDTAG "\xBBm\xBB"
+
+ class KviMircryptionEngine : public KviCryptEngine
+ {
+ Q_OBJECT
+ public:
+ KviMircryptionEngine();
+ ~KviMircryptionEngine();
+ protected:
+ KviStr m_szEncryptKey;
+ bool m_bEncryptCBC;
+ KviStr m_szDecryptKey;
+ bool m_bDecryptCBC;
+ public:
+ virtual bool isCryptographicEngine(){ return false; }; // we need to return false since it doesn't use the Qt::CTRL+P escape
+ virtual bool init(const char *encKey,int encKeyLen,const char *decKey,int decKeyLen);
+ virtual KviCryptEngine::EncryptResult encrypt(const char * plainText,KviStr &outBuffer);
+ virtual KviCryptEngine::DecryptResult decrypt(const char * inBuffer,KviStr &plainText);
+ protected:
+ bool doDecryptECB(KviStr &encoded,KviStr &plain);
+ bool doDecryptCBC(KviStr &encoded,KviStr &plain);
+ bool doEncryptECB(KviStr &plain,KviStr &encoded);
+ bool doEncryptCBC(KviStr &plain,KviStr &encoded);
+ };
+
+#endif // COMPILE_CRYPT_SUPPORT
+
+#endif // _LIBKVIRIJNDAEL_H_
diff --git a/src/modules/rijndael/rijndael.cpp b/src/modules/rijndael/rijndael.cpp
new file mode 100644
index 00000000..8adbf926
--- /dev/null
+++ b/src/modules/rijndael/rijndael.cpp
@@ -0,0 +1,1626 @@
+//
+// File : rijndael.cpp
+// Creation date : Sun Nov 5 2000 03:22:10 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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.
+//
+
+//
+// Another implementation of the Rijndael cipher.
+// This is intended to be an easily usable library file.
+// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
+//
+
+//
+// Original Copyright notice:
+//
+// rijndael-alg-fst.c v2.4 April '2000
+// rijndael-alg-fst.h
+// rijndael-api-fst.c
+// rijndael-api-fst.h
+//
+// Optimised ANSI C code
+//
+// authors: v1.0: Antoon Bosselaers
+// v2.0: Vincent Rijmen, K.U.Leuven
+// v2.3: Paulo Barreto
+// v2.4: Vincent Rijmen, K.U.Leuven
+//
+// This code is placed in the public domain.
+//
+
+//
+// This implementation works on 128 , 192 , 256 bit keys
+// and on 128 bit blocks
+//
+
+#include "kvi_settings.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+#define _RIJNDAEL_CPP_
+
+#include "rijndael.h"
+
+#include "kvi_memmove.h"
+
+//#include <stdio.h>
+//#include <stdlib.h>
+
+static UINT8 S[256]=
+{
+ 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
+ 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
+ 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
+ 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
+ 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
+ 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
+ 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
+ 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
+ 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
+ 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
+ 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
+ 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
+ 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
+ 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
+ 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
+ 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22
+};
+
+
+static UINT8 T1[256][4]=
+{
+ 0xc6,0x63,0x63,0xa5, 0xf8,0x7c,0x7c,0x84, 0xee,0x77,0x77,0x99, 0xf6,0x7b,0x7b,0x8d,
+ 0xff,0xf2,0xf2,0x0d, 0xd6,0x6b,0x6b,0xbd, 0xde,0x6f,0x6f,0xb1, 0x91,0xc5,0xc5,0x54,
+ 0x60,0x30,0x30,0x50, 0x02,0x01,0x01,0x03, 0xce,0x67,0x67,0xa9, 0x56,0x2b,0x2b,0x7d,
+ 0xe7,0xfe,0xfe,0x19, 0xb5,0xd7,0xd7,0x62, 0x4d,0xab,0xab,0xe6, 0xec,0x76,0x76,0x9a,
+ 0x8f,0xca,0xca,0x45, 0x1f,0x82,0x82,0x9d, 0x89,0xc9,0xc9,0x40, 0xfa,0x7d,0x7d,0x87,
+ 0xef,0xfa,0xfa,0x15, 0xb2,0x59,0x59,0xeb, 0x8e,0x47,0x47,0xc9, 0xfb,0xf0,0xf0,0x0b,
+ 0x41,0xad,0xad,0xec, 0xb3,0xd4,0xd4,0x67, 0x5f,0xa2,0xa2,0xfd, 0x45,0xaf,0xaf,0xea,
+ 0x23,0x9c,0x9c,0xbf, 0x53,0xa4,0xa4,0xf7, 0xe4,0x72,0x72,0x96, 0x9b,0xc0,0xc0,0x5b,
+ 0x75,0xb7,0xb7,0xc2, 0xe1,0xfd,0xfd,0x1c, 0x3d,0x93,0x93,0xae, 0x4c,0x26,0x26,0x6a,
+ 0x6c,0x36,0x36,0x5a, 0x7e,0x3f,0x3f,0x41, 0xf5,0xf7,0xf7,0x02, 0x83,0xcc,0xcc,0x4f,
+ 0x68,0x34,0x34,0x5c, 0x51,0xa5,0xa5,0xf4, 0xd1,0xe5,0xe5,0x34, 0xf9,0xf1,0xf1,0x08,
+ 0xe2,0x71,0x71,0x93, 0xab,0xd8,0xd8,0x73, 0x62,0x31,0x31,0x53, 0x2a,0x15,0x15,0x3f,
+ 0x08,0x04,0x04,0x0c, 0x95,0xc7,0xc7,0x52, 0x46,0x23,0x23,0x65, 0x9d,0xc3,0xc3,0x5e,
+ 0x30,0x18,0x18,0x28, 0x37,0x96,0x96,0xa1, 0x0a,0x05,0x05,0x0f, 0x2f,0x9a,0x9a,0xb5,
+ 0x0e,0x07,0x07,0x09, 0x24,0x12,0x12,0x36, 0x1b,0x80,0x80,0x9b, 0xdf,0xe2,0xe2,0x3d,
+ 0xcd,0xeb,0xeb,0x26, 0x4e,0x27,0x27,0x69, 0x7f,0xb2,0xb2,0xcd, 0xea,0x75,0x75,0x9f,
+ 0x12,0x09,0x09,0x1b, 0x1d,0x83,0x83,0x9e, 0x58,0x2c,0x2c,0x74, 0x34,0x1a,0x1a,0x2e,
+ 0x36,0x1b,0x1b,0x2d, 0xdc,0x6e,0x6e,0xb2, 0xb4,0x5a,0x5a,0xee, 0x5b,0xa0,0xa0,0xfb,
+ 0xa4,0x52,0x52,0xf6, 0x76,0x3b,0x3b,0x4d, 0xb7,0xd6,0xd6,0x61, 0x7d,0xb3,0xb3,0xce,
+ 0x52,0x29,0x29,0x7b, 0xdd,0xe3,0xe3,0x3e, 0x5e,0x2f,0x2f,0x71, 0x13,0x84,0x84,0x97,
+ 0xa6,0x53,0x53,0xf5, 0xb9,0xd1,0xd1,0x68, 0x00,0x00,0x00,0x00, 0xc1,0xed,0xed,0x2c,
+ 0x40,0x20,0x20,0x60, 0xe3,0xfc,0xfc,0x1f, 0x79,0xb1,0xb1,0xc8, 0xb6,0x5b,0x5b,0xed,
+ 0xd4,0x6a,0x6a,0xbe, 0x8d,0xcb,0xcb,0x46, 0x67,0xbe,0xbe,0xd9, 0x72,0x39,0x39,0x4b,
+ 0x94,0x4a,0x4a,0xde, 0x98,0x4c,0x4c,0xd4, 0xb0,0x58,0x58,0xe8, 0x85,0xcf,0xcf,0x4a,
+ 0xbb,0xd0,0xd0,0x6b, 0xc5,0xef,0xef,0x2a, 0x4f,0xaa,0xaa,0xe5, 0xed,0xfb,0xfb,0x16,
+ 0x86,0x43,0x43,0xc5, 0x9a,0x4d,0x4d,0xd7, 0x66,0x33,0x33,0x55, 0x11,0x85,0x85,0x94,
+ 0x8a,0x45,0x45,0xcf, 0xe9,0xf9,0xf9,0x10, 0x04,0x02,0x02,0x06, 0xfe,0x7f,0x7f,0x81,
+ 0xa0,0x50,0x50,0xf0, 0x78,0x3c,0x3c,0x44, 0x25,0x9f,0x9f,0xba, 0x4b,0xa8,0xa8,0xe3,
+ 0xa2,0x51,0x51,0xf3, 0x5d,0xa3,0xa3,0xfe, 0x80,0x40,0x40,0xc0, 0x05,0x8f,0x8f,0x8a,
+ 0x3f,0x92,0x92,0xad, 0x21,0x9d,0x9d,0xbc, 0x70,0x38,0x38,0x48, 0xf1,0xf5,0xf5,0x04,
+ 0x63,0xbc,0xbc,0xdf, 0x77,0xb6,0xb6,0xc1, 0xaf,0xda,0xda,0x75, 0x42,0x21,0x21,0x63,
+ 0x20,0x10,0x10,0x30, 0xe5,0xff,0xff,0x1a, 0xfd,0xf3,0xf3,0x0e, 0xbf,0xd2,0xd2,0x6d,
+ 0x81,0xcd,0xcd,0x4c, 0x18,0x0c,0x0c,0x14, 0x26,0x13,0x13,0x35, 0xc3,0xec,0xec,0x2f,
+ 0xbe,0x5f,0x5f,0xe1, 0x35,0x97,0x97,0xa2, 0x88,0x44,0x44,0xcc, 0x2e,0x17,0x17,0x39,
+ 0x93,0xc4,0xc4,0x57, 0x55,0xa7,0xa7,0xf2, 0xfc,0x7e,0x7e,0x82, 0x7a,0x3d,0x3d,0x47,
+ 0xc8,0x64,0x64,0xac, 0xba,0x5d,0x5d,0xe7, 0x32,0x19,0x19,0x2b, 0xe6,0x73,0x73,0x95,
+ 0xc0,0x60,0x60,0xa0, 0x19,0x81,0x81,0x98, 0x9e,0x4f,0x4f,0xd1, 0xa3,0xdc,0xdc,0x7f,
+ 0x44,0x22,0x22,0x66, 0x54,0x2a,0x2a,0x7e, 0x3b,0x90,0x90,0xab, 0x0b,0x88,0x88,0x83,
+ 0x8c,0x46,0x46,0xca, 0xc7,0xee,0xee,0x29, 0x6b,0xb8,0xb8,0xd3, 0x28,0x14,0x14,0x3c,
+ 0xa7,0xde,0xde,0x79, 0xbc,0x5e,0x5e,0xe2, 0x16,0x0b,0x0b,0x1d, 0xad,0xdb,0xdb,0x76,
+ 0xdb,0xe0,0xe0,0x3b, 0x64,0x32,0x32,0x56, 0x74,0x3a,0x3a,0x4e, 0x14,0x0a,0x0a,0x1e,
+ 0x92,0x49,0x49,0xdb, 0x0c,0x06,0x06,0x0a, 0x48,0x24,0x24,0x6c, 0xb8,0x5c,0x5c,0xe4,
+ 0x9f,0xc2,0xc2,0x5d, 0xbd,0xd3,0xd3,0x6e, 0x43,0xac,0xac,0xef, 0xc4,0x62,0x62,0xa6,
+ 0x39,0x91,0x91,0xa8, 0x31,0x95,0x95,0xa4, 0xd3,0xe4,0xe4,0x37, 0xf2,0x79,0x79,0x8b,
+ 0xd5,0xe7,0xe7,0x32, 0x8b,0xc8,0xc8,0x43, 0x6e,0x37,0x37,0x59, 0xda,0x6d,0x6d,0xb7,
+ 0x01,0x8d,0x8d,0x8c, 0xb1,0xd5,0xd5,0x64, 0x9c,0x4e,0x4e,0xd2, 0x49,0xa9,0xa9,0xe0,
+ 0xd8,0x6c,0x6c,0xb4, 0xac,0x56,0x56,0xfa, 0xf3,0xf4,0xf4,0x07, 0xcf,0xea,0xea,0x25,
+ 0xca,0x65,0x65,0xaf, 0xf4,0x7a,0x7a,0x8e, 0x47,0xae,0xae,0xe9, 0x10,0x08,0x08,0x18,
+ 0x6f,0xba,0xba,0xd5, 0xf0,0x78,0x78,0x88, 0x4a,0x25,0x25,0x6f, 0x5c,0x2e,0x2e,0x72,
+ 0x38,0x1c,0x1c,0x24, 0x57,0xa6,0xa6,0xf1, 0x73,0xb4,0xb4,0xc7, 0x97,0xc6,0xc6,0x51,
+ 0xcb,0xe8,0xe8,0x23, 0xa1,0xdd,0xdd,0x7c, 0xe8,0x74,0x74,0x9c, 0x3e,0x1f,0x1f,0x21,
+ 0x96,0x4b,0x4b,0xdd, 0x61,0xbd,0xbd,0xdc, 0x0d,0x8b,0x8b,0x86, 0x0f,0x8a,0x8a,0x85,
+ 0xe0,0x70,0x70,0x90, 0x7c,0x3e,0x3e,0x42, 0x71,0xb5,0xb5,0xc4, 0xcc,0x66,0x66,0xaa,
+ 0x90,0x48,0x48,0xd8, 0x06,0x03,0x03,0x05, 0xf7,0xf6,0xf6,0x01, 0x1c,0x0e,0x0e,0x12,
+ 0xc2,0x61,0x61,0xa3, 0x6a,0x35,0x35,0x5f, 0xae,0x57,0x57,0xf9, 0x69,0xb9,0xb9,0xd0,
+ 0x17,0x86,0x86,0x91, 0x99,0xc1,0xc1,0x58, 0x3a,0x1d,0x1d,0x27, 0x27,0x9e,0x9e,0xb9,
+ 0xd9,0xe1,0xe1,0x38, 0xeb,0xf8,0xf8,0x13, 0x2b,0x98,0x98,0xb3, 0x22,0x11,0x11,0x33,
+ 0xd2,0x69,0x69,0xbb, 0xa9,0xd9,0xd9,0x70, 0x07,0x8e,0x8e,0x89, 0x33,0x94,0x94,0xa7,
+ 0x2d,0x9b,0x9b,0xb6, 0x3c,0x1e,0x1e,0x22, 0x15,0x87,0x87,0x92, 0xc9,0xe9,0xe9,0x20,
+ 0x87,0xce,0xce,0x49, 0xaa,0x55,0x55,0xff, 0x50,0x28,0x28,0x78, 0xa5,0xdf,0xdf,0x7a,
+ 0x03,0x8c,0x8c,0x8f, 0x59,0xa1,0xa1,0xf8, 0x09,0x89,0x89,0x80, 0x1a,0x0d,0x0d,0x17,
+ 0x65,0xbf,0xbf,0xda, 0xd7,0xe6,0xe6,0x31, 0x84,0x42,0x42,0xc6, 0xd0,0x68,0x68,0xb8,
+ 0x82,0x41,0x41,0xc3, 0x29,0x99,0x99,0xb0, 0x5a,0x2d,0x2d,0x77, 0x1e,0x0f,0x0f,0x11,
+ 0x7b,0xb0,0xb0,0xcb, 0xa8,0x54,0x54,0xfc, 0x6d,0xbb,0xbb,0xd6, 0x2c,0x16,0x16,0x3a
+};
+
+static UINT8 T2[256][4]=
+{
+ 0xa5,0xc6,0x63,0x63, 0x84,0xf8,0x7c,0x7c, 0x99,0xee,0x77,0x77, 0x8d,0xf6,0x7b,0x7b,
+ 0x0d,0xff,0xf2,0xf2, 0xbd,0xd6,0x6b,0x6b, 0xb1,0xde,0x6f,0x6f, 0x54,0x91,0xc5,0xc5,
+ 0x50,0x60,0x30,0x30, 0x03,0x02,0x01,0x01, 0xa9,0xce,0x67,0x67, 0x7d,0x56,0x2b,0x2b,
+ 0x19,0xe7,0xfe,0xfe, 0x62,0xb5,0xd7,0xd7, 0xe6,0x4d,0xab,0xab, 0x9a,0xec,0x76,0x76,
+ 0x45,0x8f,0xca,0xca, 0x9d,0x1f,0x82,0x82, 0x40,0x89,0xc9,0xc9, 0x87,0xfa,0x7d,0x7d,
+ 0x15,0xef,0xfa,0xfa, 0xeb,0xb2,0x59,0x59, 0xc9,0x8e,0x47,0x47, 0x0b,0xfb,0xf0,0xf0,
+ 0xec,0x41,0xad,0xad, 0x67,0xb3,0xd4,0xd4, 0xfd,0x5f,0xa2,0xa2, 0xea,0x45,0xaf,0xaf,
+ 0xbf,0x23,0x9c,0x9c, 0xf7,0x53,0xa4,0xa4, 0x96,0xe4,0x72,0x72, 0x5b,0x9b,0xc0,0xc0,
+ 0xc2,0x75,0xb7,0xb7, 0x1c,0xe1,0xfd,0xfd, 0xae,0x3d,0x93,0x93, 0x6a,0x4c,0x26,0x26,
+ 0x5a,0x6c,0x36,0x36, 0x41,0x7e,0x3f,0x3f, 0x02,0xf5,0xf7,0xf7, 0x4f,0x83,0xcc,0xcc,
+ 0x5c,0x68,0x34,0x34, 0xf4,0x51,0xa5,0xa5, 0x34,0xd1,0xe5,0xe5, 0x08,0xf9,0xf1,0xf1,
+ 0x93,0xe2,0x71,0x71, 0x73,0xab,0xd8,0xd8, 0x53,0x62,0x31,0x31, 0x3f,0x2a,0x15,0x15,
+ 0x0c,0x08,0x04,0x04, 0x52,0x95,0xc7,0xc7, 0x65,0x46,0x23,0x23, 0x5e,0x9d,0xc3,0xc3,
+ 0x28,0x30,0x18,0x18, 0xa1,0x37,0x96,0x96, 0x0f,0x0a,0x05,0x05, 0xb5,0x2f,0x9a,0x9a,
+ 0x09,0x0e,0x07,0x07, 0x36,0x24,0x12,0x12, 0x9b,0x1b,0x80,0x80, 0x3d,0xdf,0xe2,0xe2,
+ 0x26,0xcd,0xeb,0xeb, 0x69,0x4e,0x27,0x27, 0xcd,0x7f,0xb2,0xb2, 0x9f,0xea,0x75,0x75,
+ 0x1b,0x12,0x09,0x09, 0x9e,0x1d,0x83,0x83, 0x74,0x58,0x2c,0x2c, 0x2e,0x34,0x1a,0x1a,
+ 0x2d,0x36,0x1b,0x1b, 0xb2,0xdc,0x6e,0x6e, 0xee,0xb4,0x5a,0x5a, 0xfb,0x5b,0xa0,0xa0,
+ 0xf6,0xa4,0x52,0x52, 0x4d,0x76,0x3b,0x3b, 0x61,0xb7,0xd6,0xd6, 0xce,0x7d,0xb3,0xb3,
+ 0x7b,0x52,0x29,0x29, 0x3e,0xdd,0xe3,0xe3, 0x71,0x5e,0x2f,0x2f, 0x97,0x13,0x84,0x84,
+ 0xf5,0xa6,0x53,0x53, 0x68,0xb9,0xd1,0xd1, 0x00,0x00,0x00,0x00, 0x2c,0xc1,0xed,0xed,
+ 0x60,0x40,0x20,0x20, 0x1f,0xe3,0xfc,0xfc, 0xc8,0x79,0xb1,0xb1, 0xed,0xb6,0x5b,0x5b,
+ 0xbe,0xd4,0x6a,0x6a, 0x46,0x8d,0xcb,0xcb, 0xd9,0x67,0xbe,0xbe, 0x4b,0x72,0x39,0x39,
+ 0xde,0x94,0x4a,0x4a, 0xd4,0x98,0x4c,0x4c, 0xe8,0xb0,0x58,0x58, 0x4a,0x85,0xcf,0xcf,
+ 0x6b,0xbb,0xd0,0xd0, 0x2a,0xc5,0xef,0xef, 0xe5,0x4f,0xaa,0xaa, 0x16,0xed,0xfb,0xfb,
+ 0xc5,0x86,0x43,0x43, 0xd7,0x9a,0x4d,0x4d, 0x55,0x66,0x33,0x33, 0x94,0x11,0x85,0x85,
+ 0xcf,0x8a,0x45,0x45, 0x10,0xe9,0xf9,0xf9, 0x06,0x04,0x02,0x02, 0x81,0xfe,0x7f,0x7f,
+ 0xf0,0xa0,0x50,0x50, 0x44,0x78,0x3c,0x3c, 0xba,0x25,0x9f,0x9f, 0xe3,0x4b,0xa8,0xa8,
+ 0xf3,0xa2,0x51,0x51, 0xfe,0x5d,0xa3,0xa3, 0xc0,0x80,0x40,0x40, 0x8a,0x05,0x8f,0x8f,
+ 0xad,0x3f,0x92,0x92, 0xbc,0x21,0x9d,0x9d, 0x48,0x70,0x38,0x38, 0x04,0xf1,0xf5,0xf5,
+ 0xdf,0x63,0xbc,0xbc, 0xc1,0x77,0xb6,0xb6, 0x75,0xaf,0xda,0xda, 0x63,0x42,0x21,0x21,
+ 0x30,0x20,0x10,0x10, 0x1a,0xe5,0xff,0xff, 0x0e,0xfd,0xf3,0xf3, 0x6d,0xbf,0xd2,0xd2,
+ 0x4c,0x81,0xcd,0xcd, 0x14,0x18,0x0c,0x0c, 0x35,0x26,0x13,0x13, 0x2f,0xc3,0xec,0xec,
+ 0xe1,0xbe,0x5f,0x5f, 0xa2,0x35,0x97,0x97, 0xcc,0x88,0x44,0x44, 0x39,0x2e,0x17,0x17,
+ 0x57,0x93,0xc4,0xc4, 0xf2,0x55,0xa7,0xa7, 0x82,0xfc,0x7e,0x7e, 0x47,0x7a,0x3d,0x3d,
+ 0xac,0xc8,0x64,0x64, 0xe7,0xba,0x5d,0x5d, 0x2b,0x32,0x19,0x19, 0x95,0xe6,0x73,0x73,
+ 0xa0,0xc0,0x60,0x60, 0x98,0x19,0x81,0x81, 0xd1,0x9e,0x4f,0x4f, 0x7f,0xa3,0xdc,0xdc,
+ 0x66,0x44,0x22,0x22, 0x7e,0x54,0x2a,0x2a, 0xab,0x3b,0x90,0x90, 0x83,0x0b,0x88,0x88,
+ 0xca,0x8c,0x46,0x46, 0x29,0xc7,0xee,0xee, 0xd3,0x6b,0xb8,0xb8, 0x3c,0x28,0x14,0x14,
+ 0x79,0xa7,0xde,0xde, 0xe2,0xbc,0x5e,0x5e, 0x1d,0x16,0x0b,0x0b, 0x76,0xad,0xdb,0xdb,
+ 0x3b,0xdb,0xe0,0xe0, 0x56,0x64,0x32,0x32, 0x4e,0x74,0x3a,0x3a, 0x1e,0x14,0x0a,0x0a,
+ 0xdb,0x92,0x49,0x49, 0x0a,0x0c,0x06,0x06, 0x6c,0x48,0x24,0x24, 0xe4,0xb8,0x5c,0x5c,
+ 0x5d,0x9f,0xc2,0xc2, 0x6e,0xbd,0xd3,0xd3, 0xef,0x43,0xac,0xac, 0xa6,0xc4,0x62,0x62,
+ 0xa8,0x39,0x91,0x91, 0xa4,0x31,0x95,0x95, 0x37,0xd3,0xe4,0xe4, 0x8b,0xf2,0x79,0x79,
+ 0x32,0xd5,0xe7,0xe7, 0x43,0x8b,0xc8,0xc8, 0x59,0x6e,0x37,0x37, 0xb7,0xda,0x6d,0x6d,
+ 0x8c,0x01,0x8d,0x8d, 0x64,0xb1,0xd5,0xd5, 0xd2,0x9c,0x4e,0x4e, 0xe0,0x49,0xa9,0xa9,
+ 0xb4,0xd8,0x6c,0x6c, 0xfa,0xac,0x56,0x56, 0x07,0xf3,0xf4,0xf4, 0x25,0xcf,0xea,0xea,
+ 0xaf,0xca,0x65,0x65, 0x8e,0xf4,0x7a,0x7a, 0xe9,0x47,0xae,0xae, 0x18,0x10,0x08,0x08,
+ 0xd5,0x6f,0xba,0xba, 0x88,0xf0,0x78,0x78, 0x6f,0x4a,0x25,0x25, 0x72,0x5c,0x2e,0x2e,
+ 0x24,0x38,0x1c,0x1c, 0xf1,0x57,0xa6,0xa6, 0xc7,0x73,0xb4,0xb4, 0x51,0x97,0xc6,0xc6,
+ 0x23,0xcb,0xe8,0xe8, 0x7c,0xa1,0xdd,0xdd, 0x9c,0xe8,0x74,0x74, 0x21,0x3e,0x1f,0x1f,
+ 0xdd,0x96,0x4b,0x4b, 0xdc,0x61,0xbd,0xbd, 0x86,0x0d,0x8b,0x8b, 0x85,0x0f,0x8a,0x8a,
+ 0x90,0xe0,0x70,0x70, 0x42,0x7c,0x3e,0x3e, 0xc4,0x71,0xb5,0xb5, 0xaa,0xcc,0x66,0x66,
+ 0xd8,0x90,0x48,0x48, 0x05,0x06,0x03,0x03, 0x01,0xf7,0xf6,0xf6, 0x12,0x1c,0x0e,0x0e,
+ 0xa3,0xc2,0x61,0x61, 0x5f,0x6a,0x35,0x35, 0xf9,0xae,0x57,0x57, 0xd0,0x69,0xb9,0xb9,
+ 0x91,0x17,0x86,0x86, 0x58,0x99,0xc1,0xc1, 0x27,0x3a,0x1d,0x1d, 0xb9,0x27,0x9e,0x9e,
+ 0x38,0xd9,0xe1,0xe1, 0x13,0xeb,0xf8,0xf8, 0xb3,0x2b,0x98,0x98, 0x33,0x22,0x11,0x11,
+ 0xbb,0xd2,0x69,0x69, 0x70,0xa9,0xd9,0xd9, 0x89,0x07,0x8e,0x8e, 0xa7,0x33,0x94,0x94,
+ 0xb6,0x2d,0x9b,0x9b, 0x22,0x3c,0x1e,0x1e, 0x92,0x15,0x87,0x87, 0x20,0xc9,0xe9,0xe9,
+ 0x49,0x87,0xce,0xce, 0xff,0xaa,0x55,0x55, 0x78,0x50,0x28,0x28, 0x7a,0xa5,0xdf,0xdf,
+ 0x8f,0x03,0x8c,0x8c, 0xf8,0x59,0xa1,0xa1, 0x80,0x09,0x89,0x89, 0x17,0x1a,0x0d,0x0d,
+ 0xda,0x65,0xbf,0xbf, 0x31,0xd7,0xe6,0xe6, 0xc6,0x84,0x42,0x42, 0xb8,0xd0,0x68,0x68,
+ 0xc3,0x82,0x41,0x41, 0xb0,0x29,0x99,0x99, 0x77,0x5a,0x2d,0x2d, 0x11,0x1e,0x0f,0x0f,
+ 0xcb,0x7b,0xb0,0xb0, 0xfc,0xa8,0x54,0x54, 0xd6,0x6d,0xbb,0xbb, 0x3a,0x2c,0x16,0x16
+};
+
+static UINT8 T3[256][4]=
+{
+ 0x63,0xa5,0xc6,0x63, 0x7c,0x84,0xf8,0x7c, 0x77,0x99,0xee,0x77, 0x7b,0x8d,0xf6,0x7b,
+ 0xf2,0x0d,0xff,0xf2, 0x6b,0xbd,0xd6,0x6b, 0x6f,0xb1,0xde,0x6f, 0xc5,0x54,0x91,0xc5,
+ 0x30,0x50,0x60,0x30, 0x01,0x03,0x02,0x01, 0x67,0xa9,0xce,0x67, 0x2b,0x7d,0x56,0x2b,
+ 0xfe,0x19,0xe7,0xfe, 0xd7,0x62,0xb5,0xd7, 0xab,0xe6,0x4d,0xab, 0x76,0x9a,0xec,0x76,
+ 0xca,0x45,0x8f,0xca, 0x82,0x9d,0x1f,0x82, 0xc9,0x40,0x89,0xc9, 0x7d,0x87,0xfa,0x7d,
+ 0xfa,0x15,0xef,0xfa, 0x59,0xeb,0xb2,0x59, 0x47,0xc9,0x8e,0x47, 0xf0,0x0b,0xfb,0xf0,
+ 0xad,0xec,0x41,0xad, 0xd4,0x67,0xb3,0xd4, 0xa2,0xfd,0x5f,0xa2, 0xaf,0xea,0x45,0xaf,
+ 0x9c,0xbf,0x23,0x9c, 0xa4,0xf7,0x53,0xa4, 0x72,0x96,0xe4,0x72, 0xc0,0x5b,0x9b,0xc0,
+ 0xb7,0xc2,0x75,0xb7, 0xfd,0x1c,0xe1,0xfd, 0x93,0xae,0x3d,0x93, 0x26,0x6a,0x4c,0x26,
+ 0x36,0x5a,0x6c,0x36, 0x3f,0x41,0x7e,0x3f, 0xf7,0x02,0xf5,0xf7, 0xcc,0x4f,0x83,0xcc,
+ 0x34,0x5c,0x68,0x34, 0xa5,0xf4,0x51,0xa5, 0xe5,0x34,0xd1,0xe5, 0xf1,0x08,0xf9,0xf1,
+ 0x71,0x93,0xe2,0x71, 0xd8,0x73,0xab,0xd8, 0x31,0x53,0x62,0x31, 0x15,0x3f,0x2a,0x15,
+ 0x04,0x0c,0x08,0x04, 0xc7,0x52,0x95,0xc7, 0x23,0x65,0x46,0x23, 0xc3,0x5e,0x9d,0xc3,
+ 0x18,0x28,0x30,0x18, 0x96,0xa1,0x37,0x96, 0x05,0x0f,0x0a,0x05, 0x9a,0xb5,0x2f,0x9a,
+ 0x07,0x09,0x0e,0x07, 0x12,0x36,0x24,0x12, 0x80,0x9b,0x1b,0x80, 0xe2,0x3d,0xdf,0xe2,
+ 0xeb,0x26,0xcd,0xeb, 0x27,0x69,0x4e,0x27, 0xb2,0xcd,0x7f,0xb2, 0x75,0x9f,0xea,0x75,
+ 0x09,0x1b,0x12,0x09, 0x83,0x9e,0x1d,0x83, 0x2c,0x74,0x58,0x2c, 0x1a,0x2e,0x34,0x1a,
+ 0x1b,0x2d,0x36,0x1b, 0x6e,0xb2,0xdc,0x6e, 0x5a,0xee,0xb4,0x5a, 0xa0,0xfb,0x5b,0xa0,
+ 0x52,0xf6,0xa4,0x52, 0x3b,0x4d,0x76,0x3b, 0xd6,0x61,0xb7,0xd6, 0xb3,0xce,0x7d,0xb3,
+ 0x29,0x7b,0x52,0x29, 0xe3,0x3e,0xdd,0xe3, 0x2f,0x71,0x5e,0x2f, 0x84,0x97,0x13,0x84,
+ 0x53,0xf5,0xa6,0x53, 0xd1,0x68,0xb9,0xd1, 0x00,0x00,0x00,0x00, 0xed,0x2c,0xc1,0xed,
+ 0x20,0x60,0x40,0x20, 0xfc,0x1f,0xe3,0xfc, 0xb1,0xc8,0x79,0xb1, 0x5b,0xed,0xb6,0x5b,
+ 0x6a,0xbe,0xd4,0x6a, 0xcb,0x46,0x8d,0xcb, 0xbe,0xd9,0x67,0xbe, 0x39,0x4b,0x72,0x39,
+ 0x4a,0xde,0x94,0x4a, 0x4c,0xd4,0x98,0x4c, 0x58,0xe8,0xb0,0x58, 0xcf,0x4a,0x85,0xcf,
+ 0xd0,0x6b,0xbb,0xd0, 0xef,0x2a,0xc5,0xef, 0xaa,0xe5,0x4f,0xaa, 0xfb,0x16,0xed,0xfb,
+ 0x43,0xc5,0x86,0x43, 0x4d,0xd7,0x9a,0x4d, 0x33,0x55,0x66,0x33, 0x85,0x94,0x11,0x85,
+ 0x45,0xcf,0x8a,0x45, 0xf9,0x10,0xe9,0xf9, 0x02,0x06,0x04,0x02, 0x7f,0x81,0xfe,0x7f,
+ 0x50,0xf0,0xa0,0x50, 0x3c,0x44,0x78,0x3c, 0x9f,0xba,0x25,0x9f, 0xa8,0xe3,0x4b,0xa8,
+ 0x51,0xf3,0xa2,0x51, 0xa3,0xfe,0x5d,0xa3, 0x40,0xc0,0x80,0x40, 0x8f,0x8a,0x05,0x8f,
+ 0x92,0xad,0x3f,0x92, 0x9d,0xbc,0x21,0x9d, 0x38,0x48,0x70,0x38, 0xf5,0x04,0xf1,0xf5,
+ 0xbc,0xdf,0x63,0xbc, 0xb6,0xc1,0x77,0xb6, 0xda,0x75,0xaf,0xda, 0x21,0x63,0x42,0x21,
+ 0x10,0x30,0x20,0x10, 0xff,0x1a,0xe5,0xff, 0xf3,0x0e,0xfd,0xf3, 0xd2,0x6d,0xbf,0xd2,
+ 0xcd,0x4c,0x81,0xcd, 0x0c,0x14,0x18,0x0c, 0x13,0x35,0x26,0x13, 0xec,0x2f,0xc3,0xec,
+ 0x5f,0xe1,0xbe,0x5f, 0x97,0xa2,0x35,0x97, 0x44,0xcc,0x88,0x44, 0x17,0x39,0x2e,0x17,
+ 0xc4,0x57,0x93,0xc4, 0xa7,0xf2,0x55,0xa7, 0x7e,0x82,0xfc,0x7e, 0x3d,0x47,0x7a,0x3d,
+ 0x64,0xac,0xc8,0x64, 0x5d,0xe7,0xba,0x5d, 0x19,0x2b,0x32,0x19, 0x73,0x95,0xe6,0x73,
+ 0x60,0xa0,0xc0,0x60, 0x81,0x98,0x19,0x81, 0x4f,0xd1,0x9e,0x4f, 0xdc,0x7f,0xa3,0xdc,
+ 0x22,0x66,0x44,0x22, 0x2a,0x7e,0x54,0x2a, 0x90,0xab,0x3b,0x90, 0x88,0x83,0x0b,0x88,
+ 0x46,0xca,0x8c,0x46, 0xee,0x29,0xc7,0xee, 0xb8,0xd3,0x6b,0xb8, 0x14,0x3c,0x28,0x14,
+ 0xde,0x79,0xa7,0xde, 0x5e,0xe2,0xbc,0x5e, 0x0b,0x1d,0x16,0x0b, 0xdb,0x76,0xad,0xdb,
+ 0xe0,0x3b,0xdb,0xe0, 0x32,0x56,0x64,0x32, 0x3a,0x4e,0x74,0x3a, 0x0a,0x1e,0x14,0x0a,
+ 0x49,0xdb,0x92,0x49, 0x06,0x0a,0x0c,0x06, 0x24,0x6c,0x48,0x24, 0x5c,0xe4,0xb8,0x5c,
+ 0xc2,0x5d,0x9f,0xc2, 0xd3,0x6e,0xbd,0xd3, 0xac,0xef,0x43,0xac, 0x62,0xa6,0xc4,0x62,
+ 0x91,0xa8,0x39,0x91, 0x95,0xa4,0x31,0x95, 0xe4,0x37,0xd3,0xe4, 0x79,0x8b,0xf2,0x79,
+ 0xe7,0x32,0xd5,0xe7, 0xc8,0x43,0x8b,0xc8, 0x37,0x59,0x6e,0x37, 0x6d,0xb7,0xda,0x6d,
+ 0x8d,0x8c,0x01,0x8d, 0xd5,0x64,0xb1,0xd5, 0x4e,0xd2,0x9c,0x4e, 0xa9,0xe0,0x49,0xa9,
+ 0x6c,0xb4,0xd8,0x6c, 0x56,0xfa,0xac,0x56, 0xf4,0x07,0xf3,0xf4, 0xea,0x25,0xcf,0xea,
+ 0x65,0xaf,0xca,0x65, 0x7a,0x8e,0xf4,0x7a, 0xae,0xe9,0x47,0xae, 0x08,0x18,0x10,0x08,
+ 0xba,0xd5,0x6f,0xba, 0x78,0x88,0xf0,0x78, 0x25,0x6f,0x4a,0x25, 0x2e,0x72,0x5c,0x2e,
+ 0x1c,0x24,0x38,0x1c, 0xa6,0xf1,0x57,0xa6, 0xb4,0xc7,0x73,0xb4, 0xc6,0x51,0x97,0xc6,
+ 0xe8,0x23,0xcb,0xe8, 0xdd,0x7c,0xa1,0xdd, 0x74,0x9c,0xe8,0x74, 0x1f,0x21,0x3e,0x1f,
+ 0x4b,0xdd,0x96,0x4b, 0xbd,0xdc,0x61,0xbd, 0x8b,0x86,0x0d,0x8b, 0x8a,0x85,0x0f,0x8a,
+ 0x70,0x90,0xe0,0x70, 0x3e,0x42,0x7c,0x3e, 0xb5,0xc4,0x71,0xb5, 0x66,0xaa,0xcc,0x66,
+ 0x48,0xd8,0x90,0x48, 0x03,0x05,0x06,0x03, 0xf6,0x01,0xf7,0xf6, 0x0e,0x12,0x1c,0x0e,
+ 0x61,0xa3,0xc2,0x61, 0x35,0x5f,0x6a,0x35, 0x57,0xf9,0xae,0x57, 0xb9,0xd0,0x69,0xb9,
+ 0x86,0x91,0x17,0x86, 0xc1,0x58,0x99,0xc1, 0x1d,0x27,0x3a,0x1d, 0x9e,0xb9,0x27,0x9e,
+ 0xe1,0x38,0xd9,0xe1, 0xf8,0x13,0xeb,0xf8, 0x98,0xb3,0x2b,0x98, 0x11,0x33,0x22,0x11,
+ 0x69,0xbb,0xd2,0x69, 0xd9,0x70,0xa9,0xd9, 0x8e,0x89,0x07,0x8e, 0x94,0xa7,0x33,0x94,
+ 0x9b,0xb6,0x2d,0x9b, 0x1e,0x22,0x3c,0x1e, 0x87,0x92,0x15,0x87, 0xe9,0x20,0xc9,0xe9,
+ 0xce,0x49,0x87,0xce, 0x55,0xff,0xaa,0x55, 0x28,0x78,0x50,0x28, 0xdf,0x7a,0xa5,0xdf,
+ 0x8c,0x8f,0x03,0x8c, 0xa1,0xf8,0x59,0xa1, 0x89,0x80,0x09,0x89, 0x0d,0x17,0x1a,0x0d,
+ 0xbf,0xda,0x65,0xbf, 0xe6,0x31,0xd7,0xe6, 0x42,0xc6,0x84,0x42, 0x68,0xb8,0xd0,0x68,
+ 0x41,0xc3,0x82,0x41, 0x99,0xb0,0x29,0x99, 0x2d,0x77,0x5a,0x2d, 0x0f,0x11,0x1e,0x0f,
+ 0xb0,0xcb,0x7b,0xb0, 0x54,0xfc,0xa8,0x54, 0xbb,0xd6,0x6d,0xbb, 0x16,0x3a,0x2c,0x16
+};
+
+static UINT8 T4[256][4]=
+{
+ 0x63,0x63,0xa5,0xc6, 0x7c,0x7c,0x84,0xf8, 0x77,0x77,0x99,0xee, 0x7b,0x7b,0x8d,0xf6,
+ 0xf2,0xf2,0x0d,0xff, 0x6b,0x6b,0xbd,0xd6, 0x6f,0x6f,0xb1,0xde, 0xc5,0xc5,0x54,0x91,
+ 0x30,0x30,0x50,0x60, 0x01,0x01,0x03,0x02, 0x67,0x67,0xa9,0xce, 0x2b,0x2b,0x7d,0x56,
+ 0xfe,0xfe,0x19,0xe7, 0xd7,0xd7,0x62,0xb5, 0xab,0xab,0xe6,0x4d, 0x76,0x76,0x9a,0xec,
+ 0xca,0xca,0x45,0x8f, 0x82,0x82,0x9d,0x1f, 0xc9,0xc9,0x40,0x89, 0x7d,0x7d,0x87,0xfa,
+ 0xfa,0xfa,0x15,0xef, 0x59,0x59,0xeb,0xb2, 0x47,0x47,0xc9,0x8e, 0xf0,0xf0,0x0b,0xfb,
+ 0xad,0xad,0xec,0x41, 0xd4,0xd4,0x67,0xb3, 0xa2,0xa2,0xfd,0x5f, 0xaf,0xaf,0xea,0x45,
+ 0x9c,0x9c,0xbf,0x23, 0xa4,0xa4,0xf7,0x53, 0x72,0x72,0x96,0xe4, 0xc0,0xc0,0x5b,0x9b,
+ 0xb7,0xb7,0xc2,0x75, 0xfd,0xfd,0x1c,0xe1, 0x93,0x93,0xae,0x3d, 0x26,0x26,0x6a,0x4c,
+ 0x36,0x36,0x5a,0x6c, 0x3f,0x3f,0x41,0x7e, 0xf7,0xf7,0x02,0xf5, 0xcc,0xcc,0x4f,0x83,
+ 0x34,0x34,0x5c,0x68, 0xa5,0xa5,0xf4,0x51, 0xe5,0xe5,0x34,0xd1, 0xf1,0xf1,0x08,0xf9,
+ 0x71,0x71,0x93,0xe2, 0xd8,0xd8,0x73,0xab, 0x31,0x31,0x53,0x62, 0x15,0x15,0x3f,0x2a,
+ 0x04,0x04,0x0c,0x08, 0xc7,0xc7,0x52,0x95, 0x23,0x23,0x65,0x46, 0xc3,0xc3,0x5e,0x9d,
+ 0x18,0x18,0x28,0x30, 0x96,0x96,0xa1,0x37, 0x05,0x05,0x0f,0x0a, 0x9a,0x9a,0xb5,0x2f,
+ 0x07,0x07,0x09,0x0e, 0x12,0x12,0x36,0x24, 0x80,0x80,0x9b,0x1b, 0xe2,0xe2,0x3d,0xdf,
+ 0xeb,0xeb,0x26,0xcd, 0x27,0x27,0x69,0x4e, 0xb2,0xb2,0xcd,0x7f, 0x75,0x75,0x9f,0xea,
+ 0x09,0x09,0x1b,0x12, 0x83,0x83,0x9e,0x1d, 0x2c,0x2c,0x74,0x58, 0x1a,0x1a,0x2e,0x34,
+ 0x1b,0x1b,0x2d,0x36, 0x6e,0x6e,0xb2,0xdc, 0x5a,0x5a,0xee,0xb4, 0xa0,0xa0,0xfb,0x5b,
+ 0x52,0x52,0xf6,0xa4, 0x3b,0x3b,0x4d,0x76, 0xd6,0xd6,0x61,0xb7, 0xb3,0xb3,0xce,0x7d,
+ 0x29,0x29,0x7b,0x52, 0xe3,0xe3,0x3e,0xdd, 0x2f,0x2f,0x71,0x5e, 0x84,0x84,0x97,0x13,
+ 0x53,0x53,0xf5,0xa6, 0xd1,0xd1,0x68,0xb9, 0x00,0x00,0x00,0x00, 0xed,0xed,0x2c,0xc1,
+ 0x20,0x20,0x60,0x40, 0xfc,0xfc,0x1f,0xe3, 0xb1,0xb1,0xc8,0x79, 0x5b,0x5b,0xed,0xb6,
+ 0x6a,0x6a,0xbe,0xd4, 0xcb,0xcb,0x46,0x8d, 0xbe,0xbe,0xd9,0x67, 0x39,0x39,0x4b,0x72,
+ 0x4a,0x4a,0xde,0x94, 0x4c,0x4c,0xd4,0x98, 0x58,0x58,0xe8,0xb0, 0xcf,0xcf,0x4a,0x85,
+ 0xd0,0xd0,0x6b,0xbb, 0xef,0xef,0x2a,0xc5, 0xaa,0xaa,0xe5,0x4f, 0xfb,0xfb,0x16,0xed,
+ 0x43,0x43,0xc5,0x86, 0x4d,0x4d,0xd7,0x9a, 0x33,0x33,0x55,0x66, 0x85,0x85,0x94,0x11,
+ 0x45,0x45,0xcf,0x8a, 0xf9,0xf9,0x10,0xe9, 0x02,0x02,0x06,0x04, 0x7f,0x7f,0x81,0xfe,
+ 0x50,0x50,0xf0,0xa0, 0x3c,0x3c,0x44,0x78, 0x9f,0x9f,0xba,0x25, 0xa8,0xa8,0xe3,0x4b,
+ 0x51,0x51,0xf3,0xa2, 0xa3,0xa3,0xfe,0x5d, 0x40,0x40,0xc0,0x80, 0x8f,0x8f,0x8a,0x05,
+ 0x92,0x92,0xad,0x3f, 0x9d,0x9d,0xbc,0x21, 0x38,0x38,0x48,0x70, 0xf5,0xf5,0x04,0xf1,
+ 0xbc,0xbc,0xdf,0x63, 0xb6,0xb6,0xc1,0x77, 0xda,0xda,0x75,0xaf, 0x21,0x21,0x63,0x42,
+ 0x10,0x10,0x30,0x20, 0xff,0xff,0x1a,0xe5, 0xf3,0xf3,0x0e,0xfd, 0xd2,0xd2,0x6d,0xbf,
+ 0xcd,0xcd,0x4c,0x81, 0x0c,0x0c,0x14,0x18, 0x13,0x13,0x35,0x26, 0xec,0xec,0x2f,0xc3,
+ 0x5f,0x5f,0xe1,0xbe, 0x97,0x97,0xa2,0x35, 0x44,0x44,0xcc,0x88, 0x17,0x17,0x39,0x2e,
+ 0xc4,0xc4,0x57,0x93, 0xa7,0xa7,0xf2,0x55, 0x7e,0x7e,0x82,0xfc, 0x3d,0x3d,0x47,0x7a,
+ 0x64,0x64,0xac,0xc8, 0x5d,0x5d,0xe7,0xba, 0x19,0x19,0x2b,0x32, 0x73,0x73,0x95,0xe6,
+ 0x60,0x60,0xa0,0xc0, 0x81,0x81,0x98,0x19, 0x4f,0x4f,0xd1,0x9e, 0xdc,0xdc,0x7f,0xa3,
+ 0x22,0x22,0x66,0x44, 0x2a,0x2a,0x7e,0x54, 0x90,0x90,0xab,0x3b, 0x88,0x88,0x83,0x0b,
+ 0x46,0x46,0xca,0x8c, 0xee,0xee,0x29,0xc7, 0xb8,0xb8,0xd3,0x6b, 0x14,0x14,0x3c,0x28,
+ 0xde,0xde,0x79,0xa7, 0x5e,0x5e,0xe2,0xbc, 0x0b,0x0b,0x1d,0x16, 0xdb,0xdb,0x76,0xad,
+ 0xe0,0xe0,0x3b,0xdb, 0x32,0x32,0x56,0x64, 0x3a,0x3a,0x4e,0x74, 0x0a,0x0a,0x1e,0x14,
+ 0x49,0x49,0xdb,0x92, 0x06,0x06,0x0a,0x0c, 0x24,0x24,0x6c,0x48, 0x5c,0x5c,0xe4,0xb8,
+ 0xc2,0xc2,0x5d,0x9f, 0xd3,0xd3,0x6e,0xbd, 0xac,0xac,0xef,0x43, 0x62,0x62,0xa6,0xc4,
+ 0x91,0x91,0xa8,0x39, 0x95,0x95,0xa4,0x31, 0xe4,0xe4,0x37,0xd3, 0x79,0x79,0x8b,0xf2,
+ 0xe7,0xe7,0x32,0xd5, 0xc8,0xc8,0x43,0x8b, 0x37,0x37,0x59,0x6e, 0x6d,0x6d,0xb7,0xda,
+ 0x8d,0x8d,0x8c,0x01, 0xd5,0xd5,0x64,0xb1, 0x4e,0x4e,0xd2,0x9c, 0xa9,0xa9,0xe0,0x49,
+ 0x6c,0x6c,0xb4,0xd8, 0x56,0x56,0xfa,0xac, 0xf4,0xf4,0x07,0xf3, 0xea,0xea,0x25,0xcf,
+ 0x65,0x65,0xaf,0xca, 0x7a,0x7a,0x8e,0xf4, 0xae,0xae,0xe9,0x47, 0x08,0x08,0x18,0x10,
+ 0xba,0xba,0xd5,0x6f, 0x78,0x78,0x88,0xf0, 0x25,0x25,0x6f,0x4a, 0x2e,0x2e,0x72,0x5c,
+ 0x1c,0x1c,0x24,0x38, 0xa6,0xa6,0xf1,0x57, 0xb4,0xb4,0xc7,0x73, 0xc6,0xc6,0x51,0x97,
+ 0xe8,0xe8,0x23,0xcb, 0xdd,0xdd,0x7c,0xa1, 0x74,0x74,0x9c,0xe8, 0x1f,0x1f,0x21,0x3e,
+ 0x4b,0x4b,0xdd,0x96, 0xbd,0xbd,0xdc,0x61, 0x8b,0x8b,0x86,0x0d, 0x8a,0x8a,0x85,0x0f,
+ 0x70,0x70,0x90,0xe0, 0x3e,0x3e,0x42,0x7c, 0xb5,0xb5,0xc4,0x71, 0x66,0x66,0xaa,0xcc,
+ 0x48,0x48,0xd8,0x90, 0x03,0x03,0x05,0x06, 0xf6,0xf6,0x01,0xf7, 0x0e,0x0e,0x12,0x1c,
+ 0x61,0x61,0xa3,0xc2, 0x35,0x35,0x5f,0x6a, 0x57,0x57,0xf9,0xae, 0xb9,0xb9,0xd0,0x69,
+ 0x86,0x86,0x91,0x17, 0xc1,0xc1,0x58,0x99, 0x1d,0x1d,0x27,0x3a, 0x9e,0x9e,0xb9,0x27,
+ 0xe1,0xe1,0x38,0xd9, 0xf8,0xf8,0x13,0xeb, 0x98,0x98,0xb3,0x2b, 0x11,0x11,0x33,0x22,
+ 0x69,0x69,0xbb,0xd2, 0xd9,0xd9,0x70,0xa9, 0x8e,0x8e,0x89,0x07, 0x94,0x94,0xa7,0x33,
+ 0x9b,0x9b,0xb6,0x2d, 0x1e,0x1e,0x22,0x3c, 0x87,0x87,0x92,0x15, 0xe9,0xe9,0x20,0xc9,
+ 0xce,0xce,0x49,0x87, 0x55,0x55,0xff,0xaa, 0x28,0x28,0x78,0x50, 0xdf,0xdf,0x7a,0xa5,
+ 0x8c,0x8c,0x8f,0x03, 0xa1,0xa1,0xf8,0x59, 0x89,0x89,0x80,0x09, 0x0d,0x0d,0x17,0x1a,
+ 0xbf,0xbf,0xda,0x65, 0xe6,0xe6,0x31,0xd7, 0x42,0x42,0xc6,0x84, 0x68,0x68,0xb8,0xd0,
+ 0x41,0x41,0xc3,0x82, 0x99,0x99,0xb0,0x29, 0x2d,0x2d,0x77,0x5a, 0x0f,0x0f,0x11,0x1e,
+ 0xb0,0xb0,0xcb,0x7b, 0x54,0x54,0xfc,0xa8, 0xbb,0xbb,0xd6,0x6d, 0x16,0x16,0x3a,0x2c
+};
+
+static UINT8 T5[256][4]=
+{
+ 0x51,0xf4,0xa7,0x50, 0x7e,0x41,0x65,0x53, 0x1a,0x17,0xa4,0xc3, 0x3a,0x27,0x5e,0x96,
+ 0x3b,0xab,0x6b,0xcb, 0x1f,0x9d,0x45,0xf1, 0xac,0xfa,0x58,0xab, 0x4b,0xe3,0x03,0x93,
+ 0x20,0x30,0xfa,0x55, 0xad,0x76,0x6d,0xf6, 0x88,0xcc,0x76,0x91, 0xf5,0x02,0x4c,0x25,
+ 0x4f,0xe5,0xd7,0xfc, 0xc5,0x2a,0xcb,0xd7, 0x26,0x35,0x44,0x80, 0xb5,0x62,0xa3,0x8f,
+ 0xde,0xb1,0x5a,0x49, 0x25,0xba,0x1b,0x67, 0x45,0xea,0x0e,0x98, 0x5d,0xfe,0xc0,0xe1,
+ 0xc3,0x2f,0x75,0x02, 0x81,0x4c,0xf0,0x12, 0x8d,0x46,0x97,0xa3, 0x6b,0xd3,0xf9,0xc6,
+ 0x03,0x8f,0x5f,0xe7, 0x15,0x92,0x9c,0x95, 0xbf,0x6d,0x7a,0xeb, 0x95,0x52,0x59,0xda,
+ 0xd4,0xbe,0x83,0x2d, 0x58,0x74,0x21,0xd3, 0x49,0xe0,0x69,0x29, 0x8e,0xc9,0xc8,0x44,
+ 0x75,0xc2,0x89,0x6a, 0xf4,0x8e,0x79,0x78, 0x99,0x58,0x3e,0x6b, 0x27,0xb9,0x71,0xdd,
+ 0xbe,0xe1,0x4f,0xb6, 0xf0,0x88,0xad,0x17, 0xc9,0x20,0xac,0x66, 0x7d,0xce,0x3a,0xb4,
+ 0x63,0xdf,0x4a,0x18, 0xe5,0x1a,0x31,0x82, 0x97,0x51,0x33,0x60, 0x62,0x53,0x7f,0x45,
+ 0xb1,0x64,0x77,0xe0, 0xbb,0x6b,0xae,0x84, 0xfe,0x81,0xa0,0x1c, 0xf9,0x08,0x2b,0x94,
+ 0x70,0x48,0x68,0x58, 0x8f,0x45,0xfd,0x19, 0x94,0xde,0x6c,0x87, 0x52,0x7b,0xf8,0xb7,
+ 0xab,0x73,0xd3,0x23, 0x72,0x4b,0x02,0xe2, 0xe3,0x1f,0x8f,0x57, 0x66,0x55,0xab,0x2a,
+ 0xb2,0xeb,0x28,0x07, 0x2f,0xb5,0xc2,0x03, 0x86,0xc5,0x7b,0x9a, 0xd3,0x37,0x08,0xa5,
+ 0x30,0x28,0x87,0xf2, 0x23,0xbf,0xa5,0xb2, 0x02,0x03,0x6a,0xba, 0xed,0x16,0x82,0x5c,
+ 0x8a,0xcf,0x1c,0x2b, 0xa7,0x79,0xb4,0x92, 0xf3,0x07,0xf2,0xf0, 0x4e,0x69,0xe2,0xa1,
+ 0x65,0xda,0xf4,0xcd, 0x06,0x05,0xbe,0xd5, 0xd1,0x34,0x62,0x1f, 0xc4,0xa6,0xfe,0x8a,
+ 0x34,0x2e,0x53,0x9d, 0xa2,0xf3,0x55,0xa0, 0x05,0x8a,0xe1,0x32, 0xa4,0xf6,0xeb,0x75,
+ 0x0b,0x83,0xec,0x39, 0x40,0x60,0xef,0xaa, 0x5e,0x71,0x9f,0x06, 0xbd,0x6e,0x10,0x51,
+ 0x3e,0x21,0x8a,0xf9, 0x96,0xdd,0x06,0x3d, 0xdd,0x3e,0x05,0xae, 0x4d,0xe6,0xbd,0x46,
+ 0x91,0x54,0x8d,0xb5, 0x71,0xc4,0x5d,0x05, 0x04,0x06,0xd4,0x6f, 0x60,0x50,0x15,0xff,
+ 0x19,0x98,0xfb,0x24, 0xd6,0xbd,0xe9,0x97, 0x89,0x40,0x43,0xcc, 0x67,0xd9,0x9e,0x77,
+ 0xb0,0xe8,0x42,0xbd, 0x07,0x89,0x8b,0x88, 0xe7,0x19,0x5b,0x38, 0x79,0xc8,0xee,0xdb,
+ 0xa1,0x7c,0x0a,0x47, 0x7c,0x42,0x0f,0xe9, 0xf8,0x84,0x1e,0xc9, 0x00,0x00,0x00,0x00,
+ 0x09,0x80,0x86,0x83, 0x32,0x2b,0xed,0x48, 0x1e,0x11,0x70,0xac, 0x6c,0x5a,0x72,0x4e,
+ 0xfd,0x0e,0xff,0xfb, 0x0f,0x85,0x38,0x56, 0x3d,0xae,0xd5,0x1e, 0x36,0x2d,0x39,0x27,
+ 0x0a,0x0f,0xd9,0x64, 0x68,0x5c,0xa6,0x21, 0x9b,0x5b,0x54,0xd1, 0x24,0x36,0x2e,0x3a,
+ 0x0c,0x0a,0x67,0xb1, 0x93,0x57,0xe7,0x0f, 0xb4,0xee,0x96,0xd2, 0x1b,0x9b,0x91,0x9e,
+ 0x80,0xc0,0xc5,0x4f, 0x61,0xdc,0x20,0xa2, 0x5a,0x77,0x4b,0x69, 0x1c,0x12,0x1a,0x16,
+ 0xe2,0x93,0xba,0x0a, 0xc0,0xa0,0x2a,0xe5, 0x3c,0x22,0xe0,0x43, 0x12,0x1b,0x17,0x1d,
+ 0x0e,0x09,0x0d,0x0b, 0xf2,0x8b,0xc7,0xad, 0x2d,0xb6,0xa8,0xb9, 0x14,0x1e,0xa9,0xc8,
+ 0x57,0xf1,0x19,0x85, 0xaf,0x75,0x07,0x4c, 0xee,0x99,0xdd,0xbb, 0xa3,0x7f,0x60,0xfd,
+ 0xf7,0x01,0x26,0x9f, 0x5c,0x72,0xf5,0xbc, 0x44,0x66,0x3b,0xc5, 0x5b,0xfb,0x7e,0x34,
+ 0x8b,0x43,0x29,0x76, 0xcb,0x23,0xc6,0xdc, 0xb6,0xed,0xfc,0x68, 0xb8,0xe4,0xf1,0x63,
+ 0xd7,0x31,0xdc,0xca, 0x42,0x63,0x85,0x10, 0x13,0x97,0x22,0x40, 0x84,0xc6,0x11,0x20,
+ 0x85,0x4a,0x24,0x7d, 0xd2,0xbb,0x3d,0xf8, 0xae,0xf9,0x32,0x11, 0xc7,0x29,0xa1,0x6d,
+ 0x1d,0x9e,0x2f,0x4b, 0xdc,0xb2,0x30,0xf3, 0x0d,0x86,0x52,0xec, 0x77,0xc1,0xe3,0xd0,
+ 0x2b,0xb3,0x16,0x6c, 0xa9,0x70,0xb9,0x99, 0x11,0x94,0x48,0xfa, 0x47,0xe9,0x64,0x22,
+ 0xa8,0xfc,0x8c,0xc4, 0xa0,0xf0,0x3f,0x1a, 0x56,0x7d,0x2c,0xd8, 0x22,0x33,0x90,0xef,
+ 0x87,0x49,0x4e,0xc7, 0xd9,0x38,0xd1,0xc1, 0x8c,0xca,0xa2,0xfe, 0x98,0xd4,0x0b,0x36,
+ 0xa6,0xf5,0x81,0xcf, 0xa5,0x7a,0xde,0x28, 0xda,0xb7,0x8e,0x26, 0x3f,0xad,0xbf,0xa4,
+ 0x2c,0x3a,0x9d,0xe4, 0x50,0x78,0x92,0x0d, 0x6a,0x5f,0xcc,0x9b, 0x54,0x7e,0x46,0x62,
+ 0xf6,0x8d,0x13,0xc2, 0x90,0xd8,0xb8,0xe8, 0x2e,0x39,0xf7,0x5e, 0x82,0xc3,0xaf,0xf5,
+ 0x9f,0x5d,0x80,0xbe, 0x69,0xd0,0x93,0x7c, 0x6f,0xd5,0x2d,0xa9, 0xcf,0x25,0x12,0xb3,
+ 0xc8,0xac,0x99,0x3b, 0x10,0x18,0x7d,0xa7, 0xe8,0x9c,0x63,0x6e, 0xdb,0x3b,0xbb,0x7b,
+ 0xcd,0x26,0x78,0x09, 0x6e,0x59,0x18,0xf4, 0xec,0x9a,0xb7,0x01, 0x83,0x4f,0x9a,0xa8,
+ 0xe6,0x95,0x6e,0x65, 0xaa,0xff,0xe6,0x7e, 0x21,0xbc,0xcf,0x08, 0xef,0x15,0xe8,0xe6,
+ 0xba,0xe7,0x9b,0xd9, 0x4a,0x6f,0x36,0xce, 0xea,0x9f,0x09,0xd4, 0x29,0xb0,0x7c,0xd6,
+ 0x31,0xa4,0xb2,0xaf, 0x2a,0x3f,0x23,0x31, 0xc6,0xa5,0x94,0x30, 0x35,0xa2,0x66,0xc0,
+ 0x74,0x4e,0xbc,0x37, 0xfc,0x82,0xca,0xa6, 0xe0,0x90,0xd0,0xb0, 0x33,0xa7,0xd8,0x15,
+ 0xf1,0x04,0x98,0x4a, 0x41,0xec,0xda,0xf7, 0x7f,0xcd,0x50,0x0e, 0x17,0x91,0xf6,0x2f,
+ 0x76,0x4d,0xd6,0x8d, 0x43,0xef,0xb0,0x4d, 0xcc,0xaa,0x4d,0x54, 0xe4,0x96,0x04,0xdf,
+ 0x9e,0xd1,0xb5,0xe3, 0x4c,0x6a,0x88,0x1b, 0xc1,0x2c,0x1f,0xb8, 0x46,0x65,0x51,0x7f,
+ 0x9d,0x5e,0xea,0x04, 0x01,0x8c,0x35,0x5d, 0xfa,0x87,0x74,0x73, 0xfb,0x0b,0x41,0x2e,
+ 0xb3,0x67,0x1d,0x5a, 0x92,0xdb,0xd2,0x52, 0xe9,0x10,0x56,0x33, 0x6d,0xd6,0x47,0x13,
+ 0x9a,0xd7,0x61,0x8c, 0x37,0xa1,0x0c,0x7a, 0x59,0xf8,0x14,0x8e, 0xeb,0x13,0x3c,0x89,
+ 0xce,0xa9,0x27,0xee, 0xb7,0x61,0xc9,0x35, 0xe1,0x1c,0xe5,0xed, 0x7a,0x47,0xb1,0x3c,
+ 0x9c,0xd2,0xdf,0x59, 0x55,0xf2,0x73,0x3f, 0x18,0x14,0xce,0x79, 0x73,0xc7,0x37,0xbf,
+ 0x53,0xf7,0xcd,0xea, 0x5f,0xfd,0xaa,0x5b, 0xdf,0x3d,0x6f,0x14, 0x78,0x44,0xdb,0x86,
+ 0xca,0xaf,0xf3,0x81, 0xb9,0x68,0xc4,0x3e, 0x38,0x24,0x34,0x2c, 0xc2,0xa3,0x40,0x5f,
+ 0x16,0x1d,0xc3,0x72, 0xbc,0xe2,0x25,0x0c, 0x28,0x3c,0x49,0x8b, 0xff,0x0d,0x95,0x41,
+ 0x39,0xa8,0x01,0x71, 0x08,0x0c,0xb3,0xde, 0xd8,0xb4,0xe4,0x9c, 0x64,0x56,0xc1,0x90,
+ 0x7b,0xcb,0x84,0x61, 0xd5,0x32,0xb6,0x70, 0x48,0x6c,0x5c,0x74, 0xd0,0xb8,0x57,0x42
+};
+
+static UINT8 T6[256][4]=
+{
+ 0x50,0x51,0xf4,0xa7, 0x53,0x7e,0x41,0x65, 0xc3,0x1a,0x17,0xa4, 0x96,0x3a,0x27,0x5e,
+ 0xcb,0x3b,0xab,0x6b, 0xf1,0x1f,0x9d,0x45, 0xab,0xac,0xfa,0x58, 0x93,0x4b,0xe3,0x03,
+ 0x55,0x20,0x30,0xfa, 0xf6,0xad,0x76,0x6d, 0x91,0x88,0xcc,0x76, 0x25,0xf5,0x02,0x4c,
+ 0xfc,0x4f,0xe5,0xd7, 0xd7,0xc5,0x2a,0xcb, 0x80,0x26,0x35,0x44, 0x8f,0xb5,0x62,0xa3,
+ 0x49,0xde,0xb1,0x5a, 0x67,0x25,0xba,0x1b, 0x98,0x45,0xea,0x0e, 0xe1,0x5d,0xfe,0xc0,
+ 0x02,0xc3,0x2f,0x75, 0x12,0x81,0x4c,0xf0, 0xa3,0x8d,0x46,0x97, 0xc6,0x6b,0xd3,0xf9,
+ 0xe7,0x03,0x8f,0x5f, 0x95,0x15,0x92,0x9c, 0xeb,0xbf,0x6d,0x7a, 0xda,0x95,0x52,0x59,
+ 0x2d,0xd4,0xbe,0x83, 0xd3,0x58,0x74,0x21, 0x29,0x49,0xe0,0x69, 0x44,0x8e,0xc9,0xc8,
+ 0x6a,0x75,0xc2,0x89, 0x78,0xf4,0x8e,0x79, 0x6b,0x99,0x58,0x3e, 0xdd,0x27,0xb9,0x71,
+ 0xb6,0xbe,0xe1,0x4f, 0x17,0xf0,0x88,0xad, 0x66,0xc9,0x20,0xac, 0xb4,0x7d,0xce,0x3a,
+ 0x18,0x63,0xdf,0x4a, 0x82,0xe5,0x1a,0x31, 0x60,0x97,0x51,0x33, 0x45,0x62,0x53,0x7f,
+ 0xe0,0xb1,0x64,0x77, 0x84,0xbb,0x6b,0xae, 0x1c,0xfe,0x81,0xa0, 0x94,0xf9,0x08,0x2b,
+ 0x58,0x70,0x48,0x68, 0x19,0x8f,0x45,0xfd, 0x87,0x94,0xde,0x6c, 0xb7,0x52,0x7b,0xf8,
+ 0x23,0xab,0x73,0xd3, 0xe2,0x72,0x4b,0x02, 0x57,0xe3,0x1f,0x8f, 0x2a,0x66,0x55,0xab,
+ 0x07,0xb2,0xeb,0x28, 0x03,0x2f,0xb5,0xc2, 0x9a,0x86,0xc5,0x7b, 0xa5,0xd3,0x37,0x08,
+ 0xf2,0x30,0x28,0x87, 0xb2,0x23,0xbf,0xa5, 0xba,0x02,0x03,0x6a, 0x5c,0xed,0x16,0x82,
+ 0x2b,0x8a,0xcf,0x1c, 0x92,0xa7,0x79,0xb4, 0xf0,0xf3,0x07,0xf2, 0xa1,0x4e,0x69,0xe2,
+ 0xcd,0x65,0xda,0xf4, 0xd5,0x06,0x05,0xbe, 0x1f,0xd1,0x34,0x62, 0x8a,0xc4,0xa6,0xfe,
+ 0x9d,0x34,0x2e,0x53, 0xa0,0xa2,0xf3,0x55, 0x32,0x05,0x8a,0xe1, 0x75,0xa4,0xf6,0xeb,
+ 0x39,0x0b,0x83,0xec, 0xaa,0x40,0x60,0xef, 0x06,0x5e,0x71,0x9f, 0x51,0xbd,0x6e,0x10,
+ 0xf9,0x3e,0x21,0x8a, 0x3d,0x96,0xdd,0x06, 0xae,0xdd,0x3e,0x05, 0x46,0x4d,0xe6,0xbd,
+ 0xb5,0x91,0x54,0x8d, 0x05,0x71,0xc4,0x5d, 0x6f,0x04,0x06,0xd4, 0xff,0x60,0x50,0x15,
+ 0x24,0x19,0x98,0xfb, 0x97,0xd6,0xbd,0xe9, 0xcc,0x89,0x40,0x43, 0x77,0x67,0xd9,0x9e,
+ 0xbd,0xb0,0xe8,0x42, 0x88,0x07,0x89,0x8b, 0x38,0xe7,0x19,0x5b, 0xdb,0x79,0xc8,0xee,
+ 0x47,0xa1,0x7c,0x0a, 0xe9,0x7c,0x42,0x0f, 0xc9,0xf8,0x84,0x1e, 0x00,0x00,0x00,0x00,
+ 0x83,0x09,0x80,0x86, 0x48,0x32,0x2b,0xed, 0xac,0x1e,0x11,0x70, 0x4e,0x6c,0x5a,0x72,
+ 0xfb,0xfd,0x0e,0xff, 0x56,0x0f,0x85,0x38, 0x1e,0x3d,0xae,0xd5, 0x27,0x36,0x2d,0x39,
+ 0x64,0x0a,0x0f,0xd9, 0x21,0x68,0x5c,0xa6, 0xd1,0x9b,0x5b,0x54, 0x3a,0x24,0x36,0x2e,
+ 0xb1,0x0c,0x0a,0x67, 0x0f,0x93,0x57,0xe7, 0xd2,0xb4,0xee,0x96, 0x9e,0x1b,0x9b,0x91,
+ 0x4f,0x80,0xc0,0xc5, 0xa2,0x61,0xdc,0x20, 0x69,0x5a,0x77,0x4b, 0x16,0x1c,0x12,0x1a,
+ 0x0a,0xe2,0x93,0xba, 0xe5,0xc0,0xa0,0x2a, 0x43,0x3c,0x22,0xe0, 0x1d,0x12,0x1b,0x17,
+ 0x0b,0x0e,0x09,0x0d, 0xad,0xf2,0x8b,0xc7, 0xb9,0x2d,0xb6,0xa8, 0xc8,0x14,0x1e,0xa9,
+ 0x85,0x57,0xf1,0x19, 0x4c,0xaf,0x75,0x07, 0xbb,0xee,0x99,0xdd, 0xfd,0xa3,0x7f,0x60,
+ 0x9f,0xf7,0x01,0x26, 0xbc,0x5c,0x72,0xf5, 0xc5,0x44,0x66,0x3b, 0x34,0x5b,0xfb,0x7e,
+ 0x76,0x8b,0x43,0x29, 0xdc,0xcb,0x23,0xc6, 0x68,0xb6,0xed,0xfc, 0x63,0xb8,0xe4,0xf1,
+ 0xca,0xd7,0x31,0xdc, 0x10,0x42,0x63,0x85, 0x40,0x13,0x97,0x22, 0x20,0x84,0xc6,0x11,
+ 0x7d,0x85,0x4a,0x24, 0xf8,0xd2,0xbb,0x3d, 0x11,0xae,0xf9,0x32, 0x6d,0xc7,0x29,0xa1,
+ 0x4b,0x1d,0x9e,0x2f, 0xf3,0xdc,0xb2,0x30, 0xec,0x0d,0x86,0x52, 0xd0,0x77,0xc1,0xe3,
+ 0x6c,0x2b,0xb3,0x16, 0x99,0xa9,0x70,0xb9, 0xfa,0x11,0x94,0x48, 0x22,0x47,0xe9,0x64,
+ 0xc4,0xa8,0xfc,0x8c, 0x1a,0xa0,0xf0,0x3f, 0xd8,0x56,0x7d,0x2c, 0xef,0x22,0x33,0x90,
+ 0xc7,0x87,0x49,0x4e, 0xc1,0xd9,0x38,0xd1, 0xfe,0x8c,0xca,0xa2, 0x36,0x98,0xd4,0x0b,
+ 0xcf,0xa6,0xf5,0x81, 0x28,0xa5,0x7a,0xde, 0x26,0xda,0xb7,0x8e, 0xa4,0x3f,0xad,0xbf,
+ 0xe4,0x2c,0x3a,0x9d, 0x0d,0x50,0x78,0x92, 0x9b,0x6a,0x5f,0xcc, 0x62,0x54,0x7e,0x46,
+ 0xc2,0xf6,0x8d,0x13, 0xe8,0x90,0xd8,0xb8, 0x5e,0x2e,0x39,0xf7, 0xf5,0x82,0xc3,0xaf,
+ 0xbe,0x9f,0x5d,0x80, 0x7c,0x69,0xd0,0x93, 0xa9,0x6f,0xd5,0x2d, 0xb3,0xcf,0x25,0x12,
+ 0x3b,0xc8,0xac,0x99, 0xa7,0x10,0x18,0x7d, 0x6e,0xe8,0x9c,0x63, 0x7b,0xdb,0x3b,0xbb,
+ 0x09,0xcd,0x26,0x78, 0xf4,0x6e,0x59,0x18, 0x01,0xec,0x9a,0xb7, 0xa8,0x83,0x4f,0x9a,
+ 0x65,0xe6,0x95,0x6e, 0x7e,0xaa,0xff,0xe6, 0x08,0x21,0xbc,0xcf, 0xe6,0xef,0x15,0xe8,
+ 0xd9,0xba,0xe7,0x9b, 0xce,0x4a,0x6f,0x36, 0xd4,0xea,0x9f,0x09, 0xd6,0x29,0xb0,0x7c,
+ 0xaf,0x31,0xa4,0xb2, 0x31,0x2a,0x3f,0x23, 0x30,0xc6,0xa5,0x94, 0xc0,0x35,0xa2,0x66,
+ 0x37,0x74,0x4e,0xbc, 0xa6,0xfc,0x82,0xca, 0xb0,0xe0,0x90,0xd0, 0x15,0x33,0xa7,0xd8,
+ 0x4a,0xf1,0x04,0x98, 0xf7,0x41,0xec,0xda, 0x0e,0x7f,0xcd,0x50, 0x2f,0x17,0x91,0xf6,
+ 0x8d,0x76,0x4d,0xd6, 0x4d,0x43,0xef,0xb0, 0x54,0xcc,0xaa,0x4d, 0xdf,0xe4,0x96,0x04,
+ 0xe3,0x9e,0xd1,0xb5, 0x1b,0x4c,0x6a,0x88, 0xb8,0xc1,0x2c,0x1f, 0x7f,0x46,0x65,0x51,
+ 0x04,0x9d,0x5e,0xea, 0x5d,0x01,0x8c,0x35, 0x73,0xfa,0x87,0x74, 0x2e,0xfb,0x0b,0x41,
+ 0x5a,0xb3,0x67,0x1d, 0x52,0x92,0xdb,0xd2, 0x33,0xe9,0x10,0x56, 0x13,0x6d,0xd6,0x47,
+ 0x8c,0x9a,0xd7,0x61, 0x7a,0x37,0xa1,0x0c, 0x8e,0x59,0xf8,0x14, 0x89,0xeb,0x13,0x3c,
+ 0xee,0xce,0xa9,0x27, 0x35,0xb7,0x61,0xc9, 0xed,0xe1,0x1c,0xe5, 0x3c,0x7a,0x47,0xb1,
+ 0x59,0x9c,0xd2,0xdf, 0x3f,0x55,0xf2,0x73, 0x79,0x18,0x14,0xce, 0xbf,0x73,0xc7,0x37,
+ 0xea,0x53,0xf7,0xcd, 0x5b,0x5f,0xfd,0xaa, 0x14,0xdf,0x3d,0x6f, 0x86,0x78,0x44,0xdb,
+ 0x81,0xca,0xaf,0xf3, 0x3e,0xb9,0x68,0xc4, 0x2c,0x38,0x24,0x34, 0x5f,0xc2,0xa3,0x40,
+ 0x72,0x16,0x1d,0xc3, 0x0c,0xbc,0xe2,0x25, 0x8b,0x28,0x3c,0x49, 0x41,0xff,0x0d,0x95,
+ 0x71,0x39,0xa8,0x01, 0xde,0x08,0x0c,0xb3, 0x9c,0xd8,0xb4,0xe4, 0x90,0x64,0x56,0xc1,
+ 0x61,0x7b,0xcb,0x84, 0x70,0xd5,0x32,0xb6, 0x74,0x48,0x6c,0x5c, 0x42,0xd0,0xb8,0x57
+};
+
+static UINT8 T7[256][4]=
+{
+ 0xa7,0x50,0x51,0xf4, 0x65,0x53,0x7e,0x41, 0xa4,0xc3,0x1a,0x17, 0x5e,0x96,0x3a,0x27,
+ 0x6b,0xcb,0x3b,0xab, 0x45,0xf1,0x1f,0x9d, 0x58,0xab,0xac,0xfa, 0x03,0x93,0x4b,0xe3,
+ 0xfa,0x55,0x20,0x30, 0x6d,0xf6,0xad,0x76, 0x76,0x91,0x88,0xcc, 0x4c,0x25,0xf5,0x02,
+ 0xd7,0xfc,0x4f,0xe5, 0xcb,0xd7,0xc5,0x2a, 0x44,0x80,0x26,0x35, 0xa3,0x8f,0xb5,0x62,
+ 0x5a,0x49,0xde,0xb1, 0x1b,0x67,0x25,0xba, 0x0e,0x98,0x45,0xea, 0xc0,0xe1,0x5d,0xfe,
+ 0x75,0x02,0xc3,0x2f, 0xf0,0x12,0x81,0x4c, 0x97,0xa3,0x8d,0x46, 0xf9,0xc6,0x6b,0xd3,
+ 0x5f,0xe7,0x03,0x8f, 0x9c,0x95,0x15,0x92, 0x7a,0xeb,0xbf,0x6d, 0x59,0xda,0x95,0x52,
+ 0x83,0x2d,0xd4,0xbe, 0x21,0xd3,0x58,0x74, 0x69,0x29,0x49,0xe0, 0xc8,0x44,0x8e,0xc9,
+ 0x89,0x6a,0x75,0xc2, 0x79,0x78,0xf4,0x8e, 0x3e,0x6b,0x99,0x58, 0x71,0xdd,0x27,0xb9,
+ 0x4f,0xb6,0xbe,0xe1, 0xad,0x17,0xf0,0x88, 0xac,0x66,0xc9,0x20, 0x3a,0xb4,0x7d,0xce,
+ 0x4a,0x18,0x63,0xdf, 0x31,0x82,0xe5,0x1a, 0x33,0x60,0x97,0x51, 0x7f,0x45,0x62,0x53,
+ 0x77,0xe0,0xb1,0x64, 0xae,0x84,0xbb,0x6b, 0xa0,0x1c,0xfe,0x81, 0x2b,0x94,0xf9,0x08,
+ 0x68,0x58,0x70,0x48, 0xfd,0x19,0x8f,0x45, 0x6c,0x87,0x94,0xde, 0xf8,0xb7,0x52,0x7b,
+ 0xd3,0x23,0xab,0x73, 0x02,0xe2,0x72,0x4b, 0x8f,0x57,0xe3,0x1f, 0xab,0x2a,0x66,0x55,
+ 0x28,0x07,0xb2,0xeb, 0xc2,0x03,0x2f,0xb5, 0x7b,0x9a,0x86,0xc5, 0x08,0xa5,0xd3,0x37,
+ 0x87,0xf2,0x30,0x28, 0xa5,0xb2,0x23,0xbf, 0x6a,0xba,0x02,0x03, 0x82,0x5c,0xed,0x16,
+ 0x1c,0x2b,0x8a,0xcf, 0xb4,0x92,0xa7,0x79, 0xf2,0xf0,0xf3,0x07, 0xe2,0xa1,0x4e,0x69,
+ 0xf4,0xcd,0x65,0xda, 0xbe,0xd5,0x06,0x05, 0x62,0x1f,0xd1,0x34, 0xfe,0x8a,0xc4,0xa6,
+ 0x53,0x9d,0x34,0x2e, 0x55,0xa0,0xa2,0xf3, 0xe1,0x32,0x05,0x8a, 0xeb,0x75,0xa4,0xf6,
+ 0xec,0x39,0x0b,0x83, 0xef,0xaa,0x40,0x60, 0x9f,0x06,0x5e,0x71, 0x10,0x51,0xbd,0x6e,
+ 0x8a,0xf9,0x3e,0x21, 0x06,0x3d,0x96,0xdd, 0x05,0xae,0xdd,0x3e, 0xbd,0x46,0x4d,0xe6,
+ 0x8d,0xb5,0x91,0x54, 0x5d,0x05,0x71,0xc4, 0xd4,0x6f,0x04,0x06, 0x15,0xff,0x60,0x50,
+ 0xfb,0x24,0x19,0x98, 0xe9,0x97,0xd6,0xbd, 0x43,0xcc,0x89,0x40, 0x9e,0x77,0x67,0xd9,
+ 0x42,0xbd,0xb0,0xe8, 0x8b,0x88,0x07,0x89, 0x5b,0x38,0xe7,0x19, 0xee,0xdb,0x79,0xc8,
+ 0x0a,0x47,0xa1,0x7c, 0x0f,0xe9,0x7c,0x42, 0x1e,0xc9,0xf8,0x84, 0x00,0x00,0x00,0x00,
+ 0x86,0x83,0x09,0x80, 0xed,0x48,0x32,0x2b, 0x70,0xac,0x1e,0x11, 0x72,0x4e,0x6c,0x5a,
+ 0xff,0xfb,0xfd,0x0e, 0x38,0x56,0x0f,0x85, 0xd5,0x1e,0x3d,0xae, 0x39,0x27,0x36,0x2d,
+ 0xd9,0x64,0x0a,0x0f, 0xa6,0x21,0x68,0x5c, 0x54,0xd1,0x9b,0x5b, 0x2e,0x3a,0x24,0x36,
+ 0x67,0xb1,0x0c,0x0a, 0xe7,0x0f,0x93,0x57, 0x96,0xd2,0xb4,0xee, 0x91,0x9e,0x1b,0x9b,
+ 0xc5,0x4f,0x80,0xc0, 0x20,0xa2,0x61,0xdc, 0x4b,0x69,0x5a,0x77, 0x1a,0x16,0x1c,0x12,
+ 0xba,0x0a,0xe2,0x93, 0x2a,0xe5,0xc0,0xa0, 0xe0,0x43,0x3c,0x22, 0x17,0x1d,0x12,0x1b,
+ 0x0d,0x0b,0x0e,0x09, 0xc7,0xad,0xf2,0x8b, 0xa8,0xb9,0x2d,0xb6, 0xa9,0xc8,0x14,0x1e,
+ 0x19,0x85,0x57,0xf1, 0x07,0x4c,0xaf,0x75, 0xdd,0xbb,0xee,0x99, 0x60,0xfd,0xa3,0x7f,
+ 0x26,0x9f,0xf7,0x01, 0xf5,0xbc,0x5c,0x72, 0x3b,0xc5,0x44,0x66, 0x7e,0x34,0x5b,0xfb,
+ 0x29,0x76,0x8b,0x43, 0xc6,0xdc,0xcb,0x23, 0xfc,0x68,0xb6,0xed, 0xf1,0x63,0xb8,0xe4,
+ 0xdc,0xca,0xd7,0x31, 0x85,0x10,0x42,0x63, 0x22,0x40,0x13,0x97, 0x11,0x20,0x84,0xc6,
+ 0x24,0x7d,0x85,0x4a, 0x3d,0xf8,0xd2,0xbb, 0x32,0x11,0xae,0xf9, 0xa1,0x6d,0xc7,0x29,
+ 0x2f,0x4b,0x1d,0x9e, 0x30,0xf3,0xdc,0xb2, 0x52,0xec,0x0d,0x86, 0xe3,0xd0,0x77,0xc1,
+ 0x16,0x6c,0x2b,0xb3, 0xb9,0x99,0xa9,0x70, 0x48,0xfa,0x11,0x94, 0x64,0x22,0x47,0xe9,
+ 0x8c,0xc4,0xa8,0xfc, 0x3f,0x1a,0xa0,0xf0, 0x2c,0xd8,0x56,0x7d, 0x90,0xef,0x22,0x33,
+ 0x4e,0xc7,0x87,0x49, 0xd1,0xc1,0xd9,0x38, 0xa2,0xfe,0x8c,0xca, 0x0b,0x36,0x98,0xd4,
+ 0x81,0xcf,0xa6,0xf5, 0xde,0x28,0xa5,0x7a, 0x8e,0x26,0xda,0xb7, 0xbf,0xa4,0x3f,0xad,
+ 0x9d,0xe4,0x2c,0x3a, 0x92,0x0d,0x50,0x78, 0xcc,0x9b,0x6a,0x5f, 0x46,0x62,0x54,0x7e,
+ 0x13,0xc2,0xf6,0x8d, 0xb8,0xe8,0x90,0xd8, 0xf7,0x5e,0x2e,0x39, 0xaf,0xf5,0x82,0xc3,
+ 0x80,0xbe,0x9f,0x5d, 0x93,0x7c,0x69,0xd0, 0x2d,0xa9,0x6f,0xd5, 0x12,0xb3,0xcf,0x25,
+ 0x99,0x3b,0xc8,0xac, 0x7d,0xa7,0x10,0x18, 0x63,0x6e,0xe8,0x9c, 0xbb,0x7b,0xdb,0x3b,
+ 0x78,0x09,0xcd,0x26, 0x18,0xf4,0x6e,0x59, 0xb7,0x01,0xec,0x9a, 0x9a,0xa8,0x83,0x4f,
+ 0x6e,0x65,0xe6,0x95, 0xe6,0x7e,0xaa,0xff, 0xcf,0x08,0x21,0xbc, 0xe8,0xe6,0xef,0x15,
+ 0x9b,0xd9,0xba,0xe7, 0x36,0xce,0x4a,0x6f, 0x09,0xd4,0xea,0x9f, 0x7c,0xd6,0x29,0xb0,
+ 0xb2,0xaf,0x31,0xa4, 0x23,0x31,0x2a,0x3f, 0x94,0x30,0xc6,0xa5, 0x66,0xc0,0x35,0xa2,
+ 0xbc,0x37,0x74,0x4e, 0xca,0xa6,0xfc,0x82, 0xd0,0xb0,0xe0,0x90, 0xd8,0x15,0x33,0xa7,
+ 0x98,0x4a,0xf1,0x04, 0xda,0xf7,0x41,0xec, 0x50,0x0e,0x7f,0xcd, 0xf6,0x2f,0x17,0x91,
+ 0xd6,0x8d,0x76,0x4d, 0xb0,0x4d,0x43,0xef, 0x4d,0x54,0xcc,0xaa, 0x04,0xdf,0xe4,0x96,
+ 0xb5,0xe3,0x9e,0xd1, 0x88,0x1b,0x4c,0x6a, 0x1f,0xb8,0xc1,0x2c, 0x51,0x7f,0x46,0x65,
+ 0xea,0x04,0x9d,0x5e, 0x35,0x5d,0x01,0x8c, 0x74,0x73,0xfa,0x87, 0x41,0x2e,0xfb,0x0b,
+ 0x1d,0x5a,0xb3,0x67, 0xd2,0x52,0x92,0xdb, 0x56,0x33,0xe9,0x10, 0x47,0x13,0x6d,0xd6,
+ 0x61,0x8c,0x9a,0xd7, 0x0c,0x7a,0x37,0xa1, 0x14,0x8e,0x59,0xf8, 0x3c,0x89,0xeb,0x13,
+ 0x27,0xee,0xce,0xa9, 0xc9,0x35,0xb7,0x61, 0xe5,0xed,0xe1,0x1c, 0xb1,0x3c,0x7a,0x47,
+ 0xdf,0x59,0x9c,0xd2, 0x73,0x3f,0x55,0xf2, 0xce,0x79,0x18,0x14, 0x37,0xbf,0x73,0xc7,
+ 0xcd,0xea,0x53,0xf7, 0xaa,0x5b,0x5f,0xfd, 0x6f,0x14,0xdf,0x3d, 0xdb,0x86,0x78,0x44,
+ 0xf3,0x81,0xca,0xaf, 0xc4,0x3e,0xb9,0x68, 0x34,0x2c,0x38,0x24, 0x40,0x5f,0xc2,0xa3,
+ 0xc3,0x72,0x16,0x1d, 0x25,0x0c,0xbc,0xe2, 0x49,0x8b,0x28,0x3c, 0x95,0x41,0xff,0x0d,
+ 0x01,0x71,0x39,0xa8, 0xb3,0xde,0x08,0x0c, 0xe4,0x9c,0xd8,0xb4, 0xc1,0x90,0x64,0x56,
+ 0x84,0x61,0x7b,0xcb, 0xb6,0x70,0xd5,0x32, 0x5c,0x74,0x48,0x6c, 0x57,0x42,0xd0,0xb8
+};
+
+static UINT8 T8[256][4]=
+{
+ 0xf4,0xa7,0x50,0x51, 0x41,0x65,0x53,0x7e, 0x17,0xa4,0xc3,0x1a, 0x27,0x5e,0x96,0x3a,
+ 0xab,0x6b,0xcb,0x3b, 0x9d,0x45,0xf1,0x1f, 0xfa,0x58,0xab,0xac, 0xe3,0x03,0x93,0x4b,
+ 0x30,0xfa,0x55,0x20, 0x76,0x6d,0xf6,0xad, 0xcc,0x76,0x91,0x88, 0x02,0x4c,0x25,0xf5,
+ 0xe5,0xd7,0xfc,0x4f, 0x2a,0xcb,0xd7,0xc5, 0x35,0x44,0x80,0x26, 0x62,0xa3,0x8f,0xb5,
+ 0xb1,0x5a,0x49,0xde, 0xba,0x1b,0x67,0x25, 0xea,0x0e,0x98,0x45, 0xfe,0xc0,0xe1,0x5d,
+ 0x2f,0x75,0x02,0xc3, 0x4c,0xf0,0x12,0x81, 0x46,0x97,0xa3,0x8d, 0xd3,0xf9,0xc6,0x6b,
+ 0x8f,0x5f,0xe7,0x03, 0x92,0x9c,0x95,0x15, 0x6d,0x7a,0xeb,0xbf, 0x52,0x59,0xda,0x95,
+ 0xbe,0x83,0x2d,0xd4, 0x74,0x21,0xd3,0x58, 0xe0,0x69,0x29,0x49, 0xc9,0xc8,0x44,0x8e,
+ 0xc2,0x89,0x6a,0x75, 0x8e,0x79,0x78,0xf4, 0x58,0x3e,0x6b,0x99, 0xb9,0x71,0xdd,0x27,
+ 0xe1,0x4f,0xb6,0xbe, 0x88,0xad,0x17,0xf0, 0x20,0xac,0x66,0xc9, 0xce,0x3a,0xb4,0x7d,
+ 0xdf,0x4a,0x18,0x63, 0x1a,0x31,0x82,0xe5, 0x51,0x33,0x60,0x97, 0x53,0x7f,0x45,0x62,
+ 0x64,0x77,0xe0,0xb1, 0x6b,0xae,0x84,0xbb, 0x81,0xa0,0x1c,0xfe, 0x08,0x2b,0x94,0xf9,
+ 0x48,0x68,0x58,0x70, 0x45,0xfd,0x19,0x8f, 0xde,0x6c,0x87,0x94, 0x7b,0xf8,0xb7,0x52,
+ 0x73,0xd3,0x23,0xab, 0x4b,0x02,0xe2,0x72, 0x1f,0x8f,0x57,0xe3, 0x55,0xab,0x2a,0x66,
+ 0xeb,0x28,0x07,0xb2, 0xb5,0xc2,0x03,0x2f, 0xc5,0x7b,0x9a,0x86, 0x37,0x08,0xa5,0xd3,
+ 0x28,0x87,0xf2,0x30, 0xbf,0xa5,0xb2,0x23, 0x03,0x6a,0xba,0x02, 0x16,0x82,0x5c,0xed,
+ 0xcf,0x1c,0x2b,0x8a, 0x79,0xb4,0x92,0xa7, 0x07,0xf2,0xf0,0xf3, 0x69,0xe2,0xa1,0x4e,
+ 0xda,0xf4,0xcd,0x65, 0x05,0xbe,0xd5,0x06, 0x34,0x62,0x1f,0xd1, 0xa6,0xfe,0x8a,0xc4,
+ 0x2e,0x53,0x9d,0x34, 0xf3,0x55,0xa0,0xa2, 0x8a,0xe1,0x32,0x05, 0xf6,0xeb,0x75,0xa4,
+ 0x83,0xec,0x39,0x0b, 0x60,0xef,0xaa,0x40, 0x71,0x9f,0x06,0x5e, 0x6e,0x10,0x51,0xbd,
+ 0x21,0x8a,0xf9,0x3e, 0xdd,0x06,0x3d,0x96, 0x3e,0x05,0xae,0xdd, 0xe6,0xbd,0x46,0x4d,
+ 0x54,0x8d,0xb5,0x91, 0xc4,0x5d,0x05,0x71, 0x06,0xd4,0x6f,0x04, 0x50,0x15,0xff,0x60,
+ 0x98,0xfb,0x24,0x19, 0xbd,0xe9,0x97,0xd6, 0x40,0x43,0xcc,0x89, 0xd9,0x9e,0x77,0x67,
+ 0xe8,0x42,0xbd,0xb0, 0x89,0x8b,0x88,0x07, 0x19,0x5b,0x38,0xe7, 0xc8,0xee,0xdb,0x79,
+ 0x7c,0x0a,0x47,0xa1, 0x42,0x0f,0xe9,0x7c, 0x84,0x1e,0xc9,0xf8, 0x00,0x00,0x00,0x00,
+ 0x80,0x86,0x83,0x09, 0x2b,0xed,0x48,0x32, 0x11,0x70,0xac,0x1e, 0x5a,0x72,0x4e,0x6c,
+ 0x0e,0xff,0xfb,0xfd, 0x85,0x38,0x56,0x0f, 0xae,0xd5,0x1e,0x3d, 0x2d,0x39,0x27,0x36,
+ 0x0f,0xd9,0x64,0x0a, 0x5c,0xa6,0x21,0x68, 0x5b,0x54,0xd1,0x9b, 0x36,0x2e,0x3a,0x24,
+ 0x0a,0x67,0xb1,0x0c, 0x57,0xe7,0x0f,0x93, 0xee,0x96,0xd2,0xb4, 0x9b,0x91,0x9e,0x1b,
+ 0xc0,0xc5,0x4f,0x80, 0xdc,0x20,0xa2,0x61, 0x77,0x4b,0x69,0x5a, 0x12,0x1a,0x16,0x1c,
+ 0x93,0xba,0x0a,0xe2, 0xa0,0x2a,0xe5,0xc0, 0x22,0xe0,0x43,0x3c, 0x1b,0x17,0x1d,0x12,
+ 0x09,0x0d,0x0b,0x0e, 0x8b,0xc7,0xad,0xf2, 0xb6,0xa8,0xb9,0x2d, 0x1e,0xa9,0xc8,0x14,
+ 0xf1,0x19,0x85,0x57, 0x75,0x07,0x4c,0xaf, 0x99,0xdd,0xbb,0xee, 0x7f,0x60,0xfd,0xa3,
+ 0x01,0x26,0x9f,0xf7, 0x72,0xf5,0xbc,0x5c, 0x66,0x3b,0xc5,0x44, 0xfb,0x7e,0x34,0x5b,
+ 0x43,0x29,0x76,0x8b, 0x23,0xc6,0xdc,0xcb, 0xed,0xfc,0x68,0xb6, 0xe4,0xf1,0x63,0xb8,
+ 0x31,0xdc,0xca,0xd7, 0x63,0x85,0x10,0x42, 0x97,0x22,0x40,0x13, 0xc6,0x11,0x20,0x84,
+ 0x4a,0x24,0x7d,0x85, 0xbb,0x3d,0xf8,0xd2, 0xf9,0x32,0x11,0xae, 0x29,0xa1,0x6d,0xc7,
+ 0x9e,0x2f,0x4b,0x1d, 0xb2,0x30,0xf3,0xdc, 0x86,0x52,0xec,0x0d, 0xc1,0xe3,0xd0,0x77,
+ 0xb3,0x16,0x6c,0x2b, 0x70,0xb9,0x99,0xa9, 0x94,0x48,0xfa,0x11, 0xe9,0x64,0x22,0x47,
+ 0xfc,0x8c,0xc4,0xa8, 0xf0,0x3f,0x1a,0xa0, 0x7d,0x2c,0xd8,0x56, 0x33,0x90,0xef,0x22,
+ 0x49,0x4e,0xc7,0x87, 0x38,0xd1,0xc1,0xd9, 0xca,0xa2,0xfe,0x8c, 0xd4,0x0b,0x36,0x98,
+ 0xf5,0x81,0xcf,0xa6, 0x7a,0xde,0x28,0xa5, 0xb7,0x8e,0x26,0xda, 0xad,0xbf,0xa4,0x3f,
+ 0x3a,0x9d,0xe4,0x2c, 0x78,0x92,0x0d,0x50, 0x5f,0xcc,0x9b,0x6a, 0x7e,0x46,0x62,0x54,
+ 0x8d,0x13,0xc2,0xf6, 0xd8,0xb8,0xe8,0x90, 0x39,0xf7,0x5e,0x2e, 0xc3,0xaf,0xf5,0x82,
+ 0x5d,0x80,0xbe,0x9f, 0xd0,0x93,0x7c,0x69, 0xd5,0x2d,0xa9,0x6f, 0x25,0x12,0xb3,0xcf,
+ 0xac,0x99,0x3b,0xc8, 0x18,0x7d,0xa7,0x10, 0x9c,0x63,0x6e,0xe8, 0x3b,0xbb,0x7b,0xdb,
+ 0x26,0x78,0x09,0xcd, 0x59,0x18,0xf4,0x6e, 0x9a,0xb7,0x01,0xec, 0x4f,0x9a,0xa8,0x83,
+ 0x95,0x6e,0x65,0xe6, 0xff,0xe6,0x7e,0xaa, 0xbc,0xcf,0x08,0x21, 0x15,0xe8,0xe6,0xef,
+ 0xe7,0x9b,0xd9,0xba, 0x6f,0x36,0xce,0x4a, 0x9f,0x09,0xd4,0xea, 0xb0,0x7c,0xd6,0x29,
+ 0xa4,0xb2,0xaf,0x31, 0x3f,0x23,0x31,0x2a, 0xa5,0x94,0x30,0xc6, 0xa2,0x66,0xc0,0x35,
+ 0x4e,0xbc,0x37,0x74, 0x82,0xca,0xa6,0xfc, 0x90,0xd0,0xb0,0xe0, 0xa7,0xd8,0x15,0x33,
+ 0x04,0x98,0x4a,0xf1, 0xec,0xda,0xf7,0x41, 0xcd,0x50,0x0e,0x7f, 0x91,0xf6,0x2f,0x17,
+ 0x4d,0xd6,0x8d,0x76, 0xef,0xb0,0x4d,0x43, 0xaa,0x4d,0x54,0xcc, 0x96,0x04,0xdf,0xe4,
+ 0xd1,0xb5,0xe3,0x9e, 0x6a,0x88,0x1b,0x4c, 0x2c,0x1f,0xb8,0xc1, 0x65,0x51,0x7f,0x46,
+ 0x5e,0xea,0x04,0x9d, 0x8c,0x35,0x5d,0x01, 0x87,0x74,0x73,0xfa, 0x0b,0x41,0x2e,0xfb,
+ 0x67,0x1d,0x5a,0xb3, 0xdb,0xd2,0x52,0x92, 0x10,0x56,0x33,0xe9, 0xd6,0x47,0x13,0x6d,
+ 0xd7,0x61,0x8c,0x9a, 0xa1,0x0c,0x7a,0x37, 0xf8,0x14,0x8e,0x59, 0x13,0x3c,0x89,0xeb,
+ 0xa9,0x27,0xee,0xce, 0x61,0xc9,0x35,0xb7, 0x1c,0xe5,0xed,0xe1, 0x47,0xb1,0x3c,0x7a,
+ 0xd2,0xdf,0x59,0x9c, 0xf2,0x73,0x3f,0x55, 0x14,0xce,0x79,0x18, 0xc7,0x37,0xbf,0x73,
+ 0xf7,0xcd,0xea,0x53, 0xfd,0xaa,0x5b,0x5f, 0x3d,0x6f,0x14,0xdf, 0x44,0xdb,0x86,0x78,
+ 0xaf,0xf3,0x81,0xca, 0x68,0xc4,0x3e,0xb9, 0x24,0x34,0x2c,0x38, 0xa3,0x40,0x5f,0xc2,
+ 0x1d,0xc3,0x72,0x16, 0xe2,0x25,0x0c,0xbc, 0x3c,0x49,0x8b,0x28, 0x0d,0x95,0x41,0xff,
+ 0xa8,0x01,0x71,0x39, 0x0c,0xb3,0xde,0x08, 0xb4,0xe4,0x9c,0xd8, 0x56,0xc1,0x90,0x64,
+ 0xcb,0x84,0x61,0x7b, 0x32,0xb6,0x70,0xd5, 0x6c,0x5c,0x74,0x48, 0xb8,0x57,0x42,0xd0
+};
+
+static UINT8 S5[256]=
+{
+ 0x52,0x09,0x6a,0xd5,
+ 0x30,0x36,0xa5,0x38,
+ 0xbf,0x40,0xa3,0x9e,
+ 0x81,0xf3,0xd7,0xfb,
+ 0x7c,0xe3,0x39,0x82,
+ 0x9b,0x2f,0xff,0x87,
+ 0x34,0x8e,0x43,0x44,
+ 0xc4,0xde,0xe9,0xcb,
+ 0x54,0x7b,0x94,0x32,
+ 0xa6,0xc2,0x23,0x3d,
+ 0xee,0x4c,0x95,0x0b,
+ 0x42,0xfa,0xc3,0x4e,
+ 0x08,0x2e,0xa1,0x66,
+ 0x28,0xd9,0x24,0xb2,
+ 0x76,0x5b,0xa2,0x49,
+ 0x6d,0x8b,0xd1,0x25,
+ 0x72,0xf8,0xf6,0x64,
+ 0x86,0x68,0x98,0x16,
+ 0xd4,0xa4,0x5c,0xcc,
+ 0x5d,0x65,0xb6,0x92,
+ 0x6c,0x70,0x48,0x50,
+ 0xfd,0xed,0xb9,0xda,
+ 0x5e,0x15,0x46,0x57,
+ 0xa7,0x8d,0x9d,0x84,
+ 0x90,0xd8,0xab,0x00,
+ 0x8c,0xbc,0xd3,0x0a,
+ 0xf7,0xe4,0x58,0x05,
+ 0xb8,0xb3,0x45,0x06,
+ 0xd0,0x2c,0x1e,0x8f,
+ 0xca,0x3f,0x0f,0x02,
+ 0xc1,0xaf,0xbd,0x03,
+ 0x01,0x13,0x8a,0x6b,
+ 0x3a,0x91,0x11,0x41,
+ 0x4f,0x67,0xdc,0xea,
+ 0x97,0xf2,0xcf,0xce,
+ 0xf0,0xb4,0xe6,0x73,
+ 0x96,0xac,0x74,0x22,
+ 0xe7,0xad,0x35,0x85,
+ 0xe2,0xf9,0x37,0xe8,
+ 0x1c,0x75,0xdf,0x6e,
+ 0x47,0xf1,0x1a,0x71,
+ 0x1d,0x29,0xc5,0x89,
+ 0x6f,0xb7,0x62,0x0e,
+ 0xaa,0x18,0xbe,0x1b,
+ 0xfc,0x56,0x3e,0x4b,
+ 0xc6,0xd2,0x79,0x20,
+ 0x9a,0xdb,0xc0,0xfe,
+ 0x78,0xcd,0x5a,0xf4,
+ 0x1f,0xdd,0xa8,0x33,
+ 0x88,0x07,0xc7,0x31,
+ 0xb1,0x12,0x10,0x59,
+ 0x27,0x80,0xec,0x5f,
+ 0x60,0x51,0x7f,0xa9,
+ 0x19,0xb5,0x4a,0x0d,
+ 0x2d,0xe5,0x7a,0x9f,
+ 0x93,0xc9,0x9c,0xef,
+ 0xa0,0xe0,0x3b,0x4d,
+ 0xae,0x2a,0xf5,0xb0,
+ 0xc8,0xeb,0xbb,0x3c,
+ 0x83,0x53,0x99,0x61,
+ 0x17,0x2b,0x04,0x7e,
+ 0xba,0x77,0xd6,0x26,
+ 0xe1,0x69,0x14,0x63,
+ 0x55,0x21,0x0c,0x7d
+};
+
+static UINT8 U1[256][4]=
+{
+ 0x00,0x00,0x00,0x00, 0x0e,0x09,0x0d,0x0b, 0x1c,0x12,0x1a,0x16, 0x12,0x1b,0x17,0x1d,
+ 0x38,0x24,0x34,0x2c, 0x36,0x2d,0x39,0x27, 0x24,0x36,0x2e,0x3a, 0x2a,0x3f,0x23,0x31,
+ 0x70,0x48,0x68,0x58, 0x7e,0x41,0x65,0x53, 0x6c,0x5a,0x72,0x4e, 0x62,0x53,0x7f,0x45,
+ 0x48,0x6c,0x5c,0x74, 0x46,0x65,0x51,0x7f, 0x54,0x7e,0x46,0x62, 0x5a,0x77,0x4b,0x69,
+ 0xe0,0x90,0xd0,0xb0, 0xee,0x99,0xdd,0xbb, 0xfc,0x82,0xca,0xa6, 0xf2,0x8b,0xc7,0xad,
+ 0xd8,0xb4,0xe4,0x9c, 0xd6,0xbd,0xe9,0x97, 0xc4,0xa6,0xfe,0x8a, 0xca,0xaf,0xf3,0x81,
+ 0x90,0xd8,0xb8,0xe8, 0x9e,0xd1,0xb5,0xe3, 0x8c,0xca,0xa2,0xfe, 0x82,0xc3,0xaf,0xf5,
+ 0xa8,0xfc,0x8c,0xc4, 0xa6,0xf5,0x81,0xcf, 0xb4,0xee,0x96,0xd2, 0xba,0xe7,0x9b,0xd9,
+ 0xdb,0x3b,0xbb,0x7b, 0xd5,0x32,0xb6,0x70, 0xc7,0x29,0xa1,0x6d, 0xc9,0x20,0xac,0x66,
+ 0xe3,0x1f,0x8f,0x57, 0xed,0x16,0x82,0x5c, 0xff,0x0d,0x95,0x41, 0xf1,0x04,0x98,0x4a,
+ 0xab,0x73,0xd3,0x23, 0xa5,0x7a,0xde,0x28, 0xb7,0x61,0xc9,0x35, 0xb9,0x68,0xc4,0x3e,
+ 0x93,0x57,0xe7,0x0f, 0x9d,0x5e,0xea,0x04, 0x8f,0x45,0xfd,0x19, 0x81,0x4c,0xf0,0x12,
+ 0x3b,0xab,0x6b,0xcb, 0x35,0xa2,0x66,0xc0, 0x27,0xb9,0x71,0xdd, 0x29,0xb0,0x7c,0xd6,
+ 0x03,0x8f,0x5f,0xe7, 0x0d,0x86,0x52,0xec, 0x1f,0x9d,0x45,0xf1, 0x11,0x94,0x48,0xfa,
+ 0x4b,0xe3,0x03,0x93, 0x45,0xea,0x0e,0x98, 0x57,0xf1,0x19,0x85, 0x59,0xf8,0x14,0x8e,
+ 0x73,0xc7,0x37,0xbf, 0x7d,0xce,0x3a,0xb4, 0x6f,0xd5,0x2d,0xa9, 0x61,0xdc,0x20,0xa2,
+ 0xad,0x76,0x6d,0xf6, 0xa3,0x7f,0x60,0xfd, 0xb1,0x64,0x77,0xe0, 0xbf,0x6d,0x7a,0xeb,
+ 0x95,0x52,0x59,0xda, 0x9b,0x5b,0x54,0xd1, 0x89,0x40,0x43,0xcc, 0x87,0x49,0x4e,0xc7,
+ 0xdd,0x3e,0x05,0xae, 0xd3,0x37,0x08,0xa5, 0xc1,0x2c,0x1f,0xb8, 0xcf,0x25,0x12,0xb3,
+ 0xe5,0x1a,0x31,0x82, 0xeb,0x13,0x3c,0x89, 0xf9,0x08,0x2b,0x94, 0xf7,0x01,0x26,0x9f,
+ 0x4d,0xe6,0xbd,0x46, 0x43,0xef,0xb0,0x4d, 0x51,0xf4,0xa7,0x50, 0x5f,0xfd,0xaa,0x5b,
+ 0x75,0xc2,0x89,0x6a, 0x7b,0xcb,0x84,0x61, 0x69,0xd0,0x93,0x7c, 0x67,0xd9,0x9e,0x77,
+ 0x3d,0xae,0xd5,0x1e, 0x33,0xa7,0xd8,0x15, 0x21,0xbc,0xcf,0x08, 0x2f,0xb5,0xc2,0x03,
+ 0x05,0x8a,0xe1,0x32, 0x0b,0x83,0xec,0x39, 0x19,0x98,0xfb,0x24, 0x17,0x91,0xf6,0x2f,
+ 0x76,0x4d,0xd6,0x8d, 0x78,0x44,0xdb,0x86, 0x6a,0x5f,0xcc,0x9b, 0x64,0x56,0xc1,0x90,
+ 0x4e,0x69,0xe2,0xa1, 0x40,0x60,0xef,0xaa, 0x52,0x7b,0xf8,0xb7, 0x5c,0x72,0xf5,0xbc,
+ 0x06,0x05,0xbe,0xd5, 0x08,0x0c,0xb3,0xde, 0x1a,0x17,0xa4,0xc3, 0x14,0x1e,0xa9,0xc8,
+ 0x3e,0x21,0x8a,0xf9, 0x30,0x28,0x87,0xf2, 0x22,0x33,0x90,0xef, 0x2c,0x3a,0x9d,0xe4,
+ 0x96,0xdd,0x06,0x3d, 0x98,0xd4,0x0b,0x36, 0x8a,0xcf,0x1c,0x2b, 0x84,0xc6,0x11,0x20,
+ 0xae,0xf9,0x32,0x11, 0xa0,0xf0,0x3f,0x1a, 0xb2,0xeb,0x28,0x07, 0xbc,0xe2,0x25,0x0c,
+ 0xe6,0x95,0x6e,0x65, 0xe8,0x9c,0x63,0x6e, 0xfa,0x87,0x74,0x73, 0xf4,0x8e,0x79,0x78,
+ 0xde,0xb1,0x5a,0x49, 0xd0,0xb8,0x57,0x42, 0xc2,0xa3,0x40,0x5f, 0xcc,0xaa,0x4d,0x54,
+ 0x41,0xec,0xda,0xf7, 0x4f,0xe5,0xd7,0xfc, 0x5d,0xfe,0xc0,0xe1, 0x53,0xf7,0xcd,0xea,
+ 0x79,0xc8,0xee,0xdb, 0x77,0xc1,0xe3,0xd0, 0x65,0xda,0xf4,0xcd, 0x6b,0xd3,0xf9,0xc6,
+ 0x31,0xa4,0xb2,0xaf, 0x3f,0xad,0xbf,0xa4, 0x2d,0xb6,0xa8,0xb9, 0x23,0xbf,0xa5,0xb2,
+ 0x09,0x80,0x86,0x83, 0x07,0x89,0x8b,0x88, 0x15,0x92,0x9c,0x95, 0x1b,0x9b,0x91,0x9e,
+ 0xa1,0x7c,0x0a,0x47, 0xaf,0x75,0x07,0x4c, 0xbd,0x6e,0x10,0x51, 0xb3,0x67,0x1d,0x5a,
+ 0x99,0x58,0x3e,0x6b, 0x97,0x51,0x33,0x60, 0x85,0x4a,0x24,0x7d, 0x8b,0x43,0x29,0x76,
+ 0xd1,0x34,0x62,0x1f, 0xdf,0x3d,0x6f,0x14, 0xcd,0x26,0x78,0x09, 0xc3,0x2f,0x75,0x02,
+ 0xe9,0x10,0x56,0x33, 0xe7,0x19,0x5b,0x38, 0xf5,0x02,0x4c,0x25, 0xfb,0x0b,0x41,0x2e,
+ 0x9a,0xd7,0x61,0x8c, 0x94,0xde,0x6c,0x87, 0x86,0xc5,0x7b,0x9a, 0x88,0xcc,0x76,0x91,
+ 0xa2,0xf3,0x55,0xa0, 0xac,0xfa,0x58,0xab, 0xbe,0xe1,0x4f,0xb6, 0xb0,0xe8,0x42,0xbd,
+ 0xea,0x9f,0x09,0xd4, 0xe4,0x96,0x04,0xdf, 0xf6,0x8d,0x13,0xc2, 0xf8,0x84,0x1e,0xc9,
+ 0xd2,0xbb,0x3d,0xf8, 0xdc,0xb2,0x30,0xf3, 0xce,0xa9,0x27,0xee, 0xc0,0xa0,0x2a,0xe5,
+ 0x7a,0x47,0xb1,0x3c, 0x74,0x4e,0xbc,0x37, 0x66,0x55,0xab,0x2a, 0x68,0x5c,0xa6,0x21,
+ 0x42,0x63,0x85,0x10, 0x4c,0x6a,0x88,0x1b, 0x5e,0x71,0x9f,0x06, 0x50,0x78,0x92,0x0d,
+ 0x0a,0x0f,0xd9,0x64, 0x04,0x06,0xd4,0x6f, 0x16,0x1d,0xc3,0x72, 0x18,0x14,0xce,0x79,
+ 0x32,0x2b,0xed,0x48, 0x3c,0x22,0xe0,0x43, 0x2e,0x39,0xf7,0x5e, 0x20,0x30,0xfa,0x55,
+ 0xec,0x9a,0xb7,0x01, 0xe2,0x93,0xba,0x0a, 0xf0,0x88,0xad,0x17, 0xfe,0x81,0xa0,0x1c,
+ 0xd4,0xbe,0x83,0x2d, 0xda,0xb7,0x8e,0x26, 0xc8,0xac,0x99,0x3b, 0xc6,0xa5,0x94,0x30,
+ 0x9c,0xd2,0xdf,0x59, 0x92,0xdb,0xd2,0x52, 0x80,0xc0,0xc5,0x4f, 0x8e,0xc9,0xc8,0x44,
+ 0xa4,0xf6,0xeb,0x75, 0xaa,0xff,0xe6,0x7e, 0xb8,0xe4,0xf1,0x63, 0xb6,0xed,0xfc,0x68,
+ 0x0c,0x0a,0x67,0xb1, 0x02,0x03,0x6a,0xba, 0x10,0x18,0x7d,0xa7, 0x1e,0x11,0x70,0xac,
+ 0x34,0x2e,0x53,0x9d, 0x3a,0x27,0x5e,0x96, 0x28,0x3c,0x49,0x8b, 0x26,0x35,0x44,0x80,
+ 0x7c,0x42,0x0f,0xe9, 0x72,0x4b,0x02,0xe2, 0x60,0x50,0x15,0xff, 0x6e,0x59,0x18,0xf4,
+ 0x44,0x66,0x3b,0xc5, 0x4a,0x6f,0x36,0xce, 0x58,0x74,0x21,0xd3, 0x56,0x7d,0x2c,0xd8,
+ 0x37,0xa1,0x0c,0x7a, 0x39,0xa8,0x01,0x71, 0x2b,0xb3,0x16,0x6c, 0x25,0xba,0x1b,0x67,
+ 0x0f,0x85,0x38,0x56, 0x01,0x8c,0x35,0x5d, 0x13,0x97,0x22,0x40, 0x1d,0x9e,0x2f,0x4b,
+ 0x47,0xe9,0x64,0x22, 0x49,0xe0,0x69,0x29, 0x5b,0xfb,0x7e,0x34, 0x55,0xf2,0x73,0x3f,
+ 0x7f,0xcd,0x50,0x0e, 0x71,0xc4,0x5d,0x05, 0x63,0xdf,0x4a,0x18, 0x6d,0xd6,0x47,0x13,
+ 0xd7,0x31,0xdc,0xca, 0xd9,0x38,0xd1,0xc1, 0xcb,0x23,0xc6,0xdc, 0xc5,0x2a,0xcb,0xd7,
+ 0xef,0x15,0xe8,0xe6, 0xe1,0x1c,0xe5,0xed, 0xf3,0x07,0xf2,0xf0, 0xfd,0x0e,0xff,0xfb,
+ 0xa7,0x79,0xb4,0x92, 0xa9,0x70,0xb9,0x99, 0xbb,0x6b,0xae,0x84, 0xb5,0x62,0xa3,0x8f,
+ 0x9f,0x5d,0x80,0xbe, 0x91,0x54,0x8d,0xb5, 0x83,0x4f,0x9a,0xa8, 0x8d,0x46,0x97,0xa3
+};
+
+static UINT8 U2[256][4]=
+{
+ 0x00,0x00,0x00,0x00, 0x0b,0x0e,0x09,0x0d, 0x16,0x1c,0x12,0x1a, 0x1d,0x12,0x1b,0x17,
+ 0x2c,0x38,0x24,0x34, 0x27,0x36,0x2d,0x39, 0x3a,0x24,0x36,0x2e, 0x31,0x2a,0x3f,0x23,
+ 0x58,0x70,0x48,0x68, 0x53,0x7e,0x41,0x65, 0x4e,0x6c,0x5a,0x72, 0x45,0x62,0x53,0x7f,
+ 0x74,0x48,0x6c,0x5c, 0x7f,0x46,0x65,0x51, 0x62,0x54,0x7e,0x46, 0x69,0x5a,0x77,0x4b,
+ 0xb0,0xe0,0x90,0xd0, 0xbb,0xee,0x99,0xdd, 0xa6,0xfc,0x82,0xca, 0xad,0xf2,0x8b,0xc7,
+ 0x9c,0xd8,0xb4,0xe4, 0x97,0xd6,0xbd,0xe9, 0x8a,0xc4,0xa6,0xfe, 0x81,0xca,0xaf,0xf3,
+ 0xe8,0x90,0xd8,0xb8, 0xe3,0x9e,0xd1,0xb5, 0xfe,0x8c,0xca,0xa2, 0xf5,0x82,0xc3,0xaf,
+ 0xc4,0xa8,0xfc,0x8c, 0xcf,0xa6,0xf5,0x81, 0xd2,0xb4,0xee,0x96, 0xd9,0xba,0xe7,0x9b,
+ 0x7b,0xdb,0x3b,0xbb, 0x70,0xd5,0x32,0xb6, 0x6d,0xc7,0x29,0xa1, 0x66,0xc9,0x20,0xac,
+ 0x57,0xe3,0x1f,0x8f, 0x5c,0xed,0x16,0x82, 0x41,0xff,0x0d,0x95, 0x4a,0xf1,0x04,0x98,
+ 0x23,0xab,0x73,0xd3, 0x28,0xa5,0x7a,0xde, 0x35,0xb7,0x61,0xc9, 0x3e,0xb9,0x68,0xc4,
+ 0x0f,0x93,0x57,0xe7, 0x04,0x9d,0x5e,0xea, 0x19,0x8f,0x45,0xfd, 0x12,0x81,0x4c,0xf0,
+ 0xcb,0x3b,0xab,0x6b, 0xc0,0x35,0xa2,0x66, 0xdd,0x27,0xb9,0x71, 0xd6,0x29,0xb0,0x7c,
+ 0xe7,0x03,0x8f,0x5f, 0xec,0x0d,0x86,0x52, 0xf1,0x1f,0x9d,0x45, 0xfa,0x11,0x94,0x48,
+ 0x93,0x4b,0xe3,0x03, 0x98,0x45,0xea,0x0e, 0x85,0x57,0xf1,0x19, 0x8e,0x59,0xf8,0x14,
+ 0xbf,0x73,0xc7,0x37, 0xb4,0x7d,0xce,0x3a, 0xa9,0x6f,0xd5,0x2d, 0xa2,0x61,0xdc,0x20,
+ 0xf6,0xad,0x76,0x6d, 0xfd,0xa3,0x7f,0x60, 0xe0,0xb1,0x64,0x77, 0xeb,0xbf,0x6d,0x7a,
+ 0xda,0x95,0x52,0x59, 0xd1,0x9b,0x5b,0x54, 0xcc,0x89,0x40,0x43, 0xc7,0x87,0x49,0x4e,
+ 0xae,0xdd,0x3e,0x05, 0xa5,0xd3,0x37,0x08, 0xb8,0xc1,0x2c,0x1f, 0xb3,0xcf,0x25,0x12,
+ 0x82,0xe5,0x1a,0x31, 0x89,0xeb,0x13,0x3c, 0x94,0xf9,0x08,0x2b, 0x9f,0xf7,0x01,0x26,
+ 0x46,0x4d,0xe6,0xbd, 0x4d,0x43,0xef,0xb0, 0x50,0x51,0xf4,0xa7, 0x5b,0x5f,0xfd,0xaa,
+ 0x6a,0x75,0xc2,0x89, 0x61,0x7b,0xcb,0x84, 0x7c,0x69,0xd0,0x93, 0x77,0x67,0xd9,0x9e,
+ 0x1e,0x3d,0xae,0xd5, 0x15,0x33,0xa7,0xd8, 0x08,0x21,0xbc,0xcf, 0x03,0x2f,0xb5,0xc2,
+ 0x32,0x05,0x8a,0xe1, 0x39,0x0b,0x83,0xec, 0x24,0x19,0x98,0xfb, 0x2f,0x17,0x91,0xf6,
+ 0x8d,0x76,0x4d,0xd6, 0x86,0x78,0x44,0xdb, 0x9b,0x6a,0x5f,0xcc, 0x90,0x64,0x56,0xc1,
+ 0xa1,0x4e,0x69,0xe2, 0xaa,0x40,0x60,0xef, 0xb7,0x52,0x7b,0xf8, 0xbc,0x5c,0x72,0xf5,
+ 0xd5,0x06,0x05,0xbe, 0xde,0x08,0x0c,0xb3, 0xc3,0x1a,0x17,0xa4, 0xc8,0x14,0x1e,0xa9,
+ 0xf9,0x3e,0x21,0x8a, 0xf2,0x30,0x28,0x87, 0xef,0x22,0x33,0x90, 0xe4,0x2c,0x3a,0x9d,
+ 0x3d,0x96,0xdd,0x06, 0x36,0x98,0xd4,0x0b, 0x2b,0x8a,0xcf,0x1c, 0x20,0x84,0xc6,0x11,
+ 0x11,0xae,0xf9,0x32, 0x1a,0xa0,0xf0,0x3f, 0x07,0xb2,0xeb,0x28, 0x0c,0xbc,0xe2,0x25,
+ 0x65,0xe6,0x95,0x6e, 0x6e,0xe8,0x9c,0x63, 0x73,0xfa,0x87,0x74, 0x78,0xf4,0x8e,0x79,
+ 0x49,0xde,0xb1,0x5a, 0x42,0xd0,0xb8,0x57, 0x5f,0xc2,0xa3,0x40, 0x54,0xcc,0xaa,0x4d,
+ 0xf7,0x41,0xec,0xda, 0xfc,0x4f,0xe5,0xd7, 0xe1,0x5d,0xfe,0xc0, 0xea,0x53,0xf7,0xcd,
+ 0xdb,0x79,0xc8,0xee, 0xd0,0x77,0xc1,0xe3, 0xcd,0x65,0xda,0xf4, 0xc6,0x6b,0xd3,0xf9,
+ 0xaf,0x31,0xa4,0xb2, 0xa4,0x3f,0xad,0xbf, 0xb9,0x2d,0xb6,0xa8, 0xb2,0x23,0xbf,0xa5,
+ 0x83,0x09,0x80,0x86, 0x88,0x07,0x89,0x8b, 0x95,0x15,0x92,0x9c, 0x9e,0x1b,0x9b,0x91,
+ 0x47,0xa1,0x7c,0x0a, 0x4c,0xaf,0x75,0x07, 0x51,0xbd,0x6e,0x10, 0x5a,0xb3,0x67,0x1d,
+ 0x6b,0x99,0x58,0x3e, 0x60,0x97,0x51,0x33, 0x7d,0x85,0x4a,0x24, 0x76,0x8b,0x43,0x29,
+ 0x1f,0xd1,0x34,0x62, 0x14,0xdf,0x3d,0x6f, 0x09,0xcd,0x26,0x78, 0x02,0xc3,0x2f,0x75,
+ 0x33,0xe9,0x10,0x56, 0x38,0xe7,0x19,0x5b, 0x25,0xf5,0x02,0x4c, 0x2e,0xfb,0x0b,0x41,
+ 0x8c,0x9a,0xd7,0x61, 0x87,0x94,0xde,0x6c, 0x9a,0x86,0xc5,0x7b, 0x91,0x88,0xcc,0x76,
+ 0xa0,0xa2,0xf3,0x55, 0xab,0xac,0xfa,0x58, 0xb6,0xbe,0xe1,0x4f, 0xbd,0xb0,0xe8,0x42,
+ 0xd4,0xea,0x9f,0x09, 0xdf,0xe4,0x96,0x04, 0xc2,0xf6,0x8d,0x13, 0xc9,0xf8,0x84,0x1e,
+ 0xf8,0xd2,0xbb,0x3d, 0xf3,0xdc,0xb2,0x30, 0xee,0xce,0xa9,0x27, 0xe5,0xc0,0xa0,0x2a,
+ 0x3c,0x7a,0x47,0xb1, 0x37,0x74,0x4e,0xbc, 0x2a,0x66,0x55,0xab, 0x21,0x68,0x5c,0xa6,
+ 0x10,0x42,0x63,0x85, 0x1b,0x4c,0x6a,0x88, 0x06,0x5e,0x71,0x9f, 0x0d,0x50,0x78,0x92,
+ 0x64,0x0a,0x0f,0xd9, 0x6f,0x04,0x06,0xd4, 0x72,0x16,0x1d,0xc3, 0x79,0x18,0x14,0xce,
+ 0x48,0x32,0x2b,0xed, 0x43,0x3c,0x22,0xe0, 0x5e,0x2e,0x39,0xf7, 0x55,0x20,0x30,0xfa,
+ 0x01,0xec,0x9a,0xb7, 0x0a,0xe2,0x93,0xba, 0x17,0xf0,0x88,0xad, 0x1c,0xfe,0x81,0xa0,
+ 0x2d,0xd4,0xbe,0x83, 0x26,0xda,0xb7,0x8e, 0x3b,0xc8,0xac,0x99, 0x30,0xc6,0xa5,0x94,
+ 0x59,0x9c,0xd2,0xdf, 0x52,0x92,0xdb,0xd2, 0x4f,0x80,0xc0,0xc5, 0x44,0x8e,0xc9,0xc8,
+ 0x75,0xa4,0xf6,0xeb, 0x7e,0xaa,0xff,0xe6, 0x63,0xb8,0xe4,0xf1, 0x68,0xb6,0xed,0xfc,
+ 0xb1,0x0c,0x0a,0x67, 0xba,0x02,0x03,0x6a, 0xa7,0x10,0x18,0x7d, 0xac,0x1e,0x11,0x70,
+ 0x9d,0x34,0x2e,0x53, 0x96,0x3a,0x27,0x5e, 0x8b,0x28,0x3c,0x49, 0x80,0x26,0x35,0x44,
+ 0xe9,0x7c,0x42,0x0f, 0xe2,0x72,0x4b,0x02, 0xff,0x60,0x50,0x15, 0xf4,0x6e,0x59,0x18,
+ 0xc5,0x44,0x66,0x3b, 0xce,0x4a,0x6f,0x36, 0xd3,0x58,0x74,0x21, 0xd8,0x56,0x7d,0x2c,
+ 0x7a,0x37,0xa1,0x0c, 0x71,0x39,0xa8,0x01, 0x6c,0x2b,0xb3,0x16, 0x67,0x25,0xba,0x1b,
+ 0x56,0x0f,0x85,0x38, 0x5d,0x01,0x8c,0x35, 0x40,0x13,0x97,0x22, 0x4b,0x1d,0x9e,0x2f,
+ 0x22,0x47,0xe9,0x64, 0x29,0x49,0xe0,0x69, 0x34,0x5b,0xfb,0x7e, 0x3f,0x55,0xf2,0x73,
+ 0x0e,0x7f,0xcd,0x50, 0x05,0x71,0xc4,0x5d, 0x18,0x63,0xdf,0x4a, 0x13,0x6d,0xd6,0x47,
+ 0xca,0xd7,0x31,0xdc, 0xc1,0xd9,0x38,0xd1, 0xdc,0xcb,0x23,0xc6, 0xd7,0xc5,0x2a,0xcb,
+ 0xe6,0xef,0x15,0xe8, 0xed,0xe1,0x1c,0xe5, 0xf0,0xf3,0x07,0xf2, 0xfb,0xfd,0x0e,0xff,
+ 0x92,0xa7,0x79,0xb4, 0x99,0xa9,0x70,0xb9, 0x84,0xbb,0x6b,0xae, 0x8f,0xb5,0x62,0xa3,
+ 0xbe,0x9f,0x5d,0x80, 0xb5,0x91,0x54,0x8d, 0xa8,0x83,0x4f,0x9a, 0xa3,0x8d,0x46,0x97
+};
+
+static UINT8 U3[256][4]=
+{
+ 0x00,0x00,0x00,0x00, 0x0d,0x0b,0x0e,0x09, 0x1a,0x16,0x1c,0x12, 0x17,0x1d,0x12,0x1b,
+ 0x34,0x2c,0x38,0x24, 0x39,0x27,0x36,0x2d, 0x2e,0x3a,0x24,0x36, 0x23,0x31,0x2a,0x3f,
+ 0x68,0x58,0x70,0x48, 0x65,0x53,0x7e,0x41, 0x72,0x4e,0x6c,0x5a, 0x7f,0x45,0x62,0x53,
+ 0x5c,0x74,0x48,0x6c, 0x51,0x7f,0x46,0x65, 0x46,0x62,0x54,0x7e, 0x4b,0x69,0x5a,0x77,
+ 0xd0,0xb0,0xe0,0x90, 0xdd,0xbb,0xee,0x99, 0xca,0xa6,0xfc,0x82, 0xc7,0xad,0xf2,0x8b,
+ 0xe4,0x9c,0xd8,0xb4, 0xe9,0x97,0xd6,0xbd, 0xfe,0x8a,0xc4,0xa6, 0xf3,0x81,0xca,0xaf,
+ 0xb8,0xe8,0x90,0xd8, 0xb5,0xe3,0x9e,0xd1, 0xa2,0xfe,0x8c,0xca, 0xaf,0xf5,0x82,0xc3,
+ 0x8c,0xc4,0xa8,0xfc, 0x81,0xcf,0xa6,0xf5, 0x96,0xd2,0xb4,0xee, 0x9b,0xd9,0xba,0xe7,
+ 0xbb,0x7b,0xdb,0x3b, 0xb6,0x70,0xd5,0x32, 0xa1,0x6d,0xc7,0x29, 0xac,0x66,0xc9,0x20,
+ 0x8f,0x57,0xe3,0x1f, 0x82,0x5c,0xed,0x16, 0x95,0x41,0xff,0x0d, 0x98,0x4a,0xf1,0x04,
+ 0xd3,0x23,0xab,0x73, 0xde,0x28,0xa5,0x7a, 0xc9,0x35,0xb7,0x61, 0xc4,0x3e,0xb9,0x68,
+ 0xe7,0x0f,0x93,0x57, 0xea,0x04,0x9d,0x5e, 0xfd,0x19,0x8f,0x45, 0xf0,0x12,0x81,0x4c,
+ 0x6b,0xcb,0x3b,0xab, 0x66,0xc0,0x35,0xa2, 0x71,0xdd,0x27,0xb9, 0x7c,0xd6,0x29,0xb0,
+ 0x5f,0xe7,0x03,0x8f, 0x52,0xec,0x0d,0x86, 0x45,0xf1,0x1f,0x9d, 0x48,0xfa,0x11,0x94,
+ 0x03,0x93,0x4b,0xe3, 0x0e,0x98,0x45,0xea, 0x19,0x85,0x57,0xf1, 0x14,0x8e,0x59,0xf8,
+ 0x37,0xbf,0x73,0xc7, 0x3a,0xb4,0x7d,0xce, 0x2d,0xa9,0x6f,0xd5, 0x20,0xa2,0x61,0xdc,
+ 0x6d,0xf6,0xad,0x76, 0x60,0xfd,0xa3,0x7f, 0x77,0xe0,0xb1,0x64, 0x7a,0xeb,0xbf,0x6d,
+ 0x59,0xda,0x95,0x52, 0x54,0xd1,0x9b,0x5b, 0x43,0xcc,0x89,0x40, 0x4e,0xc7,0x87,0x49,
+ 0x05,0xae,0xdd,0x3e, 0x08,0xa5,0xd3,0x37, 0x1f,0xb8,0xc1,0x2c, 0x12,0xb3,0xcf,0x25,
+ 0x31,0x82,0xe5,0x1a, 0x3c,0x89,0xeb,0x13, 0x2b,0x94,0xf9,0x08, 0x26,0x9f,0xf7,0x01,
+ 0xbd,0x46,0x4d,0xe6, 0xb0,0x4d,0x43,0xef, 0xa7,0x50,0x51,0xf4, 0xaa,0x5b,0x5f,0xfd,
+ 0x89,0x6a,0x75,0xc2, 0x84,0x61,0x7b,0xcb, 0x93,0x7c,0x69,0xd0, 0x9e,0x77,0x67,0xd9,
+ 0xd5,0x1e,0x3d,0xae, 0xd8,0x15,0x33,0xa7, 0xcf,0x08,0x21,0xbc, 0xc2,0x03,0x2f,0xb5,
+ 0xe1,0x32,0x05,0x8a, 0xec,0x39,0x0b,0x83, 0xfb,0x24,0x19,0x98, 0xf6,0x2f,0x17,0x91,
+ 0xd6,0x8d,0x76,0x4d, 0xdb,0x86,0x78,0x44, 0xcc,0x9b,0x6a,0x5f, 0xc1,0x90,0x64,0x56,
+ 0xe2,0xa1,0x4e,0x69, 0xef,0xaa,0x40,0x60, 0xf8,0xb7,0x52,0x7b, 0xf5,0xbc,0x5c,0x72,
+ 0xbe,0xd5,0x06,0x05, 0xb3,0xde,0x08,0x0c, 0xa4,0xc3,0x1a,0x17, 0xa9,0xc8,0x14,0x1e,
+ 0x8a,0xf9,0x3e,0x21, 0x87,0xf2,0x30,0x28, 0x90,0xef,0x22,0x33, 0x9d,0xe4,0x2c,0x3a,
+ 0x06,0x3d,0x96,0xdd, 0x0b,0x36,0x98,0xd4, 0x1c,0x2b,0x8a,0xcf, 0x11,0x20,0x84,0xc6,
+ 0x32,0x11,0xae,0xf9, 0x3f,0x1a,0xa0,0xf0, 0x28,0x07,0xb2,0xeb, 0x25,0x0c,0xbc,0xe2,
+ 0x6e,0x65,0xe6,0x95, 0x63,0x6e,0xe8,0x9c, 0x74,0x73,0xfa,0x87, 0x79,0x78,0xf4,0x8e,
+ 0x5a,0x49,0xde,0xb1, 0x57,0x42,0xd0,0xb8, 0x40,0x5f,0xc2,0xa3, 0x4d,0x54,0xcc,0xaa,
+ 0xda,0xf7,0x41,0xec, 0xd7,0xfc,0x4f,0xe5, 0xc0,0xe1,0x5d,0xfe, 0xcd,0xea,0x53,0xf7,
+ 0xee,0xdb,0x79,0xc8, 0xe3,0xd0,0x77,0xc1, 0xf4,0xcd,0x65,0xda, 0xf9,0xc6,0x6b,0xd3,
+ 0xb2,0xaf,0x31,0xa4, 0xbf,0xa4,0x3f,0xad, 0xa8,0xb9,0x2d,0xb6, 0xa5,0xb2,0x23,0xbf,
+ 0x86,0x83,0x09,0x80, 0x8b,0x88,0x07,0x89, 0x9c,0x95,0x15,0x92, 0x91,0x9e,0x1b,0x9b,
+ 0x0a,0x47,0xa1,0x7c, 0x07,0x4c,0xaf,0x75, 0x10,0x51,0xbd,0x6e, 0x1d,0x5a,0xb3,0x67,
+ 0x3e,0x6b,0x99,0x58, 0x33,0x60,0x97,0x51, 0x24,0x7d,0x85,0x4a, 0x29,0x76,0x8b,0x43,
+ 0x62,0x1f,0xd1,0x34, 0x6f,0x14,0xdf,0x3d, 0x78,0x09,0xcd,0x26, 0x75,0x02,0xc3,0x2f,
+ 0x56,0x33,0xe9,0x10, 0x5b,0x38,0xe7,0x19, 0x4c,0x25,0xf5,0x02, 0x41,0x2e,0xfb,0x0b,
+ 0x61,0x8c,0x9a,0xd7, 0x6c,0x87,0x94,0xde, 0x7b,0x9a,0x86,0xc5, 0x76,0x91,0x88,0xcc,
+ 0x55,0xa0,0xa2,0xf3, 0x58,0xab,0xac,0xfa, 0x4f,0xb6,0xbe,0xe1, 0x42,0xbd,0xb0,0xe8,
+ 0x09,0xd4,0xea,0x9f, 0x04,0xdf,0xe4,0x96, 0x13,0xc2,0xf6,0x8d, 0x1e,0xc9,0xf8,0x84,
+ 0x3d,0xf8,0xd2,0xbb, 0x30,0xf3,0xdc,0xb2, 0x27,0xee,0xce,0xa9, 0x2a,0xe5,0xc0,0xa0,
+ 0xb1,0x3c,0x7a,0x47, 0xbc,0x37,0x74,0x4e, 0xab,0x2a,0x66,0x55, 0xa6,0x21,0x68,0x5c,
+ 0x85,0x10,0x42,0x63, 0x88,0x1b,0x4c,0x6a, 0x9f,0x06,0x5e,0x71, 0x92,0x0d,0x50,0x78,
+ 0xd9,0x64,0x0a,0x0f, 0xd4,0x6f,0x04,0x06, 0xc3,0x72,0x16,0x1d, 0xce,0x79,0x18,0x14,
+ 0xed,0x48,0x32,0x2b, 0xe0,0x43,0x3c,0x22, 0xf7,0x5e,0x2e,0x39, 0xfa,0x55,0x20,0x30,
+ 0xb7,0x01,0xec,0x9a, 0xba,0x0a,0xe2,0x93, 0xad,0x17,0xf0,0x88, 0xa0,0x1c,0xfe,0x81,
+ 0x83,0x2d,0xd4,0xbe, 0x8e,0x26,0xda,0xb7, 0x99,0x3b,0xc8,0xac, 0x94,0x30,0xc6,0xa5,
+ 0xdf,0x59,0x9c,0xd2, 0xd2,0x52,0x92,0xdb, 0xc5,0x4f,0x80,0xc0, 0xc8,0x44,0x8e,0xc9,
+ 0xeb,0x75,0xa4,0xf6, 0xe6,0x7e,0xaa,0xff, 0xf1,0x63,0xb8,0xe4, 0xfc,0x68,0xb6,0xed,
+ 0x67,0xb1,0x0c,0x0a, 0x6a,0xba,0x02,0x03, 0x7d,0xa7,0x10,0x18, 0x70,0xac,0x1e,0x11,
+ 0x53,0x9d,0x34,0x2e, 0x5e,0x96,0x3a,0x27, 0x49,0x8b,0x28,0x3c, 0x44,0x80,0x26,0x35,
+ 0x0f,0xe9,0x7c,0x42, 0x02,0xe2,0x72,0x4b, 0x15,0xff,0x60,0x50, 0x18,0xf4,0x6e,0x59,
+ 0x3b,0xc5,0x44,0x66, 0x36,0xce,0x4a,0x6f, 0x21,0xd3,0x58,0x74, 0x2c,0xd8,0x56,0x7d,
+ 0x0c,0x7a,0x37,0xa1, 0x01,0x71,0x39,0xa8, 0x16,0x6c,0x2b,0xb3, 0x1b,0x67,0x25,0xba,
+ 0x38,0x56,0x0f,0x85, 0x35,0x5d,0x01,0x8c, 0x22,0x40,0x13,0x97, 0x2f,0x4b,0x1d,0x9e,
+ 0x64,0x22,0x47,0xe9, 0x69,0x29,0x49,0xe0, 0x7e,0x34,0x5b,0xfb, 0x73,0x3f,0x55,0xf2,
+ 0x50,0x0e,0x7f,0xcd, 0x5d,0x05,0x71,0xc4, 0x4a,0x18,0x63,0xdf, 0x47,0x13,0x6d,0xd6,
+ 0xdc,0xca,0xd7,0x31, 0xd1,0xc1,0xd9,0x38, 0xc6,0xdc,0xcb,0x23, 0xcb,0xd7,0xc5,0x2a,
+ 0xe8,0xe6,0xef,0x15, 0xe5,0xed,0xe1,0x1c, 0xf2,0xf0,0xf3,0x07, 0xff,0xfb,0xfd,0x0e,
+ 0xb4,0x92,0xa7,0x79, 0xb9,0x99,0xa9,0x70, 0xae,0x84,0xbb,0x6b, 0xa3,0x8f,0xb5,0x62,
+ 0x80,0xbe,0x9f,0x5d, 0x8d,0xb5,0x91,0x54, 0x9a,0xa8,0x83,0x4f, 0x97,0xa3,0x8d,0x46
+};
+
+static UINT8 U4[256][4]=
+{
+ 0x00,0x00,0x00,0x00, 0x09,0x0d,0x0b,0x0e, 0x12,0x1a,0x16,0x1c, 0x1b,0x17,0x1d,0x12,
+ 0x24,0x34,0x2c,0x38, 0x2d,0x39,0x27,0x36, 0x36,0x2e,0x3a,0x24, 0x3f,0x23,0x31,0x2a,
+ 0x48,0x68,0x58,0x70, 0x41,0x65,0x53,0x7e, 0x5a,0x72,0x4e,0x6c, 0x53,0x7f,0x45,0x62,
+ 0x6c,0x5c,0x74,0x48, 0x65,0x51,0x7f,0x46, 0x7e,0x46,0x62,0x54, 0x77,0x4b,0x69,0x5a,
+ 0x90,0xd0,0xb0,0xe0, 0x99,0xdd,0xbb,0xee, 0x82,0xca,0xa6,0xfc, 0x8b,0xc7,0xad,0xf2,
+ 0xb4,0xe4,0x9c,0xd8, 0xbd,0xe9,0x97,0xd6, 0xa6,0xfe,0x8a,0xc4, 0xaf,0xf3,0x81,0xca,
+ 0xd8,0xb8,0xe8,0x90, 0xd1,0xb5,0xe3,0x9e, 0xca,0xa2,0xfe,0x8c, 0xc3,0xaf,0xf5,0x82,
+ 0xfc,0x8c,0xc4,0xa8, 0xf5,0x81,0xcf,0xa6, 0xee,0x96,0xd2,0xb4, 0xe7,0x9b,0xd9,0xba,
+ 0x3b,0xbb,0x7b,0xdb, 0x32,0xb6,0x70,0xd5, 0x29,0xa1,0x6d,0xc7, 0x20,0xac,0x66,0xc9,
+ 0x1f,0x8f,0x57,0xe3, 0x16,0x82,0x5c,0xed, 0x0d,0x95,0x41,0xff, 0x04,0x98,0x4a,0xf1,
+ 0x73,0xd3,0x23,0xab, 0x7a,0xde,0x28,0xa5, 0x61,0xc9,0x35,0xb7, 0x68,0xc4,0x3e,0xb9,
+ 0x57,0xe7,0x0f,0x93, 0x5e,0xea,0x04,0x9d, 0x45,0xfd,0x19,0x8f, 0x4c,0xf0,0x12,0x81,
+ 0xab,0x6b,0xcb,0x3b, 0xa2,0x66,0xc0,0x35, 0xb9,0x71,0xdd,0x27, 0xb0,0x7c,0xd6,0x29,
+ 0x8f,0x5f,0xe7,0x03, 0x86,0x52,0xec,0x0d, 0x9d,0x45,0xf1,0x1f, 0x94,0x48,0xfa,0x11,
+ 0xe3,0x03,0x93,0x4b, 0xea,0x0e,0x98,0x45, 0xf1,0x19,0x85,0x57, 0xf8,0x14,0x8e,0x59,
+ 0xc7,0x37,0xbf,0x73, 0xce,0x3a,0xb4,0x7d, 0xd5,0x2d,0xa9,0x6f, 0xdc,0x20,0xa2,0x61,
+ 0x76,0x6d,0xf6,0xad, 0x7f,0x60,0xfd,0xa3, 0x64,0x77,0xe0,0xb1, 0x6d,0x7a,0xeb,0xbf,
+ 0x52,0x59,0xda,0x95, 0x5b,0x54,0xd1,0x9b, 0x40,0x43,0xcc,0x89, 0x49,0x4e,0xc7,0x87,
+ 0x3e,0x05,0xae,0xdd, 0x37,0x08,0xa5,0xd3, 0x2c,0x1f,0xb8,0xc1, 0x25,0x12,0xb3,0xcf,
+ 0x1a,0x31,0x82,0xe5, 0x13,0x3c,0x89,0xeb, 0x08,0x2b,0x94,0xf9, 0x01,0x26,0x9f,0xf7,
+ 0xe6,0xbd,0x46,0x4d, 0xef,0xb0,0x4d,0x43, 0xf4,0xa7,0x50,0x51, 0xfd,0xaa,0x5b,0x5f,
+ 0xc2,0x89,0x6a,0x75, 0xcb,0x84,0x61,0x7b, 0xd0,0x93,0x7c,0x69, 0xd9,0x9e,0x77,0x67,
+ 0xae,0xd5,0x1e,0x3d, 0xa7,0xd8,0x15,0x33, 0xbc,0xcf,0x08,0x21, 0xb5,0xc2,0x03,0x2f,
+ 0x8a,0xe1,0x32,0x05, 0x83,0xec,0x39,0x0b, 0x98,0xfb,0x24,0x19, 0x91,0xf6,0x2f,0x17,
+ 0x4d,0xd6,0x8d,0x76, 0x44,0xdb,0x86,0x78, 0x5f,0xcc,0x9b,0x6a, 0x56,0xc1,0x90,0x64,
+ 0x69,0xe2,0xa1,0x4e, 0x60,0xef,0xaa,0x40, 0x7b,0xf8,0xb7,0x52, 0x72,0xf5,0xbc,0x5c,
+ 0x05,0xbe,0xd5,0x06, 0x0c,0xb3,0xde,0x08, 0x17,0xa4,0xc3,0x1a, 0x1e,0xa9,0xc8,0x14,
+ 0x21,0x8a,0xf9,0x3e, 0x28,0x87,0xf2,0x30, 0x33,0x90,0xef,0x22, 0x3a,0x9d,0xe4,0x2c,
+ 0xdd,0x06,0x3d,0x96, 0xd4,0x0b,0x36,0x98, 0xcf,0x1c,0x2b,0x8a, 0xc6,0x11,0x20,0x84,
+ 0xf9,0x32,0x11,0xae, 0xf0,0x3f,0x1a,0xa0, 0xeb,0x28,0x07,0xb2, 0xe2,0x25,0x0c,0xbc,
+ 0x95,0x6e,0x65,0xe6, 0x9c,0x63,0x6e,0xe8, 0x87,0x74,0x73,0xfa, 0x8e,0x79,0x78,0xf4,
+ 0xb1,0x5a,0x49,0xde, 0xb8,0x57,0x42,0xd0, 0xa3,0x40,0x5f,0xc2, 0xaa,0x4d,0x54,0xcc,
+ 0xec,0xda,0xf7,0x41, 0xe5,0xd7,0xfc,0x4f, 0xfe,0xc0,0xe1,0x5d, 0xf7,0xcd,0xea,0x53,
+ 0xc8,0xee,0xdb,0x79, 0xc1,0xe3,0xd0,0x77, 0xda,0xf4,0xcd,0x65, 0xd3,0xf9,0xc6,0x6b,
+ 0xa4,0xb2,0xaf,0x31, 0xad,0xbf,0xa4,0x3f, 0xb6,0xa8,0xb9,0x2d, 0xbf,0xa5,0xb2,0x23,
+ 0x80,0x86,0x83,0x09, 0x89,0x8b,0x88,0x07, 0x92,0x9c,0x95,0x15, 0x9b,0x91,0x9e,0x1b,
+ 0x7c,0x0a,0x47,0xa1, 0x75,0x07,0x4c,0xaf, 0x6e,0x10,0x51,0xbd, 0x67,0x1d,0x5a,0xb3,
+ 0x58,0x3e,0x6b,0x99, 0x51,0x33,0x60,0x97, 0x4a,0x24,0x7d,0x85, 0x43,0x29,0x76,0x8b,
+ 0x34,0x62,0x1f,0xd1, 0x3d,0x6f,0x14,0xdf, 0x26,0x78,0x09,0xcd, 0x2f,0x75,0x02,0xc3,
+ 0x10,0x56,0x33,0xe9, 0x19,0x5b,0x38,0xe7, 0x02,0x4c,0x25,0xf5, 0x0b,0x41,0x2e,0xfb,
+ 0xd7,0x61,0x8c,0x9a, 0xde,0x6c,0x87,0x94, 0xc5,0x7b,0x9a,0x86, 0xcc,0x76,0x91,0x88,
+ 0xf3,0x55,0xa0,0xa2, 0xfa,0x58,0xab,0xac, 0xe1,0x4f,0xb6,0xbe, 0xe8,0x42,0xbd,0xb0,
+ 0x9f,0x09,0xd4,0xea, 0x96,0x04,0xdf,0xe4, 0x8d,0x13,0xc2,0xf6, 0x84,0x1e,0xc9,0xf8,
+ 0xbb,0x3d,0xf8,0xd2, 0xb2,0x30,0xf3,0xdc, 0xa9,0x27,0xee,0xce, 0xa0,0x2a,0xe5,0xc0,
+ 0x47,0xb1,0x3c,0x7a, 0x4e,0xbc,0x37,0x74, 0x55,0xab,0x2a,0x66, 0x5c,0xa6,0x21,0x68,
+ 0x63,0x85,0x10,0x42, 0x6a,0x88,0x1b,0x4c, 0x71,0x9f,0x06,0x5e, 0x78,0x92,0x0d,0x50,
+ 0x0f,0xd9,0x64,0x0a, 0x06,0xd4,0x6f,0x04, 0x1d,0xc3,0x72,0x16, 0x14,0xce,0x79,0x18,
+ 0x2b,0xed,0x48,0x32, 0x22,0xe0,0x43,0x3c, 0x39,0xf7,0x5e,0x2e, 0x30,0xfa,0x55,0x20,
+ 0x9a,0xb7,0x01,0xec, 0x93,0xba,0x0a,0xe2, 0x88,0xad,0x17,0xf0, 0x81,0xa0,0x1c,0xfe,
+ 0xbe,0x83,0x2d,0xd4, 0xb7,0x8e,0x26,0xda, 0xac,0x99,0x3b,0xc8, 0xa5,0x94,0x30,0xc6,
+ 0xd2,0xdf,0x59,0x9c, 0xdb,0xd2,0x52,0x92, 0xc0,0xc5,0x4f,0x80, 0xc9,0xc8,0x44,0x8e,
+ 0xf6,0xeb,0x75,0xa4, 0xff,0xe6,0x7e,0xaa, 0xe4,0xf1,0x63,0xb8, 0xed,0xfc,0x68,0xb6,
+ 0x0a,0x67,0xb1,0x0c, 0x03,0x6a,0xba,0x02, 0x18,0x7d,0xa7,0x10, 0x11,0x70,0xac,0x1e,
+ 0x2e,0x53,0x9d,0x34, 0x27,0x5e,0x96,0x3a, 0x3c,0x49,0x8b,0x28, 0x35,0x44,0x80,0x26,
+ 0x42,0x0f,0xe9,0x7c, 0x4b,0x02,0xe2,0x72, 0x50,0x15,0xff,0x60, 0x59,0x18,0xf4,0x6e,
+ 0x66,0x3b,0xc5,0x44, 0x6f,0x36,0xce,0x4a, 0x74,0x21,0xd3,0x58, 0x7d,0x2c,0xd8,0x56,
+ 0xa1,0x0c,0x7a,0x37, 0xa8,0x01,0x71,0x39, 0xb3,0x16,0x6c,0x2b, 0xba,0x1b,0x67,0x25,
+ 0x85,0x38,0x56,0x0f, 0x8c,0x35,0x5d,0x01, 0x97,0x22,0x40,0x13, 0x9e,0x2f,0x4b,0x1d,
+ 0xe9,0x64,0x22,0x47, 0xe0,0x69,0x29,0x49, 0xfb,0x7e,0x34,0x5b, 0xf2,0x73,0x3f,0x55,
+ 0xcd,0x50,0x0e,0x7f, 0xc4,0x5d,0x05,0x71, 0xdf,0x4a,0x18,0x63, 0xd6,0x47,0x13,0x6d,
+ 0x31,0xdc,0xca,0xd7, 0x38,0xd1,0xc1,0xd9, 0x23,0xc6,0xdc,0xcb, 0x2a,0xcb,0xd7,0xc5,
+ 0x15,0xe8,0xe6,0xef, 0x1c,0xe5,0xed,0xe1, 0x07,0xf2,0xf0,0xf3, 0x0e,0xff,0xfb,0xfd,
+ 0x79,0xb4,0x92,0xa7, 0x70,0xb9,0x99,0xa9, 0x6b,0xae,0x84,0xbb, 0x62,0xa3,0x8f,0xb5,
+ 0x5d,0x80,0xbe,0x9f, 0x54,0x8d,0xb5,0x91, 0x4f,0x9a,0xa8,0x83, 0x46,0x97,0xa3,0x8d
+};
+
+static UINT32 rcon[30]=
+{
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
+ 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
+ 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
+ 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
+ 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
+};
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// API
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Rijndael::Rijndael()
+{
+ m_state = Invalid;
+}
+
+Rijndael::~Rijndael()
+{
+ // nothing here
+}
+
+int Rijndael::init(Mode mode,Direction dir,const UINT8 * key,KeyLength keyLen,UINT8 * initVector)
+{
+ // Not initialized yet
+ m_state = Invalid;
+
+ // Check the mode
+ if((mode != CBC) && (mode != ECB) && (mode != CFB1))return RIJNDAEL_UNSUPPORTED_MODE;
+ m_mode = mode;
+
+ // And the direction
+ if((dir != Encrypt) && (dir != Decrypt))return RIJNDAEL_UNSUPPORTED_DIRECTION;
+ m_direction = dir;
+
+ // Allow to set an init vector
+ if(initVector)
+ {
+ // specified init vector
+ for(int i = 0;i < MAX_IV_SIZE;i++)
+ {
+ m_initVector[i] = initVector[i];
+ }
+ } else {
+ // zero init vector
+ for(int i = 0;i < MAX_IV_SIZE;i++)
+ {
+ m_initVector[i] = 0;
+ }
+ }
+
+ UINT32 uKeyLenInBytes;
+
+ // And check the key length
+ switch(keyLen)
+ {
+ case Key16Bytes:
+ uKeyLenInBytes = 16;
+ m_uRounds = 10;
+ break;
+ case Key24Bytes:
+ uKeyLenInBytes = 24;
+ m_uRounds = 12;
+ break;
+ case Key32Bytes:
+ uKeyLenInBytes = 32;
+ m_uRounds = 14;
+ break;
+ default:
+ return RIJNDAEL_UNSUPPORTED_KEY_LENGTH;
+ break;
+ }
+ // The number of rounds is calculated as
+ // m_uRounds = (m_uKeyLenInBits / 32) + 6;
+
+ if(!key)return RIJNDAEL_BAD_KEY;
+
+ UINT8 keyMatrix[_MAX_KEY_COLUMNS][4];
+
+ for(UINT32 i = 0;i < uKeyLenInBytes;i++)keyMatrix[i >> 2][i & 3] = key[i];
+
+ keySched(keyMatrix);
+
+ if(m_direction == Decrypt)keyEncToDec();
+
+ m_state = Valid;
+
+ return RIJNDAEL_SUCCESS;
+}
+
+int Rijndael::blockEncrypt(const UINT8 *input,int inputLen,UINT8 *outBuffer)
+{
+ int i, k, numBlocks;
+ UINT8 block[16], iv[4][4];
+
+ if(m_state != Valid)return RIJNDAEL_NOT_INITIALIZED;
+ if(m_direction != Encrypt)return RIJNDAEL_BAD_DIRECTION;
+
+ if(input == 0 || inputLen <= 0)return 0;
+
+ numBlocks = inputLen/128;
+
+ switch(m_mode){
+ case ECB:
+ for(i = numBlocks;i > 0;i--)
+ {
+ encrypt(input,outBuffer);
+ input += 16;
+ outBuffer += 16;
+ }
+ break;
+ case CBC:
+ ((UINT32*)block)[0] = ((UINT32*)m_initVector)[0] ^ ((UINT32*)input)[0];
+ ((UINT32*)block)[1] = ((UINT32*)m_initVector)[1] ^ ((UINT32*)input)[1];
+ ((UINT32*)block)[2] = ((UINT32*)m_initVector)[2] ^ ((UINT32*)input)[2];
+ ((UINT32*)block)[3] = ((UINT32*)m_initVector)[3] ^ ((UINT32*)input)[3];
+ encrypt(block,outBuffer);
+ input += 16;
+ for(i = numBlocks - 1;i > 0;i--)
+ {
+ ((UINT32*)block)[0] = ((UINT32*)outBuffer)[0] ^ ((UINT32*)input)[0];
+ ((UINT32*)block)[1] = ((UINT32*)outBuffer)[1] ^ ((UINT32*)input)[1];
+ ((UINT32*)block)[2] = ((UINT32*)outBuffer)[2] ^ ((UINT32*)input)[2];
+ ((UINT32*)block)[3] = ((UINT32*)outBuffer)[3] ^ ((UINT32*)input)[3];
+ outBuffer += 16;
+ encrypt(block,outBuffer);
+ input += 16;
+ }
+ break;
+ case CFB1:
+#if STRICT_ALIGN
+ kvi_memmove(iv,m_initVector,16);
+#else /* !STRICT_ALIGN */
+ *((UINT32*)iv[0]) = *((UINT32*)(m_initVector ));
+ *((UINT32*)iv[1]) = *((UINT32*)(m_initVector + 4));
+ *((UINT32*)iv[2]) = *((UINT32*)(m_initVector + 8));
+ *((UINT32*)iv[3]) = *((UINT32*)(m_initVector +12));
+#endif /* ?STRICT_ALIGN */
+ for(i = numBlocks; i > 0; i--)
+ {
+ for(k = 0; k < 128; k++)
+ {
+ *((UINT32*) block ) = *((UINT32*)iv[0]);
+ *((UINT32*)(block+ 4)) = *((UINT32*)iv[1]);
+ *((UINT32*)(block+ 8)) = *((UINT32*)iv[2]);
+ *((UINT32*)(block+12)) = *((UINT32*)iv[3]);
+ encrypt(block,block);
+ outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
+ iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
+ iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
+ iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
+ iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
+ iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
+ iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
+ iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
+ iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
+ iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
+ iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
+ iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
+ iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
+ iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
+ iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
+ iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
+ iv[3][3] = (iv[3][3] << 1) | (outBuffer[k/8] >> (7-(k&7))) & 1;
+ }
+ }
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ return 128 * numBlocks;
+}
+
+int Rijndael::padEncrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer)
+{
+ int i, numBlocks, padLen;
+ UINT8 block[16], *iv;
+
+ if(m_state != Valid)return RIJNDAEL_NOT_INITIALIZED;
+ if(m_direction != Encrypt)return RIJNDAEL_NOT_INITIALIZED;
+
+ if(input == 0 || inputOctets <= 0)return 0;
+
+ numBlocks = inputOctets/16;
+
+ switch(m_mode)
+ {
+ case ECB:
+ for(i = numBlocks; i > 0; i--)
+ {
+ encrypt(input, outBuffer);
+ input += 16;
+ outBuffer += 16;
+ }
+ padLen = 16 - (inputOctets - 16*numBlocks);
+// assert(padLen > 0 && padLen <= 16);
+ kvi_memmove(block, input, 16 - padLen);
+ kvi_memset(block + 16 - padLen, padLen, padLen);
+ encrypt(block,outBuffer);
+ break;
+ case CBC:
+ iv = m_initVector;
+ for(i = numBlocks; i > 0; i--)
+ {
+ ((UINT32*)block)[0] = ((UINT32*)input)[0] ^ ((UINT32*)iv)[0];
+ ((UINT32*)block)[1] = ((UINT32*)input)[1] ^ ((UINT32*)iv)[1];
+ ((UINT32*)block)[2] = ((UINT32*)input)[2] ^ ((UINT32*)iv)[2];
+ ((UINT32*)block)[3] = ((UINT32*)input)[3] ^ ((UINT32*)iv)[3];
+ encrypt(block, outBuffer);
+ iv = outBuffer;
+ input += 16;
+ outBuffer += 16;
+ }
+ padLen = 16 - (inputOctets - 16*numBlocks);
+// assert(padLen > 0 && padLen <= 16); // DO SOMETHING HERE ?
+ for (i = 0; i < 16 - padLen; i++) {
+ block[i] = input[i] ^ iv[i];
+ }
+ for (i = 16 - padLen; i < 16; i++) {
+ block[i] = (UINT8)padLen ^ iv[i];
+ }
+ encrypt(block,outBuffer);
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ return 16*(numBlocks + 1);
+}
+
+int Rijndael::blockDecrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer)
+{
+ int i, k, numBlocks;
+ UINT8 block[16], iv[4][4];
+
+ if(m_state != Valid)return RIJNDAEL_NOT_INITIALIZED;
+ if((m_mode != CFB1) && (m_direction == Encrypt))return RIJNDAEL_BAD_DIRECTION;
+
+ if (input == 0 || inputLen <= 0)return 0;
+
+ numBlocks = inputLen/128;
+
+ switch(m_mode)
+ {
+ case ECB:
+ for (i = numBlocks; i > 0; i--)
+ {
+ decrypt(input,outBuffer);
+ input += 16;
+ outBuffer += 16;
+ }
+ break;
+ case CBC:
+#if STRICT_ALIGN
+ kvi_memmove(iv,m_initVector,16);
+#else
+ *((UINT32*)iv[0]) = *((UINT32*)(m_initVector ));
+ *((UINT32*)iv[1]) = *((UINT32*)(m_initVector+ 4));
+ *((UINT32*)iv[2]) = *((UINT32*)(m_initVector+ 8));
+ *((UINT32*)iv[3]) = *((UINT32*)(m_initVector+12));
+#endif
+ for (i = numBlocks; i > 0; i--)
+ {
+ decrypt(input, block);
+ ((UINT32*)block)[0] ^= *((UINT32*)iv[0]);
+ ((UINT32*)block)[1] ^= *((UINT32*)iv[1]);
+ ((UINT32*)block)[2] ^= *((UINT32*)iv[2]);
+ ((UINT32*)block)[3] ^= *((UINT32*)iv[3]);
+#if STRICT_ALIGN
+ kvi_memmove(iv, input, 16);
+ kvi_memmove(outBuf, block, 16);
+#else
+ *((UINT32*)iv[0]) = ((UINT32*)input)[0]; ((UINT32*)outBuffer)[0] = ((UINT32*)block)[0];
+ *((UINT32*)iv[1]) = ((UINT32*)input)[1]; ((UINT32*)outBuffer)[1] = ((UINT32*)block)[1];
+ *((UINT32*)iv[2]) = ((UINT32*)input)[2]; ((UINT32*)outBuffer)[2] = ((UINT32*)block)[2];
+ *((UINT32*)iv[3]) = ((UINT32*)input)[3]; ((UINT32*)outBuffer)[3] = ((UINT32*)block)[3];
+#endif
+ input += 16;
+ outBuffer += 16;
+ }
+ break;
+ case CFB1:
+#if STRICT_ALIGN
+ kvi_memmove(iv, m_initVector, 16);
+#else
+ *((UINT32*)iv[0]) = *((UINT32*)(m_initVector));
+ *((UINT32*)iv[1]) = *((UINT32*)(m_initVector+ 4));
+ *((UINT32*)iv[2]) = *((UINT32*)(m_initVector+ 8));
+ *((UINT32*)iv[3]) = *((UINT32*)(m_initVector+12));
+#endif
+ for(i = numBlocks; i > 0; i--)
+ {
+ for(k = 0; k < 128; k++)
+ {
+ *((UINT32*) block ) = *((UINT32*)iv[0]);
+ *((UINT32*)(block+ 4)) = *((UINT32*)iv[1]);
+ *((UINT32*)(block+ 8)) = *((UINT32*)iv[2]);
+ *((UINT32*)(block+12)) = *((UINT32*)iv[3]);
+ encrypt(block, block);
+ iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
+ iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
+ iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
+ iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
+ iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
+ iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
+ iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
+ iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
+ iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
+ iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
+ iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
+ iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
+ iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
+ iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
+ iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
+ iv[3][3] = (iv[3][3] << 1) | (input[k/8] >> (7-(k&7))) & 1;
+ outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
+ }
+ }
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ return 128*numBlocks;
+}
+
+int Rijndael::padDecrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer)
+{
+ int i, numBlocks, padLen;
+ UINT8 block[16];
+ UINT32 iv[4];
+
+ if(m_state != Valid)return RIJNDAEL_NOT_INITIALIZED;
+ if(m_direction != Decrypt)return RIJNDAEL_BAD_DIRECTION;
+
+ if(input == 0 || inputOctets <= 0)return 0;
+
+ if((inputOctets % 16) != 0)return RIJNDAEL_CORRUPTED_DATA;
+
+ numBlocks = inputOctets/16;
+
+ switch(m_mode){
+ case ECB:
+ for (i = numBlocks - 1; i > 0; i--)
+ {
+ decrypt(input, outBuffer);
+ input += 16;
+ outBuffer += 16;
+ }
+
+ decrypt(input, block);
+ padLen = block[15];
+ if (padLen >= 16)return RIJNDAEL_CORRUPTED_DATA;
+ for(i = 16 - padLen; i < 16; i++)
+ {
+ if(block[i] != padLen)return RIJNDAEL_CORRUPTED_DATA;
+ }
+ kvi_memmove(outBuffer, block, 16 - padLen);
+ break;
+ case CBC:
+ kvi_memmove(iv, m_initVector, 16);
+ /* all blocks but last */
+ for (i = numBlocks - 1; i > 0; i--)
+ {
+ decrypt(input, block);
+ ((UINT32*)block)[0] ^= iv[0];
+ ((UINT32*)block)[1] ^= iv[1];
+ ((UINT32*)block)[2] ^= iv[2];
+ ((UINT32*)block)[3] ^= iv[3];
+ kvi_memmove(iv, input, 16);
+ kvi_memmove(outBuffer, block, 16);
+ input += 16;
+ outBuffer += 16;
+ }
+ /* last block */
+ decrypt(input, block);
+ ((UINT32*)block)[0] ^= iv[0];
+ ((UINT32*)block)[1] ^= iv[1];
+ ((UINT32*)block)[2] ^= iv[2];
+ ((UINT32*)block)[3] ^= iv[3];
+ padLen = block[15];
+ if(padLen <= 0 || padLen > 16)return RIJNDAEL_CORRUPTED_DATA;
+ for(i = 16 - padLen; i < 16; i++)
+ {
+ if(block[i] != padLen)return RIJNDAEL_CORRUPTED_DATA;
+ }
+ kvi_memmove(outBuffer, block, 16 - padLen);
+ break;
+
+ default:
+ return -1;
+ break;
+ }
+
+ return 16*numBlocks - padLen;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ALGORITHM
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void Rijndael::keySched(UINT8 key[_MAX_KEY_COLUMNS][4])
+{
+ int j,rconpointer = 0;
+
+ // Calculate the necessary round keys
+ // The number of calculations depends on keyBits and blockBits
+ int uKeyColumns = m_uRounds - 6;
+
+ UINT8 tempKey[_MAX_KEY_COLUMNS][4];
+
+ // Copy the input key to the temporary key matrix
+
+ for(j = 0;j < uKeyColumns;j++)
+ {
+ *((UINT32*)(tempKey[j])) = *((UINT32*)(key[j]));
+ }
+
+ unsigned int r = 0;
+ int t = 0;
+
+ // copy values into round key array
+ for(j = 0;(j < uKeyColumns) && (r <= m_uRounds); )
+ {
+ for(;(j < uKeyColumns) && (t < 4); j++, t++)
+ {
+ *((UINT32*)m_expandedKey[r][t]) = *((UINT32*)tempKey[j]);
+ }
+
+
+ if(t == 4)
+ {
+ r++;
+ t = 0;
+ }
+ }
+
+ while(r <= m_uRounds)
+ {
+ tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]];
+ tempKey[0][1] ^= S[tempKey[uKeyColumns-1][2]];
+ tempKey[0][2] ^= S[tempKey[uKeyColumns-1][3]];
+ tempKey[0][3] ^= S[tempKey[uKeyColumns-1][0]];
+ tempKey[0][0] ^= rcon[rconpointer++];
+
+ if (uKeyColumns != 8)
+ {
+ for(j = 1; j < uKeyColumns; j++)
+ {
+ *((UINT32*)tempKey[j]) ^= *((UINT32*)tempKey[j-1]);
+ }
+ } else {
+ for(j = 1; j < uKeyColumns/2; j++)
+ {
+ *((UINT32*)tempKey[j]) ^= *((UINT32*)tempKey[j-1]);
+ }
+ tempKey[uKeyColumns/2][0] ^= S[tempKey[uKeyColumns/2 - 1][0]];
+ tempKey[uKeyColumns/2][1] ^= S[tempKey[uKeyColumns/2 - 1][1]];
+ tempKey[uKeyColumns/2][2] ^= S[tempKey[uKeyColumns/2 - 1][2]];
+ tempKey[uKeyColumns/2][3] ^= S[tempKey[uKeyColumns/2 - 1][3]];
+ for(j = uKeyColumns/2 + 1; j < uKeyColumns; j++)
+ {
+ *((UINT32*)tempKey[j]) ^= *((UINT32*)tempKey[j-1]);
+ }
+ }
+ for(j = 0; (j < uKeyColumns) && (r <= m_uRounds); )
+ {
+ for(; (j < uKeyColumns) && (t < 4); j++, t++)
+ {
+ *((UINT32*)m_expandedKey[r][t]) = *((UINT32*)tempKey[j]);
+ }
+ if(t == 4)
+ {
+ r++;
+ t = 0;
+ }
+ }
+ }
+}
+
+void Rijndael::keyEncToDec()
+{
+ UINT8 *w;
+
+ for(unsigned int r = 1; r < m_uRounds; r++)
+ {
+ w = m_expandedKey[r][0];
+ *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]);
+ w = m_expandedKey[r][1];
+ *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]);
+ w = m_expandedKey[r][2];
+ *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]);
+ w = m_expandedKey[r][3];
+ *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]);
+ }
+}
+
+void Rijndael::encrypt(const UINT8 a[16], UINT8 b[16])
+{
+ unsigned int r;
+ UINT8 temp[4][4];
+
+ *((UINT32*)temp[0]) = *((UINT32*)(a )) ^ *((UINT32*)m_expandedKey[0][0]);
+ *((UINT32*)temp[1]) = *((UINT32*)(a+ 4)) ^ *((UINT32*)m_expandedKey[0][1]);
+ *((UINT32*)temp[2]) = *((UINT32*)(a+ 8)) ^ *((UINT32*)m_expandedKey[0][2]);
+ *((UINT32*)temp[3]) = *((UINT32*)(a+12)) ^ *((UINT32*)m_expandedKey[0][3]);
+ *((UINT32*)(b )) = *((UINT32*)T1[temp[0][0]])
+ ^ *((UINT32*)T2[temp[1][1]])
+ ^ *((UINT32*)T3[temp[2][2]])
+ ^ *((UINT32*)T4[temp[3][3]]);
+ *((UINT32*)(b + 4)) = *((UINT32*)T1[temp[1][0]])
+ ^ *((UINT32*)T2[temp[2][1]])
+ ^ *((UINT32*)T3[temp[3][2]])
+ ^ *((UINT32*)T4[temp[0][3]]);
+ *((UINT32*)(b + 8)) = *((UINT32*)T1[temp[2][0]])
+ ^ *((UINT32*)T2[temp[3][1]])
+ ^ *((UINT32*)T3[temp[0][2]])
+ ^ *((UINT32*)T4[temp[1][3]]);
+ *((UINT32*)(b +12)) = *((UINT32*)T1[temp[3][0]])
+ ^ *((UINT32*)T2[temp[0][1]])
+ ^ *((UINT32*)T3[temp[1][2]])
+ ^ *((UINT32*)T4[temp[2][3]]);
+ for(r = 1; r < m_uRounds-1; r++)
+ {
+ *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)m_expandedKey[r][0]);
+ *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)m_expandedKey[r][1]);
+ *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)m_expandedKey[r][2]);
+ *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)m_expandedKey[r][3]);
+
+ *((UINT32*)(b )) = *((UINT32*)T1[temp[0][0]])
+ ^ *((UINT32*)T2[temp[1][1]])
+ ^ *((UINT32*)T3[temp[2][2]])
+ ^ *((UINT32*)T4[temp[3][3]]);
+ *((UINT32*)(b + 4)) = *((UINT32*)T1[temp[1][0]])
+ ^ *((UINT32*)T2[temp[2][1]])
+ ^ *((UINT32*)T3[temp[3][2]])
+ ^ *((UINT32*)T4[temp[0][3]]);
+ *((UINT32*)(b + 8)) = *((UINT32*)T1[temp[2][0]])
+ ^ *((UINT32*)T2[temp[3][1]])
+ ^ *((UINT32*)T3[temp[0][2]])
+ ^ *((UINT32*)T4[temp[1][3]]);
+ *((UINT32*)(b +12)) = *((UINT32*)T1[temp[3][0]])
+ ^ *((UINT32*)T2[temp[0][1]])
+ ^ *((UINT32*)T3[temp[1][2]])
+ ^ *((UINT32*)T4[temp[2][3]]);
+ }
+ *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)m_expandedKey[m_uRounds-1][0]);
+ *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)m_expandedKey[m_uRounds-1][1]);
+ *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)m_expandedKey[m_uRounds-1][2]);
+ *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)m_expandedKey[m_uRounds-1][3]);
+ b[ 0] = T1[temp[0][0]][1];
+ b[ 1] = T1[temp[1][1]][1];
+ b[ 2] = T1[temp[2][2]][1];
+ b[ 3] = T1[temp[3][3]][1];
+ b[ 4] = T1[temp[1][0]][1];
+ b[ 5] = T1[temp[2][1]][1];
+ b[ 6] = T1[temp[3][2]][1];
+ b[ 7] = T1[temp[0][3]][1];
+ b[ 8] = T1[temp[2][0]][1];
+ b[ 9] = T1[temp[3][1]][1];
+ b[10] = T1[temp[0][2]][1];
+ b[11] = T1[temp[1][3]][1];
+ b[12] = T1[temp[3][0]][1];
+ b[13] = T1[temp[0][1]][1];
+ b[14] = T1[temp[1][2]][1];
+ b[15] = T1[temp[2][3]][1];
+ *((UINT32*)(b )) ^= *((UINT32*)m_expandedKey[m_uRounds][0]);
+ *((UINT32*)(b+ 4)) ^= *((UINT32*)m_expandedKey[m_uRounds][1]);
+ *((UINT32*)(b+ 8)) ^= *((UINT32*)m_expandedKey[m_uRounds][2]);
+ *((UINT32*)(b+12)) ^= *((UINT32*)m_expandedKey[m_uRounds][3]);
+}
+
+void Rijndael::decrypt(const UINT8 a[16], UINT8 b[16])
+{
+ int r;
+ UINT8 temp[4][4];
+
+ *((UINT32*)temp[0]) = *((UINT32*)(a )) ^ *((UINT32*)m_expandedKey[m_uRounds][0]);
+ *((UINT32*)temp[1]) = *((UINT32*)(a+ 4)) ^ *((UINT32*)m_expandedKey[m_uRounds][1]);
+ *((UINT32*)temp[2]) = *((UINT32*)(a+ 8)) ^ *((UINT32*)m_expandedKey[m_uRounds][2]);
+ *((UINT32*)temp[3]) = *((UINT32*)(a+12)) ^ *((UINT32*)m_expandedKey[m_uRounds][3]);
+
+ *((UINT32*)(b )) = *((UINT32*)T5[temp[0][0]])
+ ^ *((UINT32*)T6[temp[3][1]])
+ ^ *((UINT32*)T7[temp[2][2]])
+ ^ *((UINT32*)T8[temp[1][3]]);
+ *((UINT32*)(b+ 4)) = *((UINT32*)T5[temp[1][0]])
+ ^ *((UINT32*)T6[temp[0][1]])
+ ^ *((UINT32*)T7[temp[3][2]])
+ ^ *((UINT32*)T8[temp[2][3]]);
+ *((UINT32*)(b+ 8)) = *((UINT32*)T5[temp[2][0]])
+ ^ *((UINT32*)T6[temp[1][1]])
+ ^ *((UINT32*)T7[temp[0][2]])
+ ^ *((UINT32*)T8[temp[3][3]]);
+ *((UINT32*)(b+12)) = *((UINT32*)T5[temp[3][0]])
+ ^ *((UINT32*)T6[temp[2][1]])
+ ^ *((UINT32*)T7[temp[1][2]])
+ ^ *((UINT32*)T8[temp[0][3]]);
+ for(r = m_uRounds-1; r > 1; r--)
+ {
+ *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)m_expandedKey[r][0]);
+ *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)m_expandedKey[r][1]);
+ *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)m_expandedKey[r][2]);
+ *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)m_expandedKey[r][3]);
+ *((UINT32*)(b )) = *((UINT32*)T5[temp[0][0]])
+ ^ *((UINT32*)T6[temp[3][1]])
+ ^ *((UINT32*)T7[temp[2][2]])
+ ^ *((UINT32*)T8[temp[1][3]]);
+ *((UINT32*)(b+ 4)) = *((UINT32*)T5[temp[1][0]])
+ ^ *((UINT32*)T6[temp[0][1]])
+ ^ *((UINT32*)T7[temp[3][2]])
+ ^ *((UINT32*)T8[temp[2][3]]);
+ *((UINT32*)(b+ 8)) = *((UINT32*)T5[temp[2][0]])
+ ^ *((UINT32*)T6[temp[1][1]])
+ ^ *((UINT32*)T7[temp[0][2]])
+ ^ *((UINT32*)T8[temp[3][3]]);
+ *((UINT32*)(b+12)) = *((UINT32*)T5[temp[3][0]])
+ ^ *((UINT32*)T6[temp[2][1]])
+ ^ *((UINT32*)T7[temp[1][2]])
+ ^ *((UINT32*)T8[temp[0][3]]);
+ }
+
+ *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)m_expandedKey[1][0]);
+ *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)m_expandedKey[1][1]);
+ *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)m_expandedKey[1][2]);
+ *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)m_expandedKey[1][3]);
+ b[ 0] = S5[temp[0][0]];
+ b[ 1] = S5[temp[3][1]];
+ b[ 2] = S5[temp[2][2]];
+ b[ 3] = S5[temp[1][3]];
+ b[ 4] = S5[temp[1][0]];
+ b[ 5] = S5[temp[0][1]];
+ b[ 6] = S5[temp[3][2]];
+ b[ 7] = S5[temp[2][3]];
+ b[ 8] = S5[temp[2][0]];
+ b[ 9] = S5[temp[1][1]];
+ b[10] = S5[temp[0][2]];
+ b[11] = S5[temp[3][3]];
+ b[12] = S5[temp[3][0]];
+ b[13] = S5[temp[2][1]];
+ b[14] = S5[temp[1][2]];
+ b[15] = S5[temp[0][3]];
+ *((UINT32*)(b )) ^= *((UINT32*)m_expandedKey[0][0]);
+ *((UINT32*)(b+ 4)) ^= *((UINT32*)m_expandedKey[0][1]);
+ *((UINT32*)(b+ 8)) ^= *((UINT32*)m_expandedKey[0][2]);
+ *((UINT32*)(b+12)) ^= *((UINT32*)m_expandedKey[0][3]);
+}
+
+#endif // COMPILE_CRYPT_SUPPORT
diff --git a/src/modules/rijndael/rijndael.h b/src/modules/rijndael/rijndael.h
new file mode 100644
index 00000000..e720df3e
--- /dev/null
+++ b/src/modules/rijndael/rijndael.h
@@ -0,0 +1,153 @@
+#ifndef _RIJNDAEL_H_
+#define _RIJNDAEL_H_
+
+//
+// File : rijndael.h
+// Creation date : Sun Nov 5 2000 15:42:14 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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.
+//
+
+//
+// Another implementation of the Rijndael cipher.
+// This is intended to be an easily usable library file.
+// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
+//
+
+//
+// Original Copyright notice:
+//
+// rijndael-alg-fst.c v2.4 April '2000
+// rijndael-alg-fst.h
+// rijndael-api-fst.c
+// rijndael-api-fst.h
+//
+// Optimised ANSI C code
+//
+// authors: v1.0: Antoon Bosselaers
+// v2.0: Vincent Rijmen, K.U.Leuven
+// v2.3: Paulo Barreto
+// v2.4: Vincent Rijmen, K.U.Leuven
+//
+// This code is placed in the public domain.
+//
+
+//
+// This implementation works on 128 , 192 , 256 bit keys
+// and on 128 bit blocks
+//
+
+//
+// Example of usage:
+//
+// // Input data
+// unsigned char key[32]; // The key
+// initializeYour256BitKey(); // Obviously initialized with sth
+// const unsigned char * plainText = getYourPlainText(); // Your plain text
+// int plainTextLen = strlen(plainText); // Plain text length
+//
+// // Encrypting
+// Rijndael rin;
+// unsigned char output[plainTextLen + 16];
+//
+// rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes);
+// // It is a good idea to check the error code
+// int len = rin.padEncrypt(plainText,len,output);
+// if(len >= 0)useYourEncryptedText();
+// else encryptError(len);
+//
+// // Decrypting: we can reuse the same object
+// unsigned char output2[len];
+// rin.init(Rijndael::ECB,Rijndael::Decrypt,keyMaterial,Rijndael::Key32Bytes));
+// len = rin.padDecrypt(output,len,output2);
+// if(len >= 0)useYourDecryptedText();
+// else decryptError(len);
+//
+
+#include "kvi_settings.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+#define _MAX_KEY_COLUMNS (256/32)
+#define _MAX_ROUNDS 14
+//#define BITSPERBLOCK 128 /* Default number of bits in a cipher block */
+#define MAX_IV_SIZE 16
+
+// We assume that unsigned int is 32 bits long....
+typedef unsigned char UINT8;
+typedef unsigned int UINT32;
+typedef unsigned short UINT16;
+
+#define RIJNDAEL_SUCCESS 0
+#define RIJNDAEL_UNSUPPORTED_MODE -1
+#define RIJNDAEL_UNSUPPORTED_DIRECTION -2
+#define RIJNDAEL_UNSUPPORTED_KEY_LENGTH -3
+#define RIJNDAEL_BAD_KEY -4
+#define RIJNDAEL_NOT_INITIALIZED -5
+#define RIJNDAEL_BAD_DIRECTION -6
+#define RIJNDAEL_CORRUPTED_DATA -7
+
+class Rijndael
+{
+public:
+ enum Direction { Encrypt , Decrypt };
+ enum Mode { ECB , CBC , CFB1 };
+ enum KeyLength { Key16Bytes , Key24Bytes , Key32Bytes };
+
+ Rijndael();
+ ~Rijndael();
+protected:
+ enum State { Valid , Invalid };
+
+ State m_state;
+ Mode m_mode;
+ Direction m_direction;
+ UINT8 m_initVector[MAX_IV_SIZE];
+ UINT32 m_uRounds;
+ UINT8 m_expandedKey[_MAX_ROUNDS+1][4][4];
+public:
+ // Initializes the crypt session
+ // Returns RIJNDAEL_SUCCESS or an error code
+ int init(Mode mode,Direction dir,const UINT8 *key,KeyLength keyLen,UINT8 * initVector = 0);
+ // Input len is in BITS!
+ // Encrypts inputLen / 128 blocks of input and puts it in outBuffer
+ // outBuffer must be at least inputLen / 8 bytes long.
+ // Returns the encrypted buffer length in BITS or an error code < 0 in case of error
+ int blockEncrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer);
+ // Input len is in BYTES!
+ // outBuffer must be at least inputLen + 16 bytes long
+ // Returns the encrypted buffer length in BYTES or an error code < 0 in case of error
+ int padEncrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer);
+ // Input len is in BITS!
+ // outBuffer must be at least inputLen / 8 bytes long
+ // Returns the decrypted buffer length in BITS and an error code < 0 in case of error
+ int blockDecrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer);
+ // Input len is in BYTES!
+ // outBuffer must be at least inputLen bytes long
+ // Returns the decrypted buffer length in BYTES and an error code < 0 in case of error
+ int padDecrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer);
+protected:
+ void keySched(UINT8 key[_MAX_KEY_COLUMNS][4]);
+ void keyEncToDec();
+ void encrypt(const UINT8 a[16], UINT8 b[16]);
+ void decrypt(const UINT8 a[16], UINT8 b[16]);
+};
+
+#endif // COMPILE_CRYPT_SUPPORT
+
+#endif // _RIJNDAEL_H_
diff --git a/src/modules/setup/Makefile.am b/src/modules/setup/Makefile.am
new file mode 100644
index 00000000..73e3bcec
--- /dev/null
+++ b/src/modules/setup/Makefile.am
@@ -0,0 +1,26 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvisetup.la
+
+libkvisetup_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvisetup_la_SOURCES = libkvisetup.cpp setupwizard.cpp
+libkvisetup_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= setupwizard.h
+
+#datadir = $(picsdir)
+
+#data_DATA = kvi_dock.png
+
+#EXTRA_DIST = $(data_DATA)
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+setupwizard.cpp: setupwizard.moc
diff --git a/src/modules/setup/libkvisetup.cpp b/src/modules/setup/libkvisetup.cpp
new file mode 100644
index 00000000..7f5bad25
--- /dev/null
+++ b/src/modules/setup/libkvisetup.cpp
@@ -0,0 +1,158 @@
+//=============================================================================
+//
+// File : libkvisetup.cpp
+// Creation date : Sat Oct 6 02:08:24 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2004 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_module.h"
+
+#include "setupwizard.h"
+
+#include <qstring.h>
+#include <qfile.h>
+
+#include "kvi_options.h"
+#include "kvi_defaults.h"
+#include "kvi_app.h"
+#include "kvi_kvs_script.h"
+#include "kvi_kvs_variantlist.h"
+#include "kvi_window.h"
+#include "kvi_theme.h"
+#include "kvi_ircserverdb.h"
+
+// this will be choosen during the setup process
+QString g_szChoosenIncomingDirectory;
+//int g_iThemeToApply = THEME_APPLY_NONE;
+bool bNeedToApplyDefaults;
+unsigned int uPort;
+QString szHost;
+QString szUrl;
+QString szMircServers;
+QString szMircIni;
+
+
+
+
+// this is called by KviApp when no local kvirc directory has been found
+// we have nothing to rely on yet... (settings have not been loaded yet)
+KVIMODULEEXPORTFUNC bool setup_begin()
+{
+ // FIXME: try to guess the user's .kvirc directory
+ // and the preferred nickname from a previous installation
+
+ KviSetupWizard * w = new KviSetupWizard();
+ int retcode = w->exec();
+ delete w;
+ return (retcode == QDialog::Accepted);
+}
+
+
+// this is called just after the first startup
+// all the subsystems are up and running (we even have a nice console
+// to write on if needed).
+// all the options are loaded.
+KVIMODULEEXPORTFUNC void setup_finish()
+{
+ if(bNeedToApplyDefaults)
+ {
+ KVI_OPTION_STRING(KviOption_stringIncomingPath) = g_szChoosenIncomingDirectory;
+ // Reset the quit message and the real name... if they contain the KVIrc version
+ // then probably the user hasn't even edited them.
+ if(KVI_OPTION_STRING(KviOption_stringQuitMessage).find("KVIrc",0,false) != -1)
+ KVI_OPTION_STRING(KviOption_stringQuitMessage) = KVI_DEFAULT_QUIT_MESSAGE;
+ // We deserve to change the user's part message in something nice :)
+ KVI_OPTION_STRING(KviOption_stringPartMessage) = KVI_DEFAULT_PART_MESSAGE;
+
+ // FIXME: Should we also change these ?
+ // #define KVI_DEFAULT_CTCP_USERINFO_REPLY "I'm too lazy to edit this field."
+ // #define KVI_DEFAULT_AWAY_MESSAGE "I'm off to see the wizard."
+
+ // Apply the choosen default theme
+ QString szDir;
+/* switch(g_iThemeToApply)
+ {
+ case THEME_APPLY_HIRES:
+ g_pApp->getGlobalKvircDirectory(szDir,KviApp::Themes,"default.hires");
+ g_pApp->loadTheme(szDir);
+ break;
+ case THEME_APPLY_LORES:
+ g_pApp->getGlobalKvircDirectory(szDir,KviApp::Themes,"default.lores");
+ g_pApp->loadTheme(szDir);
+ break;
+ // default: no theme
+ }*/
+
+ g_pApp->getGlobalKvircDirectory(szDir,KviApp::Themes,"silverirc");
+ KviThemeInfo out;
+ KviTheme::load(szDir,out);
+
+ if(!szMircServers.isEmpty())
+ {
+ g_pIrcServerDataBase->loadFromMircIni(szMircServers,szMircIni,
+ KVI_OPTION_STRINGLIST(KviOption_stringlistRecentServers));
+ g_pApp->saveIrcServerDataBase();
+ }
+
+ g_pApp->loadDefaultScript();
+ if(!szUrl.isEmpty())
+ {
+ KviKvsVariantList * pParams = new KviKvsVariantList();
+ pParams->append(szUrl);
+ KviKvsScript::run("openurl $0",g_pActiveWindow,pParams);
+ delete pParams;
+ KVI_OPTION_BOOL(KviOption_boolShowServersConnectDialogOnStart) = TRUE;
+ } else if(!szHost.isEmpty()) {
+ KviKvsVariantList * pParams = new KviKvsVariantList();
+ pParams->append(szHost);
+ pParams->append((kvs_int_t)uPort);
+ KviKvsScript::run("server $0 $1",g_pActiveWindow,pParams);
+ delete pParams;
+ KVI_OPTION_BOOL(KviOption_boolShowServersConnectDialogOnStart) = TRUE;
+ }
+ }
+}
+
+static bool setup_module_init(KviModule *m)
+{
+ bNeedToApplyDefaults=true;
+ return true;
+}
+
+static bool setup_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+static bool setup_module_can_unload(KviModule *m)
+{
+ return true; // can be always unloaded...this module does basically nothing
+}
+
+KVIRC_MODULE(
+ "Setup wizard",
+ "1.0.0",
+ "Szymon Stefanek <pragma at kvirc dot net>" ,
+ "First-time-run setup wizard",
+ setup_module_init ,
+ setup_module_can_unload,
+ 0,
+ setup_module_cleanup
+)
diff --git a/src/modules/setup/setupwizard.cpp b/src/modules/setup/setupwizard.cpp
new file mode 100644
index 00000000..5b8c1ff7
--- /dev/null
+++ b/src/modules/setup/setupwizard.cpp
@@ -0,0 +1,1132 @@
+//===============================================================================
+//
+// File : setupwizard.cpp
+// Creation date : Sat Oct 6 02:06:53 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2004 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.
+//
+//==============================================================================
+
+bool g_bFoundMirc;
+
+#include "setupwizard.h"
+
+#include "kvi_app.h"
+#include "kvi_locale.h"
+#include "kvi_fileutils.h"
+#include "kvi_defaults.h"
+#include "kvi_msgbox.h"
+#include "kvi_tal_filedialog.h"
+#include "kvi_qstring.h"
+#include "kvi_env.h"
+#include "kvi_options.h"
+#include "kvi_config.h"
+
+#include <kvi_tal_textedit.h>
+#include <qmessagebox.h>
+#include <qdir.h>
+#include <qpushbutton.h>
+#include <qvalidator.h>
+#include <qtextcodec.h>
+#include <qlayout.h>
+#include "kvi_tal_hbox.h"
+
+#ifdef COMPILE_ON_WINDOWS
+ #include <windows.h>
+ #include <winnls.h> // for MultiByteToWideChar
+ #include <objbase.h> // CoCreateInstance , CoInitialize & CO.
+ #include <shlobj.h> // IShellLink IPersistFile & CO.
+#else
+ #include <unistd.h> // for symlink()
+#endif
+
+#ifdef COMPILE_USE_QT4
+ #include <QDesktopWidget>
+#endif
+
+// libkvisetup.cpp
+extern QString g_szChoosenIncomingDirectory;
+//extern int g_iThemeToApply;
+extern bool bNeedToApplyDefaults;
+extern unsigned int uPort;
+extern QString szHost;
+extern QString szUrl;
+extern QString szMircServers;
+extern QString szMircIni;
+
+#ifdef COMPILE_ON_WINDOWS
+ #define KVI_LOCAL_KVIRC_SUBDIRECTORY_NAME "KVIrc"
+#else
+ #define KVI_LOCAL_KVIRC_SUBDIRECTORY_NAME ".kvirc"
+#endif
+
+KviSetupPage::KviSetupPage(KviSetupWizard * w)
+: QWidget(w)
+{
+ QGridLayout * g = new QGridLayout(this);
+
+ //setBackgroundColor(QColor(255,0,0));
+
+ // we need this to set localized text on buttons (see QT doc/ KviTalWizard class)
+ w->KviTalWizard::backButton()->setText(__tr2qs("< &Back"));
+ w->KviTalWizard::nextButton()->setText(__tr2qs("&Next >"));
+ w->KviTalWizard::finishButton()->setText(__tr2qs("Finish"));
+ w->KviTalWizard::cancelButton()->setText(__tr2qs("Cancel"));
+ //w->KviTalWizard::helpButton()->setText(__tr2qs("Help"));
+
+ m_pPixmapLabel = new QLabel(this);
+ g->addWidget(m_pPixmapLabel,0,0);
+
+ m_pPixmapLabel->setPixmap(*(w->m_pLabelPixmap));
+ m_pPixmapLabel->setFixedSize(w->m_pLabelPixmap->size());
+ m_pPixmapLabel->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+ m_pPixmapLabel->setMargin(0);
+
+ g->setSpacing(8);
+ g->setMargin(0);
+
+ m_pVBox = new KviTalVBox(this);
+ m_pVBox->setSpacing(4);
+ m_pVBox->setMargin(0);
+ //m_pVBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding));
+ //m_pVBox->setBackgroundColor(QColor(0,80,0));
+ //m_pVBox->setMaximumHeight(450);
+ g->addWidget(m_pVBox,0,1);
+
+ g->setColStretch(1,1);
+
+ QLabel * l = new QLabel(m_pVBox);
+ l->setAlignment(Qt::AlignAuto | Qt::AlignTop);
+ /*
+ QString szHeader = "<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\" style=\"margin:0px;padding:0px;\" width=\"100%\"><tr><td bgcolor=\"#303030\">" \
+ "<h1><font color=\"#FFFFFF\">KVIrc " KVI_VERSION "</font></h1>" \
+ "</td></tr></table>";
+ */
+ QString szHeader = "<h1><font color=\"#FFFFFF\">&nbsp;KVIrc " KVI_VERSION "</font></h1>";
+ l->setText(szHeader);
+ l->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+ l->setAlignment(Qt::AlignAuto | Qt::AlignVCenter);
+ l->setMargin(0);
+ l->setBackgroundColor(QColor(48,48,48));
+
+ m_pTextLabel = new QLabel(m_pVBox);
+#ifdef COMPILE_USE_QT4
+ m_pTextLabel->setWordWrap(true);
+#endif
+ m_pTextLabel->setAlignment(Qt::AlignJustify | Qt::AlignTop);
+ m_pVBox->setStretchFactor(m_pTextLabel,1);
+}
+
+KviSetupPage::~KviSetupPage()
+{
+}
+
+
+KviSetupWizard::KviSetupWizard()
+: KviTalWizard(0)
+{
+ setModal(true);
+
+ g_bFoundMirc = false;
+ QString szLabelText;
+
+ QString szImagePath;
+ g_pApp->getGlobalKvircDirectory(szImagePath,KviApp::Pics,"kvi_setup_label.png");
+
+ m_pLabelPixmap = new QPixmap(szImagePath);
+ if(m_pLabelPixmap->isNull())
+ {
+ delete m_pLabelPixmap;
+ m_pLabelPixmap = new QPixmap(250,450);
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Welcome
+
+ m_pWelcome = new KviSetupPage(this);
+
+ // here we go...
+ QString szText = __tr2qs("<p>" \
+ "<h2>Welcome :)</h2>" \
+ "This is your first time running this version of KVIrc.<br>" \
+ "This wizard will guide you through the few steps " \
+ "required to complete the setup.<br><br>" \
+ "If you had a previous version of KVIrc installed, no worries. You will " \
+ "have a chance to preserve the old configuration." \
+ "</p>" \
+ "<p>Click \"<b>Next</b>\" to proceed.</p>");
+
+ m_pWelcome->m_pTextLabel->setText(szText);
+
+ addPage(m_pWelcome,__tr2qs("Welcome to KVIrc"));
+
+ setBackEnabled(m_pWelcome,false);
+ setHelpEnabled(m_pWelcome,false);
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // License
+#ifndef COMPILE_ON_WINDOWS //it have been already shown by installer
+ KviSetupPage * m_pLicense = new KviSetupPage(this);
+ m_pLicense->m_pTextLabel->setText(__tr2qs( \
+ "<p>All of the files in this distribution are covered by the GPL. " \
+ "In human terms this can be read as follows:<br>" \
+ "<ul>" \
+ "<li><b>KVIrc is free</b>, use it, have fun! <b>:)</b></li>" \
+ "<li>If you use <b>any</b> part of KVIrc in your own project, you <b>must</b> release that project under the same license.</li>" \
+ "</ul></p>" \
+ "<p>The \"legalese\" version of the license is shown in the box below.</p>"));
+
+ KviTalTextEdit * ed = new KviTalTextEdit(m_pLicense->m_pVBox);
+ ed->setReadOnly(true);
+ ed->setWordWrap(KviTalTextEdit::NoWrap);
+ QString szLicense;
+ QString szLicensePath;
+ g_pApp->getGlobalKvircDirectory(szLicensePath,KviApp::License,"EULA");
+ if(!KviFileUtils::loadFile(szLicensePath,szLicense))
+ {
+ szLicense = __tr("Oops... can't find the license file.\n" \
+ "It MUST be included in the distribution...\n" \
+ "Please report to <pragma at kvirc dot net>");
+ }
+ ed->setText(szLicense);
+
+ m_pLicense->m_pVBox->setStretchFactor(ed,1);
+
+ addPage(m_pLicense,__tr2qs("Dreaded License Agreement"));
+
+ setHelpEnabled(m_pLicense,false);
+
+ setCaption(__tr2qs("KVIrc Setup"));
+#else
+ m_pLicense = 0;
+#endif
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Directories
+
+ m_pDirectory = new KviSetupPage(this);
+
+ m_pDirectory->m_pTextLabel->setText(__tr2qs("<p>Please choose a folder for " \
+ "KVIrc to store its settings and other data, and another for downloaded files. " \
+ "Make sure that you have permission to write to both folders.<br><br>" \
+ "The suggested locations are fine in most cases, so if you don't know what " \
+ "is this about, just click \"<b>Next</b>\".<br><br>" \
+ "If you had a previous version of KVIrc installed, you can choose " \
+ "the existing directory for the settings, and your configuration " \
+ "will be preserved." \
+ "</p>"));
+
+ addPage(m_pDirectory,__tr2qs("Application Folders"));
+
+ QString tmp;
+
+ m_pDirButtonGroup = new KviTalVButtonGroup(__tr2qs("Store configuration in folder"),m_pDirectory->m_pVBox);
+ m_pDirUsePrev = new QRadioButton(__tr2qs("Use settings folder from previous installation"),m_pDirButtonGroup);
+ connect(m_pDirUsePrev,SIGNAL(clicked()),this,SLOT(oldDirClicked()));
+
+ m_pOldPathBox = new KviTalHBox(m_pDirButtonGroup);
+ m_pOldDataPathEdit = new QLineEdit(m_pOldPathBox);
+ connect(m_pOldDataPathEdit,SIGNAL(textChanged ( const QString & )),this,SLOT(oldDataTextChanged ( const QString & )));
+
+ QPushButton * pb = new QPushButton(__tr2qs("&Browse..."),m_pOldPathBox);
+ connect(pb,SIGNAL(clicked()),this,SLOT(chooseOldDataPath()));
+ m_pOldPathBox->setSpacing(3);
+ m_pOldPathBox->setStretchFactor(m_pOldDataPathEdit,1);
+
+ m_pDirUseNew = new QRadioButton(__tr2qs("Use new settings folder"),m_pDirButtonGroup);
+ connect(m_pDirUseNew,SIGNAL(clicked()),this,SLOT(newDirClicked()));
+
+ QLabel* l = new QLabel(m_pDirButtonGroup);
+ l->setText(__tr2qs("Settings folder:"));
+
+ m_pNewPathBox = new KviTalHBox(m_pDirButtonGroup);
+ m_pDataPathEdit = new QLineEdit(m_pNewPathBox);
+
+ pb = new QPushButton(__tr2qs("&Browse..."),m_pNewPathBox);
+ connect(pb,SIGNAL(clicked()),this,SLOT(chooseDataPath()));
+
+ m_pNewPathBox->setSpacing(3);
+ m_pNewPathBox->setStretchFactor(m_pDataPathEdit,1);
+
+#ifdef COMPILE_ON_WINDOWS
+ tmp = QTextCodec::codecForLocale()->toUnicode(getenv( "APPDATA" ));
+ if(tmp.isEmpty())
+ tmp = QDir::homeDirPath();
+#else
+ tmp = QDir::homeDirPath();
+#endif //COMPILE_ON_WINDOWS
+ KviQString::ensureLastCharIs(tmp,KVI_PATH_SEPARATOR_CHAR);
+ tmp.append(KVI_LOCAL_KVIRC_SUBDIRECTORY_NAME);
+ KviFileUtils::adjustFilePath(tmp);
+ m_pDataPathEdit->setText(tmp);
+
+
+
+ l = new QLabel(m_pDirButtonGroup);
+ l->setText(__tr2qs("Download files to folder:"));
+
+
+ m_pNewIncomingBox = new KviTalHBox(m_pDirButtonGroup);
+
+ m_pIncomingPathEdit = new QLineEdit(m_pNewIncomingBox);
+
+ pb = new QPushButton(__tr2qs("&Browse..."),m_pNewIncomingBox);
+ connect(pb,SIGNAL(clicked()),this,SLOT(chooseIncomingPath()));
+
+ m_pNewIncomingBox->setSpacing(3);
+ m_pNewIncomingBox->setStretchFactor(m_pIncomingPathEdit,1);
+
+ tmp = QDir::homeDirPath();
+ KviQString::ensureLastCharIs(tmp,KVI_PATH_SEPARATOR_CHAR);
+ tmp.append(KVI_DEFAULT_INCOMING_SUBDIRECTORY_NAME);
+ KviFileUtils::adjustFilePath(tmp);
+ m_pIncomingPathEdit->setText(tmp);
+
+ m_pDirUseNew->toggle();
+ newDirClicked();
+
+#ifdef COMPILE_ON_WINDOWS
+ m_pDirMakePortable = new QRadioButton(__tr2qs("All settings in shared program folder (portable)")
+ ,m_pDirButtonGroup);
+#endif
+ // Pragma: Unused, takes only space.
+ //m_pDirRestore = new QRadioButton(__tr2qs("Restore from backup archive"),m_pDirButtonGroup);
+ //m_pDirRestore->setEnabled(FALSE);
+
+ //l = new QLabel(m_pDirectory->m_pVBox,"<b> </b>");
+
+ //m_pDirectory->m_pVBox->setStretchFactor(m_pDirectory->m_pTextLabel,1);
+
+ setHelpEnabled(m_pDirectory,false);
+
+ connect(m_pDataPathEdit,SIGNAL(textChanged ( const QString & )),this,SLOT(newDataTextChanged ( const QString & )));
+ connect(m_pIncomingPathEdit,SIGNAL(textChanged ( const QString & )),this,SLOT(newIncomingTextChanged ( const QString & )));
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Identity
+
+ m_pIdentity = new KviSetupPage(this);
+
+ m_pIdentity->m_pTextLabel->setText(__tr2qs("Please choose a Nickname.<br><br>" \
+ "Your nickname is the name that other IRC users will know you by. " \
+ "It can't contain spaces or punctuation. Some IRC networks will shorten your nickname if it is more than 32 characters " \
+ "long.<br><br>"
+ "If in doubt, just enter the first nick that comes to mind. " \
+ "You will be able to change it later in the Identity properties, or with the /NICK command."));
+
+ QString nick;
+ char * nnn = kvi_getenv("USER");
+ if(nnn)nick = nnn;
+ else nick = "newbie";
+ if(nick.isEmpty())nick = "newbie";
+ if(nick == "root")nick = "newbie";
+//m_pIdentity->m_pVBox
+//__tr2qs("Basic Properties")
+ KviTalGroupBox * gbox = new KviTalGroupBox(1,Qt::Horizontal,QString(),m_pIdentity->m_pVBox);
+
+ m_pNickSelector = new KviStringSelector(gbox,__tr2qs("Nickname:"),&(KVI_OPTION_STRING(KviOption_stringNickname1)),true);
+ m_pNickSelector->setMinimumLabelWidth(120);
+
+ QValidator * v = new QRegExpValidator(QRegExp("[^-0-9 ][^ ]*"),gbox);
+ m_pNickSelector->setValidator(v);
+
+ QString szOptionalCtcpUserInfo = __tr2qs("This field is optional and will appear as part of the CTCP USERINFO reply.");
+ QString szCenterBegin("<center>");
+ QString szCenterEnd("</center>");
+ QString szTrailing = "<br><br>" + szOptionalCtcpUserInfo + szCenterEnd;
+
+ gbox = new KviTalGroupBox(1,Qt::Horizontal,__tr2qs("Profile"),m_pIdentity->m_pVBox);
+
+ m_pRealNameSelector = new KviStringSelector(gbox,__tr2qs("Real name:"),&(KVI_OPTION_STRING(KviOption_stringRealname)),true);
+ m_pRealNameSelector->setMinimumLabelWidth(120);
+
+ KviTalHBox* hb = new KviTalHBox(gbox);
+ hb->setSpacing(4);
+
+ l = new QLabel(__tr2qs("Age:"),hb);
+ l->setMinimumWidth(120);
+
+ m_pAgeCombo = new QComboBox(hb);
+
+ m_pAgeCombo->insertItem(__tr2qs("Unspecified"));
+ unsigned int i;
+ for(i=1;i<120;i++)
+ {
+ QString tmp;
+ tmp.setNum(i);
+ m_pAgeCombo->insertItem(tmp);
+ }
+
+ bool bOk;
+ i = KVI_OPTION_STRING(KviOption_stringCtcpUserInfoAge).toUInt(&bOk);
+ if(!bOk)i = 0;
+ if(i > 120)i = 120;
+ m_pAgeCombo->setCurrentItem(i);
+
+ hb->setStretchFactor(m_pAgeCombo,1);
+
+
+ hb = new KviTalHBox(gbox);
+ hb->setSpacing(4);
+
+ l = new QLabel(__tr2qs("Gender:"),hb);
+ l->setMinimumWidth(120);
+
+ m_pGenderCombo = new QComboBox(hb);
+
+ m_pGenderCombo->insertItem(__tr2qs("Unspecified"));
+ m_pGenderCombo->insertItem(__tr2qs("Female"));
+ m_pGenderCombo->insertItem(__tr2qs("Male"));
+
+ if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender),"Male"))
+ m_pGenderCombo->setCurrentItem(2);
+ else if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender),"Female"))
+ m_pGenderCombo->setCurrentItem(1);
+ else
+ m_pGenderCombo->setCurrentItem(0);
+
+ hb->setStretchFactor(m_pGenderCombo,1);
+
+ m_pLocationSelector = new KviStringSelector(gbox,__tr2qs("Location:"),&(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoLocation)),true);
+ m_pLocationSelector->setMinimumLabelWidth(120);
+
+ m_pLanguagesSelector = new KviStringSelector(gbox,__tr2qs("Languages:"),&(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoLanguages)),true);
+ m_pLanguagesSelector->setMinimumLabelWidth(120);
+
+ //m_pOtherInfoSelector = new KviStringSelector(gbox,__tr2qs("Other:"),&(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoOther)),true);
+ //m_pOtherInfoSelector->setMinimumLabelWidth(120);
+
+ addPage(m_pIdentity,__tr2qs("Identity"));
+
+ //l = new QLabel(m_pIdentity->m_pVBox,"<b> </b>");
+
+ setHelpEnabled(m_pIdentity,false);
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Default theme
+/* m_pTheme = new KviSetupPage(this);
+ m_pTheme->m_pTextLabel->setText(__tr2qs( \
+ "<p>Here you can choose the default appearance of KVIrc.<br><br>" \
+ "The Fancy Theme uses icons, a transparent background and a lot of colors. " \
+ "The Minimalist Theme is designed for low-color displays " \
+ "or for \"console\" extremists; it's more or less white text on a black background.<br><br>" \
+ "If you had a previous version of KVIrc installed, you can choose to not apply any theme " \
+ "in order to preserve your current visual settings.<br><br>" \
+ "If you don't know what to choose, just use the default.</p>"));
+
+ m_pThemeButtonGroup = new KviTalVButtonGroup(m_pTheme->m_pVBox);
+
+ KviTalHBox* pThemesHb = new KviTalHBox(m_pThemeButtonGroup);
+
+ KviTalVBox* pThemesVb = new KviTalVBox(pThemesHb);
+
+ QString szThemeImagePath;
+ g_pApp->getGlobalKvircDirectory(szThemeImagePath,KviApp::Pics,"kvi_setup_theme_hires.png");
+
+ QPixmap* pHiResPixmap = new QPixmap(szThemeImagePath);
+ if(pHiResPixmap->isNull())
+ {
+ delete pHiResPixmap;
+ pHiResPixmap= new QPixmap(250,200);
+ }
+
+ QLabel* pPixmapLabelHiRes = new QLabel(pThemesVb);
+
+ pPixmapLabelHiRes->setPixmap(*pHiResPixmap);
+ pPixmapLabelHiRes->setFixedSize(pHiResPixmap->size());
+ pPixmapLabelHiRes->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+ pPixmapLabelHiRes->setMargin(0);
+
+ m_pThemeHiRes = new QRadioButton(__tr2qs("&Fancy Theme"),pThemesVb);
+
+ pThemesVb = new KviTalVBox(pThemesHb);
+ g_pApp->getGlobalKvircDirectory(szThemeImagePath,KviApp::Pics,"kvi_setup_theme_lowres.png");
+ QPixmap* pLowResPixmap = new QPixmap(szThemeImagePath);
+ if(pLowResPixmap->isNull())
+ {
+ delete pLowResPixmap;
+ pLowResPixmap= new QPixmap(250,200);
+ }
+
+ QLabel* pPixmapLabelLowRes = new QLabel(pThemesVb);
+
+ pPixmapLabelLowRes->setPixmap(*pLowResPixmap);
+ pPixmapLabelLowRes->setFixedSize(pLowResPixmap->size());
+ pPixmapLabelLowRes->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+ pPixmapLabelLowRes->setMargin(0);
+
+ m_pThemeLoRes = new QRadioButton(__tr2qs("&Minimalist Theme"),pThemesVb);
+ m_pThemeNone = new QRadioButton(__tr2qs("&Don't apply any theme"),m_pThemeButtonGroup);
+ m_pThemeButtonGroup->insert(m_pThemeHiRes);
+ m_pThemeButtonGroup->insert(m_pThemeLoRes);
+
+ m_pThemeHiRes->setChecked(true);
+
+ addPage(m_pTheme,__tr2qs("Default Theme"));
+
+ setHelpEnabled(m_pTheme,false);*/
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Desktop integration
+
+ m_pDesktopIntegration = new KviSetupPage(this);
+
+ szText = __tr2qs( \
+ "<p>" \
+ "Here you can choose how much KVIrc will integrate with " \
+ "your system." \
+ "<br><br>" \
+ "The default settings are fine for most users so if " \
+ "you're in doubt just click \"<b>Next</b>\" and go to the next screen." \
+ "</p>");
+
+ m_pDesktopIntegration->m_pTextLabel->setText(szText);
+
+ addPage(m_pDesktopIntegration,__tr2qs("Desktop Integration"));
+
+#ifdef COMPILE_ON_WINDOWS
+ m_pCreateUrlHandlers = new QCheckBox(__tr2qs("Make KVIrc default IRC client"),m_pDesktopIntegration->m_pVBox);
+ m_pCreateUrlHandlers->setChecked(true);
+#endif
+#ifdef COMPILE_KDE_SUPPORT
+ m_pCreateDesktopShortcut = new QCheckBox(__tr2qs("Create desktop shortcut"),m_pDesktopIntegration->m_pVBox);
+ m_pCreateDesktopShortcut->setChecked(true);
+#endif
+
+#ifdef COMPILE_ON_WINDOWS
+ m_pUseMircServerList = new QRadioButton(__tr2qs("Import server list from mIRC"),m_pDesktopIntegration->m_pVBox);
+ m_pUseMircServerList->setEnabled(false);
+#endif
+
+ setHelpEnabled(m_pDesktopIntegration,false);
+
+ /*
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Server config
+ m_pServers = new KviSetupPage(this);
+
+ m_pServers->m_pTextLabel->setText(__tr2qs( \
+ "Now you should specify an IRC server, to be connected to it"));
+
+
+ m_pServersButtonGroup = new KviTalVButtonGroup(__tr2qs("Choose a server to connect"),m_pServers->m_pVBox);
+
+ m_pServersChooseFromList = new QRadioButton(__tr2qs("Choose from built-in server list"),m_pServersButtonGroup);
+
+ m_pServersSpecifyManually = new QRadioButton(__tr2qs("Specify server manually"),m_pServersButtonGroup);
+ hb = new KviTalHBox(m_pServersButtonGroup);
+
+ m_uServerPort=6667;
+ m_pServerHostSelector = new KviStringSelector(hb,__tr2qs("Server:"),&m_szServerHost,true);
+ m_pServerPortSelector = new KviUIntSelector(hb,__tr2qs("Port:"),&m_uServerPort,1,65536,6667,true,false);
+
+
+ m_pServersOpenIrcUrl = new QRadioButton(__tr2qs("Open irc:// or irc6:// URL"),m_pServersButtonGroup);
+ m_szServerUrl="irc://";
+ m_pServerUrlSelector = new KviStringSelector(m_pServersButtonGroup,__tr2qs("URL:"),&m_szServerUrl,true);
+
+ */
+/*
+ m_pServersLoadConfig = new QRadioButton(__tr2qs("Use server config"),m_pServersButtonGroup);
+ m_pServersLoadConfig->setEnabled(FALSE);
+ m_pServerConfigSelector = new KviFileSelector(m_pServersButtonGroup,__tr2qs("Config file:"),&m_szServerConfigFile,true);
+ m_pServerConfigSelector->setEnabled(FALSE);
+*/
+ /*
+ m_pServersChooseFromList->toggle();
+ addPage(m_pServers,__tr2qs("Choose a server to connect"));
+ */
+ setFinishEnabled(m_pDesktopIntegration,true);
+ setHelpEnabled(m_pDesktopIntegration,false);
+
+ // Preconfigured values
+#ifdef COMPILE_ON_WINDOWS
+ QString szTmp;
+ g_pApp->getGlobalKvircDirectory(szTmp,KviApp::Config,"preinstalled.kvc");
+ if(KviFileUtils::fileExists(szTmp))
+ {
+ KviConfig cfg(szTmp,KviConfig::Read);
+ cfg.setGroup("Setup");
+ if(cfg.readBoolEntry("hideServerList",FALSE))
+ {
+ //setPageEnabled(m_pServers,false);
+ //setFinishEnabled(m_pIdentity,true);
+ KVI_OPTION_BOOL(KviOption_boolShowChannelsJoinOnIrc) = false;
+ KVI_OPTION_BOOL(KviOption_boolShowServersConnectDialogOnStart) = false;
+ }
+ int iDir;
+ iDir=cfg.readIntEntry("settingsDir",-1);
+ if(iDir>0) {
+ switch(iDir)
+ {
+ case 1:
+ m_pDirUseNew->toggle();
+ setPageEnabled(m_pDirectory,false);
+ break;
+ case 2:
+ m_pDirMakePortable->toggle();
+ setPageEnabled(m_pDirectory,false);
+ break;
+ }
+ }
+ }
+
+ //mIRC import
+ #define QUERY_BUFFER 2048
+ char* buffer;
+ DWORD len = QUERY_BUFFER;
+ buffer = (char*)malloc(len*sizeof(char));
+ HKEY hKey;
+ QString szMircDir;
+
+ if(RegOpenKeyEx(HKEY_CLASSES_ROOT,"ChatFile\\DefaultIcon",0,KEY_READ,&hKey) == ERROR_SUCCESS )
+ {
+ if( RegQueryValueEx( hKey,0,0,0,(LPBYTE)buffer,&len) == ERROR_SUCCESS)
+ {
+ szMircDir = QString::fromLocal8Bit(buffer,len);
+
+ szMircDir.remove('"');
+ QString szMircFile = KviFileUtils::extractFileName(szMircDir);
+ szMircFile = szMircFile.left(szMircFile.length()-4); //cut off ".exe"
+ szMircDir = KviFileUtils::extractFilePath(szMircDir);
+
+ szMircIni = szMircDir + "/" + szMircFile + ".ini";
+
+ if(!KviFileUtils::fileExists(szMircIni))
+ szMircIni = szMircDir + "/mirc.ini";
+
+ if(!KviFileUtils::fileExists(szMircIni))
+ szMircIni = szMircDir + "/pirc.ini";
+
+ if(KviFileUtils::fileExists(szMircIni)){
+ KviConfig cfg(szMircIni,KviConfig::Read,true);
+ if(cfg.hasGroup("mirc"))
+ {
+ g_bFoundMirc = true;
+ cfg.setGroup("mirc");
+ m_pNickSelector->setText(cfg.readQStringEntry("nick",KVI_OPTION_STRING(KviOption_stringNickname1)));
+ m_pRealNameSelector->setText(cfg.readQStringEntry("user",KVI_OPTION_STRING(KviOption_stringRealname)));
+ KVI_OPTION_STRING(KviOption_stringNickname2) =
+ cfg.readQStringEntry("anick",KVI_OPTION_STRING(KviOption_stringNickname2));
+ KVI_OPTION_STRING(KviOption_stringUsername) =
+ cfg.readQStringEntry("email",KVI_OPTION_STRING(KviOption_stringUsername)).section('@',0,0);
+
+ if(cfg.hasGroup("files"))
+ {
+ m_szMircServerIniFile = cfg.readQStringEntry("servers","servers.ini");
+ m_szMircServerIniFile.prepend('/');
+ m_szMircServerIniFile.prepend(szMircDir);
+ if(KviFileUtils::fileExists(m_szMircServerIniFile))
+ {
+ m_pUseMircServerList->setEnabled(true);
+ m_pUseMircServerList->setChecked(true);
+ }
+ }
+ //KviMessageBox::information(__tr2qs("Setup found existing mIRC installation. It will try to import "
+ // "some of mIRC settings and serverlist. If you don't want to do it, unselect import in setup pages"));
+ }
+ }
+ }
+ }
+ free(buffer);
+
+#endif
+
+ //setMinimumSize(630,450);
+}
+
+
+KviSetupWizard::~KviSetupWizard()
+{
+ delete m_pLabelPixmap;
+}
+
+void KviSetupWizard::showEvent(QShowEvent *e)
+{
+ int w = QApplication::desktop()->width();
+ int h = QApplication::desktop()->height();
+
+ int ww = width();
+ int wh = height();
+
+ if(w < 800)
+ {
+ // 640x480
+ if(ww < 630)ww = 630;
+ } else {
+ if(ww < 770)ww = 770;
+ }
+
+ //wh = sizeHint().height();
+
+ setGeometry((w - ww) / 2,(h - wh) / 2,ww,wh);
+
+ KviTalWizard::showEvent(e);
+}
+
+void KviSetupWizard::oldDirClicked()
+{
+ m_pOldPathBox->setEnabled(true);
+ m_pNewPathBox->setEnabled(false);
+ m_pNewIncomingBox->setEnabled(false);
+
+ if(m_pIdentity) setPageEnabled(m_pIdentity,false);
+// if(m_pTheme) setPageEnabled(m_pTheme,false);
+ if(m_pServers) setPageEnabled(m_pServers,false);
+
+ if(m_pOldDataPathEdit->text().isEmpty()) setNextEnabled(m_pDirectory,false);
+ else setNextEnabled(m_pDirectory,true);
+}
+
+void KviSetupWizard::oldDataTextChanged ( const QString & str)
+{
+ setNextEnabled(m_pDirectory,!str.isEmpty());
+}
+
+void KviSetupWizard::newDataTextChanged ( const QString & str)
+{
+ setNextEnabled(m_pDirectory,!str.isEmpty() && !m_pIncomingPathEdit->text().isEmpty());
+}
+
+void KviSetupWizard::newIncomingTextChanged ( const QString & str)
+{
+ setNextEnabled(m_pDirectory,!str.isEmpty() && !m_pDataPathEdit->text().isEmpty());
+}
+
+void KviSetupWizard::newDirClicked()
+{
+ m_pOldPathBox->setEnabled(false);
+ m_pNewPathBox->setEnabled(true);
+ m_pNewIncomingBox->setEnabled(true);
+
+ if(m_pIdentity) setPageEnabled(m_pIdentity,true);
+// if(m_pTheme) setPageEnabled(m_pTheme,true);
+ if(m_pServers) setPageEnabled(m_pServers,true);
+
+ if(m_pDataPathEdit->text().isEmpty() || m_pIncomingPathEdit->text().isEmpty()) setNextEnabled(m_pDirectory,false);
+ else setNextEnabled(m_pDirectory,true);
+}
+void KviSetupWizard::chooseOldDataPath()
+{
+ QString szBuffer = KviTalFileDialog::getExistingDirectoryPath(m_pDataPathEdit->text(),__tr2qs("Choose an Old Configuration Folder - KVIrc Setup"),0);
+ if(!szBuffer.isEmpty())
+ {
+ KviQString::ensureLastCharIs(szBuffer,KVI_PATH_SEPARATOR_CHAR);
+ if(!g_pApp->checkLocalKvircDirectory(szBuffer))
+ {
+ if(
+ QMessageBox::question(
+ this,
+ __tr2qs("Do not overwrite folder? - KVIrc"),
+ tr("A folder %1 seems to be not a valid KVIrc settings folder."
+ "Do you want to use it anyway?")
+ .arg( szBuffer ),
+ __tr2qs("&Yes"), __tr2qs("&No"),
+ QString::null, 0, 1 ) == 0
+ ) {
+ m_pOldDataPathEdit->setText(szBuffer);
+ }
+ } else {
+ m_pOldDataPathEdit->setText(szBuffer);
+ }
+ }
+}
+
+void KviSetupWizard::chooseDataPath()
+{
+ QString szBuffer = KviTalFileDialog::getExistingDirectoryPath(m_pDataPathEdit->text(),__tr2qs("Choose a Configuration Folder - KVIrc Setup"),0);
+ if(!szBuffer.isEmpty())
+ {
+ KviQString::ensureLastCharIs(szBuffer,KVI_PATH_SEPARATOR_CHAR);
+ m_pDataPathEdit->setText(szBuffer);
+ }
+}
+
+void KviSetupWizard::chooseIncomingPath()
+{
+ //QString szBuffer = QFileDialog::getExistingDirectory(m_pIncomingPathEdit->text(),0,0,__tr2qs("Choose the download folder"));
+ QString szBuffer = KviTalFileDialog::getExistingDirectoryPath(m_pIncomingPathEdit->text(),__tr2qs("Choose a Download Folder - KVIrc Setup"),0);
+ if(!szBuffer.isEmpty())
+ {
+ m_pIncomingPathEdit->setText(szBuffer);
+ }
+}
+
+
+void KviSetupWizard::makeLink()
+{
+#ifdef COMPILE_ON_WINDOWS
+ // Let's make a link on the desktop :)
+ // You need this horrible snippet of code to create a shortcut!!!!
+ //
+ // you have to:
+ // - dig in the registry ,
+ // - trigger the entire COM subsystem
+ // - bring up a couple of OLE interfaces....
+ // - use some obscure functions like MultiByteToWideChar
+ // - and the finally drop the entire OLE+COM interface in the garbadge
+ // ...
+ // Isn't this horrible ? (compared to symlink()!)
+ //
+
+ // Well..let's go (please note that we don't handle most possible errors!
+ // otherwise there would be 150 lines for a stupid symlink!)
+
+ HKEY hCU;
+ DWORD lpType;
+ ULONG ulSize = MAX_PATH;
+ char szLink[MAX_PATH];
+
+ // Dig in the registry looking up the Desktop path
+ if(RegOpenKeyEx(HKEY_CURRENT_USER,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
+ 0,KEY_QUERY_VALUE,&hCU) == ERROR_SUCCESS)
+ {
+ RegQueryValueEx(hCU,"Desktop",NULL,&lpType,
+ (unsigned char *)&szLink,&ulSize);
+ RegCloseKey(hCU);
+ }
+
+ // Build our paths
+ QString szLinkTarget = szLink;
+ szLinkTarget.append("\\kvirc.lnk");
+
+ QString szKvircExec = g_pApp->m_szGlobalKvircDir;
+ szKvircExec.append("\\kvirc.exe");
+
+ // Trigger a horrible machinery
+ CoInitialize(NULL); // we need COM+OLE
+
+ // Fiddle with an obscure shell interface
+ IShellLink* psl;
+
+ // Get a pointer to the IShellLink interface: this is kinda ugly :)
+ if(CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,
+ IID_IShellLink,(void **)&psl) == S_OK)
+ {
+ // just for fun , lookup another shell interface
+
+ IPersistFile* ppf;
+
+ // Query IShellLink for the IPersistFile interface for
+ // saving the shell link in persistent storage.
+ if(psl->QueryInterface(IID_IPersistFile,(void **)&ppf) == S_OK)
+ {
+ WORD wsz[MAX_PATH];
+ // Set the path to the shell link target.
+ psl->SetPath(QTextCodec::codecForLocale()->fromUnicode(szKvircExec).data());
+ // Set the description of the shell link.
+ psl->SetDescription("kvirc");
+ // Ensure string is ANSI.
+ MultiByteToWideChar(CP_ACP,0,QTextCodec::codecForLocale()->fromUnicode(szLinkTarget).data(),-1,(LPWSTR)wsz,MAX_PATH);
+ // Save the link via the IPersistFile::Save method.
+ ppf->Save((LPCOLESTR)wsz,true);
+ ppf->Release();
+ }
+ psl->Release();
+ }
+ // And throw OLE & Co. in the garbadge
+ CoUninitialize();
+#endif //COMPILE_ON_WINDOWS
+
+#ifdef COMPILE_KDE_SUPPORT
+ QString tmp = QDir::homeDirPath();
+ KviQString::ensureLastCharIs(tmp,KVI_PATH_SEPARATOR_CHAR);
+ tmp.append("Desktop");
+ KviQString::ensureLastCharIs(tmp,KVI_PATH_SEPARATOR_CHAR);
+ tmp.append("kvirc.desktop");
+
+ QString contents = "[Desktop Entry]\n" \
+ "GenericName=IRC Client\n" \
+ "Comment=Connect to Internet Relay Chat\n" \
+ "Exec=kvirc -m %u\n" \
+ "Icon=kvirc\n" \
+ "MapNotify=true\n" \
+ "Name=KVIrc 3\n" \
+ "Terminal=false\n" \
+ "Type=Application\n" \
+ "X-KDE-SubstituteUID=false\n";
+
+ KviFileUtils::writeFile(tmp,contents,false);
+#endif //COMPILE_KDE_SUPPORT
+
+}
+
+void KviSetupWizard::setUrlHandlers()
+{
+#ifdef COMPILE_ON_WINDOWS
+ QString szReg = "REGEDIT4\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc]\r\n" \
+ "@=\"URL:IRC Protocol\"\r\n" \
+ "\"IRC Protocol\"=\"http://www.kvirc.net/\"\r\n" \
+ "\"EditFlags\"=hex:02,00,00,00\r\n" \
+ "\"URL Protocol\"=""\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc\\DefaultIcon]\r\n" \
+ "@=\"\\\"@KVIRCEXECUTABLE@\\\"\"\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc\\shell]\r\n" \
+ "@=\"\"\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc\\shell\\open]\r\n" \
+ "\"EditFlags\"=hex:01,00,00,00\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc\\shell\\open\\command]\r\n" \
+ "@=\"\\\"@KVIRCEXECUTABLE@\\\" %1\"\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc6]\r\n" \
+ "@=\"URL:IRC6 Protocol\"\r\n" \
+ "\"IRC6 Protocol\"=\"http://www.kvirc.net/\"\r\n" \
+ "\"EditFlags\"=hex:02,00,00,00\r\n" \
+ "\"URL Protocol\"=""\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc6\\DefaultIcon]\r\n" \
+ "@=\"\\\"@KVIRCEXECUTABLE@\\\"\"\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc6\\shell]\r\n" \
+ "@=\"\"\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc6\\shell\\open]\r\n" \
+ "\"EditFlags\"=hex:01,00,00,00\r\n" \
+ "\r\n" \
+ "[HKEY_CLASSES_ROOT\\irc6\\shell\\open\\command]\r\n" \
+ "@=\"\\\"@KVIRCEXECUTABLE@\\\" %1\"\r\n";
+
+ QString szKvircExec = g_pApp->m_szGlobalKvircDir;
+ szKvircExec.append("\\kvirc.exe");
+ szKvircExec.replace("\\","\\\\");
+
+ szReg.replace("@KVIRCEXECUTABLE@",QTextCodec::codecForLocale()->fromUnicode(szKvircExec));
+
+ QString szRegFile = g_pApp->m_szGlobalKvircDir;
+ szRegFile.append("\\kvirc.reg");
+
+ KviFileUtils::writeFile(szRegFile,szReg,false);
+
+ QString szCmd = "regedit /S \"";
+ szCmd += szRegFile;
+ szCmd += "\"";
+
+ WinExec(QTextCodec::codecForLocale()->fromUnicode(szCmd).data(),SW_SHOW);
+#endif
+}
+
+void KviSetupWizard::reject()
+{
+ if(QMessageBox::warning(this,__tr2qs("Abort Setup - KVIrc Setup"),
+ __tr2qs("You have chosen to abort the setup.<br>KVIrc cannot run until you complete this procedure.<br><br>Do you really wish to abort?"),
+ QMessageBox::Yes,QMessageBox::No|QMessageBox::Default|QMessageBox::Escape) != QMessageBox::Yes)return;
+
+ KviTalWizard::reject();
+}
+
+void KviSetupWizard::accept()
+{
+ QString szDir;
+
+ if(m_pDirUsePrev->isOn())
+ {
+ bNeedToApplyDefaults=false;
+ g_pApp->m_szLocalKvircDir = m_pOldDataPathEdit->text();
+ } else {
+ bNeedToApplyDefaults=true;
+ if(m_pDirUseNew->isOn()) {
+ szDir = m_pDataPathEdit->text();
+ }
+#ifdef COMPILE_ON_WINDOWS
+ else { //portable
+ szDir = g_pApp->applicationDirPath()+KVI_PATH_SEPARATOR_CHAR+"Settings";
+ }
+#endif
+
+ KviFileUtils::adjustFilePath(szDir);
+ KviQString::ensureLastCharIs(szDir,KVI_PATH_SEPARATOR_CHAR);
+ if(!KviFileUtils::directoryExists(szDir))
+ {
+ if(!KviFileUtils::makeDir(szDir))
+ {
+ KviMessageBox::warning(__tr("Cannot create directory %s.\n" \
+ "You may not have write permission " \
+ "for that path. Please go back and choose another directory."));
+ setCurrentPage(m_pDirectory);
+ return;
+ }
+ } /*else {
+ kvi_infoBox(__tr("Kvirc setup"),
+ __tr("The directory '%s' already exists.\n" \
+ "(maybe from a previous Kvirc installation)\n"\
+ "If you experience any problems try deleting the old directory:\n" \
+ "the setup program will be started automatically again."),szDir.ptr());
+ }*/
+
+ g_pApp->m_szLocalKvircDir = szDir;
+ KviFileUtils::adjustFilePath(g_pApp->m_szLocalKvircDir);
+
+ if(m_pDirUseNew->isOn()) {
+ szDir = m_pIncomingPathEdit->text();
+ }
+#ifdef COMPILE_ON_WINDOWS
+ else { //portable
+ szDir = g_pApp->applicationDirPath()+KVI_PATH_SEPARATOR_CHAR+"Downloads";
+ }
+#endif
+
+ KviFileUtils::adjustFilePath(szDir);
+ if(!KviFileUtils::directoryExists(szDir))
+ {
+ if(!KviFileUtils::makeDir(szDir))
+ {
+ KviMessageBox::warning(__tr("Cannot create directory %s.\n" \
+ "You may not have write permission " \
+ "for that path. Please go back and choose another directory."));
+ setCurrentPage(m_pDirectory);
+ return;
+ }
+ }
+
+ g_szChoosenIncomingDirectory = szDir;
+
+#ifndef COMPILE_ON_WINDOWS
+ // Make local->global link
+ QString localPath = QString("%1/global").arg(g_pApp->m_szLocalKvircDir);
+ unlink(QTextCodec::codecForLocale()->fromUnicode(localPath).data());
+ symlink(QTextCodec::codecForLocale()->fromUnicode(g_pApp->m_szGlobalKvircDir).data(),QTextCodec::codecForLocale()->fromUnicode(localPath).data());
+#endif
+
+#ifdef COMPILE_KDE_SUPPORT
+ if(m_pCreateDesktopShortcut->isChecked())
+ makeLink();
+#endif
+
+#ifdef COMPILE_ON_WINDOWS
+ if(m_pCreateUrlHandlers->isChecked())
+ setUrlHandlers();
+#endif
+
+/* if(m_pTheme)
+ {
+ if(m_pThemeButtonGroup->selected() == m_pThemeHiRes)
+ {
+ g_iThemeToApply = THEME_APPLY_HIRES;
+ } else if(m_pThemeButtonGroup->selected() == m_pThemeLoRes)
+ {
+ g_iThemeToApply = THEME_APPLY_LORES;
+ } else {
+ g_iThemeToApply = THEME_APPLY_NONE;
+ }
+ }
+*/
+ if(m_pIdentity)
+ {
+ m_pNickSelector->commit();
+ m_pRealNameSelector->commit();
+ m_pLocationSelector->commit();
+ m_pLanguagesSelector->commit();
+ //m_pOtherInfoSelector->commit();
+
+ KVI_OPTION_STRING(KviOption_stringNickname1).stripWhiteSpace();
+ KVI_OPTION_STRING(KviOption_stringNickname1).replace(" ","");
+
+ if(KVI_OPTION_STRING(KviOption_stringNickname1).length() > 32)
+ {
+ QString tmp = KVI_OPTION_STRING(KviOption_stringNickname1).left(32);
+ KVI_OPTION_STRING(KviOption_stringNickname1) = tmp;
+ }
+
+ if(KVI_OPTION_STRING(KviOption_stringNickname1).isEmpty())KVI_OPTION_STRING(KviOption_stringNickname1) = "newbie";
+
+ QString szNickPart;
+ if(KVI_OPTION_STRING(KviOption_stringNickname1).length() < 31)
+ {
+ szNickPart = KVI_OPTION_STRING(KviOption_stringNickname1);
+ } else {
+ szNickPart = KVI_OPTION_STRING(KviOption_stringNickname1).left(30);
+ }
+
+ QString alt = szNickPart;
+ alt.prepend("|"); // <-- this is an erroneous nickname on IrcNet :/
+ alt.append("|");
+ if(!g_bFoundMirc)
+ KVI_OPTION_STRING(KviOption_stringNickname2) = alt;
+ alt = szNickPart;
+ alt.prepend("_");
+ alt.append("_");
+ KVI_OPTION_STRING(KviOption_stringNickname3) = alt;
+ alt = szNickPart;
+ alt.append("2");
+ KVI_OPTION_STRING(KviOption_stringNickname4) = alt;
+
+ int i = m_pAgeCombo->currentItem();
+ if(i < 0)i = 0;
+ if(i > 120)i = 120;
+ if(i <= 0)KVI_OPTION_STRING(KviOption_stringCtcpUserInfoAge) = "";
+ else KVI_OPTION_STRING(KviOption_stringCtcpUserInfoAge).setNum(i);
+
+ switch(m_pGenderCombo->currentItem())
+ {
+ case 1:
+ // this should be in english
+ KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender) = "Female";
+ break;
+ case 2:
+ // this should be in english
+ KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender) = "Male";
+ break;
+ default:
+ KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender) = "";
+ break;
+ }
+ /*
+ m_pServerHostSelector->commit();
+ m_pServerUrlSelector->commit();
+ //m_pServerConfigSelector->commit();
+ m_pServerPortSelector->commit();
+
+ if(m_pServersSpecifyManually->isOn())
+ {
+ KVI_OPTION_BOOL(KviOption_boolShowServersConnectDialogOnStart) = FALSE;
+ szHost = m_szServerHost;
+ uPort=m_uServerPort;
+ } else if(m_pServersOpenIrcUrl->isOn())
+ {
+ KVI_OPTION_BOOL(KviOption_boolShowServersConnectDialogOnStart) = FALSE;
+ szUrl=m_szServerUrl;
+ }
+ */
+#ifdef COMPILE_ON_WINDOWS
+ if(m_pUseMircServerList->isEnabled() && m_pUseMircServerList->isOn())
+ szMircServers = m_szMircServerIniFile;
+#endif
+ }
+ }
+#ifdef COMPILE_ON_WINDOWS
+ if(m_pDirMakePortable->isOn())
+ {
+ KviFileUtils::writeFile(g_pApp->applicationDirPath()+KVI_PATH_SEPARATOR_CHAR+"portable","true");
+ } else {
+#endif
+ g_pApp->saveKvircDirectory();
+#ifdef COMPILE_ON_WINDOWS
+ }
+#endif
+ KviTalWizard::accept();
+}
+
+#include "setupwizard.moc"
diff --git a/src/modules/setup/setupwizard.h b/src/modules/setup/setupwizard.h
new file mode 100644
index 00000000..2492007a
--- /dev/null
+++ b/src/modules/setup/setupwizard.h
@@ -0,0 +1,164 @@
+#ifndef _SETUPWIZARD_H_
+#define _SETUPWIZARD_H_
+//=============================================================================
+//
+// File : setupwizard.h
+// Creation date : Sat Oct 6 02:06:51 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2007 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_tal_wizard.h>
+#include "kvi_tal_vbox.h"
+#include "kvi_tal_hbox.h"
+#include "kvi_tal_groupbox.h"
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qlineedit.h>
+#ifdef COMPILE_USE_QT4
+#include <q3buttongroup.h>
+#define KviTalVButtonGroup Q3VButtonGroup
+#else
+ #include <qvbuttongroup.h>
+#define KviTalVButtonGroup QVButtonGroup
+#endif
+#include <qradiobutton.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+
+#include "kvi_settings.h"
+#include "kvi_string.h"
+#include "kvi_selectors.h"
+
+class KviSetupWizard;
+
+class KviSetupPage : public QWidget
+{
+ Q_OBJECT
+public:
+ KviSetupPage(KviSetupWizard * w);
+ ~KviSetupPage();
+public:
+ KviTalVBox * m_pVBox;
+ QLabel * m_pPixmapLabel;
+ QLabel * m_pTextLabel;
+
+};
+
+
+#define THEME_APPLY_NONE 0
+#define THEME_APPLY_HIRES 1
+#define THEME_APPLY_LORES 2
+
+class KviSetupWizard : public KviTalWizard
+{
+ Q_OBJECT
+public:
+ KviSetupWizard();
+ ~KviSetupWizard();
+public:
+ QPixmap * m_pLabelPixmap;
+
+ KviSetupPage * m_pWelcome;
+ KviSetupPage * m_pLicense;
+ KviSetupPage * m_pDirectory;
+ KviSetupPage * m_pIdentity;
+// KviSetupPage * m_pTheme;
+ KviSetupPage * m_pDesktopIntegration;
+ KviSetupPage * m_pServers;
+
+ // Theme
+ KviTalVButtonGroup * m_pThemeButtonGroup;
+
+ QRadioButton * m_pThemeHiRes;
+ QRadioButton * m_pThemeLoRes;
+ QRadioButton * m_pThemeNone;
+
+ // Welcome
+ QCheckBox * m_pCreateUrlHandlers;
+ QCheckBox * m_pCreateDesktopShortcut;
+
+ //Dir
+ QLineEdit * m_pDataPathEdit;
+ QLineEdit * m_pIncomingPathEdit;
+ KviTalVButtonGroup * m_pDirButtonGroup;
+ QRadioButton * m_pDirUsePrev;
+ QRadioButton * m_pDirUseNew;
+#ifdef COMPILE_ON_WINDOWS
+ QRadioButton * m_pDirMakePortable;
+#endif
+ //QRadioButton * m_pDirRestore;
+ QLineEdit * m_pOldDataPathEdit;
+ KviTalHBox * m_pOldPathBox;
+ KviTalHBox * m_pNewPathBox;
+ KviTalHBox * m_pNewIncomingBox;
+
+ //Identify
+ QComboBox * m_pAgeCombo;
+ QComboBox * m_pGenderCombo;
+
+ KviStringSelector * m_pNickSelector;
+ KviStringSelector * m_pRealNameSelector;
+ KviStringSelector * m_pLocationSelector;
+ KviStringSelector * m_pLanguagesSelector;
+ //KviStringSelector * m_pOtherInfoSelector;
+
+ //Servers
+ //KviTalVButtonGroup * m_pServersButtonGroup;
+ //QRadioButton * m_pServersChooseFromList;
+ //QRadioButton * m_pServersSpecifyManually;
+ //QRadioButton * m_pServersOpenIrcUrl;
+ //QRadioButton * m_pServersLoadConfig;
+#ifdef COMPILE_ON_WINDOWS
+ QString m_szMircServerIniFile;
+ QRadioButton * m_pUseMircServerList;
+#endif
+
+ QString m_szServerConfigFile;
+ QString m_szServerUrl;
+ QString m_szServerHost;
+ unsigned int m_uServerPort;
+
+ KviStringSelector * m_pServerHostSelector;
+ KviStringSelector * m_pServerUrlSelector;
+ //KviFileSelector * m_pServerConfigSelector;
+ KviUIntSelector *m_pServerPortSelector;
+
+protected:
+ void makeLink();
+ void setUrlHandlers();
+ virtual void showEvent(QShowEvent *e);
+public slots:
+ void chooseOldDataPath();
+ void chooseDataPath();
+ void chooseIncomingPath();
+ virtual void accept();
+ virtual void reject();
+
+ void oldDirClicked();
+ void newDirClicked();
+
+ void oldDataTextChanged ( const QString & );
+ void newDataTextChanged ( const QString & );
+ void newIncomingTextChanged ( const QString & );
+};
+
+
+#endif //_SETUPWIZARD_H_
diff --git a/src/modules/sharedfile/Makefile.am b/src/modules/sharedfile/Makefile.am
new file mode 100644
index 00000000..5c4ace3b
--- /dev/null
+++ b/src/modules/sharedfile/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvisharedfile.la
+
+libkvisharedfile_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvisharedfile_la_SOURCES = libkvisharedfile.cpp
+libkvisharedfile_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+#noinst_HEADERS= sharedfilewindow.h
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/sharedfile/libkvisharedfile.cpp b/src/modules/sharedfile/libkvisharedfile.cpp
new file mode 100644
index 00000000..93959f77
--- /dev/null
+++ b/src/modules/sharedfile/libkvisharedfile.cpp
@@ -0,0 +1,281 @@
+//=============================================================================
+//
+// File : libkvisharedfile.cpp (orig : libkvioffer.cpp)
+// Creation date : Wed Sep 27 2000 20:59:02 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2005 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_module.h"
+
+#include "kvi_sharedfiles.h"
+#include "kvi_ircmask.h"
+#include "kvi_fileutils.h"
+#include "kvi_locale.h"
+
+#include "kvi_out.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_window.h"
+#include "kvi_frame.h"
+
+
+#include <time.h>
+#include "kvi_pointerhashtable.h"
+
+extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager;
+
+
+/*
+ @doc: sharedfile.add
+ @type:
+ command
+ @title:
+ sharedfile.add
+ @keyterms:
+ trading files by dcc
+ @short:
+ Adds a file sharedfile
+ @syntax:
+ sharedfile.add [-t=<timeout:integer>] [-n=<visible name>] <filename> [user_mask]
+ @switches:
+ !sw: -t=<timeout> | --timeout=<timeout>
+ Specified the timeout after that the share will be automatically removed
+ !sw: -n=<visible name> | --name=<visible name>
+ Explicitly specifies the visible name of the share
+ @description:
+ Adds <filename> to the list of the active shared files.
+ The users will be able to request the file via [cmd]dcc.get[/cmd].
+ If [user_mask] is specified , the access to the file is limited
+ to the users that match this mask, otherwise the mask will
+ be automatically set to '*!*@*'.[br]
+ If the 't' switch is used, the sharedfile will be removed after
+ <timeout> seconds. If the 'n' switch is used, the sharedfile
+ will be visible to the oter users as <visible name> instead
+ of the real <filename> (stripped of the leading path).
+ <filename> must be an absolute path.
+ @seealso:
+ [cmd]sharedfile.remove[/cmd], [cmd]sharedfile.list[/cmd],
+ [cmd]dcc.get[/cmd]
+*/
+
+static bool sharedfile_kvs_cmd_add(KviKvsModuleCommandCall * c)
+{
+ QString szFileName,szUserMask;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szFileName)
+ KVSM_PARAMETER("user_mask",KVS_PT_NONEMPTYSTRING,KVS_PF_OPTIONAL,szUserMask)
+ KVSM_PARAMETERS_END(c)
+
+ if(!KviFileUtils::isReadable(szFileName))
+ {
+ c->warning(__tr2qs_ctx("The file '%Q' is not readable","sharedfile"),&szFileName);
+ return true;
+ }
+
+ if(szUserMask.isEmpty())szUserMask="*!*@*";
+ KviIrcMask u(szUserMask);
+
+ QString szm;
+ u.mask(szm);
+
+ kvs_int_t timeout = 0;
+
+ if(KviKvsVariant * v = c->switches()->find('t',"timeout"))
+ {
+ if(!v->asInteger(timeout))
+ {
+ c->warning(__tr2qs_ctx("Invalid timeout, ignoring","sharedfile"));
+ timeout = 0;
+ }
+ }
+
+ QString szVisibleName = szFileName;
+ KviQString::cutToLast(szVisibleName,'/');
+
+ if(KviKvsVariant * n = c->switches()->find('n',"name"))
+ {
+ QString tmp;
+ n->asString(tmp);
+ if(tmp.isEmpty())
+ {
+ c->warning(__tr2qs_ctx("Invalid visible name: using default","sharedfile"));
+ } else szVisibleName = tmp;
+ }
+
+ if(!g_pSharedFilesManager->addSharedFile(szVisibleName,szFileName,szUserMask,timeout))
+ {
+ c->warning(__tr2qs_ctx("Ops..failed to add the sharedfile...","sharedfile"));
+ }
+
+ return true;
+}
+
+
+/*
+ @doc: sharedfile.remove
+ @type:
+ command
+ @title:
+ sharedfile.remove
+ @keyterms:
+ trading files by dcc
+ @short:
+ Removes a shared file
+ @syntax:
+ sharedfile.remove <visible name:string> <user mask:string> [filesize:integer]
+ @description:
+ Removes the shared file that matches <visible name> and <user mask>.
+ If [filesize] is specified, then it must be matched by the entry
+ to be removed.
+ @seealso:
+ [cmd]sharedfile.add[/cmd], [cmd]sharedfile.list[/cmd], [cmd]sharedfile.clear[/cmd]
+*/
+
+static bool sharedfile_kvs_cmd_remove(KviKvsModuleCommandCall * c)
+{
+ QString szVisibleName,szUserMask;
+ kvs_uint_t uSize;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("visible_name",KVS_PT_NONEMPTYSTRING,0,szVisibleName)
+ KVSM_PARAMETER("user_mask",KVS_PT_NONEMPTYSTRING,0,szUserMask)
+ KVSM_PARAMETER("filesize",KVS_PT_UINT,KVS_PF_OPTIONAL,uSize)
+ KVSM_PARAMETERS_END(c)
+
+ if(!g_pSharedFilesManager->removeSharedFile(szVisibleName,szUserMask,uSize))
+ c->warning(__tr2qs_ctx("No sharedfile with visible name '%Q' and user mask '%Q'","sharedfile"),&szVisibleName,&szUserMask);
+
+ return true;
+}
+
+
+
+/*
+ @doc: sharedfile.clear
+ @type:
+ command
+ @title:
+ sharedfile.clear
+ @keyterms:
+ trading files by dcc, shared files
+ @short:
+ Clears the shared files list
+ @syntax:
+ sharedfile.clear
+ @description:
+ Clears the shared files list
+ @seealso:
+ [cmd]sharedfile.add[/cmd], [cmd]sharedfile.list[/cmd], [cmd]sharedfile.remove[/cmd]
+*/
+
+static bool sharedfile_kvs_cmd_clear(KviKvsModuleCommandCall * c)
+{
+ g_pSharedFilesManager->clear();
+ return true;
+}
+
+
+/*
+ @doc: sharedfile.list
+ @type:
+ command
+ @title:
+ sharedfile.list
+ @keyterms:
+ trading files by dcc
+ @short:
+ Lists the active file sharedfile
+ @syntax:
+ sharedfile.list
+ @description:
+ Lists the active file sharedfile.
+ @seealso:
+ [cmd]sharedfile.add[/cmd], [cmd]sharedfile.remove[/cmd]
+*/
+
+static bool sharedfile_kvs_cmd_list(KviKvsModuleCommandCall * c)
+{
+ KviPointerHashTableIterator<QString,KviSharedFileList> it(*(g_pSharedFilesManager->sharedFileListDict()));
+
+ int idx = 0;
+
+ while(KviSharedFileList * l = it.current())
+ {
+ for(KviSharedFile * o = l->first();o;o = l->next())
+ {
+ c->window()->output(KVI_OUT_NONE,"%c%d. %s",
+ KVI_TEXT_BOLD,idx + 1,it.currentKey().utf8().data());
+ c->window()->output(KVI_OUT_NONE,__tr2qs_ctx(" File: %s (%u bytes)","sharedfile"),
+ o->absFilePath().utf8().data(),o->fileSize());
+ c->window()->output(KVI_OUT_NONE,__tr2qs_ctx(" Mask: %s","sharedfile"),
+ o->userMask().utf8().data());
+ if(o->expireTime() > 0)
+ {
+ int secs = ((int)(o->expireTime())) - ((int)(time(0)));
+ int hour = secs / 3600;
+ secs = secs % 3600;
+ int mins = secs / 60;
+ secs = secs % 60;
+ c->window()->output(KVI_OUT_NONE,__tr2qs_ctx(" Expires in %d hours %d minutes %d seconds","sharedfile"),
+ hour,mins,secs);
+ }
+ ++idx;
+ }
+ ++it;
+ }
+
+//#warning "FIND A BETTER KVI_OUT_*"
+
+ if(idx == 0)c->window()->outputNoFmt(KVI_OUT_NONE,__tr2qs_ctx("No active file sharedfile","sharedfile"));
+ else c->window()->output(KVI_OUT_NONE,__tr2qs_ctx("Total: %d sharedfile","sharedfile"),idx);
+
+ return true;
+}
+
+
+static bool sharedfile_module_init(KviModule * m)
+{
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"add",sharedfile_kvs_cmd_add);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"remove",sharedfile_kvs_cmd_remove);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"list",sharedfile_kvs_cmd_list);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"clear",sharedfile_kvs_cmd_clear);
+
+ return true;
+}
+
+static bool sharedfile_module_can_unload(KviModule *m)
+{
+ return true;
+}
+
+static bool sharedfile_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "Offer", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000-2003 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "User interface to the file sharing system",
+ sharedfile_module_init,
+ sharedfile_module_can_unload,
+ 0,
+ sharedfile_module_cleanup
+)
diff --git a/src/modules/sharedfileswindow/Makefile.am b/src/modules/sharedfileswindow/Makefile.am
new file mode 100644
index 00000000..f43e1e67
--- /dev/null
+++ b/src/modules/sharedfileswindow/Makefile.am
@@ -0,0 +1,22 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+SUBDIRS = caps
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvisharedfileswindow.la
+
+libkvisharedfileswindow_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvisharedfileswindow_la_SOURCES = libkvisharedfileswindow.cpp sharedfileswindow.cpp
+libkvisharedfileswindow_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= sharedfileswindow.h
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+sharedfileswindow.cpp: m_sharedfileswindow.moc
diff --git a/src/modules/sharedfileswindow/caps/Makefile.am b/src/modules/sharedfileswindow/caps/Makefile.am
new file mode 100644
index 00000000..bc03ac24
--- /dev/null
+++ b/src/modules/sharedfileswindow/caps/Makefile.am
@@ -0,0 +1,9 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir = $(pluglibdir)/caps/tool/
+
+tmp_DATA= sharedfileswindow
+
+EXTRA_DIST = $(tmp_DATA)
diff --git a/src/modules/sharedfileswindow/caps/sharedfileswindow b/src/modules/sharedfileswindow/caps/sharedfileswindow
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/modules/sharedfileswindow/caps/sharedfileswindow
diff --git a/src/modules/sharedfileswindow/libkvisharedfileswindow.cpp b/src/modules/sharedfileswindow/libkvisharedfileswindow.cpp
new file mode 100644
index 00000000..a7cab111
--- /dev/null
+++ b/src/modules/sharedfileswindow/libkvisharedfileswindow.cpp
@@ -0,0 +1,158 @@
+//==================================================================================
+//
+// File : libkvisharedfileswindow.cpp
+// Creation date : Mon Apr 21 2003 23:14:12 CEST by Szymon Stefanek
+//
+// Copyright (C) 2003 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_module.h"
+
+
+#include "sharedfileswindow.h"
+
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_window.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+
+#include <qsplitter.h>
+
+#define KVI_SHARED_FILES_WINDOW_EXTENSION_NAME "Shared files window extension"
+
+KviSharedFilesWindow * g_pSharedFilesWindow = 0;
+
+static KviModuleExtension * sharedfileswindow_extension_alloc(KviModuleExtensionAllocStruct * s)
+{
+ bool bCreateMinimized = false;
+ bool bNoRaise = false;
+
+ if(!g_pSharedFilesWindow)
+ {
+ if(s->pParams)
+ {
+ if(QVariant * v = s->pParams->find("bCreateMinimized"))
+ {
+ if(v->isValid())
+ {
+ if(v->type() == QVariant::Bool)
+ {
+ bCreateMinimized = v->toBool();
+ }
+ }
+ }
+ }
+
+ g_pSharedFilesWindow = new KviSharedFilesWindow(s->pDescriptor,g_pFrame);
+ g_pFrame->addWindow(g_pSharedFilesWindow,!bCreateMinimized);
+ if(bCreateMinimized)g_pSharedFilesWindow->minimize();
+ return g_pSharedFilesWindow;
+ }
+
+ if(s->pParams)
+ {
+ if(QVariant * v = s->pParams->find("bNoRaise"))
+ {
+ if(v)
+ {
+ if(v->isValid() && v->type() == QVariant::Bool)
+ bNoRaise = v->toBool();
+ }
+ }
+ }
+
+ if(!bNoRaise)g_pSharedFilesWindow->delayedAutoRaise();
+ return g_pSharedFilesWindow;
+}
+
+
+/*
+ @doc: sharedfileswindow.open
+ @type:
+ command
+ @title:
+ sharedfileswindow.open
+ @short:
+ Opens the shared files window
+ @syntax:
+ sharedfileswindow.open [-m] [-n]
+ @switches:
+ !sw: -m
+ Causes the window to be created as minimized
+ !sw: -n
+ Causes the window to be not raised if already open
+ @description:
+ Opens the shared files window
+*/
+
+static bool sharedfileswindow_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ KviModuleExtensionDescriptor * d = c->module()->findExtensionDescriptor("tool",KVI_SHARED_FILES_WINDOW_EXTENSION_NAME);
+ if(d)
+ {
+ KviPointerHashTable<QString,QVariant> dict(17,true);
+ dict.setAutoDelete(true);
+ dict.replace("bCreateMinimized",new QVariant(c->hasSwitch('m',"minimized")));
+ dict.replace("bNoRaise",new QVariant(c->hasSwitch('n',"noraise")));
+
+ d->allocate(c->window(),&dict,0);
+ } else {
+ c->warning("Ops.. internal error");
+ }
+ return true;
+}
+
+static bool sharedfileswindow_module_init(KviModule * m)
+{
+ KviModuleExtensionDescriptor * d = m->registerExtension("tool",
+ KVI_SHARED_FILES_WINDOW_EXTENSION_NAME,
+ __tr2qs_ctx("Manage S&hared Files","sharedfileswindow"),
+ sharedfileswindow_extension_alloc);
+
+ if(d)d->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SHAREDFILES)));
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",sharedfileswindow_kvs_cmd_open);
+ return true;
+}
+
+static bool sharedfileswindow_module_cleanup(KviModule *m)
+{
+ if(g_pSharedFilesWindow)
+ {
+ delete g_pSharedFilesWindow;
+ g_pSharedFilesWindow = 0;
+ }
+ return true;
+}
+
+static bool sharedfileswindow_module_can_unload(KviModule *m)
+{
+ return (!g_pSharedFilesWindow);
+}
+
+KVIRC_MODULE(
+ "SharedFilesWindow",
+ "1.0.0",
+ "Copyright (C) 2003 Szymon Stefanek (pragma at kvirc dot net)",
+ "Shared files window extension",
+ sharedfileswindow_module_init,
+ sharedfileswindow_module_can_unload,
+ 0,
+ sharedfileswindow_module_cleanup
+)
diff --git a/src/modules/sharedfileswindow/sharedfileswindow.cpp b/src/modules/sharedfileswindow/sharedfileswindow.cpp
new file mode 100644
index 00000000..aa851684
--- /dev/null
+++ b/src/modules/sharedfileswindow/sharedfileswindow.cpp
@@ -0,0 +1,742 @@
+//==================================================================================
+//
+// File : sharedfileswindow.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) 1999-2001 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 "sharedfileswindow.h"
+
+#include "kvi_debug.h"
+#include "kvi_iconmanager.h"
+#include "kvi_ircview.h"
+#include "kvi_out.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_out.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_themedlabel.h"
+#include "kvi_input.h"
+#include "kvi_filedialog.h"
+#include "kvi_styled_controls.h"
+
+#include <qdatetimeedit.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qsplitter.h>
+#include "kvi_tal_hbox.h"
+#include "kvi_tal_vbox.h"
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qmessagebox.h>
+#include <qfileinfo.h>
+
+extern KviSharedFilesWindow * g_pSharedFilesWindow;
+extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager;
+
+KviSharedFileEditDialog::KviSharedFileEditDialog(QWidget * par,KviSharedFile * f)
+: QDialog(par,"shared_file_editor",true)
+{
+ QGridLayout * g = new QGridLayout(this,1,1,11,6);
+
+ setCaption(__tr2qs_ctx("Edit Shared File - KVIrc","sharedfileswindow"));
+
+ QLabel * l = new QLabel(__tr2qs_ctx("Share name:","sharedfileswindow"),this);
+ g->addWidget(l, 0, 0 );
+
+ m_pShareNameEdit = new QLineEdit(this);
+ g->addMultiCellWidget( m_pShareNameEdit, 0, 0, 1, 3 );
+
+ l = new QLabel(__tr2qs_ctx("File path:","sharedfileswindow"),this);
+ g->addWidget(l, 1, 0 );
+
+ m_pFilePathEdit = new QLineEdit(this);
+ g->addMultiCellWidget( m_pFilePathEdit, 1, 1, 1, 2 );
+
+ m_pBrowseButton = new QPushButton(__tr2qs_ctx("&Browse...","sharedfileswindow"),this);
+ g->addWidget( m_pBrowseButton, 1, 3 );
+ connect(m_pBrowseButton,SIGNAL(clicked()),this,SLOT(browse()));
+
+ l = new QLabel(__tr2qs_ctx("User mask:","sharedfileswindow"),this);
+ g->addWidget(l, 2, 0 );
+
+ m_pUserMaskEdit = new QLineEdit(this);
+ g->addMultiCellWidget( m_pUserMaskEdit, 2, 2, 1, 3 );
+
+ m_pExpireCheckBox = new KviStyledCheckBox(__tr2qs_ctx("Expire at:","sharedfileswindow"),this);
+ g->addWidget(m_pExpireCheckBox,3,0);
+
+ m_pExpireDateTimeEdit = new QDateTimeEdit(this);
+ g->addMultiCellWidget(m_pExpireDateTimeEdit, 3, 3, 1, 3 );
+
+ connect(m_pExpireCheckBox,SIGNAL(toggled(bool)),m_pExpireDateTimeEdit,SLOT(setEnabled(bool)));
+
+ QPushButton * pb;
+
+ pb = new QPushButton(__tr2qs_ctx("&OK","sharedfileswindow"),this);
+ connect(pb,SIGNAL(clicked()),this,SLOT(okClicked()));
+ pb->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ g->addWidget(pb,5,2);
+ pb = new QPushButton(__tr2qs_ctx("Cancel","sharedfileswindow"),this);
+ connect(pb,SIGNAL(clicked()),this,SLOT(reject()));
+ pb->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ g->addWidget(pb,5,3);
+
+ g->setRowStretch(4,1);
+ g->setColStretch(0,1);
+
+ if(f)
+ {
+ m_pShareNameEdit->setText(f->name());
+ m_pFilePathEdit->setText(f->absFilePath());
+ m_pUserMaskEdit->setText(f->userMask());
+ QDateTime dt;
+ dt.setTime_t(f->expireTime());
+ m_pExpireDateTimeEdit->setDateTime(dt);
+ m_pExpireCheckBox->setChecked(f->expires());
+ m_pExpireDateTimeEdit->setEnabled(f->expires());
+ } else {
+ m_pExpireCheckBox->setChecked(false);
+ m_pExpireDateTimeEdit->setDateTime(QDateTime::currentDateTime());
+ m_pExpireDateTimeEdit->setEnabled(false);
+ }
+
+}
+
+KviSharedFileEditDialog::~KviSharedFileEditDialog()
+{
+
+}
+
+void KviSharedFileEditDialog::browse()
+{
+ QString szBuf;
+ QString szTxt = m_pFilePathEdit->text();
+ if(!KviFileDialog::askForOpenFileName(szBuf,__tr2qs("Choose the file to share"),szTxt))return;
+ m_pFilePathEdit->setText(szBuf);
+}
+
+KviSharedFile * KviSharedFileEditDialog::getResult()
+{
+ QString szName = m_pShareNameEdit->text();
+ QString szPath = m_pFilePathEdit->text();
+ QString szMask = m_pUserMaskEdit->text();
+ QDateTime dt = m_pExpireDateTimeEdit->dateTime();
+ bool bExpires = m_pExpireCheckBox->isChecked();
+ QFileInfo f(szPath);
+ return new KviSharedFile(szName,szPath,szMask,bExpires ? dt.toTime_t() : (time_t)0,f.size());
+}
+
+void KviSharedFileEditDialog::okClicked()
+{
+ QString szName = m_pShareNameEdit->text();
+ QString szPath = m_pFilePathEdit->text();
+ QDateTime dt = m_pExpireDateTimeEdit->dateTime();
+ bool bExpires = m_pExpireCheckBox->isChecked();
+ if(bExpires && (dt <= QDateTime::currentDateTime()))
+ {
+ QMessageBox::warning(this,__tr2qs_ctx("Invalid expire time","sharedfileswindow"),
+ __tr2qs_ctx("The expire date/time is in the past: please either remove the \"expires\"" \
+ "check mark or specify a expire date/time in the future","sharedfileswindow"),
+ __tr2qs_ctx("OK","sharedfileswindow"));
+ return;
+ }
+
+ if(szName.isEmpty())
+ {
+ QMessageBox::warning(this,__tr2qs_ctx("Invalid share name","sharedfileswindow"),
+ __tr2qs_ctx("The share name can't be empty, please correct it","sharedfileswindow"),
+ __tr2qs_ctx("OK","sharedfileswindow"));
+ return;
+ }
+
+ QFileInfo f(szPath);
+ if(!(f.exists() && f.isFile() && f.isReadable()))
+ {
+ QMessageBox::warning(this,__tr2qs_ctx("Can't open the file","sharedfileswindow"),
+ __tr2qs_ctx("The file doesn't exist or it is not readable, please check the path","sharedfileswindow"),
+ __tr2qs_ctx("OK","sharedfileswindow"));
+ return;
+ }
+
+ accept();
+}
+
+
+KviSharedFilesListViewItem::KviSharedFilesListViewItem(KviTalListView * lv,KviSharedFile * f)
+: KviTalListViewItem(lv,f->name())
+{
+ setText(1,f->absFilePath());
+ setText(2,f->userMask());
+ if(f->expires())
+ {
+ QDateTime dt;
+ dt.setTime_t(f->expireTime());
+ setText(3,dt.toString());
+ } else {
+ setText(3,__tr2qs_ctx("Never","sharedfileswindow"));
+ }
+ m_pSharedFilePointer = f;
+}
+
+KviSharedFilesListViewItem::~KviSharedFilesListViewItem()
+{
+}
+
+
+KviSharedFilesWindow::KviSharedFilesWindow(KviModuleExtensionDescriptor * d,KviFrame * lpFrm)
+: KviWindow(KVI_WINDOW_TYPE_TOOL,lpFrm,"shared files window",0) , KviModuleExtension(d)
+{
+ g_pSharedFilesWindow = this;
+#ifdef COMPILE_USE_QT4
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"splitter");
+#else
+ m_pSplitter = new QSplitter(QSplitter::Horizontal,this,"splitter");
+#endif
+
+ KviTalVBox * vbox = new KviTalVBox(m_pSplitter);
+
+ m_pListView = new KviTalListView(vbox);
+ //m_pListView->header()->hide();
+ m_pListView->setAllColumnsShowFocus(true);
+ m_pListView->addColumn(__tr2qs_ctx("Name","sharedfileswindow"),200);
+ m_pListView->addColumn(__tr2qs_ctx("Filename","sharedfileswindow"),300);
+ m_pListView->addColumn(__tr2qs_ctx("Mask","sharedfileswindow"),200);
+ m_pListView->addColumn(__tr2qs_ctx("Expires","sharedfileswindow"),200);
+ m_pListView->setSelectionMode(KviTalListView::Single);
+ connect(m_pListView,SIGNAL(selectionChanged()),this,SLOT(enableButtons()));
+
+ connect(g_pSharedFilesManager,SIGNAL(sharedFilesChanged()),this,SLOT(fillFileView()));
+ connect(g_pSharedFilesManager,SIGNAL(sharedFileAdded(KviSharedFile *)),this,SLOT(sharedFileAdded(KviSharedFile *)));
+ connect(g_pSharedFilesManager,SIGNAL(sharedFileRemoved(KviSharedFile *)),this,SLOT(sharedFileRemoved(KviSharedFile *)));
+
+ KviTalHBox * b = new KviTalHBox(vbox);
+
+ m_pAddButton = new QPushButton(__tr2qs_ctx("&Add...","sharedfileswindow"),b);
+ connect(m_pAddButton,SIGNAL(clicked()),this,SLOT(addClicked()));
+ m_pRemoveButton = new QPushButton(__tr2qs_ctx("Re&move","sharedfileswindow"),b);
+ connect(m_pRemoveButton,SIGNAL(clicked()),this,SLOT(removeClicked()));
+ m_pEditButton = new QPushButton(__tr2qs_ctx("&Edit","sharedfileswindow"),b);
+ connect(m_pEditButton,SIGNAL(clicked()),this,SLOT(editClicked()));
+
+ fillFileView();
+}
+
+KviSharedFilesWindow::~KviSharedFilesWindow()
+{
+ g_pSharedFilesWindow = 0;
+}
+
+void KviSharedFilesWindow::enableButtons()
+{
+ KviTalListViewItem * it = m_pListView->currentItem();
+ m_pEditButton->setEnabled(it);
+ m_pRemoveButton->setEnabled(it);
+}
+
+void KviSharedFilesWindow::removeClicked()
+{
+ KviSharedFilesListViewItem * it = (KviSharedFilesListViewItem *)m_pListView->currentItem();
+ if(!it)return;
+
+ g_pSharedFilesManager->removeSharedFile(it->readOnlySharedFilePointer()->name(),it->readOnlySharedFilePointer());
+}
+
+void KviSharedFilesWindow::addClicked()
+{
+ KviSharedFileEditDialog dlg(0);
+ if(dlg.exec() != QDialog::Accepted)return;
+
+ KviSharedFile * f = dlg.getResult();
+ if(!f)return;
+ g_pSharedFilesManager->addSharedFile(f);
+}
+
+void KviSharedFilesWindow::editClicked()
+{
+ KviSharedFilesListViewItem * it = (KviSharedFilesListViewItem *)m_pListView->currentItem();
+ if(!it)return;
+
+ KviSharedFileEditDialog dlg(0,it->readOnlySharedFilePointer());
+ if(dlg.exec() != QDialog::Accepted)return;
+
+ KviSharedFilesListViewItem * it2 = (KviSharedFilesListViewItem *)m_pListView->currentItem();
+ if(it2 != it)return; // ooops ?
+ KviSharedFile * f = dlg.getResult();
+ if(!f)return; // ooops 2 ?
+
+ g_pSharedFilesManager->removeSharedFile(it->readOnlySharedFilePointer()->name(),it->readOnlySharedFilePointer());
+ g_pSharedFilesManager->addSharedFile(f);
+}
+
+void KviSharedFilesWindow::fillFileView()
+{
+ m_pListView->clear();
+ KviPointerHashTableIterator<QString,KviSharedFileList> it(*(g_pSharedFilesManager->sharedFileListDict()));
+
+ KviSharedFilesListViewItem * itm;
+
+ while(KviSharedFileList * l = it.current())
+ {
+ for(KviSharedFile * o = l->first();o;o = l->next())
+ {
+ itm = new KviSharedFilesListViewItem(m_pListView,o);
+ }
+ ++it;
+ }
+ enableButtons();
+}
+
+void KviSharedFilesWindow::sharedFileAdded(KviSharedFile * f)
+{
+ KviSharedFilesListViewItem * it;
+ it = new KviSharedFilesListViewItem(m_pListView,f);
+ enableButtons();
+}
+
+void KviSharedFilesWindow::sharedFileRemoved(KviSharedFile * f)
+{
+ KviTalListViewItem * it = m_pListView->firstChild();
+ while(it)
+ {
+ if(((KviSharedFilesListViewItem *)it)->readOnlySharedFilePointer() == f)
+ {
+ delete ((KviSharedFilesListViewItem *)it);
+ return;
+ }
+ it = it->nextSibling();
+ }
+ enableButtons();
+}
+
+
+
+/*
+void KviSharedFilesWindow::tipRequest(KviDynamicToolTip * tip,const QPoint &pnt)
+{
+
+ KviSharedFilesItem * it = (KviSharedFilesItem *)m_pListView->itemAt(pnt);
+ if(!it)return;
+ QString txt = it->transfer()->tipText();
+ tip->tip(m_pListView->itemRect(it),txt);
+
+}
+*/
+/*
+void KviSharedFilesWindow::fillTransferView()
+{
+ KviPointerList<KviSharedFiles> * l = KviSharedFilesManager::instance()->transferList();
+ if(!l)return;
+ KviSharedFilesItem * it;
+ for(KviSharedFiles * t = l->first();t;t = l->next())
+ {
+ it = new KviSharedFilesItem(m_pListView,t);
+ t->setDisplayItem(it);
+ }
+}
+
+KviSharedFilesItem * KviSharedFilesWindow::findItem(KviSharedFiles * t)
+{
+ KviSharedFilesItem * it = (KviSharedFilesItem *)m_pListView->firstChild();
+ while(it)
+ {
+ if(it->transfer() == t)return it;
+ it = (KviSharedFilesItem *)(it->nextSibling());
+ }
+ return 0;
+}
+
+void KviSharedFilesWindow::transferRegistered(KviSharedFiles * t)
+{
+ KviSharedFilesItem * it = new KviSharedFilesItem(m_pListView,t);
+ //t->setDisplayItem(it);
+}
+
+void KviSharedFilesWindow::transferUnregistering(KviSharedFiles * t)
+{
+ KviSharedFilesItem * it = findItem(t);
+ //t->setDisplayItem(0);
+ if(it)delete it;
+}
+
+void KviSharedFilesWindow::rightButtonPressed(KviTalListViewItem *it,const QPoint &pnt,int col)
+{
+ 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)
+ {
+ KviSharedFilesItem * i = (KviSharedFilesItem *)it;
+ if(i->transfer())
+ {
+
+ QString szFile = i->transfer()->localFileName();
+ if(!szFile.isEmpty())
+ {
+ m_pLocalFilePopup->clear();
+
+ QString tmp = "<b>file:/";
+ tmp += szFile;
+ tmp += "</b><br>";
+
+ QFileInfo fi(szFile);
+ if(fi.exists())
+ {
+ tmp += "<nobr>";
+ tmp += __tr2qs_ctx("Size: %1 bytes","filetransferwindow").arg(fi.size());
+ tmp += "</nobr><br>";
+ }
+
+#ifdef COMPILE_KDE_SUPPORT
+ tmp += "<nobr>Mime: ";
+ tmp += KMimeType::findByPath(szFile)->name();
+ tmp += "</nobr>";
+#endif //COMPILE_KDE_SUPPORT
+
+ QLabel * l = new QLabel(tmp,m_pLocalFilePopup);
+ l->setFrameStyle(QFrame::Raised | QFrame::Panel);
+ m_pLocalFilePopup->insertItem(l);
+
+#ifdef COMPILE_KDE_SUPPORT
+ QString mimetype = KMimeType::findByPath(szFile)->name();
+ KServiceTypeProfile::OfferList offers = KServiceTypeProfile::offers(mimetype,"Application");
+
+ m_pOpenFilePopup->clear();
+
+ int id;
+ int idx = 0;
+
+ for(KServiceTypeProfile::OfferList::Iterator itOffers = offers.begin();
+ itOffers != offers.end(); ++itOffers)
+ {
+ id = m_pOpenFilePopup->insertItem((*itOffers).service()->pixmap(KIcon::Small),(*itOffers).service()->name());
+ m_pOpenFilePopup->setItemParameter(id,idx);
+ idx++;
+ }
+
+ m_pOpenFilePopup->insertSeparator();
+
+ id = m_pOpenFilePopup->insertItem(__tr2qs_ctx("Default application","filetransferwindow"),this,SLOT(openLocalFile()));
+ m_pOpenFilePopup->setItemParameter(id,-1);
+ 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 folder","filetransferwindow"),this,SLOT(openLocalFileFolder()));
+ m_pLocalFilePopup->insertItem(__tr2qs_ctx("Reach in terminal","filetransferwindow"),this,SLOT(openLocalFileTerminal()));
+ m_pLocalFilePopup->insertSeparator();
+#endif //COMPILE_KDE_SUPPORT
+ m_pLocalFilePopup->insertItem(__tr2qs_ctx("Copy path to clipboard","filetransferwindow"),this,SLOT(copyLocalFileToClipboard()));
+
+ m_pContextPopup->insertItem(__tr2qs_ctx("Local file","filetransferwindow"),m_pLocalFilePopup);
+ }
+
+ i->transfer()->fillContextPopup(m_pContextPopup,col);
+ m_pContextPopup->insertSeparator();
+ }
+ }
+
+
+ bool bHaveTerminated = false;
+ KviSharedFilesItem * item = (KviSharedFilesItem *)m_pListView->firstChild();
+ while(item)
+ {
+ if(item->transfer()->terminated())
+ {
+ bHaveTerminated = true;
+ break;
+ }
+ item = (KviSharedFilesItem *)item->nextSibling();
+ }
+
+ id = m_pContextPopup->insertItem(__tr2qs_ctx("Clear terminated","filetransferwindow"),this,SLOT(clearTerminated()));
+ m_pContextPopup->setItemEnabled(id,bHaveTerminated);
+
+ id = m_pContextPopup->insertItem(__tr2qs_ctx("Clear all","filetransferwindow"),this,SLOT(clearAll()));
+ m_pContextPopup->setItemEnabled(id,it);
+
+ m_pContextPopup->popup(pnt);
+}
+
+
+KviSharedFiles * KviSharedFilesWindow::selectedTransfer()
+{
+ KviTalListViewItem * it = m_pListView->selectedItem();
+ if(!it)return 0;
+ KviSharedFilesItem * i = (KviSharedFilesItem *)it;
+ return i->transfer();
+}
+
+void KviSharedFilesWindow::openFilePopupActivated(int id)
+{
+#ifdef COMPILE_KDE_SUPPORT
+ int ip = m_pOpenFilePopup->itemParameter(id);
+ if(ip < 0)return;
+ QString txt = m_pOpenFilePopup->text(id);
+
+ KviSharedFiles * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+
+ QString mimetype = KMimeType::findByPath(tmp)->name();
+ KServiceTypeProfile::OfferList offers = KServiceTypeProfile::offers(mimetype,"Application");
+
+ for(KServiceTypeProfile::OfferList::Iterator itOffers = offers.begin();
+ itOffers != offers.end(); ++itOffers)
+ {
+ if(txt == (*itOffers).service()->name())
+ {
+ KURL::List lst;
+ KURL url;
+ url.setPath(tmp);
+ lst.append(url);
+ KRun::run(*((*itOffers).service()), lst);
+ break;
+ }
+ }
+#endif //COMPILE_KDE_SUPPORT
+}
+
+void KviSharedFilesWindow::openLocalFileTerminal()
+{
+#ifdef COMPILE_KDE_SUPPORT
+ KviSharedFiles * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+
+ int idx = tmp.findRev("/");
+ if(idx == -1)return;
+ tmp = tmp.left(idx);
+
+ tmp.prepend("konsole --workdir=\"");
+ tmp.append("\"");
+
+ KRun::runCommand(tmp);
+#endif //COMPILE_KDE_SUPPORT
+}
+
+void KviSharedFilesWindow::openLocalFile()
+{
+#ifdef COMPILE_KDE_SUPPORT
+ KviSharedFiles * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+
+ QString mimetype = KMimeType::findByPath(tmp)->name();
+ KService::Ptr offer = KServiceTypeProfile::preferredService(mimetype,"Application");
+ if(!offer)
+ {
+ openLocalFileWith();
+ return;
+ }
+
+ KURL::List lst;
+ KURL url;
+ url.setPath(tmp);
+ lst.append(url);
+ KRun::run(*offer, lst);
+#endif //COMPILE_KDE_SUPPORT
+}
+
+void KviSharedFilesWindow::openLocalFileWith()
+{
+#ifdef COMPILE_KDE_SUPPORT
+ KviSharedFiles * 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);
+#endif //COMPILE_KDE_SUPPORT
+}
+
+void KviSharedFilesWindow::copyLocalFileToClipboard()
+{
+ KviSharedFiles * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+ QApplication::clipboard()->setSelectionMode(false);
+ QApplication::clipboard()->setText(tmp);
+ QApplication::clipboard()->setSelectionMode(true);
+ QApplication::clipboard()->setText(tmp);
+}
+
+void KviSharedFilesWindow::openLocalFileFolder()
+{
+#ifdef COMPILE_KDE_SUPPORT
+ KviSharedFiles * t = selectedTransfer();
+ if(!t)return;
+ QString tmp = t->localFileName();
+ if(tmp.isEmpty())return;
+
+ int idx = tmp.findRev("/");
+ if(idx == -1)return;
+ tmp = tmp.left(idx);
+
+ QString mimetype = KMimeType::findByPath(tmp)->name(); // inode/directory
+ KService::Ptr offer = KServiceTypeProfile::preferredService(mimetype,"Application");
+ if(!offer)return;
+
+ KURL::List lst;
+ KURL url;
+ url.setPath(tmp);
+ lst.append(url);
+ KRun::run(*offer, lst);
+#endif //COMPILE_KDE_SUPPORT
+}
+
+void KviSharedFilesWindow::heartbeat()
+{
+ if(m_pListView->childCount() < 1)return;
+
+ KviTalListViewItem * i1;
+ KviTalListViewItem * i2;
+
+ i1 = m_pListView->itemAt(QPoint(1,1));
+ if(!i1)
+ {
+ m_pListView->viewport()->update();
+ return;
+ }
+ i2 = m_pListView->itemAt(QPoint(1,m_pListView->viewport()->height() - 2));
+ if(i2)i2 = i2->nextSibling();
+
+ while(i1 && (i1 != i2))
+ {
+ if(((KviSharedFilesItem *)i1)->transfer()->active())
+ {
+ m_pListView->repaintItem(i1);
+ }
+ i1 = i1->nextSibling();
+ }
+}
+
+void KviSharedFilesWindow::clearAll()
+{
+ if(QMessageBox::information(this,__tr2qs_ctx("Clear all transfers","filetransferwindow"),
+ __tr2qs_ctx("Remove all the transfers including the running ones ?","filetransferwindow"),
+ __tr2qs_ctx("Yes","filetransferwindow"),__tr2qs_ctx("No","filetransferwindow")) != 0)return;
+
+ KviSharedFilesManager::instance()->killAllTransfers();
+}
+
+void KviSharedFilesWindow::clearTerminated()
+{
+ KviSharedFilesManager::instance()->killTerminatedTransfers();
+}
+*/
+void KviSharedFilesWindow::getBaseLogFileName(KviStr &buffer)
+{
+ buffer.sprintf("SHAREDFILES");
+}
+
+QPixmap * KviSharedFilesWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_SHAREDFILES);
+}
+
+void KviSharedFilesWindow::resizeEvent(QResizeEvent *e)
+{
+ //int h = m_pInput->heightHint();
+ m_pSplitter->setGeometry(0,0,width(),height());
+ //m_pInput->setGeometry(0,height() - h,width(),h);
+}
+
+QSize KviSharedFilesWindow::sizeHint() const
+{
+ return m_pSplitter->sizeHint();
+}
+
+void KviSharedFilesWindow::fillCaptionBuffers()
+{
+ m_szPlainTextCaption = __tr2qs_ctx("Shared Files","sharedfileswindow");
+
+ m_szHtmlActiveCaption = "<nobr><font color=\"";
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += "\"><b>";
+ m_szHtmlActiveCaption += m_szPlainTextCaption;
+ m_szHtmlActiveCaption += "</b></font></nobr>";
+
+ m_szHtmlInactiveCaption = "<nobr><font color=\"";
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += "\"><b>";
+ m_szHtmlInactiveCaption += m_szPlainTextCaption;
+ m_szHtmlInactiveCaption += "</b></font></nobr>";
+
+}
+
+void KviSharedFilesWindow::die()
+{
+ close();
+}
+
+
+
+//#warning "Load & save properties of this kind of window"
+
+//void KviSharedFilesWindow::saveProperties()
+//{
+// KviWindowProperty p;
+// p.rect = externalGeometry();
+// p.isDocked = isAttacched();
+// QValueList<int> 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 KviSharedFilesWindow::setProperties(KviWindowProperty *p)
+//{
+// QValueList<int> l;
+// l.append(p->splitWidth1);
+// l.append(p->splitWidth2);
+// m_pVertSplitter->setSizes(l);
+// m_pIrcView->setTimestamp(p->timestamp);
+// m_pIrcView->setShowImages(p->imagesVisible);
+//}
+
+
+#include "m_sharedfileswindow.moc"
diff --git a/src/modules/sharedfileswindow/sharedfileswindow.h b/src/modules/sharedfileswindow/sharedfileswindow.h
new file mode 100644
index 00000000..f46bd6df
--- /dev/null
+++ b/src/modules/sharedfileswindow/sharedfileswindow.h
@@ -0,0 +1,114 @@
+#ifndef _SHAREDFILESWINDOW_H_
+#define _SHAREDFILESWINDOW_H_
+//==================================================================================
+//
+// File : sharedfileswindow.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 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 "kvi_window.h"
+#include "kvi_string.h"
+#include "kvi_sparser.h"
+#include "kvi_console.h"
+#include "kvi_moduleextension.h"
+#include "kvi_sharedfiles.h"
+#include "kvi_styled_controls.h"
+
+#include "kvi_tal_listview.h"
+#include <qdialog.h>
+
+class QGridLayout;
+class QDateTimeEdit;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+
+class KviSharedFilesListViewItem : public KviTalListViewItem
+{
+public:
+ KviSharedFilesListViewItem(KviTalListView * lv,KviSharedFile * f);
+ ~KviSharedFilesListViewItem();
+protected:
+ KviSharedFile * m_pSharedFilePointer; // THIS IS READ ONLY!
+public:
+ KviSharedFile * readOnlySharedFilePointer(){ return m_pSharedFilePointer; };
+};
+
+
+
+class KviSharedFileEditDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviSharedFileEditDialog(QWidget* par,KviSharedFile * f = 0);
+ ~KviSharedFileEditDialog();
+
+ QDateTimeEdit * m_pExpireDateTimeEdit;
+ QLineEdit * m_pFilePathEdit;
+ QLineEdit * m_pUserMaskEdit;
+ QPushButton * m_pBrowseButton;
+ QLineEdit * m_pShareNameEdit;
+ KviStyledCheckBox * m_pExpireCheckBox;
+public:
+ KviSharedFile * getResult();
+protected slots:
+ void okClicked();
+ void browse();
+};
+
+
+
+
+class KviSharedFilesWindow : public KviWindow , public KviModuleExtension
+{
+ friend class KviSharedFilesItem;
+ Q_OBJECT
+public:
+ KviSharedFilesWindow(KviModuleExtensionDescriptor * d,KviFrame * lpFrm);
+ ~KviSharedFilesWindow();
+protected:
+ QSplitter * m_pVertSplitter;
+
+ KviTalListView * m_pListView;
+
+ QPushButton * m_pRemoveButton;
+ QPushButton * m_pEditButton;
+ QPushButton * m_pAddButton;
+public: // Methods
+ virtual void die();
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void getBaseLogFileName(KviStr &buffer);
+public:
+ virtual QSize sizeHint() const;
+protected slots:
+ void fillFileView();
+ void sharedFileAdded(KviSharedFile * f);
+ void sharedFileRemoved(KviSharedFile * f);
+ void enableButtons();
+ void removeClicked();
+ void addClicked();
+ void editClicked();
+};
+
+#endif //_SHAREDFILESWINDOW_H_
diff --git a/src/modules/snd/Makefile.am b/src/modules/snd/Makefile.am
new file mode 100644
index 00000000..d5776010
--- /dev/null
+++ b/src/modules/snd/Makefile.am
@@ -0,0 +1,22 @@
+###############################################################################
+# KVirc IRC client Makestr - 10.03.2002 Juanjo lvarez <juanjux@yahoo.es>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+-I/usr/include/kde/arts\
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvisnd.la
+
+libkvisnd_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvisnd_la_SOURCES = libkvisnd.cpp
+libkvisnd_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+
+noinst_HEADERS= libkvisnd.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkvisnd.cpp: libkvisnd.moc
diff --git a/src/modules/snd/libkvisnd.cpp b/src/modules/snd/libkvisnd.cpp
new file mode 100644
index 00000000..bf0d2eab
--- /dev/null
+++ b/src/modules/snd/libkvisnd.cpp
@@ -0,0 +1,744 @@
+//=============================================================================
+//
+// File : libkvisnd.cpp
+// Creation date : Thu Dec 27 2002 17:13:12 GMT by Juanjo �varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Juanjo �varez (juanjux at yahoo dot es)
+// Copyright (C) 2002 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 "libkvisnd.h"
+#include "kvi_module.h"
+#include "kvi_debug.h"
+
+#include "kvi_fileutils.h"
+#include "kvi_malloc.h"
+#include "kvi_window.h"
+#include "kvi_out.h"
+#include "kvi_locale.h"
+#include "kvi_qstring.h"
+
+#include <qsound.h>
+
+#ifdef COMPILE_ON_WINDOWS
+ #include <mmsystem.h>
+#else //!COMPILE_ON_WINDOWS
+
+ #include <qfile.h>
+ #include <unistd.h>
+ #include <errno.h>
+
+ #ifdef COMPILE_ESD_SUPPORT
+ #include <esd.h>
+ #endif //COMPILE_ESD_SUPPORT
+
+ #ifdef COMPILE_OSS_SUPPORT
+ #include <fcntl.h>
+ #include <sys/ioctl.h>
+ #ifdef HAVE_LINUX_SOUNDCARD_H
+ #include <linux/soundcard.h>
+ #else
+ // Hint by Andy Fawcett: Thnx :)
+ #ifdef HAVE_SYS_SOUNDCARD_H
+ #include <sys/soundcard.h>
+ #else
+ #warning "Ops.. have no soundcard.h ? ... we're going to fail here :/"
+ #endif
+ #endif
+ #ifdef COMPILE_AUDIOFILE_SUPPORT
+ #include <audiofile.h>
+ #endif //COMPILE_AUDIOFILE_SUPPORT
+ #endif //COMPILE_OSS_SUPPORT
+
+ #ifdef COMPILE_ARTS_SUPPORT
+ #include <arts/soundserver.h>
+
+ static Arts::Dispatcher * g_pArtsDispatcher = 0;
+
+ #endif //COMPILE_ARTS_SUPPORT
+
+#endif
+
+static KviSoundPlayer * g_pSoundPlayer = 0;
+
+KviSoundPlayer::KviSoundPlayer()
+: QObject()
+{
+ m_pThreadList = new KviPointerList<KviSoundThread>;
+ m_pThreadList->setAutoDelete(true);
+
+ m_pSoundSystemDict = new KviPointerHashTable<QString,SoundSystemRoutine>(17,false);
+ m_pSoundSystemDict->setAutoDelete(true);
+
+#ifdef COMPILE_ON_WINDOWS
+ m_pSoundSystemDict->insert("winmm",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playWinmm)));
+#else //!COMPILE_ON_WINDOWS
+ #ifdef COMPILE_OSS_SUPPORT
+ #ifdef COMPILE_AUDIOFILE_SUPPORT
+ m_pSoundSystemDict->insert("oss+audiofile",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playOssAudiofile)));
+ #endif //COMPILE_AUDIOFILE_SUPPORT
+ m_pSoundSystemDict->insert("oss",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playOss)));
+ #endif //COMPILE_OSS_SUPPORT
+ #ifdef COMPILE_ESD_SUPPORT
+ m_pSoundSystemDict->insert("esd",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playEsd)));
+ #endif //COMPILE_ESD_SUPPORT
+ #ifdef COMPILE_ARTS_SUPPORT
+ m_pSoundSystemDict->insert("arts",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playArts)));
+ #endif //COMPILE_ARTS_SUPPORT
+#endif //!COMPILE_ON_WINDOWS
+
+#if QT_VERSION >= 0x030100
+ if(QSound::isAvailable())
+ m_pSoundSystemDict->insert("qt",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playQt)));
+#else
+ if(QSound::available())
+ m_pSoundSystemDict->insert("qt",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playQt)));
+#endif
+
+ m_pSoundSystemDict->insert("null",new SoundSystemRoutine(KVI_PTR2MEMBER(KviSoundPlayer::playNull)));
+
+}
+
+KviSoundPlayer::~KviSoundPlayer()
+{
+ m_pThreadList->setAutoDelete(false);
+ while(KviSoundThread * t = m_pThreadList->first())delete t;
+ delete m_pThreadList;
+ KviThreadManager::killPendingEvents(this);
+ delete m_pSoundSystemDict;
+
+#ifndef COMPILE_ON_WINDOWS
+ #ifdef COMPILE_ARTS_SUPPORT
+ if(g_pArtsDispatcher)delete g_pArtsDispatcher;
+ g_pArtsDispatcher = 0;
+ #endif
+#endif //!COMPILE_ON_WINDOWS
+ g_pSoundPlayer = 0;
+}
+
+void KviSoundPlayer::getAvailableSoundSystems(QStringList *l)
+{
+ KviPointerHashTableIterator<QString,SoundSystemRoutine> it(*m_pSoundSystemDict);
+ while(it.current())
+ {
+ l->append(it.currentKey());
+ ++it;
+ }
+}
+
+
+bool KviSoundPlayer::havePlayingSounds()
+{
+ return (m_pThreadList->count() > 0);
+}
+
+void KviSoundPlayer::registerSoundThread(KviSoundThread * t)
+{
+ m_pThreadList->append(t);
+}
+
+void KviSoundPlayer::unregisterSoundThread(KviSoundThread * t)
+{
+ m_pThreadList->removeRef(t);
+}
+
+bool KviSoundPlayer::event(QEvent * e)
+{
+ if(e->type() == KVI_THREAD_EVENT)
+ {
+ KviThread * t = ((KviThreadEvent *)e)->sender();
+ if(!t)return true; // huh ?
+ delete (KviSoundThread *)t;
+ return true;
+ }
+ return QObject::event(e);
+}
+
+
+void KviSoundPlayer::detectSoundSystem()
+{
+#ifdef COMPILE_ON_WINDOWS
+ KVI_OPTION_STRING(KviOption_stringSoundSystem) = "winmm";
+#else
+ #ifdef COMPILE_ARTS_SUPPORT
+ if(!g_pArtsDispatcher)g_pArtsDispatcher = new Arts::Dispatcher();
+
+ Arts::SimpleSoundServer *server = new Arts::SimpleSoundServer(Arts::Reference("global:Arts_SimpleSoundServer"));
+ if(!server->isNull())
+ {
+ //Don't change the order of those deletes!
+ KVI_OPTION_STRING(KviOption_stringSoundSystem) = "arts";
+ delete server;
+ return;
+ }
+ delete server;
+ #endif //COMPILE_ARTS_SUPPORT
+ #ifdef COMPILE_ESD_SUPPORT
+ esd_format_t format = ESD_BITS16 | ESD_STREAM | ESD_PLAY | ESD_MONO;
+ int esd_fd = esd_play_stream(format, 8012, NULL, "kvirc");
+ if(esd_fd >= 0)
+ {
+ KVI_OPTION_STRING(KviOption_stringSoundSystem) = "esd";
+ return;
+ }
+ #endif
+ #ifdef COMPILE_OSS_SUPPORT
+ #ifdef COMPILE_AUDIOFILE_SUPPORT
+ KVI_OPTION_STRING(KviOption_stringSoundSystem) = "oss+audiofile";
+ return;
+ #endif
+ KVI_OPTION_STRING(KviOption_stringSoundSystem) = "oss";
+ #endif
+
+#if QT_VERSION >= 0x030100
+ if(QSound::isAvailable())
+#else
+ if(QSound::available())
+#endif
+ {
+ KVI_OPTION_STRING(KviOption_stringSoundSystem) = "qt";
+ return;
+ }
+
+ KVI_OPTION_STRING(KviOption_stringSoundSystem) = "null";
+#endif
+}
+
+#ifdef COMPILE_ON_WINDOWS
+ bool KviSoundPlayer::playWinmm(const QString &szFileName)
+ {
+ if(isMuted()) return true;
+ sndPlaySound(szFileName.local8Bit().data(),SND_ASYNC | SND_NODEFAULT);
+ return true;
+ }
+#else //!COMPILE_ON_WINDOWS
+ #ifdef COMPILE_OSS_SUPPORT
+ #ifdef COMPILE_AUDIOFILE_SUPPORT
+ bool KviSoundPlayer::playOssAudiofile(const QString &szFileName)
+ {
+ if(isMuted()) return true;
+ KviOssAudiofileSoundThread * t = new KviOssAudiofileSoundThread(szFileName);
+ if(!t->start())
+ {
+ delete t;
+ return false;
+ }
+ return true;
+ }
+ #endif //COMPILE_AUDIOFILE_SUPPORT
+ bool KviSoundPlayer::playOss(const QString &szFileName)
+ {
+ if(isMuted()) return true;
+ KviOssSoundThread * t = new KviOssSoundThread(szFileName);
+ if(!t->start())
+ {
+ delete t;
+ return false;
+ }
+ return true;
+ }
+ #endif //COMPILE_OSS_SUPPORT
+ #ifdef COMPILE_ESD_SUPPORT
+ bool KviSoundPlayer::playEsd(const QString &szFileName)
+ {
+ if(isMuted()) return true;
+ KviEsdSoundThread * t = new KviEsdSoundThread(szFileName);
+ if(!t->start())
+ {
+ delete t;
+ return false;
+ }
+ return true;
+ }
+ #endif //COMPILE_ESD_SUPPORT
+ #ifdef COMPILE_ARTS_SUPPORT
+ bool KviSoundPlayer::playArts(const QString &szFileName)
+ {
+ if(isMuted()) return true;
+ KviArtsSoundThread * t = new KviArtsSoundThread(szFileName);
+ if(!t->start())
+ {
+ delete t;
+ return false;
+ }
+ return true;
+ }
+ #endif //COMPILE_ARTS_SUPPORT
+#endif //!COMPILE_ON_WINDOWS
+
+bool KviSoundPlayer::playQt(const QString &szFileName)
+{
+ if(isMuted()) return true;
+ QSound::play(szFileName);
+ return true;
+}
+
+bool KviSoundPlayer::playNull(const QString &szFileName)
+{
+ // null sound system
+ return true;
+}
+
+
+bool KviSoundPlayer::play(const QString &szFileName)
+{
+ if(isMuted()) return true;
+ SoundSystemRoutine * r = m_pSoundSystemDict->find(KVI_OPTION_STRING(KviOption_stringSoundSystem));
+
+ if(!r)
+ {
+ if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringSoundSystem),"unknown"))
+ {
+ detectSoundSystem();
+ r = m_pSoundSystemDict->find(KVI_OPTION_STRING(KviOption_stringSoundSystem));
+ if(!r)return false;
+ } else {
+ return false;
+ }
+ }
+
+ return (this->*(*r))(szFileName);
+}
+
+
+
+
+KviSoundThread::KviSoundThread(const QString &szFileName)
+: KviThread()
+{
+ g_pSoundPlayer->registerSoundThread(this);
+ m_szFileName = szFileName;
+}
+
+KviSoundThread::~KviSoundThread()
+{
+ g_pSoundPlayer->unregisterSoundThread(this);
+}
+
+void KviSoundThread::play()
+{
+}
+
+void KviSoundThread::run()
+{
+ play();
+#ifndef COMPILE_ON_WINDOWS
+ postEvent(g_pSoundPlayer,new KviThreadEvent(KVI_THREAD_EVENT_SUCCESS));
+#endif
+}
+
+
+#ifndef COMPILE_ON_WINDOWS
+ #ifdef COMPILE_OSS_SUPPORT
+ #ifdef COMPILE_AUDIOFILE_SUPPORT
+ KviOssAudiofileSoundThread::KviOssAudiofileSoundThread(const QString &szFileName)
+ : KviSoundThread(szFileName)
+ {
+ }
+
+ KviOssAudiofileSoundThread::~KviOssAudiofileSoundThread()
+ {
+ }
+
+ void KviOssAudiofileSoundThread::play()
+ {
+ #define BUFFER_FRAMES 4096
+
+ AFfilehandle file;
+ AFframecount framesRead;
+ int sampleFormat, sampleWidth, channelCount, format, freq;
+ float frameSize;
+ void * buffer;
+
+ file = afOpenFile(m_szFileName.utf8().data(),"r",NULL);
+ afGetVirtualSampleFormat(file, AF_DEFAULT_TRACK, &sampleFormat, &sampleWidth);
+ frameSize = afGetVirtualFrameSize(file, AF_DEFAULT_TRACK, 1);
+ channelCount = afGetVirtualChannels(file, AF_DEFAULT_TRACK);
+ buffer = kvi_malloc(int(BUFFER_FRAMES * frameSize));
+
+ int audiofd_c = open("/dev/dsp", O_WRONLY | O_EXCL | O_NDELAY);
+ QFile audiofd;
+ audiofd.open(IO_WriteOnly,audiofd_c);
+
+ if(audiofd_c < 0)
+ {
+ debug("Could not open audio devive /dev/dsp! [OSS]");
+ debug("(the device is probably busy)");
+ goto exit_thread;
+ }
+
+ if (sampleWidth == 8) format = AFMT_U8;
+ else if (sampleWidth == 16)format = AFMT_S16_NE;
+
+ if (ioctl(audiofd.handle(),SNDCTL_DSP_SETFMT, &format) == -1)
+ {
+ debug("Could not set format width to DSP! [OSS]");
+ goto exit_thread;
+ }
+
+ if (ioctl(audiofd.handle(), SNDCTL_DSP_CHANNELS, &channelCount) == -1)
+ {
+ debug("Could not set DSP channels! [OSS]");
+ goto exit_thread;
+ }
+
+ freq = (int) afGetRate(file, AF_DEFAULT_TRACK);
+ if (ioctl(audiofd.handle(), SNDCTL_DSP_SPEED, &freq) == -1)
+ {
+ debug("Could not set DSP speed %d! [OSS]",freq);
+ goto exit_thread;
+ }
+
+ framesRead = afReadFrames(file, AF_DEFAULT_TRACK, buffer, BUFFER_FRAMES);
+
+ while(framesRead > 0)
+ {
+ audiofd.writeBlock((char *)buffer,(int)(framesRead * frameSize));
+ framesRead = afReadFrames(file, AF_DEFAULT_TRACK, buffer,BUFFER_FRAMES);
+ }
+
+ exit_thread:
+ audiofd.close();
+ if(audiofd_c >= 0)close(audiofd_c);
+ afCloseFile(file);
+ kvi_free(buffer);
+ }
+ #endif //COMPILE_AUDIOFILE_SUPPORT
+
+
+ KviOssSoundThread::KviOssSoundThread(const QString &szFileName)
+ : KviSoundThread(szFileName)
+ {
+ }
+
+ KviOssSoundThread::~KviOssSoundThread()
+ {
+ }
+
+ void KviOssSoundThread::play()
+ {
+ #define OSS_BUFFER_SIZE 16384
+
+ QFile f(m_szFileName);
+ int fd = -1;
+ char buf[OSS_BUFFER_SIZE];
+ int iDataLen = 0;
+ int iSize = 0;
+
+ if(!f.open(IO_ReadOnly))
+ {
+ debug("Could not open sound file %s! [OSS]",m_szFileName.utf8().data());
+ return;
+ }
+
+ iSize = f.size();
+
+ if(iSize < 24)
+ {
+ debug("Could not play sound, file %s too small! [OSS]",m_szFileName.utf8().data());
+ goto exit_thread;
+ }
+
+ if(f.readBlock(buf,24) < 24)
+ {
+ debug("Error while reading the sound file header (%s)! [OSS]",m_szFileName.utf8().data());
+ goto exit_thread;
+ }
+
+ iSize -= 24;
+
+ fd = open("/dev/audio", O_WRONLY | O_EXCL | O_NDELAY);
+ if(fd < 0)
+ {
+ debug("Could not open device file /dev/audio!");
+ debug("Maybe other program is using the device? Hint: fuser -uv /dev/audio");
+ goto exit_thread;
+ }
+
+
+ while(iSize > 0)
+ {
+ int iCanRead = OSS_BUFFER_SIZE - iDataLen;
+ if(iCanRead > 0)
+ {
+ int iToRead = iSize > iCanRead ? iCanRead : iSize;
+ int iReaded = f.readBlock(buf + iDataLen,iToRead);
+ if(iReaded < 1)
+ {
+ debug("Error while reading the file data (%s)! [OSS]",m_szFileName.utf8().data());
+ goto exit_thread;
+ }
+ iSize -= iReaded;
+ iDataLen += iReaded;
+ }
+ if(iDataLen > 0)
+ {
+ int iWritten = write(fd,buf,iDataLen);
+ if(iWritten < 0)
+ {
+ if((errno != EINTR) && (errno != EAGAIN))
+ {
+ debug("Error while writing the audio data (%s)! [OSS]",m_szFileName.utf8().data());
+ goto exit_thread;
+ }
+ }
+ iDataLen -= iWritten;
+ } else {
+ // nothing to write ????
+ goto exit_thread;
+ }
+ }
+
+ exit_thread:
+ f.close();
+ if(fd > 0)close(fd);
+ }
+
+
+ #endif //COMPILE_OSS_SUPPORT
+
+ #ifdef COMPILE_ESD_SUPPORT
+
+ KviEsdSoundThread::KviEsdSoundThread(const QString &szFileName)
+ : KviSoundThread(szFileName)
+ {
+ }
+
+ KviEsdSoundThread::~KviEsdSoundThread()
+ {
+ }
+
+ void KviEsdSoundThread::play()
+ {
+ // ESD has a really nice API
+ if(!esd_play_file(NULL,m_szFileName.utf8().data(),1))
+ debug("Could not play sound %s! [ESD]",m_szFileName.utf8().data());
+ }
+
+ #endif //COMPILE_ESD_SUPPORT
+
+ #ifdef COMPILE_ARTS_SUPPORT
+
+ KviArtsSoundThread::KviArtsSoundThread(const QString &szFileName)
+ : KviSoundThread(szFileName)
+ {
+ }
+
+ KviArtsSoundThread::~KviArtsSoundThread()
+ {
+ }
+
+ void KviArtsSoundThread::play()
+ {
+ if(!g_pArtsDispatcher)g_pArtsDispatcher = new Arts::Dispatcher;
+
+ Arts::SimpleSoundServer *server = new Arts::SimpleSoundServer(Arts::Reference("global:Arts_SimpleSoundServer"));
+ if(server->isNull())
+ {
+ debug("Can't connect to sound server to play file %s",m_szFileName.utf8().data());
+ } else {
+ server->play(m_szFileName);
+ }
+ delete server;
+ }
+ #endif
+
+
+#endif //!COMPILE_ON_WINDOWS
+
+
+/*
+ @doc: snd.play
+ @type:
+ command
+ @title:
+ snd.play
+ @short:
+ Play a sound file from the disk
+ @syntax:
+ snd.play [-q|quiet] <filename:string>
+ @description:
+ Play a file, using the sound system specified by the user in the options.[br]
+ The supported file formats vary from one sound system to another, but the best
+ bet could be Au Law (.au) files. Artsd, EsounD and Linux/OSS with audiofile support also
+ support other formats like .wav files but in OSS without audiofile only .au files are
+ supported.
+ On windows the supported file formats are determined by the drivers installed.
+ You should be able to play at least *.wav files.[br]
+ (This is a task where the Windows interface is really well done, I must say that :)
+ @switches:
+ !sw: -q | --quiet
+ Causes the command to run quietly (no complains about missing files, invalid formats...
+*/
+
+static bool snd_kvs_cmd_play(KviKvsModuleCommandCall * c)
+{
+ QString szFile;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("file name",KVS_PT_STRING,0,szFile)
+ KVSM_PARAMETERS_END(c)
+ if(szFile.isEmpty() || (!KviFileUtils::fileExists(szFile)))
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("Sound file '%Q' not found"),&szFile);
+ return true;
+ }
+
+ if(!g_pSoundPlayer->play(szFile))
+ {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("Unable to play sound '%Q'"),&szFile);
+ }
+
+ return true;
+}
+
+static bool snd_kvs_cmd_autodetect(KviKvsModuleCommandCall * c)
+{
+ g_pSoundPlayer->detectSoundSystem();
+ if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringSoundSystem),"null"))
+ {
+ c->window()->outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Sorry , I can't find a sound system to use on this machine"));
+ } else {
+ c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Sound system detected to: %s"),KVI_OPTION_STRING(KviOption_stringSoundSystem).utf8().data());
+ }
+ return true;
+}
+
+
+/*
+ @doc: snd.mute
+ @type:
+ command
+ @title:
+ snd.mute
+ @short:
+ Mute all sounds
+ @syntax:
+ snd.mute
+ @description:
+ Mute all sounds
+*/
+
+static bool snd_kvs_cmd_mute(KviKvsModuleCommandCall * c)
+{
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETERS_END(c)
+ g_pSoundPlayer->setMuted(TRUE);
+ return true;
+}
+
+/*
+ @doc: snd.unmute
+ @type:
+ command
+ @title:
+ snd.unmute
+ @short:
+ UnMute all sounds
+ @syntax:
+ snd.mute
+ @description:
+ UnMute all sounds
+*/
+
+static bool snd_kvs_cmd_unmute(KviKvsModuleCommandCall * c)
+{
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETERS_END(c)
+ g_pSoundPlayer->setMuted(FALSE);
+ return true;
+}
+
+/*
+ @doc: snd.isMuted
+ @type:
+ function
+ @title:
+ $snd.isMuted
+ @short:
+ Returns if the sounds muted
+ @syntax:
+ <bool> $snd.isMuted()
+ @description:
+ Returns if the sounds muted
+*/
+
+
+static bool snd_kvs_fnc_ismuted(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setBoolean(g_pSoundPlayer->isMuted());
+ return true;
+}
+
+static bool snd_module_init(KviModule * m)
+{
+ g_pSoundPlayer = new KviSoundPlayer();
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"autodetect",snd_kvs_cmd_autodetect);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"play",snd_kvs_cmd_play);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"mute",snd_kvs_cmd_mute);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"unmute",snd_kvs_cmd_unmute);
+
+ KVSM_REGISTER_FUNCTION(m,"isMuted",snd_kvs_fnc_ismuted);
+
+ return true;
+}
+
+static bool snd_module_cleanup(KviModule *m)
+{
+ delete g_pSoundPlayer;
+ g_pSoundPlayer = 0;
+ return true;
+}
+
+static bool snd_module_can_unload(KviModule *m)
+{
+ return !(g_pSoundPlayer->havePlayingSounds());
+}
+
+static bool snd_module_ctrl(KviModule * m,const char * operation,void * param)
+{
+ if(kvi_strEqualCI(operation,"getAvailableSoundSystems"))
+ {
+ // we expect param to be a pointer to QStringList
+ QStringList *l=(QStringList *)param;
+ g_pSoundPlayer->getAvailableSoundSystems(l);
+ return true;
+ }
+ if(kvi_strEqualCI(operation,"detectSoundSystem"))
+ {
+ g_pSoundPlayer->detectSoundSystem();
+ return true;
+ }
+ return false;
+}
+
+
+KVIRC_MODULE(
+ "Sound", // module name
+ "1.0.0", // module version
+ "(C) 2002 Szymon Stefanek (pragma at kvirc dot net)," \
+ "Juanjo Alvarez (juanjux at yahoo dot es)", // author & (C)
+ "Sound playing commands",
+ snd_module_init,
+ snd_module_can_unload,
+ snd_module_ctrl,
+ snd_module_cleanup
+)
+
+#include "libkvisnd.moc"
diff --git a/src/modules/snd/libkvisnd.h b/src/modules/snd/libkvisnd.h
new file mode 100644
index 00000000..6becfa38
--- /dev/null
+++ b/src/modules/snd/libkvisnd.h
@@ -0,0 +1,213 @@
+#ifndef _LIBKVISND_H_
+#define _LIBKVISND_H_
+
+//
+// File : libkvisnd.h
+// Creation date : Apr 21 2002 12:30:25 CEST by Juan Jos��varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 <qobject.h>
+
+#include "kvi_thread.h"
+#include "kvi_string.h"
+
+#include "kvi_pointerlist.h"
+#include "kvi_pointerhashtable.h"
+#include "kvi_options.h"
+
+//class KviWavSoundFileReader
+//{
+//public:
+// KviWavSoundFileReader(QFile * f);
+// ~KviWavSoundFileReader();
+//protected:
+// QFile * m_pFile;
+//public:
+// static bool recognize(KviFile * f);
+// bool readHeader();
+//};
+
+
+//bool KviWavSoundFileReader::recognize(KviFile * f)
+//{
+// kvi_u32_t tag;
+// if(!f->load(tag))return false;
+//
+// f->at(0);
+//}
+
+//bool KviWavSoundFileReader::readHeader()
+//{
+//
+//
+// tag = get_le32(pb);
+//
+// if (tag != MKTAG('R', 'I', 'F', 'F'))
+// return -1;
+// get_le32(pb); /* file size */
+// tag = get_le32(pb);
+// if (tag != MKTAG('W', 'A', 'V', 'E'))
+// return -1;
+//
+// size = find_tag(pb, MKTAG('f', 'm', 't', ' '));
+// if (size < 0)
+// return -1;
+// id = get_le16(pb);
+// channels = get_le16(pb);
+// rate = get_le32(pb);
+// bit_rate = get_le32(pb) * 8;
+// get_le16(pb); /* block align */
+// get_le16(pb); /* bits per sample */
+// if (size >= 18) {
+// /* wav_extra_size */
+// extra_size = get_le16(pb);
+// /* skip unused data */
+// url_fseek(pb, size - 18, SEEK_CUR);
+// }
+//
+// size = find_tag(pb, MKTAG('d', 'a', 't', 'a'));
+// if (size < 0)
+// return -1;
+//
+// /* now we are ready: build format streams */
+// st = malloc(sizeof(AVStream));
+// if (!st)
+// return -1;
+// s->nb_streams = 1;
+// s->streams[0] = st;
+//
+// st->id = 0;
+//
+// st->codec.codec_type = CODEC_TYPE_AUDIO;
+// st->codec.codec_tag = id;
+// st->codec.codec_id = codec_get_id(codec_wav_tags, id);
+// st->codec.channels = channels;
+// st->codec.sample_rate = rate;
+//}
+
+class KviSoundThread : public KviThread
+{
+public:
+ KviSoundThread(const QString &szFileName);
+ virtual ~KviSoundThread();
+protected:
+ QString m_szFileName;
+protected:
+ virtual void play();
+ virtual void run();
+};
+
+#ifndef COMPILE_ON_WINDOWS
+ #ifdef COMPILE_OSS_SUPPORT
+ class KviOssSoundThread : public KviSoundThread
+ {
+ public:
+ KviOssSoundThread(const QString &szFileName);
+ virtual ~KviOssSoundThread();
+ protected:
+ virtual void play();
+ };
+
+ #ifdef COMPILE_AUDIOFILE_SUPPORT
+ class KviOssAudiofileSoundThread : public KviSoundThread
+ {
+ public:
+ KviOssAudiofileSoundThread(const QString &szFileName);
+ virtual ~KviOssAudiofileSoundThread();
+ protected:
+ virtual void play();
+ };
+ #endif //COMPILE_AUDIOFILE_SUPPORT
+ #endif //COMPILE_OSS_SUPPORT
+
+ #ifdef COMPILE_ESD_SUPPORT
+ class KviEsdSoundThread : public KviSoundThread
+ {
+ public:
+ KviEsdSoundThread(const QString &szFileName);
+ virtual ~KviEsdSoundThread();
+ protected:
+ virtual void play();
+ };
+ #endif //COMPILE_ESD_SUPPORT
+
+ #ifdef COMPILE_ARTS_SUPPORT
+ class KviArtsSoundThread : public KviSoundThread
+ {
+ public:
+ KviArtsSoundThread(const QString &szFileName);
+ virtual ~KviArtsSoundThread();
+ protected:
+ virtual void play();
+ };
+ #endif //COMPILE_ARTS_SUPPORT
+#endif //!COMPILE_ON_WINDOWS
+
+class KviSoundPlayer;
+
+typedef bool (KviSoundPlayer::*SoundSystemRoutine)(const QString &szFileName);
+
+class KviSoundPlayer : public QObject
+{
+ friend class KviSoundThread;
+ Q_OBJECT
+public:
+ KviSoundPlayer();
+ virtual ~KviSoundPlayer();
+public:
+ bool play(const QString &szFileName);
+ void detectSoundSystem();
+ bool havePlayingSounds();
+ //void getAvailableSoundSystems(KviPointerList<QString> * l);
+ void getAvailableSoundSystems(QStringList * l);
+ bool isMuted() {return KVI_OPTION_BOOL(KviOption_boolMuteAllSounds); };
+ void setMuted(bool muted) {KVI_OPTION_BOOL(KviOption_boolMuteAllSounds)=muted;};
+protected:
+ KviPointerList<KviSoundThread> * m_pThreadList;
+ KviPointerHashTable<QString,SoundSystemRoutine> * m_pSoundSystemDict;
+protected:
+ void registerSoundThread(KviSoundThread * t);
+ void unregisterSoundThread(KviSoundThread * t);
+ virtual bool event(QEvent *e);
+protected:
+#ifdef COMPILE_ON_WINDOWS
+ bool playWinmm(const QString &szFileName);
+#else //!COMPILE_ON_WINDOWS
+ #ifdef COMPILE_OSS_SUPPORT
+ bool playOss(const QString &szFileName);
+ #ifdef COMPILE_AUDIOFILE_SUPPORT
+ bool playOssAudiofile(const QString &szFileName);
+ #endif //COMPILE_AUDIOFILE_SUPPORT
+ #endif //COMPILE_OSS_SUPPORT
+ #ifdef COMPILE_ARTS_SUPPORT
+ bool playArts(const QString &szFileName);
+ #endif //COMPILE_ARTS_SUPPORT
+ #ifdef COMPILE_ESD_SUPPORT
+ bool playEsd(const QString &szFileName);
+ #endif //COMPILE_ESD_SUPPORT
+#endif //!COMPILE_ON_WINDOWS
+ bool playQt(const QString &szFileName);
+ bool playNull(const QString &szFileName);
+};
+
+
+#endif // _KVISND_H_
diff --git a/src/modules/socketspy/Makefile.am b/src/modules/socketspy/Makefile.am
new file mode 100644
index 00000000..7e0a4b6b
--- /dev/null
+++ b/src/modules/socketspy/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvisocketspy.la
+
+libkvisocketspy_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvisocketspy_la_SOURCES = libkvisocketspy.cpp socketspywindow.cpp
+libkvisocketspy_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= socketspywindow.h
+
+m_%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+socketspywindow.cpp: m_socketspywindow.moc
diff --git a/src/modules/socketspy/libkvisocketspy.cpp b/src/modules/socketspy/libkvisocketspy.cpp
new file mode 100644
index 00000000..c4076620
--- /dev/null
+++ b/src/modules/socketspy/libkvisocketspy.cpp
@@ -0,0 +1,92 @@
+//
+// File : libkvisocketspy.cpp
+// Creation date : Sun Nov 26 2000 13:05:00 CEST by Szymon Stefanek
+//
+// Copyright (C) 1999-2000 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_module.h"
+
+
+#include "socketspywindow.h"
+
+#include "kvi_frame.h"
+#include "kvi_window.h"
+#include "kvi_locale.h"
+
+#include <qsplitter.h>
+
+KviPointerList<KviSocketSpyWindow> * g_pSocketSpyWindowList = 0;
+
+
+/*
+ @doc: socketspy.open
+ @type:
+ command
+ @title:
+ socketspy.open
+ @short:
+ Opens a SocketSpy window
+ @syntax:
+ socketspy.open
+ @description:
+ Creates a new socketspy window. A SocketSpy window
+ monitors the incoming and outgoing raw data on the
+ irc socket of the current irc context.
+*/
+
+static bool socketspy_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ if(!c->window()->console())return c->context()->errorNoIrcContext();
+ KviSocketSpyWindow *w = new KviSocketSpyWindow(c->window()->frame(),c->window()->console());
+ c->window()->frame()->addWindow(w);
+ return true;
+}
+
+static bool socketspy_module_init(KviModule * m)
+{
+ g_pSocketSpyWindowList = new KviPointerList<KviSocketSpyWindow>;
+ g_pSocketSpyWindowList->setAutoDelete(false);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",socketspy_kvs_cmd_open);
+ return true;
+}
+
+static bool socketspy_module_cleanup(KviModule *m)
+{
+ while(g_pSocketSpyWindowList->first())g_pSocketSpyWindowList->first()->die();
+ delete g_pSocketSpyWindowList;
+ g_pSocketSpyWindowList = 0;
+ return true;
+}
+
+static bool socketspy_module_can_unload(KviModule *m)
+{
+ return (g_pSocketSpyWindowList->isEmpty());
+}
+
+KVIRC_MODULE(
+ "SocketSpy", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "SocketSpy irc socket traffic monitor",
+ socketspy_module_init,
+ socketspy_module_can_unload,
+ 0,
+ socketspy_module_cleanup
+)
diff --git a/src/modules/socketspy/socketspywindow.cpp b/src/modules/socketspy/socketspywindow.cpp
new file mode 100644
index 00000000..4d59b5aa
--- /dev/null
+++ b/src/modules/socketspy/socketspywindow.cpp
@@ -0,0 +1,125 @@
+//
+// File : socketspywindow.cpp
+// Creation date : Thu Aug 31 2000 15:02:22 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the socketspys of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public 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 "socketspywindow.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_ircview.h"
+#include "kvi_out.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_console.h"
+
+#include <qsplitter.h>
+//#include "kvi_module.h"
+
+extern KviPointerList<KviSocketSpyWindow> * g_pSocketSpyWindowList;
+
+KviSocketSpyWindow::KviSocketSpyWindow(KviFrame * lpFrm,KviConsole * lpConsole)
+: KviWindow(KVI_WINDOW_TYPE_SOCKETSPY,lpFrm,"socket_spy",lpConsole) , KviIrcDataStreamMonitor(lpConsole->context())
+{
+ g_pSocketSpyWindowList->append(this);
+ #ifdef COMPILE_USE_QT4
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"splitter");
+ #else
+ m_pSplitter = new QSplitter(QSplitter::Horizontal,this,"splitter");
+#endif
+ m_pIrcView = new KviIrcView(m_pSplitter,lpFrm,this);
+ // Ensure proper focusing
+ //setFocusHandler(m_pIrcView,this);
+}
+
+KviSocketSpyWindow::~KviSocketSpyWindow()
+{
+ g_pSocketSpyWindowList->removeRef(this);
+}
+
+void KviSocketSpyWindow::die()
+{
+ close();
+}
+
+QPixmap * KviSocketSpyWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_SPY);
+}
+
+void KviSocketSpyWindow::resizeEvent(QResizeEvent *e)
+{
+ m_pSplitter->setGeometry(0,0,width(),height());
+}
+
+QSize KviSocketSpyWindow::sizeHint() const
+{
+ return m_pIrcView->sizeHint();
+}
+
+void KviSocketSpyWindow::getBaseLogFileName(KviStr &buffer)
+{
+ buffer.sprintf("SOCKETSPY_%d",console()->ircContextId());
+}
+
+void KviSocketSpyWindow::fillCaptionBuffers()
+{
+ KviQString::sprintf(m_szPlainTextCaption,__tr2qs("Socket Spy [IRC Context %u]"),m_pConsole->ircContextId());
+
+ KviQString::sprintf(m_szHtmlActiveCaption,
+ __tr2qs("<nobr><font color=\"%s\"><b>Socket Spy</b></font> " \
+ "<font color=\"%s\">[IRC Context %u]</font></nobr>"),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name().ascii(),
+ m_pConsole->ircContextId());
+
+ KviQString::sprintf(m_szHtmlInactiveCaption,
+ __tr2qs("<nobr><font color=\"%s\"><b>Socket Spy</b></font> " \
+ "<font color=\"%s\">[IRC Context %u]</font></nobr>"),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name().ascii(),
+ m_pConsole->ircContextId());
+}
+
+void KviSocketSpyWindow::incomingMessage(const char * message)
+{
+ outputNoFmt(KVI_OUT_SOCKETMESSAGE,console()->decodeText(message));
+}
+
+void KviSocketSpyWindow::outgoingMessage(const char * message,int len)
+{
+ KviStr str(message,len);
+ outputNoFmt(KVI_OUT_RAW,console()->decodeText(str.ptr()));
+}
+
+void KviSocketSpyWindow::connectionInitiated()
+{
+ output(KVI_OUT_SOCKETWARNING,__tr2qs("Socket open"));
+}
+
+void KviSocketSpyWindow::connectionTerminated()
+{
+ output(KVI_OUT_SOCKETWARNING,__tr2qs("Socket closed"));
+}
+
+void KviSocketSpyWindow::applyOptions()
+{
+ m_pIrcView->applyOptions();
+ KviWindow::applyOptions();
+}
+#include "m_socketspywindow.moc"
diff --git a/src/modules/socketspy/socketspywindow.h b/src/modules/socketspy/socketspywindow.h
new file mode 100644
index 00000000..ab516d3e
--- /dev/null
+++ b/src/modules/socketspy/socketspywindow.h
@@ -0,0 +1,53 @@
+#ifndef _SOCKETSPYWINDOW_H_
+#define _SOCKETSPYWINDOW_H_
+//
+// File : socketspywindow.h
+// Creation date : Sun Nov 26 2000 13:13:00 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the socketspys of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public 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_window.h"
+#include "kvi_string.h"
+#include "kvi_ircdatastreammonitor.h"
+
+class KviConsole;
+
+class KviSocketSpyWindow : public KviWindow, public KviIrcDataStreamMonitor
+{
+ Q_OBJECT
+public:
+ KviSocketSpyWindow(KviFrame * lpFrm,KviConsole * lpConsole);
+ ~KviSocketSpyWindow();
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void getBaseLogFileName(KviStr &buffer);
+ virtual void applyOptions();
+public:
+ virtual QSize sizeHint() const;
+ virtual void incomingMessage(const char * message);
+ // message is NOT null terminated! For proxy connections it might spit out binary data!
+ virtual void outgoingMessage(const char * message,int len);
+ virtual void connectionInitiated();
+ virtual void connectionTerminated();
+ virtual void die();
+};
+
+#endif //_KVI_SOCKETSPYWINDOW_H_
diff --git a/src/modules/spaste/Makefile.am b/src/modules/spaste/Makefile.am
new file mode 100644
index 00000000..f1a6f719
--- /dev/null
+++ b/src/modules/spaste/Makefile.am
@@ -0,0 +1,24 @@
+###############################################################################
+# KVirc IRC client Makestr - 10.03.2002 Juanjo lvarez <juanjux@yahoo.es>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+-I/usr/include/kde/arts\
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+#ARTS_LD_FLAGS = -DPIC -fPIC
+#ARTS_C_FLAGS = -L/usr/lib -ldl -lartsc -lpthread
+pluglib_LTLIBRARIES = libkvispaste.la
+
+libkvispaste_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvispaste_la_SOURCES = libkvispaste.cpp controller.cpp
+libkvispaste_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+
+noinst_HEADERS= controller.h libkvispaste.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+controller.cpp: controller.moc
diff --git a/src/modules/spaste/controller.cpp b/src/modules/spaste/controller.cpp
new file mode 100644
index 00000000..5a132dbd
--- /dev/null
+++ b/src/modules/spaste/controller.cpp
@@ -0,0 +1,121 @@
+// File : controller.cpp
+// Creation date : Thu Apr 30 2002 17:13:12 GMT by Juanjo lvarez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Juanjo lvarez (juanjux@yahoo.es)
+// Copyright (C) 2002 Szymon Stefanek (kvirc@tin.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 "controller.h"
+#include "kvi_window.h"
+#include "kvi_console.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+
+#include <qtimer.h>
+#include <qstringlist.h>
+#include <qclipboard.h>
+
+extern KviPointerList<SPasteController> * g_pControllerList;
+
+SPasteController::SPasteController(KviWindow * w,int id)
+ : m_pClipBuff(NULL),m_pFile(NULL),m_pId(id),m_pWindow(w)
+{
+ g_pControllerList->append(this);
+ //m_pWindow = w;
+ m_pTimer = new QTimer(this);
+}
+
+SPasteController::~SPasteController()
+{
+ g_pControllerList->removeRef(this);
+ if(m_pFile)
+ {
+ m_pFile->close();
+ delete m_pFile;
+ }
+ if(m_pTimer)
+ {
+ m_pTimer->stop();
+ delete m_pTimer;
+ }
+ if(m_pClipBuff)
+ delete m_pClipBuff;
+}
+
+bool SPasteController::pasteFileInit(QString &fileName)
+{
+ if(m_pClipBuff)return false; // can't paste a file while pasting the clipboard
+ if(m_pFile)return false; // can't paste two files at a time
+ m_pFile = new QFile(fileName);
+ if(!m_pFile->open(IO_ReadOnly))return false;
+ connect(m_pTimer,SIGNAL(timeout()),this,SLOT(pasteFile()));
+ m_pTimer->start(KVI_OPTION_UINT(KviOption_uintPasteDelay));
+ return true;
+}
+
+bool SPasteController::pasteClipboardInit(void)
+{
+ if(m_pFile)return false; // can't paste clipboard while pasting a file
+ QString tmp(g_pApp->clipboard()->text());
+ if(m_pClipBuff)
+ {
+ (*m_pClipBuff) += QStringList::split("\n",tmp,true);
+ } else {
+ m_pClipBuff = new QStringList(QStringList::split("\n",tmp,true));
+ m_clipBuffIterator = m_pClipBuff->begin();
+ }
+ connect(m_pTimer,SIGNAL(timeout()),this,SLOT(pasteClipboard()));
+ m_pTimer->start(KVI_OPTION_UINT(KviOption_uintPasteDelay));
+ return true;
+}
+
+void SPasteController::pasteFile(void)
+{
+#ifndef COMPILE_USE_QT4
+ QString line;
+ if(m_pFile->readLine(line,999) != -1)
+ {
+ if(line.isEmpty())
+ line = QChar(KVI_TEXT_RESET);
+ if( (!g_pApp->windowExists(m_pWindow)) || m_pWindow->console()->isNotConnected() )
+ {
+ m_pFile->close();
+ delete this;
+ } else m_pWindow->ownMessage(line.ascii());
+ } else { //File finished
+ m_pFile->close();
+ delete this;
+ }
+#endif
+}
+
+void SPasteController::pasteClipboard(void)
+{
+ if(m_clipBuffIterator != m_pClipBuff->end())
+ {
+ if((!g_pApp->windowExists(m_pWindow)) || m_pWindow->console()->isNotConnected() )
+ delete this;
+ else {
+ if((*m_clipBuffIterator).isEmpty())(*m_clipBuffIterator) = QChar(KVI_TEXT_RESET);
+ m_pWindow->ownMessage((*m_clipBuffIterator).ascii()); // <-- not good :/
+ ++m_clipBuffIterator;
+ }
+ } else delete this;//Clipboard finished
+}
+
+#include "controller.moc"
diff --git a/src/modules/spaste/controller.h b/src/modules/spaste/controller.h
new file mode 100644
index 00000000..55aeeaab
--- /dev/null
+++ b/src/modules/spaste/controller.h
@@ -0,0 +1,59 @@
+// File : controller.h
+// Creation date : Thu Apr 30 2002 17:13:12 GMT by Juanjo lvarez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Juanjo lvarez (juanjux@yahoo.es)
+// Copyright (C) 2002 Szymon Stefanek (kvirc@tin.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.
+
+#ifndef SPASTE_CONTROLLER_H
+#define SPASTE_CONTROLLER_H
+
+#include "kvi_window.h"
+#include "kvi_string.h"
+
+#include <qobject.h>
+#include <qstringlist.h>
+#include <qfile.h>
+
+class SPasteController : public QObject
+{
+ Q_OBJECT
+public:
+ SPasteController(KviWindow * w,int id);
+ ~SPasteController();
+
+ //bool pasteFileInit(KviStr * fileName);
+ bool pasteFileInit(QString &fileName);
+ bool pasteClipboardInit(void);
+ int getId(void){return m_pId;};
+ KviWindow * window(void){return m_pWindow;};
+ //void stop(void);
+protected slots:
+ void pasteFile(void);
+ void pasteClipboard(void);
+
+private:
+ QStringList *m_pClipBuff;
+ QFile *m_pFile;
+ int m_pId;
+ KviWindow *m_pWindow;
+ QTimer *m_pTimer;
+ QStringList::Iterator m_clipBuffIterator;
+};
+
+#endif //SPASTE_CONTROLLER_H
+
diff --git a/src/modules/spaste/libkvispaste.cpp b/src/modules/spaste/libkvispaste.cpp
new file mode 100644
index 00000000..6b310324
--- /dev/null
+++ b/src/modules/spaste/libkvispaste.cpp
@@ -0,0 +1,346 @@
+// File : libkvispaste.cpp
+// Creation date : Thu Dec 27 2002 17:13:12 GMT by Juanjo �varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Juanjo �varez (juanjux@yahoo.es)
+// Copyright (C) 2002 Szymon Stefanek (kvirc@tin.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 "libkvispaste.h"
+#include "controller.h"
+
+#include "kvi_module.h"
+
+#include "kvi_fileutils.h"
+#include "kvi_app.h"
+#include "kvi_locale.h"
+
+#include "kvi_console.h"
+#include "kvi_options.h"
+#include "kvi_out.h"
+
+#include <qfile.h>
+#include <qclipboard.h>
+
+#ifndef COMPILE_ON_WINDOWS
+ #include <unistd.h>
+#endif
+
+KviPointerList<SPasteController> * g_pControllerList = 0;
+int ctrlId = 0;
+
+static SPasteController * spaste_find_controller(KviWindow * w)
+{
+ for(SPasteController * spc = g_pControllerList->first();spc;spc = g_pControllerList->next())
+ {
+ if(spc->window() == w)return spc;
+ }
+ return 0;
+}
+
+static KviWindow * spaste_kvs_find_window(QString &win, KviKvsModuleCommandCall * c)
+{
+ KviWindow * w;
+ if(!win.isEmpty())w = g_pApp->findWindow(win);
+ else w = c->window();
+ if(!w)
+ {
+ c->warning(__tr("Window with ID '%Q' not found"),&win);
+ return 0;
+ }
+ if((w->type() == KVI_WINDOW_TYPE_CHANNEL) || (w->type() == KVI_WINDOW_TYPE_QUERY) || (w->type() == KVI_WINDOW_TYPE_DCCCHAT))return w;
+ c->warning(__tr2qs("The specified window (%Q) is not a channel/query/DCC chat"),&win);
+ return 0;
+}
+//-------------------------------------------------
+/*
+ @doc: spaste.file
+ @type:
+ command
+ @title:
+ spaste.file
+ @short:
+ Sends the contents of a file to a window, with a delay between each line
+ @syntax:
+ spaste.file <filename:string> [window:string]
+ @description:
+ Sends the contents of a file to a conversation window doing a pause between each line. [br]
+ the optional window parameter must be a channel, query or DCC chat window, if [br]
+ no window is specified the text will be send to the current window.
+ @seealso:
+ [cmd]spaste.clipboard[/cmd],
+ [cmd]spaste.stop[/cmd],
+ [cmd]spaste.list[/cmd],
+ [cmd]spaste.setdelay[/cmd]
+*/
+//-------------------------------------------
+// spaste.file
+//-------------------------------------------
+
+static bool spaste_kvs_cmd_file(KviKvsModuleCommandCall * c)
+{
+ QString szFile,szWindow;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("file name",KVS_PT_STRING,0,szFile)
+ KVSM_PARAMETER("window",KVS_PT_STRING,KVS_PF_OPTIONAL,szWindow)
+ KVSM_PARAMETERS_END(c)
+
+ KviWindow * window = spaste_kvs_find_window(szWindow,c);
+ if( (!window) || window->console()->isNotConnected())return false;
+
+ if(szFile.isEmpty() || (!KviFileUtils::fileExists(szFile.ascii())))
+ {
+ c->warning(__tr2qs("File not found or empty"));
+ return false;
+ }
+
+ QFile tmp(szFile);
+ if(!tmp.open(IO_ReadOnly)) {
+ c->warning(__tr2qs("I can't open that file"));
+ return false;
+ }
+ tmp.close();
+
+ SPasteController * controller = spaste_find_controller(window);
+ if(!controller)controller = new SPasteController(window,++ctrlId);
+ if(!controller->pasteFileInit(szFile)) {
+ c->warning(__tr2qs("Could not paste file"));
+ return false;
+ }
+ return true;
+}
+
+
+/*
+ @doc: spaste.clipboard
+ @type:
+ command
+ @title:
+ spaste.clipboard
+ @short:
+ Sends the contents of the clipboard to a window, pausing between each line
+ @syntax:
+ spaste.clipboard [window:string]
+ @description:
+ Sends the contents of the clipboard to a conversation window, with a delay between each line. [br]
+ the optional window parameter must be a channel, query or DCC chat window. [br]
+ If no window is specified, the text will be sent to the current window.
+ @seealso:
+ [cmd]spaste.file[/cmd],
+ [cmd]spaste.stop[/cmd],
+ [cmd]spaste.list[/cmd],
+ [cmd]spaste.setdelay[/cmd]
+*/
+//-------------------------------------------------
+// spaste.clipboard
+//-------------------------------------------------
+
+static bool spaste_kvs_cmd_clipboard(KviKvsModuleCommandCall * c)
+{
+ QString szWindow;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window",KVS_PT_STRING,KVS_PF_OPTIONAL,szWindow)
+ KVSM_PARAMETERS_END(c)
+ KviWindow * window = spaste_kvs_find_window(szWindow,c);
+ if( (!window) || window->console()->isNotConnected())return false;
+
+ SPasteController * controller = spaste_find_controller(window);
+ if(!controller)controller = new SPasteController(window,++ctrlId);
+ controller->pasteClipboardInit();
+ return true;
+}
+
+/*
+ @doc: spaste.stop
+ @type:
+ command
+ @title:
+ spaste.stop
+ @short:
+ Stops one or more slow-paste process.
+ @syntax:
+ spaste.stop [-a] [id:integer]
+ @description:
+ This commands stop one or more slow-paste processes. It can operate in three ways. The first, [br]
+ without any parameter or switch, stops all slow-paste processes running in the same window [br]
+ as the command. The second, using the -a switch, stops all slow paste processes running [br]
+ on all windows. The third form, without the switch and specifying a numerical slow paste process ID [br]
+ (which you can obtain with the [cmd]spaste.list[/cmd] command), stops only that process ID.
+ @switches:
+ !sw: -a | --all
+ Stops all slow paste processes running
+ @seealso:
+ [cmd]spaste.clipboard[/cmd],
+ [cmd]spaste.file[/cmd],
+ [cmd]spaste.list[/cmd],
+ [cmd]spaste.setdelay[/cmd]
+
+*/
+//--------------------------------------------------
+// spaste.stop
+//--------------------------------------------------
+
+static bool spaste_kvs_cmd_stop(KviKvsModuleCommandCall * c)
+{
+ kvs_int_t iId=0;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("delay",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,iId)
+ KVSM_PARAMETERS_END(c)
+
+ if(c->hasSwitch('a',"all")) //Delete all spaste's
+ {
+ while(g_pControllerList->first()) delete g_pControllerList->first();
+ return true;
+ } else {
+ KviPointerListIterator<SPasteController> it(*g_pControllerList);
+ SPasteController *item;
+
+ if(!iId) //Delete all spaste's from the current window
+ {
+ if((c->window()->type() != KVI_WINDOW_TYPE_CHANNEL) && (c->window()->type() != KVI_WINDOW_TYPE_QUERY) && (c->window()->type() != KVI_WINDOW_TYPE_DCCCHAT))
+ {
+ QString szWinId = c->window()->id();
+ c->warning(__tr2qs("The specified window (%Q) is not a channel/query/dcc"),&szWinId);
+ return false;
+ } else {
+ while( (item = it.current()) != 0)
+ {
+ ++it;
+ if(kvi_strEqualCS(item->window()->id(),c->window()->id()))delete item;
+ }
+ }
+ } else //Delete the spaste with the given id
+ {
+ while( (item = it.current()) != 0)
+ {
+ ++it;
+ if(item->getId() == iId)delete item;
+ }
+ }
+ return true;
+ }
+}
+
+/*
+ @doc: spaste.list
+ @type:
+ command
+ @title:
+ spaste.list
+ @short:
+ Lists all the running spaste processes.
+ @syntax:
+ spaste.list
+ @description:
+ This command will list in the window where it is executed all the current slow-paste [br]
+ processes, their identification numbers, and the windows where they are running. [br]
+ @seealso:
+ [cmd]spaste.clipboard[/cmd],
+ [cmd]spaste.file[/cmd],
+ [cmd]spaste.stop[/cmd],
+ [cmd]spaste.setdelay[/cmd]
+*/
+//--------------------------------------------------
+// spaste.list
+//--------------------------------------------------
+
+static bool spaste_kvs_cmd_list(KviKvsModuleCommandCall * c)
+{
+ KviPointerListIterator<SPasteController> it(*g_pControllerList);
+ SPasteController *item;
+
+ while( (item = it.current()) != 0)
+ {
+ ++it;
+ QString szWinId = item->window()->id();
+ c->window()->output(KVI_OUT_NONE,__tr2qs("Slow-paste ID:%d Window:%Q"),item->getId(),&szWinId);
+ }
+ return true;
+}
+
+/*
+ @doc: spaste.setdelay
+ @type:
+ command
+ @title:
+ spaste.setdelay
+ @short:
+ Sets the delay time in miliseconds for the spaste module command delay
+ @syntax:
+ spaste.setdelay <time_in_msecs:integer>
+ @description:
+ Sets the delay time in milliseconds for the spaste module command delay.
+ @seealso:
+ [cmd]spaste.clipboard[/cmd],
+ [cmd]spaste.file[/cmd],
+ [cmd]spaste.stop[/cmd],
+ [cmd]spaste.list[/cmd]
+*/
+//-------------------------------------------------
+// spaste.setdelay
+//-------------------------------------------------
+
+
+static bool spaste_kvs_cmd_setdelay(KviKvsModuleCommandCall * c)
+{
+ kvs_int_t delay;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("delay",KVS_PT_INTEGER,0,delay)
+ KVSM_PARAMETERS_END(c)
+ KVI_OPTION_UINT(KviOption_uintPasteDelay) = delay;
+ return true;
+}
+
+//-------------------------------------------------
+static bool spaste_module_init(KviModule * m)
+{
+ g_pControllerList = new KviPointerList<SPasteController>;
+ g_pControllerList->setAutoDelete(false);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"file",spaste_kvs_cmd_file);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"clipboard",spaste_kvs_cmd_clipboard);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setdelay",spaste_kvs_cmd_setdelay);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"stop",spaste_kvs_cmd_stop);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"list",spaste_kvs_cmd_list);
+ return true;
+}
+//-------------------------------------------------
+static bool spaste_module_cleanup(KviModule *m)
+{
+ while(g_pControllerList->first()) delete g_pControllerList->first();
+ delete g_pControllerList;
+ g_pControllerList = 0;
+
+ return true;
+}
+//-------------------------------------------------
+static bool spaste_module_can_unload(KviModule *m)
+{
+ return (g_pControllerList->isEmpty());
+}
+//-------------------------------------------------
+KVIRC_MODULE(
+ "SPaste", // module name
+ "1.0.0", // module version
+ " (C) 2002 Juanjo Alvarez (juanjux@yahoo.es)", // author & (C)
+ "Delayed paste commands",
+ spaste_module_init,
+ spaste_module_can_unload,
+ 0,
+ spaste_module_cleanup
+)
diff --git a/src/modules/spaste/libkvispaste.h b/src/modules/spaste/libkvispaste.h
new file mode 100644
index 00000000..53724c2d
--- /dev/null
+++ b/src/modules/spaste/libkvispaste.h
@@ -0,0 +1,13 @@
+#ifndef KVISPASTE_H
+#define KVISPASTE_H
+
+#include "kvi_window.h"
+
+typedef struct _SPasteThreadData {
+ QString * strData;
+ KviWindow * win;
+} SPasteThreadData;
+
+
+
+#endif
diff --git a/src/modules/str/Makefile.am b/src/modules/str/Makefile.am
new file mode 100644
index 00000000..7fe7e93a
--- /dev/null
+++ b/src/modules/str/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makestr - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvistr.la
+
+libkvistr_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvistr_la_SOURCES = libkvistr.cpp
+libkvistr_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/str/libkvistr.cpp b/src/modules/str/libkvistr.cpp
new file mode 100644
index 00000000..58549f57
--- /dev/null
+++ b/src/modules/str/libkvistr.cpp
@@ -0,0 +1,2330 @@
+//=============================================================================
+//
+// File : libkvistr.cpp
+// Creation date : Thu Dec 27 2001 17:13:12 GMT by Szymon Stefanek
+//
+// This str is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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.
+//
+//=============================================================================
+
+//#warning: FIXME: Incomplete documentation ('seealso', 'example', etc)
+
+#include "kvi_module.h"
+
+#include "kvi_locale.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_qstring.h"
+#include "kvi_debug.h"
+#include "kvi_settings.h"
+#include "kvi_malloc.h"
+
+#include "kvi_kvs_arraycast.h"
+#include <qregexp.h>
+#include <qclipboard.h>
+
+#ifdef COMPILE_SSL_SUPPORT
+ #include <openssl/evp.h>
+#endif
+
+/*
+ @doc: str.section
+ @type:
+ function
+ @title:
+ $str.section
+ @short:
+ Returns a section of the string.
+ @syntax:
+ <string> $str.section(<string_to_split:string>,<separator:string>,<pos_from:int>,<pos_to:int>)
+ @description:
+ Returns a section of the string.
+ The <string_to_split> is treated as a sequence of fields separated by <separator>.[br]
+ The returned string consists of the fields from position start <pos_from> to position end <pos_to>.[br]
+ Fields are numbered 0, 1, 2, etc., counting from the left, and -1, -2, etc., counting from right to left.[br]
+ @examples:
+ [example]
+ %s = $str.section( "forename**middlename**surname**phone","**", 2, 2 );
+ %s is "surname".
+ [/example]
+*/
+
+static bool str_kvs_fnc_section(KviKvsModuleFunctionCall * c)
+{
+ QString szString, szSeparator,szSplittedString;
+ kvs_int_t iPosFrom, iPosTo;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string_to_split",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("separator",KVS_PT_NONEMPTYSTRING,0,szSeparator)
+ KVSM_PARAMETER("pos_from",KVS_PT_INT,0,iPosFrom)
+ KVSM_PARAMETER("pos_to",KVS_PT_INT,0,iPosTo)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.section(szSeparator,iPosFrom,iPosTo));
+ return true;
+}
+
+/*
+ @doc: str.fromClipboard
+ @type:
+ function
+ @title:
+ $str.fromClipboard
+ @short:
+ Returns a string from clipboard.
+ @syntax:
+ <string> $str.fromClipboard()
+ @description:
+ Returns clipboard's contents.
+ @examples:
+ [example]
+ %s = $str.fromClipboard();
+ [/example]
+ @seealso:
+ [cmd]str.toClipboard[/cmd]
+*/
+
+static bool str_kvs_fnc_fromclipboard(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETERS_END(c)
+ QClipboard *cb = QApplication::clipboard();
+ szString = cb->text(QClipboard::Clipboard);
+ c->returnValue()->setString(szString);
+ return true;
+}
+
+/*
+ @doc: system.toClipboard
+ @type:
+ command
+ @title:
+ system.toClipboard
+ @keyterms:
+ OS clipboard
+ @short:
+ Sets the OS clipboard contents
+ @syntax:
+ system.setenv <value:string>
+ @description:
+ Sets the OS clipboard contents
+ @seealso:
+ [fnc]$str.fromClipboard[/fnc]
+*/
+
+static bool str_kvs_cmd_toClipboard(KviKvsModuleCommandCall * c)
+{
+ QString szValue;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("value",KVS_PT_STRING,KVS_PF_OPTIONAL,szValue)
+ KVSM_PARAMETERS_END(c)
+ QClipboard *cb = QApplication::clipboard();
+ cb->setText(szValue, QClipboard::Clipboard );
+ return true;
+}
+
+/*
+ @doc: str.len
+ @type:
+ function
+ @title:
+ $str.len
+ @short:
+ Returns the lenght of the given string
+ @syntax:
+ <uint> $str.len(<data:string>)
+ @description:
+ Returns the lenght (that is, number of characters) of the given string.
+ This function is internally aliased to [fnc]$str.length[/fnc]() too.
+*/
+
+/*
+ @doc: str.length
+ @type:
+ function
+ @title:
+ $str.length
+ @short:
+ Returns the lenght of the given string
+ @syntax:
+ <uint> $str.length(<data:string>)
+ @description:
+ Returns the lenght (that is, number of characters) of the given string.
+ This function is internally aliased to [fnc]$str.len[/fnc]() too.
+*/
+
+static bool str_kvs_fnc_len(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setInteger(szString.length());
+ return true;
+}
+
+/*
+ @doc: str.lowcase
+ @type:
+ function
+ @title:
+ $str.lowcase
+ @short:
+ Returns the given string with all characters turned to lower case
+ @syntax:
+ <string> $str.lowcase(<string_to_convert:string>)
+ @description:
+ Returns the <string_to_convert> with all characters turned to lower case.
+ Warning: this function uses ISO-8859-1 locale to make the case translation.
+ If you want to use a locale aware translation mapping then please
+ use localelowcase.
+*/
+
+static bool str_kvs_fnc_lowcase(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string_to_convert",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(KviQString::lowerISO88591(szString));
+ return true;
+}
+/*
+ @doc: str.upcase
+ @type:
+ function
+ @title:
+ $str.upcase
+ @short:
+ Returns the given string with all characters turned to upper case
+ @syntax:
+ <string> $str.upcase(<string_to_convert:string>)
+ @description:
+ Returns the given <string_to_convert> with all characters turned to lower case.
+ Warning: this function uses ISO-8859-1 locale to make the case translation.
+ If you want to use a locale aware translation mapping then please
+ use $str.localeupcase.
+*/
+
+static bool str_kvs_fnc_upcase(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string_to_convert",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(KviQString::upperISO88591(szString));
+ return true;
+}
+/*
+ @doc: str.localelowcase
+ @type:
+ function
+ @title:
+ $str.localelowcase
+ @short:
+ Returns the given string with all characters turned to lower case
+ @syntax:
+ <string> $str.localelowcase(<string_to_convert:string>)
+ @description:
+ Returns the given <string_to_convert> with all characters turned to lower case.
+ Warning: this function is locale aware and it may produce unexpected
+ results in locales that contain strange exceptions (like Turkish which maps
+ i to Y with an accent). For IRC interaction you might prefer using $str.lowcase
+*/
+
+static bool str_kvs_fnc_localelowcase(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string_to_convert",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.lower());
+ return true;
+}
+
+/*
+ @doc: str.localeupcase
+ @type:
+ function
+ @title:
+ $str.localeupcase
+ @short:
+ Returns the given string with all characters turned to upper case
+ @syntax:
+ <string> $str.localeupcase(<string_to_convert:string>)
+ @description:
+ Returns the given <string_to_convert> with all characters turned to lower case.
+ Warning: this function is locale aware and it may produce unexpected
+ results in locales that contain strange exceptions (like Turkish which maps
+ i to Y with an accent). For IRC interaction you might prefer using $str.upcase
+*/
+
+static bool str_kvs_fnc_localeupcase(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string_to_convert",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.upper());
+ return true;
+}
+
+/*
+ @doc: str.isnumber
+ @type:
+ function
+ @title:
+ $str.isnumber
+ @short:
+ Returns 1 if the given string represents a number
+ @syntax:
+ <bool> $str.isnumber(<givenstring:string>)
+ @description:
+ Returns 1 if the given string represents a number, 0 if not.
+*/
+
+static bool str_kvs_fnc_isnumber(KviKvsModuleFunctionCall * c)
+{
+ KviKvsVariant * v;
+ KviKvsNumber num;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("givenstring",KVS_PT_VARIANT,0,v)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setBoolean(v->asNumber(num));
+ return true;
+}
+
+
+/*
+ @doc: str.isunsignednumber
+ @type:
+ function
+ @title:
+ $str.isunsignednumber
+ @short:
+ Returns 1 if the given string represents an unsigned number
+ @syntax:
+ <bool> $str.isunsignednumber(<givenstring:string>)
+ @description:
+ Returns 1 if the given string represents an unsigned number, 0 if not.
+*/
+
+static bool str_kvs_fnc_isunsignednumber(KviKvsModuleFunctionCall * c)
+{
+ KviKvsVariant * v;
+ KviKvsNumber nNum;
+ bool bRet;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("givenstring",KVS_PT_VARIANT,0,v)
+ KVSM_PARAMETERS_END(c)
+ if(!v->asNumber(nNum)) bRet = false;
+ else
+ {
+ if(nNum.isInteger())
+ {
+ bRet = nNum.integer() >= 0;
+ }
+ else
+ {
+ bRet = nNum.real() >= 0.0;
+ }
+ }
+ c->returnValue()->setBoolean(bRet);
+ return true;
+}
+
+/*
+ @doc: str.isempty
+ @type:
+ function
+ @title:
+ $str.isempty
+ @short:
+ Returns 1 if the given string don't have any character.
+ @syntax:
+ <string> $str.isEmpty(<givenstring:string>)
+ @description:
+ Returns 1 if the given string don't have any character (that is, is empty).
+ This function is almost useless since it is equivalent to the
+ comparison with an empty string...
+*/
+
+static bool str_kvs_fnc_isempty(KviKvsModuleFunctionCall * c)
+{
+ QString v;
+ bool bRet;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("datastring",KVS_PT_STRING,0,v)
+ KVSM_PARAMETERS_END(c)
+ if(v.isEmpty()) bRet = true;
+ else bRet = false;
+ c->returnValue()->setBoolean(bRet);
+ return true;
+}
+
+/*
+ @doc: str.contains
+ @type:
+ function
+ @title:
+ $str.contains
+ @short:
+ Returns 1 if the first parameter contains the second
+ @syntax:
+ <bool> $str.contains(<container:string>,<tofind:string>)
+ @description:
+ Returns 1 if the first string parameter contains the second string parameter.
+ This function is case sensitive.
+ @seealso:
+ [fnc]$str.containsnocase[/fnc]()
+*/
+
+
+static bool str_kvs_fnc_contains(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szSubString;
+ bool bIs;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("container",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("tofind",KVS_PT_STRING,0,szSubString)
+ KVSM_PARAMETERS_END(c)
+ bIs = szString.find(szSubString) != -1;
+ c->returnValue()->setBoolean(bIs);
+ return true;
+}
+
+/*
+ @doc: str.containsnocase
+ @type:
+ function
+ @title:
+ $str.containsnocase
+ @short:
+ Returns 1 if the first parameter contains the second, case insensitive
+ @syntax:
+ <bool> $str.containsnocase(<container:string>,<tofind:string>)
+ @description:
+ Returns 1 if the first string parameter contains the second string parameter
+ whithout taking in consideration the case of the characters in the string.
+ @seealso:
+ [fnc]$str.contains[/fnc]
+*/
+
+static bool str_kvs_fnc_containsnocase(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szSubString;
+ bool bIs;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("container",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("tofind",KVS_PT_STRING,0,szSubString)
+ KVSM_PARAMETERS_END(c)
+ bIs = szString.find(szSubString,0,false) != -1;
+ c->returnValue()->setBoolean(bIs);
+ return true;
+}
+
+/*
+ @doc: str.equal
+ @type:
+ function
+ @title:
+ $str.equal
+ @short:
+ Returns 1 if the two string parameters are equal
+ @syntax:
+ <bool> $str.equal(<fromcompare:string>,<tocompare:string>)
+ @description:
+ Returns 1 if the two string parameters are equal. This function is case sensitive.
+ @seealso:
+ [fnc]$str.equalnocase[/fnc]()
+*/
+
+static bool str_kvs_fnc_equal(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ bool bIs;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("fromcompare",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("tocompare",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ bIs = KviQString::equalCS(szString,szString2);
+ c->returnValue()->setBoolean(bIs);
+ return true;
+}
+/*
+ @doc: str.equalnocase
+ @type:
+ function
+ @title:
+ $str.equalnocase
+ @short:
+ Returns 1 if the two string parameters are equal, case insensitive
+ @syntax:
+ <bool> $str.equalnocase(<fromcompare:string>,<tocompare:string>)
+ @description:
+ Returns 1 if the two strngs parameters are equal, without taking the case of the
+ characters in consideration.
+ @seealso:
+ [fnc]$str.equal[/fnc]()
+*/
+
+static bool str_kvs_fnc_equalnocase(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ bool bIs;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("fromcompare",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("tocompare",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ bIs = KviQString::equalCI(szString,szString2);
+ c->returnValue()->setBoolean(bIs);
+ return true;
+}
+
+/*
+ @doc: str.cmp
+ @type:
+ function
+ @title:
+ $str.cmp
+ @short:
+ Compare two strings alphabetically
+ @syntax:
+ <bool> $str.cmp(<fromcompare:string>,<tocompare:string>)
+ @description:
+ This function compares two strings alphabetically. If the first string is 'greater'
+ than the second, it will return a positive number, a negative number is the second is
+ greater and 0 if the two strings are equal.
+ @seealso:
+ [fnc]$str.cmpnocase[/fnc]()
+*/
+
+static bool str_kvs_fnc_cmp(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ int iCmp;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("fromcompare",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("tocompare",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ iCmp = KviQString::cmpCS(szString,szString2);
+ c->returnValue()->setInteger(iCmp);
+ return true;
+}
+
+/*
+ @doc: str.cmpnocase
+ @type:
+ function
+ @title:
+ $str.cmpnocase
+ @short:
+ Compare two strings alphabetically, case insensitive.
+ @syntax:
+ <bool> $str.cmpnocase(<fromcompare:string>,<tocompare:string>)
+ @description:
+ This function compares two strings alphabetically. If the first string is 'greater'
+ than the second, it will return a positive number, a negative number is the second is
+ greater and 0 if the two strings are equal. This function is case insensitive.
+ @seealso:
+ [fnc]$str.cmp[/fnc]()
+*/
+static bool str_kvs_fnc_cmpnocase(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ int iCmp;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("fromcompare",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("tocompare",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ iCmp = KviQString::cmpCI(szString,szString2);
+ c->returnValue()->setInteger(iCmp);
+ return true;
+}
+
+/*
+ @doc: str.find
+ @type:
+ function
+ @title:
+ $str.find
+ @short:
+ Find the index of the nth ocurrence of a substring in a string
+ @syntax:
+ <int> $str.find(<findIn:string>,<tofind:string>[,ocurrence:int])
+ @description:
+ This function search in the string given as the first parameter for the string
+ given as his second parameter, and will return the index where the nth ocurrence
+ given as the third parameter is found or -1 if it's not located. It starts
+ counting at 0. If occurence is not specified then the first occurence
+ is searched. WARNING: The occurente number starts from 1! (Yes, that's a bug, but
+ for backward compatibility it must remain as it is :( ).[br]
+ FIXME: The semantics of this function are totally broken :(
+*/
+
+static bool str_kvs_fnc_find(KviKvsModuleFunctionCall * c)
+{
+ QString szFindIn, szToFind;
+ kvs_int_t iOcurence;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szFindIn)
+ KVSM_PARAMETER("tofind",KVS_PT_STRING,0,szToFind)
+ KVSM_PARAMETER("ocurrence",KVS_PT_INTEGER,KVS_PF_OPTIONAL,iOcurence)
+ KVSM_PARAMETERS_END(c)
+ int pos = 1;
+ if(iOcurence!=0)
+ pos = iOcurence;
+ if(pos<1)
+ {
+ c->returnValue()->setInteger(-1);
+ return true;
+ }
+ if(szFindIn.isEmpty())
+ {
+ c->returnValue()->setInteger(-1);
+ return true;
+ }
+ if(szToFind.isEmpty())
+ {
+ c->returnValue()->setInteger(-1);
+ return true;
+ }
+ int cnt = 1;
+ int idx;
+ int totalIdx = 0;
+
+ while (cnt<=pos)
+ {
+ idx = szFindIn.right(szFindIn.length() - totalIdx).find(szToFind);
+ if(idx == -1)
+ {
+ c->returnValue()->setInteger(-1);
+ return true;
+ }
+ //Idx only gives the index until the pos _before_ the matched string so if this is
+ //not the match we want (cont != 0) we skip it
+ totalIdx += (idx + (cnt == pos ? 0 : szToFind.length()));
+ ++cnt;
+ }
+ c->returnValue()->setInteger(totalIdx);
+ return true;
+}
+/*
+ @doc: str.findfirst
+ @type:
+ function
+ @title:
+ $str.findfirst
+ @short:
+ Find the index of a substring in a string
+ @syntax:
+ <int> $str.findfirst(<findIn:string>,<toFind:string>)
+ @description:
+ This function search in the string given as the first parameter for the string
+ given as his second parameter, and will return the index where is first located or
+ -1 if it's not located. It starts counting at 0.
+*/
+
+static bool str_kvs_fnc_findfirst(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("toFind",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setInteger(szString.find(szString2));
+ return true;
+}
+/*
+ @doc: str.findfirstnocase
+ @type:
+ function
+ @title:
+ $str.findfirstnocase
+ @short:
+ Find the index of a substring in a string, case insensitive
+ @syntax:
+ <int> $str.findfirstnocase(<findIn:string>,<toFind:string>)
+ @description:
+ This function search in the string given as the first parameter for the string
+ given as his second parameter, and will return the index where is first located or
+ -1 if it's not located. This function is case insensitive.
+*/
+
+static bool str_kvs_fnc_findfirstnocase(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("toFind",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setInteger(szString.find(szString2,0,false));
+ return true;
+}
+/*
+ @doc: str.findlast
+ @type:
+ function
+ @title:
+ $str.findlast
+ @short:
+ Find the last index of a substring in a string
+ @syntax:
+ <int> $str.findlast(<findIn:string>,<toFind:string>)
+ @description:
+ This function search in the string given as the first parameter for the string
+ given as his second parameter, and will return the index where is last located or
+ -1 if it's not located.
+*/
+
+static bool str_kvs_fnc_findlast(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("toFind",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setInteger(szString.findRev(szString2));
+ return true;
+}
+/*
+ @doc: str.findlastnocase
+ @type:
+ function
+ @title:
+ $str.findlastnocase
+ @short:
+ Find the last index of a substring in a string, case insensitive
+ @syntax:
+ <int> $str.findlastnocase(<findIn:string>,<toFind:string>)
+ @description:
+ This function search in the string given as the first parameter for the string
+ given as his second parameter, and will return the index where is last located or
+ -1 if it's not located. This function is case insensitive.
+*/
+
+static bool str_kvs_fnc_findlastnocase(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("toFind",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setInteger(szString.findRev(szString2,-1,false));
+ return true;
+}
+/*
+ @doc: str.left
+ @type:
+ function
+ @title:
+ $str.left
+ @short:
+ Returns a substring starting from the left until the given index.
+ @syntax:
+ <string> $str.left(<data:string>,<index:int>)
+ @description:
+ This function returns a substring of the first string parameter which is the
+ string starting from the left until the index specified in the second parameter.
+*/
+
+static bool str_kvs_fnc_left(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ kvs_int_t iIdx;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("index",KVS_PT_INTEGER,0,iIdx)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.left(iIdx));
+ return true;
+}
+/*
+ @doc: str.right
+ @type:
+ function
+ @title:
+ $str.right
+ @short:
+ Returns a substring starting from the right until the given index.
+ @syntax:
+ <string> $str.right(<data:string>,<index:int>)
+ @description:
+ This function returns a substring of the first string parameter which is the
+ string starting from the right until the index specified in the second parameter.
+ The index start counting at the last character and increase until the first.
+*/
+
+static bool str_kvs_fnc_right(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ kvs_int_t iIdx;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("index",KVS_PT_INTEGER,0,iIdx)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.right(iIdx));
+ return true;
+}
+/*
+ @doc: str.mid
+ @type:
+ function
+ @title:
+ $str.mid
+ @short:
+ Returns a substring starting from a given index.
+ @syntax:
+ <string> $str.mid(<data:string>,<startidx:int>,<nchars:int>)
+ @description:
+ This function returns a substring of the first string parameter wich is the
+ string starting at the (numeric) index given with startidx and counting nchars
+ forward.
+*/
+
+static bool str_kvs_fnc_mid(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ kvs_int_t iIdx,iNchars;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("startidx",KVS_PT_INTEGER,0,iIdx)
+ KVSM_PARAMETER("nchars",KVS_PT_INTEGER,0,iNchars)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.mid(iIdx,iNchars));
+ return true;
+}
+/*
+ @doc: str.append
+ @type:
+ function
+ @title:
+ $str.append
+ @short:
+ Append one string to another.
+ @syntax:
+ <string> $str.append(<string:string>,<toappend:string>)
+ @description:
+ This function returns a string created appending the second string parameter
+ to the end of the first string parameter.
+*/
+
+static bool str_kvs_fnc_append(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("toappend",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.append(szString2));
+ return true;
+}
+/*
+ @doc: str.prepend
+ @type:
+ function
+ @title:
+ $str.prepend
+ @short:
+ Prepend one string to another.
+ @syntax:
+ <string> $str.prepend(<string:string>,<toprepend:string>)
+ @description:
+ This function returns a string created prepending the second string parameter
+ to the start of the first string parameter.
+*/
+
+static bool str_kvs_fnc_prepend(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("toprepend",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.prepend(szString2));
+ return true;
+}
+/*
+ @doc: str.insert
+ @type:
+ function
+ @title:
+ $str.insert
+ @short:
+ Inserts a substring in a string at a given index
+ @syntax:
+ <string> $str.insert(<string:string>,<substring:string>,<index:int>)
+ @description:
+ Inserts the substring given in the second parameter in the string given in the
+ first parameter at the index given in the third parameter, then returns the
+ resulting string.
+*/
+
+static bool str_kvs_fnc_insert(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szString2;
+ kvs_int_t iIdx;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("substring",KVS_PT_STRING,0,szString2)
+ KVSM_PARAMETER("nchars",KVS_PT_INTEGER,0,iIdx)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.insert(iIdx,szString2));
+ return true;
+}
+/*
+ @doc: str.strip
+ @type:
+ function
+ @title:
+ $str.strip
+ @short:
+ Returns a whitespace stripped string
+ @syntax:
+ <string> $str.strip(<string:string>)
+ @description:
+ Returns a left and right whitespace stripped version of the string given as the
+ first parameter.
+*/
+
+static bool str_kvs_fnc_strip(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(szString.stripWhiteSpace());
+ return true;
+}
+/*
+ @doc: str.stripleft
+ @type:
+ function
+ @title:
+ $str.stripleft
+ @short:
+ Returns a left whitespace stripped string
+ @syntax:
+ <string> $str.stripleft(<string:string>)
+ @description:
+ Returns a left whitespace stripped version of the string given as the
+ first parameter.
+*/
+
+static bool str_kvs_fnc_stripleft(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ if(szString.length() > 0)
+ {
+ int idx = 0;
+ while(szString[idx].isSpace())idx++;
+ if(idx > 0)szString.remove(0,idx);
+ }
+ c->returnValue()->setString(szString);
+ return true;
+}
+/*
+ @doc: str.stripright
+ @type:
+ function
+ @title:
+ $str.stripright
+ @short:
+ Returns a right whitespace stripped string
+ @syntax:
+ <string> $str.stripright(<string:string>)
+ @description:
+ Returns a right whitespace stripped version of the string given as the
+ first parameter.
+*/
+
+static bool str_kvs_fnc_stripright(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ int iIdx = 0;
+ while(szString.at(szString.length() - (iIdx+1)).isSpace()) iIdx++;
+ if(iIdx > 0)szString.remove(szString.length() - iIdx,iIdx);
+ c->returnValue()->setString(szString);
+ return true;
+}
+
+/*
+ @doc: str.stripcolors
+ @type:
+ function
+ @title:
+ $str.stripcolors
+ @short:
+ Returns a mirc color codes stripped string
+ @syntax:
+ <string> $str.stripcolors(<string:string>)
+ @description:
+ Removes all mirc color codes from a string, including also bold, underline, reverse,
+ icon, crypting and ctcp control codes.
+*/
+
+static bool str_kvs_fnc_stripcolors(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ c->returnValue()->setString(KviMircCntrl::stripControlBytes(szString));
+ return true;
+}
+
+/*
+ @doc: str.replace
+ @type:
+ function
+ @title:
+ $str.replace
+ @short:
+ Replace substrings in a string
+ @syntax:
+ <string> $str.replace(<string:string>,<replacewith:string>,<toreplace:string>)
+ @description:
+ This function returns a string created replacing all ocurrences of the third parameter
+ ('toreplace') in the string given as the first parameter ('string') with the string
+ given as the second parameter ('replacewith').
+ The string replacement is case sensitive!.
+ FIXME: The order of the parameters in this function is illogical (and probably incompatible
+ with any other scripting language) :D
+ @examples:
+ [example]
+ echo $str.replace("I like big networks","neural","big")
+ [/example]
+*/
+
+static bool str_kvs_fnc_replace(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szNewstr,szToreplace;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("newstr",KVS_PT_STRING,0,szNewstr)
+ KVSM_PARAMETER("toreplace",KVS_PT_STRING,0,szToreplace)
+ KVSM_PARAMETERS_END(c)
+ szString.replace(szToreplace,szNewstr);
+ c->returnValue()->setString(szString);
+ return true;
+}
+
+/*
+ @doc: str.replacenocase
+ @type:
+ function
+ @title:
+ $str.replacenocase
+ @short:
+ Replace substrings in a string ignoring case
+ @syntax:
+ <string> $str.replacenocase(<string:string>,<newstr:string>,<toreplace:string>)
+ @description:
+ This function returns a string created replacing all ocurrences of the third parameter
+ ('toreplace') in the string given as the first parameter ('string') with the string
+ given as the second parameter ('newstr').[br]
+ The replacement is case insensitive.[br]
+ FIXME: The order of the parameters in this function is illogical (and probably incompatible
+ with any other scripting language) :D
+*/
+
+static bool str_kvs_fnc_replacenocase(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szNewstr,szToreplace;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("newstr",KVS_PT_STRING,0,szNewstr)
+ KVSM_PARAMETER("toreplace",KVS_PT_STRING,0,szToreplace)
+ KVSM_PARAMETERS_END(c)
+ szString.replace(szToreplace,szNewstr,false);
+ c->returnValue()->setString(szString);
+ return true;
+}
+
+/*
+ @doc: str.urlencode
+ @type:
+ function
+ @title:
+ $str.urlencode
+ @short:
+ Returns a browser formatted string
+ @syntax:
+ <string> $str.urlencode(<string:string>)
+ @description:
+ This function returns a string created replacing all ocurrences in the parameter ('string') with their respective html entities.[br]
+ The replacement is case insensitive.[br]
+ FIXME: This function use the same replace order as $str.replace so it incompatible
+ with any other scripting language) :D
+*/
+
+static bool str_kvs_fnc_urlencode(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szNewstr;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+
+ char * toReplace[]={" ", "#", "$", "&", "/", ":", "<", "=", ">", "?", "@", "[", "\\", "]", "^", "`", "{", "|", "}", "~"};
+ char * newStr[]={"%20", "%23", "%24", "&amp;", "%2F", "%3A", "&lt;", "%3D", "&gt;", "%3F", "%40", "%5B", "%5C", "%5D", "%5E", "%60", "%7B", "%7C", "%7D", "%7E"};
+
+ /*
+ for(int idx=0,idx<22,idx++)
+ szNewstr=szString.replace(toReplace[idx],newStr[idx],false);
+ */
+
+ int idx=0;
+ while(idx<20){
+ szNewstr=szString.replace(toReplace[idx],newStr[idx],false);
+ idx++;
+ }
+
+ c->returnValue()->setString(szNewstr);
+ return true;
+}
+
+/*
+ @doc: str.lefttofirst
+ @type:
+ function
+ @title:
+ $str.lefttofirst
+ @short:
+ Returns the left part of a string until a given substring
+ @syntax:
+ <string> $str.lefttofirst(<string:string>,<substring:string>)
+ @description:
+ This function returns the left part of the string given as the first parameter
+ from the start until the string given as the second parameter is found. It don't
+ include the substring of the second parameter in the returned value. If the second
+ parameter is not found, the entire string is returned.
+ The match is case insensitive.
+*/
+
+static bool str_kvs_fnc_lefttofirst(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szNewstr;
+ int where;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("substring",KVS_PT_STRING,0,szNewstr)
+ KVSM_PARAMETERS_END(c)
+ where = szString.find(szNewstr,false);
+ if(where != -1) c->returnValue()->setString(szString.left(where));
+ else c->returnValue()->setString(szString);
+ return true;
+}
+/*
+ @doc: str.lefttolast
+ @type:
+ function
+ @title:
+ $str.lefttolast
+ @short:
+ Returns the left part of a string until the last ocurrence of a given substring
+ @syntax:
+ <string> $str.lefttolast(<string:string>,<substring:string>)
+ @description:
+ This function returns the left part of the string given as the first parameter
+ from the start until the last ocurrence of the string given as the second parameter
+ is found. It don't include the substring of the second parameter in the returned value.
+ If the second parameter is not found, the entire string is returned.
+ The match is case insensitive
+*/
+
+static bool str_kvs_fnc_lefttolast(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szNewstr;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("substring",KVS_PT_STRING,0,szNewstr)
+ KVSM_PARAMETERS_END(c)
+ int where = szString.findRev(szNewstr,-1,false);
+ if(where != -1) c->returnValue()->setString(szString.left(where));
+ else c->returnValue()->setString(szString);
+ return true;
+}
+/*
+ @doc: str.rightfromfirst
+ @type:
+ function
+ @title:
+ $str.rightfromfirst
+ @short:
+ Returns the right part of a string from the first ocurrence of a given substring
+ @syntax:
+ <string> $str.rightfromfirst(<string:string>,<substring:string>)
+ @description:
+ This function returns the right part of the string given as the first parameter
+ from the position where the first ocurrence of the string given as the second parameter
+ is found. It don't include the substring of the second parameter in the returned value.
+ If the second parameter is not found, an empty string is returned..
+ The match is case insensitive
+*/
+
+static bool str_kvs_fnc_rightfromfirst(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szNewstr;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("substring",KVS_PT_STRING,0,szNewstr)
+ KVSM_PARAMETERS_END(c)
+ int idx = szString.find(szNewstr,false);
+ if(idx != -1) c->returnValue()->setString(szString.right(szString.length()-(idx+szNewstr.length())));
+ else c->returnValue()->setString("");
+ return true;
+}
+/*
+ @doc: str.rightfromlast
+ @type:
+ function
+ @title:
+ $str.rightfromlast
+ @short:
+ Returns the right part of a string from the last ocurrence of a given substring
+ @syntax:
+ <string> $str.rightfromlast(<string:string>,<substring:string>)
+ @description:
+ This function returns the right part of the string given as the first parameter
+ from the position where the last ocurrence of the string given as the second parameter
+ is found. It don't include the substring of the second parameter in the returned value.
+ If the second parameter is not found, an empty string is returned..
+ The match is case insensitive.
+*/
+
+
+static bool str_kvs_fnc_rightfromlast(KviKvsModuleFunctionCall * c)
+{
+ QString szString,szNewstr;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("substring",KVS_PT_STRING,0,szNewstr)
+ KVSM_PARAMETERS_END(c)
+ int idx = szString.findRev(szNewstr,-1,false);
+ if(idx != -1) c->returnValue()->setString(szString.right(szString.length()-(idx+szNewstr.length())));
+ else c->returnValue()->setString("");
+ return true;
+}
+
+/*
+ @doc: str.match
+ @type:
+ function
+ @title:
+ $str.match
+ @short:
+ Matches a fixed string against a wildcard expression
+ @syntax:
+ <bool> $str.match(<expression:string>,<string:string>[,<flags:string>])
+ @description:
+ Returns 1 if the fixed <string> matches the <expression>, 0 otherwise.[br]
+ If <flags> contains the flag 'r' then <expression> is treated as a full
+ regular expression otherwise it is treated as a simple wildcard expression containing
+ the classic wildcards '*' and '?'.[br]
+ If <flags> contains the flag 'e' then only an exact match is considered (e.g. the full
+ <string> is exactly matched by <expression>), otherwise partial matches are allowed too (e.g.
+ <expression> is found inside <string>).[br]
+ The match is case sensitive.[br]
+ @examples:
+ [example]
+ %test = "Hello! My nickname is Pragma"
+ [cmd]if[/cmd]($str.match(Pragma*,%test))[cmd]echo[/cmd] "Matches Pragma*"
+ [cmd]if[/cmd]($str.match(*Pragma,%test))[cmd]echo[/cmd] "Matches *Pragma"
+ [cmd]if[/cmd]($str.match(H*y*i?k*a,%test))[cmd]echo[/cmd] "Matches H*y*i?k*a"
+ [cmd]if[/cmd]($str.match(H*y*i?K*a,%test))[cmd]echo[/cmd] "Matches H*y*i?K*a"
+ [/example]
+ @seealso:
+ [fnc]$str.matchnocase[/fnc]
+*/
+
+static bool str_kvs_fnc_match(KviKvsModuleFunctionCall * c)
+{
+ QString szWildcard,szString,szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("wildcard",KVS_PT_NONEMPTYSTRING,0,szWildcard)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETERS_END(c)
+ bool bRegExp = (szFlags.find(QChar('r')) != -1) || (szFlags.find(QChar('R')) != -1);
+ bool bExact = (szFlags.find(QChar('e')) != -1) || (szFlags.find(QChar('E')) != -1);
+ c->returnValue()->setBoolean(KviQString::matchStringCS(szWildcard,szString,bRegExp,bExact));
+ return true;
+}
+
+/*
+ @doc: str.matchnocase
+ @type:
+ function
+ @title:
+ $str.matchnocase
+ @short:
+ Matches a fixed string against a wildcard expression (case insensitive)
+ @syntax:
+ <bool> $str.matchnocase(<expression>,<string:string>[,<flags:string>])
+ @description:
+ Returns 1 if the fixed <string> matches the <expression>, 0 otherwise.[br]
+ If <flags> contains the flag 'r' then <expression> is treated as a full
+ regular expression otherwise it is treated as a simple wildcard expression containing
+ the classic wildcards '*' and '?'.[br]
+ If <flags> contains the flag 'e' then only an exact match is considered (e.g. the full
+ <string> is exactly matched by <expression>), otherwise partial matches are allowed too (e.g.
+ <expression> is found inside <string>).[br]
+ The match is case insensitive.[br]
+ @examples:
+ [example]
+ %test = "Hello! My nickname is Pragma"
+ [cmd]if[/cmd]($str.match(pragma*,%test))[cmd]echo[/cmd] "Matches pragma*"
+ [cmd]if[/cmd]($str.match(*pragma,%test))[cmd]echo[/cmd] "Matches *pragma"
+ [cmd]if[/cmd]($str.match(H*y*i?k*a,%test))[cmd]echo[/cmd] "Matches H*y*i?k*a"
+ [cmd]if[/cmd]($str.match(H*y*i?K*a,%test))[cmd]echo[/cmd] "Matches H*y*i?K*a"
+ [cmd]if[/cmd]($str.match(G*if?sx,%test))[cmd]echo[/cmd] "Matches G*if?sx"
+ [/example]
+ @seealso:
+ [fnc]$str.match[/fnc]
+*/
+
+static bool str_kvs_fnc_matchnocase(KviKvsModuleFunctionCall * c)
+{
+ QString szWildcard,szString,szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("wildcard",KVS_PT_NONEMPTYSTRING,0,szWildcard)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETERS_END(c)
+ bool bRegExp = (szFlags.find(QChar('r')) != -1) || (szFlags.find(QChar('R')) != -1);
+ bool bExact = (szFlags.find(QChar('e')) != -1) || (szFlags.find(QChar('E')) != -1);
+ c->returnValue()->setBoolean(KviQString::matchStringCI(szWildcard,szString,bRegExp,bExact));
+ return true;
+}
+
+/*
+
+ @doc: str.word
+ @type:
+ function
+ @title:
+ $str.word
+ @short:
+ Returns the nth word in a string
+ @syntax:
+ <string> $str.word(<n:int>,<string:string>)
+ @description:
+ Returns the nth word inside the <string> (with n starting from 0!)[br]
+ A word is a substring not containing spaces (ASCII chars 32, carriage returns , tabs etc...).[br]
+ If the string contains less than n+1 words then an empty string is returned.[br]
+ This function is faster than a call to [fnc]split[/fnc]() and array indexing
+ if you need a single word to be extracted from a complex string.[br]
+ If you need to manage more than one word from the string then the [fnc]split[/fnc]()
+ method is more efficient.[br]
+ This function is a special case of [fnc]$str.token[/fnc]() and it runs a bit faster.
+ @examples:
+ [example]
+ %test = "this is a string full of words"
+ [cmd]echo[/cmd] $str.word(4,%test)
+ [/example]
+ @seealso:
+ [fnc]$str.token[/fnc]
+*/
+
+static bool str_kvs_fnc_word(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ kvs_int_t iOccurence;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("occurence",KVS_PT_INT,0,iOccurence)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ int idx = 0;
+ int cnt = 0;
+ int begin;
+ int len = szString.length();
+ while (idx<len)
+ {
+ QChar szTmp = szString[idx].unicode();
+ while (szTmp.isSpace())
+ {
+ idx++;
+ szTmp = szString[idx].unicode();
+ }
+ begin = idx;
+ while (idx<len && !szTmp.isSpace())
+ {
+ idx++;
+ szTmp = szString[idx].unicode();
+ }
+ if (iOccurence == (kvs_int_t)cnt)
+ {
+ c->returnValue()->setString(szString.mid(begin,idx-begin));
+ return true;
+ }
+ cnt ++;
+ }
+ return true;
+
+}
+/*
+ @doc: str.token
+ @type:
+ function
+ @title:
+ $str.token
+ @short:
+ Returns the nth token in a string
+ @syntax:
+ <string> $str.token(<n:int>,<separator:string>,<string:string>)
+ @description:
+ Returns the nth token inside the <string> (with n starting from 0!)[br]
+ A token is a substring not containing the characters listed in <separators>.[br]
+ If the string contains less than n+1 tokens then an empty string is returned.[br]
+ [fnc]$str.word[/fnc]() is an optimized function dedicated to the special case
+ in that <separators> is a string containing all the whitespace characters.[br]
+ Please note that this function is SLOW. You might want to take a look at [fnc]$str.word[/fnc]()
+ or even better to [fnc]$str.split[/fnc]().[br]
+ This function is case sensitive: you need to specify both cases in the <separators> string
+ if you want to do a case insensitive tokenization.[br]
+ @examples:
+ [example]
+ %test = "21 hours 10 minutes 15 seconds"
+ [cmd]echo[/cmd] $str.token(1," hoursmintecd",%test)
+ [/example]
+ @seealso:
+ [fnc]$str.word[/fnc][br]
+ [fnc]$str.split[/fnc][br]
+*/
+
+static bool str_kvs_fnc_token(KviKvsModuleFunctionCall * c)
+{
+ QString szString,sep;
+ kvs_uint_t n;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("n",KVS_PT_UINT,0,n)
+ KVSM_PARAMETER("separator",KVS_PT_STRING,0,sep)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETERS_END(c)
+ if(sep.isEmpty())
+ {
+ c->returnValue()->setString(szString);
+ return true;
+ }
+
+ int idx = 0;
+ int cnt = 0;
+ int begin;
+ int len = szString.length();
+ while (idx<len)
+ {
+ QChar szTmp = szString[idx].unicode();
+// while (szTmp==sep)
+ while (sep.contains(szTmp))
+ {
+ idx++;
+ szTmp = szString[idx].unicode();
+ }
+ begin = idx;
+ while (idx<len && !sep.contains(szTmp))
+ {
+ idx++;
+ szTmp = szString[idx].unicode();
+ }
+ if (n == cnt)
+ {
+ c->returnValue()->setString(szString.mid(begin,idx-begin));
+ return true;
+ }
+ cnt ++;
+ }
+ return true;
+}
+
+/*
+ @doc: str.charsum
+ @type:
+ function
+ @title:
+ $str.charsum
+ @short:
+ Returns the sum of the character codes of the string
+ @syntax:
+ <int> $str.charsum(<data:string>[,<bCaseInsensitive:boolean>])
+ @description:
+ Returns the sum of the character codes of the parameter <string>.
+ The sum is suitable for implementing a simple hashing algorithm.[br]
+ If <bCaseInsensitive> is specified and $true then the string
+ will be converted to lowercase first.
+*/
+
+
+static bool str_kvs_fnc_charsum(KviKvsModuleFunctionCall * c)
+{
+ QString szString;
+ bool bCaseInsensitive;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_STRING,0,szString)
+ KVSM_PARAMETER("bCaseInsensitive",KVS_PT_BOOL,KVS_PF_OPTIONAL,bCaseInsensitive)
+ KVSM_PARAMETERS_END(c)
+ unsigned int sum = 0;
+ int idx = 0;
+ int len = szString.length();
+ if(bCaseInsensitive)
+ {
+ while(idx < len)
+ {
+ sum += szString[idx].lower().unicode();
+ idx++;
+ }
+ } else {
+ while(idx < len)
+ {
+ sum += szString[idx].unicode();
+ idx++;
+ }
+ }
+ c->returnValue()->setInteger(sum);
+ return true;
+}
+
+
+/*
+ @doc: str.digest
+ @type:
+ function
+ @title:
+ $str.digest
+ @short:
+ Returns the sum of the character codes of the string
+ @syntax:
+ <string> $str.digest(<data:string>[,<algorythm:string>])
+ @description:
+ Calculates digest for given string using algorithm passed as 2nd argument.
+ Currently supported: md5, md4, md2, sha1, mdc2, ripemd160, dss1
+ Default is md5. Requires OpenSSL support
+*/
+
+
+static bool str_kvs_fnc_digest(KviKvsModuleFunctionCall * c)
+{
+#ifdef COMPILE_SSL_SUPPORT
+ QString szString,szType,szResult;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_NONEMPTYSTRING,0,szString)
+ KVSM_PARAMETER("algorythm",KVS_PT_NONEMPTYSTRING,KVS_PF_OPTIONAL,szType)
+ KVSM_PARAMETERS_END(c)
+
+ if(szType.isEmpty()) szType="md5";
+
+ EVP_MD_CTX mdctx;
+ const EVP_MD *md;
+ unsigned char md_value[EVP_MAX_MD_SIZE];
+ unsigned int md_len, i;
+ char buff[3];
+ OpenSSL_add_all_digests();
+
+ md = EVP_get_digestbyname(szType.utf8().data());
+ if(!md) {
+ c->warning(__tr2qs("%Q algorytm is not supported"),&szType);
+ return true;
+ }
+
+ EVP_MD_CTX_init(&mdctx);
+ EVP_DigestInit_ex(&mdctx, md, NULL);
+ EVP_DigestUpdate(&mdctx, szString.utf8().data(), szString.utf8().length());
+ EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
+ EVP_MD_CTX_cleanup(&mdctx);
+
+ for(i = 0; i < md_len; i++)
+ {
+#ifdef COMPILE_ON_WINDOWS
+ _snprintf(buff,3,"%02x",md_value[i]);
+#else
+ snprintf(buff,3,"%02x",md_value[i]);
+#endif
+ szResult.append(buff);
+ }
+
+ c->returnValue()->setString(szResult);
+#else
+ c->warning(__tr2qs("KVIrc is compiled without OpenSSL support. $str.digest function disabled"));
+#endif
+
+ return true;
+}
+
+/*
+ @doc: str.join
+ @type:
+ function
+ @title:
+ $str.join
+ @short:
+ Returns a string joined from several strings
+ @syntax:
+ <string> $str.join(<separator:string>,<data:array>[,<flags:string>])
+ @description:
+ Joins all the string in the <data> array by using
+ the specified <separator> and returns the result.
+ If <flags> contains the character "n" then empty strings in teh <data>
+ array are skipped.
+
+*/
+
+
+static bool str_kvs_fnc_join(KviKvsModuleFunctionCall * c)
+{
+ QString szSep;
+ KviKvsArrayCast ac;
+ QString szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("separator",KVS_PT_STRING,0,szSep)
+ KVSM_PARAMETER("data",KVS_PT_ARRAYCAST,0,ac)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETERS_END(c)
+
+ QString szRet;
+ bool bSkipEmpty = szFlags.find('n',0,false) != -1;
+
+ bool bFirst = true;
+
+ if(KviKvsArray * a = ac.array())
+ {
+ kvs_uint_t uIdx = 0;
+ kvs_uint_t uSize = a->size();
+ while(uIdx < uSize)
+ {
+ KviKvsVariant * v = a->at(uIdx);
+ if(v)
+ {
+ QString tmp;
+ v->asString(tmp);
+ if(bFirst)
+ {
+ szRet = tmp;
+ bFirst = false;
+ } else {
+ szRet += szSep;
+ szRet += tmp;
+ }
+ } else {
+ if(!bSkipEmpty)
+ {
+ if(bFirst)
+ {
+ bFirst = false;
+ } else {
+ szRet += szSep;
+ }
+ }
+ }
+ uIdx++;
+ }
+ }
+
+ c->returnValue()->setString(szRet);
+ return true;
+}
+
+
+/*
+ @doc: str.grep
+ @type:
+ function
+ @title:
+ $str.grep
+ @short:
+ Emulates the GNU Regular Expression Parser
+ @syntax:
+ <array> $str.grep(<match:string>,<strings:array>[,<flags:string>])
+ @description:
+ Returns an array with the elements of <strings> which match the string <match>.
+ <flags> can be any combination of the characters 's','w' and 'r'.[br]
+ If the flag 'w' is specified then <match> is assumed to be a wildcard regular
+ expression (with * and ? wildcards). If the flag 'r' is specified
+ then <match> is assumed to be a standard regular expression. If none of
+ 'w' and 'r' is specified then <match> is treated as a simple string to be
+ searched in each element of the <strings> array. 'r' takes precedence over 'w'.
+ If the flag 's' is specified the matches are case sensitive.[br]
+ Note that since almost any other variable type can be automatically cast
+ to an array, then you can use this function also on scalars or hashes.
+ @examples:
+ [example]
+ [comment]# Find all the nicknames starting with the letter A or a[/comment]
+ [cmd]echo[/cmd] $str.grep("^a",[fnc]$chan.users[/fnc],"r")
+ [comment]# Find the current CPU speed (on UNIX like machines only)[/comment]
+ [cmd]echo[/cmd] $str.grep("MHz",[fnc]$str.split[/fnc]([fnc]$lf[/fnc],[fnc]$file.read[/fnc]("/proc/cpuinfo")))
+ [comment]# simply check if the specified string matches a regular expression[/comment]
+ [comment]# (this in fact is a little tricky, but you will probably not notice it :D)[/comment]
+ [cmd]if[/cmd]($str.grep("[st]+","test string","r"))[cmd]echo[/cmd] "Yeah, it matches!"
+ [/example]
+ @seealso:
+ [fnc]$array[/fnc]
+*/
+
+static bool str_kvs_fnc_grep(KviKvsModuleFunctionCall * c)
+{
+ KviKvsArrayCast ac;
+ QString szMatch,szFlags;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("match",KVS_PT_STRING,0,szMatch)
+ KVSM_PARAMETER("strings",KVS_PT_ARRAYCAST,0,ac)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETERS_END(c)
+
+ KviKvsArray * n = new KviKvsArray();
+ c->returnValue()->setArray(n);
+
+ KviKvsArray * a = ac.array();
+
+ bool bCaseSensitive = szFlags.find('s',0,false) != -1;
+ bool bRegexp = szFlags.find('r',0,false) != -1;
+ bool bWild = szFlags.find('w',0,false) != -1;
+ int idx = 0;
+ int cnt = a->size();
+
+ int i = 0;
+ if(bRegexp || bWild)
+ {
+ QRegExp re(szMatch,bCaseSensitive,bWild);
+ while(idx < cnt)
+ {
+ KviKvsVariant * v = a->at(idx);
+ if(v)
+ {
+ QString sz;
+ v->asString(sz);
+ if(re.search(sz) != -1)
+ {
+ n->set(i,new KviKvsVariant(sz));
+ i++;
+ }
+ }
+ idx++;
+ }
+ } else {
+ while(idx < cnt)
+ {
+ KviKvsVariant * v = a->at(idx);
+ if(v)
+ {
+ QString sz;
+ v->asString(sz);
+ if(sz.find(szMatch,0,bCaseSensitive) != -1)
+ {
+ n->set(i,new KviKvsVariant(sz));
+ i++;
+ }
+ }
+ idx++;
+ }
+ }
+
+ return true;
+}
+
+
+/*
+ @doc: str.split
+ @type:
+ function
+ @title:
+ $str.split
+ @short:
+ Splits a string to an array
+ @syntax:
+ <array> $str.split(<separator:string>,<data:string>[,<flags:string>[,<maxfields:integer>]])
+ @description:
+ Splits the <data> string by <separator> and returns an array of substrings.[br]
+ <flags> may be a combination of the characters 's', 'w', 'r' and 'n'.[br]
+ If s is specified, <separator> matching is case sensitive, otherwise is case insensitive.[br]
+ If w is specified, <separator> is treated as a wildcard-type regular expression
+ (with * and ? wildcars).[br]
+ If r is specified, <separator> is treated as a extended-type regular expression
+ (with character classes, special escapes etc..).[br]
+ If both w and r are specified w takes precedence.[br]
+ If none of w and r are specified <separator> is treated as a simple string to be matched.[br]
+ If 'n' is specified then eventual empty fields are discarded.[br]
+ If <maxfield> is specified then at most <maxfields> items are returned in the array (i.e. the last
+ item may be not splitted completly).
+ @examples:
+ [example]
+ [comment]# Split the fields[/comment]
+ %test[] = $str.split(!,"Field0!Field1!Field2!Field3!!Field5")
+ echo %test[]
+ %i = 0
+ [cmd]while[/cmd](%i < %test[]#)
+ {
+ [cmd]echo[/cmd] "Field %i: %test[%i]"
+ %i++;
+ }
+ [/example]
+ Regexp splitting:
+ [example]
+ %Test[] = $str.split("[ ]*[0-9][0-9]*-","AllOfThem: 1-Balboy 2-Pragma 3-Iakkolo 4-Crocodile",r)
+ echo %Test[]
+ %Test[] = $str.split("Y*H","hihiYeaHhohohoyeahYepYEAHhi",sw)
+ echo %Test[]
+ [/example]
+ If used in "non-array" context it returns just a comma separated list of substrings:[br]
+ [example]
+ [cmd]echo[/cmd] $str.split("[ ]*","Condense spaces and change &nbsp; &nbsp; all &nbsp; &nbsp; &nbsp; it in commas",r)
+ [/example]
+*/
+
+static bool str_kvs_fnc_split(KviKvsModuleFunctionCall * c)
+{
+ QString szSep,szStr,szFla;
+ kvs_int_t iMaxItems;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("separator",KVS_PT_STRING,0,szSep)
+ KVSM_PARAMETER("string",KVS_PT_STRING,0,szStr)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFla)
+ KVSM_PARAMETER("maxitems",KVS_PT_INTEGER,KVS_PF_OPTIONAL,iMaxItems)
+ KVSM_PARAMETERS_END(c)
+
+ if(c->params()->count() < 4)iMaxItems = -1;
+
+ KviKvsArray * a = new KviKvsArray();
+ c->returnValue()->setArray(a);
+
+ if(szSep.isEmpty())
+ {
+ a->set(0,new KviKvsVariant(szStr));
+ return true;
+ }
+
+ if(iMaxItems == 0)return true;
+
+ bool bWild = szFla.find('w',0,false) != -1;
+ bool bContainsR = szFla.find('r',0,false) != -1;
+ bool bCaseSensitive = szFla.find('s',0,false) != -1;
+ bool bNoEmpty = szFla.find('n',0,false) != -1;
+
+ int id = 0;
+
+ int iMatch = 0;
+ int iStrLen = szStr.length();
+ int iBegin = 0;
+
+ if(bContainsR || bWild)
+ {
+ QRegExp re(szSep,bCaseSensitive,bWild);
+
+ while((iMatch != -1) && (iMatch < iStrLen) && ((id < (iMaxItems-1)) || (iMaxItems < 0)))
+ {
+ iMatch = re.search(szStr,iBegin);
+ if(iMatch != -1)
+ {
+ int len = re.matchedLength();
+ if((len == 0) && (iBegin == iMatch))iMatch++; // safety measure for empty string matching
+
+ QString tmp = szStr.mid(iBegin,iMatch - iBegin);
+ if(bNoEmpty)
+ {
+ if(!tmp.isEmpty())
+ {
+ a->set(id,new KviKvsVariant(tmp));
+ id++;
+ }
+ } else {
+ a->set(id,new KviKvsVariant(tmp));
+ id++;
+ }
+
+ iMatch += len;
+ iBegin = iMatch;
+ }
+ }
+ } else {
+ while((iMatch != -1) && (iMatch < iStrLen) && ((id < (iMaxItems-1)) || (iMaxItems < 0)))
+ {
+ iMatch = szStr.find(szSep,iBegin,bCaseSensitive);
+ if(iMatch != -1)
+ {
+ QString tmp = szStr.mid(iBegin,iMatch - iBegin);
+ if(bNoEmpty)
+ {
+ if(!tmp.isEmpty())
+ {
+ a->set(id,new KviKvsVariant(tmp));
+ id++;
+ }
+ } else {
+ a->set(id,new KviKvsVariant(tmp));
+ id++;
+ }
+
+ iMatch += szSep.length();
+ iBegin = iMatch;
+ }
+ }
+ }
+
+ if(iBegin < iStrLen)
+ {
+ QString tmpx = szStr.right(iStrLen-iBegin);
+ if(bNoEmpty)
+ {
+ if(!tmpx.isEmpty())
+ a->set(id,new KviKvsVariant(tmpx));
+ } else {
+ a->set(id,new KviKvsVariant(tmpx));
+ }
+ } else {
+ if(!bNoEmpty)
+ a->set(id,new KviKvsVariant(QString::null)); // empty string at the end
+ }
+
+ return true;
+}
+
+/*
+ @doc: str.printf
+ @type:
+ function
+ @title:
+ $str.printf
+ @short:
+ Returns a formatted string in a C sprintf-like fashion.
+ @syntax:
+ <string> $str.printf(<format:string>[,<parameter:variant>[...]]);
+ @description:
+ This function acts like the C sprintf(): it returns
+ a string formatted by following the specification in <format>
+ and by using the following corresponding variadic parameters.
+ Since the percent sign is used as variable prefix in KVIrc,
+ this function uses the question mark '?' instead.[br]
+ The <format> string can contain the following escape sequences:[br]
+ [br]
+ [table]
+ [tr][td][b]?s[/b][/td][td]The next parameter is evaluated as a string and substituted in place of ?s[/td][/tr]
+ [tr][td][b]?d[/b][/td][td]The next parameter is evaluated as a signed integer and substituted in place of ?d[/td][/tr]
+ [tr][td][b]?i[/b][/td][td]Same as ?d[/td][/tr]
+ [tr][td][b]?u[/b][/td][td]The next parameter is evaluated as an unsigned signed integer and substituted in place of ?d[/td][/tr]
+ [tr][td][b]?x[/b][/td][td]The next parameter is evaluated as an unsigned integer and its hexadecimal rappresentation
+ is substituted in place of ?x[/td][/tr]
+ [tr][td][b]?h[/b][/td][td]Same as ?x[/td][/tr]
+ [tr][td][b]?X[/b][/td][td]Same as ?x but uppercase hexadecimal digits are used[/td][/tr]
+ [tr][td][b]?H[/b][/td][td]Same as ?X[/td][/tr]
+ [tr][td][b]??[/b][/td][td]A literal question mark[/td][/tr]
+ [tr][td][b]?[.N]f[/b][/td][td]The next parameter is evaluated as a real floating point value
+ and its rappresentation substituted in place of ?f. The optional [.N] modifier,
+ where N is an unsigned integer, rappresents the desired precision.[/td][/tr]
+ [tr][td][b]?[.N]e[/b][/td][td]The next parameter is evaluated as a real floating point value
+ and its scientific rappresentation substituted in place of ?e. The optional [.N] modifier,
+ where N is an unsigned integer, rappresents the desired precision.[/td][/tr]
+ [tr][td][b]?[.N]E[/b][/td][td]Same as ?e but an uppercase E is used as the exponent prefix[/td][/tr]
+ [/table]
+ @examples:
+ [example]
+ %val = $(1.0 / 3.0);
+ $str.printf("1/3 with a precision of 3 digits is ?.3f, while in scientific notation it's ?e",%val,%val)
+ [/example]
+*/
+
+
+static bool str_kvs_fnc_printf(KviKvsModuleFunctionCall * c)
+{
+ QString szFormat;
+ KviKvsVariantList vArgs;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("format",KVS_PT_STRING,0,szFormat)
+ KVSM_PARAMETER("vArgs",KVS_PT_VARIANTLIST,0,vArgs)
+ KVSM_PARAMETERS_END(c)
+
+ QString s;
+
+#define MEMINCREMENT 32
+
+ int reallen = 0;
+ int allocsize = MEMINCREMENT;
+
+ //s.setLength(allocsize);
+
+ const QChar * fmt = KviQString::nullTerminatedArray(szFormat);
+
+ if(fmt)
+ {
+ QChar * buffer = (QChar *)kvi_malloc(sizeof(QChar) * allocsize);
+ //QChar * p = (QChar *)s.unicode();
+
+ //9999999999999999999999999999999\0
+ char numberBuffer[1024];
+ char *pNumBuf;
+ kvs_uint_t tmp;
+ kvs_int_t argValue;
+ kvs_uint_t argUValue;
+ kvs_real_t argRValue;
+
+ QChar * p = buffer;
+
+ #define INCREMENT_MEM \
+ { \
+ allocsize += MEMINCREMENT; \
+ buffer = (QChar *)kvi_realloc(buffer,sizeof(QChar) * allocsize); \
+ p = buffer + reallen; \
+ }
+
+ #define INCREMENT_MEM_BY(numchars) \
+ { \
+ allocsize += numchars + MEMINCREMENT; \
+ buffer = (QChar *)kvi_realloc(buffer,sizeof(QChar) * allocsize); \
+ p = buffer + reallen; \
+ }
+
+ KviKvsVariant * pVar;
+
+ pVar = vArgs.first();
+
+ for(; fmt->unicode() ; ++fmt)
+ {
+ if(reallen == allocsize)INCREMENT_MEM
+
+ //copy up to a '?'
+ if(fmt->unicode() != '?')
+ {
+ *p++ = *fmt;
+ reallen++;
+ continue;
+ }
+
+ ++fmt; //skip this '?'
+ switch(fmt->unicode())
+ {
+ case 's':
+ {
+ QString sz;
+ if(pVar)pVar->asString(sz);
+ if(sz.isEmpty())continue;
+ int len = sz.length();
+ if((allocsize - reallen) < len)INCREMENT_MEM_BY(len)
+ const QChar * ch = sz.unicode();
+ while(len--)*p++ = *ch++;
+ reallen += sz.length();
+ pVar = vArgs.next();
+ continue;
+ }
+ case 'd': //signed integer
+ {
+ if(pVar)
+ {
+ if(!pVar->asInteger(argValue))
+ {
+ c->warning(__tr2qs("Invalid argument for ?d escape sequence, 0 assumed"));
+ argValue = 0;
+ }
+ } else {
+ c->warning(__tr2qs("Missing argument for ?d escape sequence, 0 assumed"));
+ argValue = 0;
+ }
+ argValue = 0;
+ if(argValue < 0)
+ { //negative integer
+ *p++ = '-';
+ reallen++;
+ argValue = -argValue; //need to have it positive
+ // most negative integer exception (avoid completely senseless (non digit) responses)
+ if(argValue < 0)argValue = 0; //we get -0 here
+ }
+ //write the number in a temporary buffer
+ pNumBuf = numberBuffer;
+ do {
+ tmp = argValue / 10;
+ *pNumBuf++ = argValue - (tmp * 10) + '0';
+ } while((argValue = tmp));
+ //copy now....
+ argUValue = pNumBuf - numberBuffer; //length of the number string
+ if((allocsize - reallen) < (int)argUValue)INCREMENT_MEM_BY(argUValue)
+ do { *p++ = QChar(*--pNumBuf); } while(pNumBuf != numberBuffer);
+ reallen += argUValue;
+ pVar = vArgs.next();
+ continue;
+ }
+ case 'u': //unsigned integer
+ {
+ if(pVar)
+ {
+ if(!pVar->asInteger(argValue))
+ {
+ c->warning(__tr2qs("Invalid argument for ?u escape sequence, 0 assumed"));
+ argValue = 0;
+ }
+ } else {
+ c->warning(__tr2qs("Missing argument for ?u escape sequence, 0 assumed"));
+ argValue = 0;
+ }
+ argUValue = (kvs_uint_t)argValue;
+ //write the number in a temporary buffer
+ pNumBuf = numberBuffer;
+ do {
+ tmp = argUValue / 10;
+ *pNumBuf++ = argUValue - (tmp * 10) + '0';
+ } while((argUValue = tmp));
+ //copy now....
+ argValue = pNumBuf - numberBuffer; //length of the number string
+ if((allocsize - reallen) < argValue)INCREMENT_MEM_BY(argValue)
+ do { *p++ = *--pNumBuf; } while(pNumBuf != numberBuffer);
+ reallen += argValue;
+ pVar = vArgs.next();
+ continue;
+ }
+ case 'h':
+ case 'x': // hexadecimal unsigned integer
+ {
+ static char hexsmalldigits[]="0123456789abcdef";
+
+ if(pVar)
+ {
+ if(!pVar->asInteger(argValue))
+ {
+ c->warning(__tr2qs("Invalid argument for ?x escape sequence, 0 assumed"));
+ argValue = 0;
+ }
+ } else {
+ c->warning(__tr2qs("Missing argument for ?x escape sequence, 0 assumed"));
+ argValue = 0;
+ }
+ argUValue = (kvs_uint_t)argValue;
+
+ //write the number in a temporary buffer
+ pNumBuf = numberBuffer;
+ do {
+ tmp = argUValue / 16;
+ *pNumBuf++ = hexsmalldigits[argUValue - (tmp * 16)];
+ } while((argUValue = tmp));
+ //copy now....
+ argValue = pNumBuf - numberBuffer; //length of the number string
+ if((allocsize - reallen) < argValue)INCREMENT_MEM_BY(argValue)
+ do { *p++ = *--pNumBuf; } while(pNumBuf != numberBuffer);
+ reallen += argValue;
+ pVar = vArgs.next();
+ continue;
+ }
+ case 'H':
+ case 'X': // hexadecimal unsigned integer
+ {
+ static char hexbigdigits[]="0123456789ABCDEF";
+ if(pVar)
+ {
+ if(!pVar->asInteger(argValue))
+ {
+ c->warning(__tr2qs("Invalid argument for ?X escape sequence, 0 assumed"));
+ argValue = 0;
+ }
+ } else {
+ c->warning(__tr2qs("Missing argument for ?X escape sequence, 0 assumed"));
+ argValue = 0;
+ }
+ argUValue = (kvs_uint_t)argValue;
+ //write the number in a temporary buffer
+ pNumBuf = numberBuffer;
+ do {
+ tmp = argUValue / 16;
+ *pNumBuf++ = hexbigdigits[argUValue - (tmp * 16)];
+ } while((argUValue = tmp));
+ //copy now....
+ argValue = pNumBuf - numberBuffer; //length of the number string
+ if((allocsize - reallen) < argValue)INCREMENT_MEM_BY(argValue)
+ do { *p++ = *--pNumBuf; } while(pNumBuf != numberBuffer);
+ reallen += argValue;
+ pVar = vArgs.next();
+ continue;
+ }
+ case '?':
+ {
+ if(fmt->unicode())
+ {
+ if(reallen == allocsize)INCREMENT_MEM
+ *p++ = *fmt;
+ reallen++;
+ }
+ continue;
+ }
+ break;
+ case '.':
+ {
+ // precision mark
+ const QChar * save = fmt;
+ fmt++;
+ unsigned int uPrecision = 0;
+
+ char fmtbuffer[8];
+ fmtbuffer[0] = '%';
+ fmtbuffer[1] = '.';
+
+ int idx = 2;
+
+ while((fmt->unicode() >= '0') && (fmt->unicode() <= '9') && (idx < 6))
+ {
+ uPrecision *= 10;
+ fmtbuffer[idx] = fmt->unicode();
+ uPrecision += fmtbuffer[idx] - '0';
+ fmt++;
+ idx++;
+ }
+ fmtbuffer[idx] = fmt->unicode();
+ fmtbuffer[idx+1] = 0;
+
+ if(pVar)
+ {
+ if(!pVar->asReal(argRValue))
+ {
+ c->warning(__tr2qs("Invalid argument for a floating point escape sequence, 0.0 assumed"));
+ argRValue = 0.0;
+ }
+ } else {
+ c->warning(__tr2qs("Missing argument for a floating point escape sequence, 0.0 assumed"));
+ argRValue = 0;
+ }
+ switch(fmt->unicode())
+ {
+ case 'e':
+ case 'E':
+ case 'F':
+ case 'f':
+ ::sprintf(numberBuffer,fmtbuffer,argRValue);
+ //copy now....
+ argValue = kvi_strLen(numberBuffer);
+ if((allocsize - reallen) < argValue)INCREMENT_MEM_BY(argValue)
+ pNumBuf = numberBuffer;
+ while(*pNumBuf){ *p++ = *pNumBuf++; }
+ reallen += argValue;
+ break;
+ default:
+ // anything else is crap.. invalid format
+ fmt = save;
+ *p++ = '?'; //write it
+ reallen++;
+ if(fmt->unicode())
+ {
+ if(reallen == allocsize)INCREMENT_MEM
+ *p++ = *fmt;
+ reallen++;
+ }
+ break;
+ }
+ pVar = vArgs.next();
+ continue;
+ }
+ break;
+ default: //a normal ? followed by some char
+ {
+ *p++ = '?'; //write it
+ reallen++;
+ if(fmt->unicode())
+ {
+ if(reallen == allocsize)INCREMENT_MEM
+ *p++ = *fmt;
+ reallen++;
+ }
+ continue;
+ }
+ }
+ }
+
+ s.setUnicode(buffer,reallen);
+ kvi_free(buffer);
+ }
+
+ c->returnValue()->setString(s);
+ return true;
+}
+
+
+
+/*********************************************************************/
+// Module stuff
+/********************************************************************/
+
+static bool str_module_init(KviModule * m)
+{
+ KVSM_REGISTER_FUNCTION(m,"split",str_kvs_fnc_split);
+ KVSM_REGISTER_FUNCTION(m,"grep",str_kvs_fnc_grep);
+ KVSM_REGISTER_FUNCTION(m,"charsum",str_kvs_fnc_charsum);
+ KVSM_REGISTER_FUNCTION(m,"len",str_kvs_fnc_len);
+ KVSM_REGISTER_FUNCTION(m,"length",str_kvs_fnc_len);
+ KVSM_REGISTER_FUNCTION(m,"isempty",str_kvs_fnc_isempty);
+ KVSM_REGISTER_FUNCTION(m,"join",str_kvs_fnc_join);
+
+ KVSM_REGISTER_FUNCTION(m,"section",str_kvs_fnc_section);
+ KVSM_REGISTER_FUNCTION(m,"lowcase",str_kvs_fnc_lowcase);
+ KVSM_REGISTER_FUNCTION(m,"upcase",str_kvs_fnc_upcase);
+ KVSM_REGISTER_FUNCTION(m,"localeupcase",str_kvs_fnc_localeupcase);
+ KVSM_REGISTER_FUNCTION(m,"localelowcase",str_kvs_fnc_localelowcase);
+ KVSM_REGISTER_FUNCTION(m,"isnumber",str_kvs_fnc_isnumber);
+ KVSM_REGISTER_FUNCTION(m,"isunsignednumber",str_kvs_fnc_isunsignednumber);
+ KVSM_REGISTER_FUNCTION(m,"contains",str_kvs_fnc_contains);
+ KVSM_REGISTER_FUNCTION(m,"containsnocase",str_kvs_fnc_containsnocase);
+ KVSM_REGISTER_FUNCTION(m,"equal",str_kvs_fnc_equal);
+ KVSM_REGISTER_FUNCTION(m,"equalnocase",str_kvs_fnc_equalnocase);
+ KVSM_REGISTER_FUNCTION(m,"cmp",str_kvs_fnc_cmp);
+ KVSM_REGISTER_FUNCTION(m,"cmpnocase",str_kvs_fnc_cmpnocase);
+ KVSM_REGISTER_FUNCTION(m,"find",str_kvs_fnc_find);
+ KVSM_REGISTER_FUNCTION(m,"findfirst",str_kvs_fnc_findfirst);
+ KVSM_REGISTER_FUNCTION(m,"findfirstnocase",str_kvs_fnc_findfirstnocase);
+ KVSM_REGISTER_FUNCTION(m,"findlast",str_kvs_fnc_findlast);
+ KVSM_REGISTER_FUNCTION(m,"findlastnocase",str_kvs_fnc_findlastnocase);
+ KVSM_REGISTER_FUNCTION(m,"left",str_kvs_fnc_left);
+ KVSM_REGISTER_FUNCTION(m,"right",str_kvs_fnc_right);
+ KVSM_REGISTER_FUNCTION(m,"mid",str_kvs_fnc_mid);
+ KVSM_REGISTER_FUNCTION(m,"append",str_kvs_fnc_append);
+ KVSM_REGISTER_FUNCTION(m,"prepend",str_kvs_fnc_prepend);
+ KVSM_REGISTER_FUNCTION(m,"insert",str_kvs_fnc_insert);
+ KVSM_REGISTER_FUNCTION(m,"strip",str_kvs_fnc_strip);
+ KVSM_REGISTER_FUNCTION(m,"stripright",str_kvs_fnc_stripright);
+ KVSM_REGISTER_FUNCTION(m,"stripleft",str_kvs_fnc_stripleft);
+ KVSM_REGISTER_FUNCTION(m,"stripcolors",str_kvs_fnc_stripcolors);
+ KVSM_REGISTER_FUNCTION(m,"replace",str_kvs_fnc_replace);
+ KVSM_REGISTER_FUNCTION(m,"replacenocase",str_kvs_fnc_replacenocase);
+ KVSM_REGISTER_FUNCTION(m,"urlencode",str_kvs_fnc_urlencode);
+ KVSM_REGISTER_FUNCTION(m,"lefttolast",str_kvs_fnc_lefttolast);
+ KVSM_REGISTER_FUNCTION(m,"lefttofirst",str_kvs_fnc_lefttofirst);
+ KVSM_REGISTER_FUNCTION(m,"rightfromfirst",str_kvs_fnc_rightfromfirst);
+ KVSM_REGISTER_FUNCTION(m,"rightfromlast",str_kvs_fnc_rightfromlast);
+ KVSM_REGISTER_FUNCTION(m,"match",str_kvs_fnc_match);
+ KVSM_REGISTER_FUNCTION(m,"matchnocase",str_kvs_fnc_matchnocase);
+ KVSM_REGISTER_FUNCTION(m,"word",str_kvs_fnc_word);
+ KVSM_REGISTER_FUNCTION(m,"token",str_kvs_fnc_token);
+ KVSM_REGISTER_FUNCTION(m,"fromClipboard",str_kvs_fnc_fromclipboard);
+ KVSM_REGISTER_FUNCTION(m,"digest",str_kvs_fnc_digest);
+ KVSM_REGISTER_FUNCTION(m,"printf",str_kvs_fnc_printf);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"toClipboard",str_kvs_cmd_toClipboard);
+ return true;
+}
+
+static bool str_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "File", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)"\
+ " (C) 2002 Juanjo Alvarez (juanjux@yahoo.es)" \
+ " (C) 2005 Tonino Imbesi (grifisx at barmes dot org)" \
+ " (C) 2005 Alessandro Carbone (noldor at barmes dot org)", // author & (C)
+ "Interface to the str system",
+ str_module_init,
+ 0,
+ 0,
+ str_module_cleanup
+)
diff --git a/src/modules/system/Makefile.am b/src/modules/system/Makefile.am
new file mode 100644
index 00000000..69302d13
--- /dev/null
+++ b/src/modules/system/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makesystem - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvisystem.la
+
+libkvisystem_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvisystem_la_SOURCES = libkvisystem.cpp plugin.cpp
+libkvisystem_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS = plugin.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/system/libkvisystem.cpp b/src/modules/system/libkvisystem.cpp
new file mode 100644
index 00000000..54ada405
--- /dev/null
+++ b/src/modules/system/libkvisystem.cpp
@@ -0,0 +1,749 @@
+//=============================================================================
+//
+// File : libkvisystem.cpp
+// Creation date : Fri Nov 16 03:50:12 2001 GMT by Szymon Stefanek
+//
+// This system is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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 "kvi_module.h"
+#include "kvi_string.h"
+#include "kvi_library.h"
+#include "kvi_thread.h"
+
+#include "kvi_locale.h"
+#include "kvi_qcstring.h"
+#include "kvi_app.h"
+#include "kvi_env.h"
+#include "kvi_osinfo.h"
+#include "kvi_qcstring.h"
+
+#include <qclipboard.h>
+
+#ifndef COMPILE_ON_WINDOWS
+ #include <sys/utsname.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+#endif
+
+#ifdef COMPILE_KDE_SUPPORT
+ #include <dcopclient.h>
+#endif
+
+#include "kvi_modulemanager.h"
+
+#include "plugin.h"
+
+KviPluginManager * g_pPluginManager;
+
+/*
+ @doc: system.ostype
+ @type:
+ function
+ @title:
+ $system.ostype
+ @short:
+ Returns the type of the operating system
+ @syntax:
+ <string> $system.ostype()
+ @description:
+ Returns the current type of operating system: unix,macosx or windows.[br]
+*/
+
+static bool system_kvs_fnc_ostype(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setString(KviOsInfo::type());
+ return true;
+}
+/*
+ @doc: system.osname
+ @type:
+ function
+ @title:
+ $system.osname
+ @short:
+ Returns the name of the operating system
+ @syntax:
+ <string> $system.osname()
+ @description:
+ Returns the name of the operating system. On UNIX like machines
+ this is the field sysname of the utsname structure returned by
+ the uname() syscall.
+*/
+
+static bool system_kvs_fnc_osname(KviKvsModuleFunctionCall *c)
+{
+ c->returnValue()->setString(KviOsInfo::name());
+ return true;
+}
+
+
+/*
+ @doc: system.osversion
+ @type:
+ function
+ @title:
+ $system.osversion
+ @short:
+ Returns the version of the operating system
+ @syntax:
+ <string> $system.osversion()
+ @description:
+ Returns the version of the operating system.[br]
+*/
+
+static bool system_kvs_fnc_osversion(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::version());
+ return true;
+}
+
+/*
+ @doc: system.osrelease
+ @type:
+ function
+ @title:
+ $system.osrelease
+ @short:
+ Returns the release of the operating system
+ @syntax:
+ <string> $system.osrelease()
+ @description:
+ Returns the release of the operating system.[br]
+*/
+
+static bool system_kvs_fnc_osrelease(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::release());
+ return true;
+}
+
+/*
+ @doc: system.osmachine
+ @type:
+ function
+ @title:
+ $system.osmachine
+ @short:
+ Returns the machine of the operating system
+ @syntax:
+ <string> $system.osmachine()
+ @description:
+ Returns the machine of the operating system.[br]
+*/
+
+static bool system_kvs_fnc_osmachine(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::machine());
+ return true;
+}
+
+/*
+ @doc: system.osnodename
+ @type:
+ function
+ @title:
+ $system.osnodename
+ @short:
+ Returns the nodename of the operating system
+ @syntax:
+ <string> $system.osnodename()
+ @description:
+ Returns the nodename of the operating system.[br]
+*/
+
+static bool system_kvs_fnc_osnodename(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::nodename());
+ return true;
+}
+
+/*
+ @doc: system.getenv
+ @keyterms:
+ Enviroinement variables
+ @type:
+ function
+ @title:
+ $system.getenv
+ @short:
+ Returns the value of an enviroinement variable
+ @syntax:
+ <string> $system.getenv(<variable:string>)
+ @description:
+ Returns the value of the enviroinement <variable>.[br]
+*/
+
+static bool system_kvs_fnc_getenv(KviKvsModuleFunctionCall *c)
+{
+ QString szVariable;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("variable",KVS_PT_NONEMPTYSTRING,0,szVariable)
+ KVSM_PARAMETERS_END(c)
+
+ KviQCString szVar = szVariable.local8Bit();
+#ifdef COMPILE_ON_WINDOWS
+ QString env = getenv(szVar.data());
+ QString def = __tr2qs("No environment variable found, please don't use the %% in the request");
+ c->returnValue()->setString(env.isEmpty() ? QString::fromLocal8Bit(env) : QString::fromLocal8Bit(def));
+#else
+ char * b = kvi_getenv(szVar.data());
+ c->returnValue()->setString(b ? QString::fromLocal8Bit(b) : QString::null);
+#endif
+ return true;
+}
+
+/*
+ @doc: system.clipboard
+ @keyterms:
+ Clipboard management
+ @type:
+ function
+ @title:
+ $system.clipboard
+ @short:
+ Returns the value of the system clipboard
+ @syntax:
+ <string> $system.clipboard()
+ @description:
+ Returns the current value of the system clipboard.
+ Please note that there are systems that have the concept
+ of "selection" (most notably X11) which is NOT the same as the clipboard.
+ See [fnc]$system.selection[/fnc]().
+ @seealso:
+ [fnc]$system.selection[/fnc],
+ [cmd]system.setClipboard[/cmd],
+ [cmd]system.setSelection[/cmd]
+*/
+
+static bool system_kvs_fnc_clipboard(KviKvsModuleFunctionCall *c)
+{
+ c->returnValue()->setString(g_pApp->clipboard()->text(QClipboard::Clipboard));
+ return true;
+}
+
+
+/*
+ @doc: system.setClipboard
+ @type:
+ command
+ @title:
+ system.setClipboard
+ @keyterms:
+ Clipboard management
+ @short:
+ Sets the current system clipboard contents
+ @syntax:
+ system.setClipboard <data:string>
+ @description:
+ Sets the system clipboard contents to the string <data>.
+ Please note that there are systems that have the concept
+ of "selection" (most notably X11) which is NOT the same as the clipboard.
+ See [fnc]$system.selection[/fnc]().
+ @seealso:
+ [fnc]$system.selection[/fnc],
+ [fnc]$system.clipboard[/fnc],
+ [cmd]system.setSelection[/cmd]
+*/
+
+static bool system_kvs_cmd_setClipboard(KviKvsModuleCommandCall * c)
+{
+ QString szValue;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_STRING,KVS_PF_OPTIONAL,szValue)
+ KVSM_PARAMETERS_END(c)
+ g_pApp->clipboard()->setText(szValue,QClipboard::Clipboard);
+ return true;
+}
+
+/*
+ @doc: system.setSelection
+ @type:
+ command
+ @title:
+ system.setSelection
+ @keyterms:
+ Clipboard management
+ @short:
+ Sets the current system selection contents
+ @syntax:
+ system.setSelection <data:string>
+ @description:
+ Sets the system selection contents to the string <data>.
+ Please note that this command will work only on systems that have the concept
+ of "selection" (most notably X11) which is NOT the same as the clipboard.
+ @seealso:
+ [fnc]$system.selection[/fnc],
+ [fnc]$system.clipboard[/fnc],
+ [cmd]system.setClipboard[/cmd]
+*/
+
+static bool system_kvs_cmd_setSelection(KviKvsModuleCommandCall * c)
+{
+ QString szValue;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_STRING,KVS_PF_OPTIONAL,szValue)
+ KVSM_PARAMETERS_END(c)
+ g_pApp->clipboard()->setText(szValue,QClipboard::Selection);
+ return true;
+}
+
+/*
+ @doc: system.selection
+ @keyterms:
+ Clipboard management
+ @type:
+ function
+ @title:
+ $system.selection
+ @short:
+ Returns the value of the system selection
+ @syntax:
+ <string> $system.selection()
+ @description:
+ Returns the current value of the system selection.
+ This function will work only on systems that have the concept
+ of "selection" (most notably X11) which is NOT the same as clipboard.
+ On other systems this function will always return an empty string.
+ See [fnc]$system.clipboard[/fnc]().
+ @seealso:
+ [fnc]$system.clipboard[/fnc],
+ [cmd]system.setClipboard[/cmd],
+ [cmd]system.setSelection[/cmd]
+*/
+
+static bool system_kvs_fnc_selection(KviKvsModuleFunctionCall *c)
+{
+ c->returnValue()->setString(g_pApp->clipboard()->text(QClipboard::Selection));
+ return true;
+}
+
+
+/*
+ @doc: system.checkModule
+ @keyterms:
+ Module checking
+ @type:
+ function
+ @title:
+ $system.checkModule
+ @short:
+ Checks if a KVIrc module is loadable
+ @syntax:
+ <boolean> $system.checkModule(<module_name:string>)
+ @description:
+ Attempts to load the specified module and returns
+ $true if succesfull and $false otherwise. This can
+ be effectively used to test if a KVIrc exension module
+ is present on the system and can be loaded by the
+ KVIrc engine.
+*/
+
+static bool system_kvs_fnc_checkModule(KviKvsModuleFunctionCall *c)
+{
+ QString szModuleName;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("module_name",KVS_PT_STRING,0,szModuleName)
+ KVSM_PARAMETERS_END(c)
+
+ c->returnValue()->setBoolean(g_pModuleManager->loadModule(szModuleName.utf8().data()));
+ return true;
+}
+
+
+/*
+ @doc: system.hostname
+ @keyterms:
+ System information
+ @type:
+ function
+ @title:
+ $system.hostname
+ @short:
+ Returns the hostname of the machine that KVIrc is running on
+ @syntax:
+ <string> $system.hostname()
+ @description:
+ Returns the hostname of the machine that KVIrc is running on.[br]
+*/
+
+static bool system_kvs_fnc_hostname(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::hostname());
+ return true;
+}
+
+
+/*
+ @doc: system.dcop
+ @keyterms:
+ System information
+ @type:
+ function
+ @title:
+ $system.dcop
+ @short:
+ Performs a DCOP call
+ @syntax:
+ <variant> $system.dcop(<application:string>,<objectid:string>,<function:string>[,<parameter1:string>[,<parameter2:string>[,...]]])
+ @description:
+ This function allows performing simple DCOP calls without executing
+ an external process. This feature is available ONLY when KDE support
+ is compiled in the executable: this means that this function is absolutely
+ non portable (don't use it in scripts that you're going to distribute).
+ <application> is the name of the application being called, <objectid> is the
+ identifier of the object called, <function> is the function to be executed
+ on the remote object and <parameter1>,<parameter2>,... is the list of
+ parameters to be passed. The <function> name must contain the
+ trailing parenthesis and parameter specification (see examples).
+ The parameters MUST be in the form "type=value"
+ where "type" is the C++ type of the parameter and value
+ is the string rappresentation of the parameter data. Currently
+ KVIrc supports only QString,KviQCString,bool,int and uint data types.[br]
+ The returned value is the string rappresentation of the returned
+ data if the return type is known, otherwise it is the name of the data type returned.
+ [br]
+ If the application name is prefixed with "?" then the call is performed in "remote test"
+ mode: no "remote" errors are printed and the function returns 1 if the call executed
+ succesfully and 0 if the call failed. This can be used with the very first
+ call to programmaticaly test if the remote application is running.
+ @examples:
+ [example]
+ echo $system.dcop("kdesktop","KBackgroundIface","currentWallpaper(int)","int=0")
+ echo $system.dcop("kdesktop","KScreensaverIface","lock()")
+ # we can also ignore the return value in several ways
+ %dummy = $system.dcop("kicker","kicker","showKMenu()")
+ $system.dcop("kdesktop","KScreensaverIface","save()")
+ $system.dcop("kicker","Panel","addBrowserButton(QString)","QString=/")
+ # runtime test if a call would work (i.e. , kicker is running at all, parameters are right etc...)
+ if($system.dcop("?kicker","kicker","showKMenu()"))echo "Can't make dcop calls to kicker!"
+ [/example]
+*/
+
+static bool system_kvs_fnc_dcop(KviKvsModuleFunctionCall *c)
+{
+ bool bTestMode = false;
+
+ KviQCString szApp,szObj,szFun;
+ QStringList parms;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("application",KVS_PT_NONEMPTYCSTRING,0,szApp)
+ KVSM_PARAMETER("objectid",KVS_PT_NONEMPTYCSTRING,0,szObj)
+ KVSM_PARAMETER("function",KVS_PT_NONEMPTYCSTRING,0,szFun)
+ KVSM_PARAMETER("parameter_list",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,parms)
+ KVSM_PARAMETERS_END(c)
+
+ if((szApp.data()) && (szApp.length() > 1))
+ {
+ if(*(szApp.data()) == '?')
+ {
+ bTestMode = true;
+ szApp.remove(0,1);
+ }
+ }
+
+#ifdef COMPILE_KDE_SUPPORT
+
+ QByteArray ba;
+ QDataStream ds(ba, IO_WriteOnly);
+
+ for ( QStringList::Iterator it = parms.begin(); it != parms.end(); ++it )
+ {
+ KviStr tmp = *it;
+
+ if(tmp.isEmpty())
+ {
+ c->warning(__tr2qs("Invalid DCOP parameter syntax"));
+ return false;
+ }
+
+ KviStr szType = tmp.leftToFirst('=',false);
+ tmp.cutToFirst('=',true);
+ if(szType.isEmpty())szType = "int";
+ bool bOk;
+ if(kvi_strEqualCI("int",szType.ptr()) || kvi_strEqualCI("long",szType.ptr()))
+ {
+ int iii = tmp.toInt(&bOk);
+ if(!bOk)
+ {
+ c->warning(__tr2qs("The specified parameter is not an integer"));
+ return false;
+ }
+ ds << iii;
+ } else if(kvi_strEqualCI("QString",szType.ptr()))
+ {
+ QString ddd = tmp.ptr();
+ ds << ddd;
+ } else if(kvi_strEqualCI("KviQCString",szType.ptr()))
+ {
+ KviQCString qcs = tmp.ptr();
+ ds << qcs;
+ } else if(kvi_strEqualCI("bool",szType.ptr()))
+ {
+ bool bbb = kvi_strEqualCI(tmp.ptr(),"true");
+ ds << bbb;
+ } else if(kvi_strEqualCI("unsigned int",szType.ptr()) || kvi_strEqualCI("uint",szType.ptr()) || kvi_strEqualCI("Q_UINT32",szType.ptr()))
+ {
+ unsigned int uii = tmp.toUInt(&bOk);
+ if(!bOk)
+ {
+ c->warning(__tr2qs("The specified parameter is not an integer"));
+ return false;
+ }
+ ds << uii;
+ } else {
+ c->warning(__tr2qs("Unsupported DCOP parameter type %s"),tmp.ptr());
+ return false;
+ }
+ }
+
+ QByteArray rba;
+ KviQCString szRetType;
+
+ bool bRet = g_pApp->dcopClient()->call(szApp,szObj,szFun,ba,szRetType,rba);
+
+ if(!bRet)
+ {
+ if(!bTestMode)
+ c->warning(__tr2qs("DCOP call failed"));
+ c->returnValue()->setInteger(0);
+ } else {
+ if(bTestMode)
+ c->returnValue()->setInteger(1);
+ else {
+ QDataStream ret(rba, IO_ReadOnly);
+ if(szRetType == "bool")
+ {
+ bool bqw;
+ ret >> bqw;
+ c->returnValue()->setInteger(bqw ? 1 : 0);
+ } else if(szRetType == "QString")
+ {
+ QString szz;
+ ret >> szz;
+ c->returnValue()->setString(szz);
+ } else if(szRetType == "QCString")
+ {
+ KviQCString sss;
+ ret >> sss;
+ c->returnValue()->setString(sss.data());
+ } else if((szRetType == "uint") || (szRetType == "unsigned int") || (szRetType == "Q_UINT32"))
+ {
+ unsigned int ui3;
+ ret >> ui3;
+ c->returnValue()->setInteger(ui3);
+ } else if((szRetType == "int") || (szRetType == "long"))
+ {
+ int iii;
+ ret >> iii;
+ c->returnValue()->setInteger(iii);
+ } else if(szRetType == "QCStringList")
+ {
+#ifndef COMPILE_USE_QT4
+ QCStringList csl;
+ ret >> csl;
+ KviKvsArray * arry = new KviKvsArray();
+ int idx = 0;
+ for(QCStringList::Iterator iter = csl.begin();iter != csl.end();++iter)
+ {
+ arry->set(idx,new KviKvsVariant(QString(*iter)));
+ idx++;
+ }
+ c->returnValue()->setArray(arry);
+#endif
+ } else if(szRetType == "QStringList")
+ {
+ QStringList csl;
+ ret >> csl;
+ KviKvsArray * arry = new KviKvsArray();
+ int idx = 0;
+ for(QStringList::Iterator iter = csl.begin();iter != csl.end();++iter)
+ {
+ arry->set(idx,new KviKvsVariant(*iter));
+ idx++;
+ }
+ c->returnValue()->setArray(arry);
+ } else {
+ c->returnValue()->setString(szRetType.data());
+ }
+ }
+ }
+#else
+ if(!bTestMode)
+ c->warning(__tr2qs("DCOP calls are available only when KDE support is compiled in"));
+ c->returnValue()->setInteger(0);
+#endif
+
+ return true;
+}
+
+
+/*
+ @doc: system.setenv
+ @type:
+ command
+ @title:
+ system.setenv
+ @keyterms:
+ Enviroinement variables
+ @short:
+ Sets an enviroinement variable
+ @syntax:
+ system.setenv <variable:string> [<value:string>]
+ @description:
+ Sets the enviroinement <variable> to the <value> string.[br]
+ If <value> is not given , the <variable> is unset.[br]
+ @seealso:
+ [fnc]$system.getenv[/fnc]
+*/
+
+
+static bool system_kvs_cmd_setenv(KviKvsModuleCommandCall * c)
+{
+ QString szVariable,szValue;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("variable",KVS_PT_NONEMPTYSTRING,0,szVariable)
+ KVSM_PARAMETER("value",KVS_PT_STRING,KVS_PF_OPTIONAL,szValue)
+ KVSM_PARAMETERS_END(c)
+
+ KviQCString szVar = szVariable.local8Bit();
+ KviQCString szVal = szValue.local8Bit();
+
+ if(szVal.isEmpty())kvi_unsetenv(szVar.data());
+ else
+ {
+/*#ifdef COMPILE_ON_WINDOWS
+ QString Var,Val,VarAndVal;
+ Val = szVar.data();
+ Var = szVal.data();
+ VarAndVal = Var+"="+Val;
+ putenv(VarAndVal);
+#else*/ // <-- this stuff is implicit in kvi_setenv: that's why we have the kvi_ version.
+ kvi_setenv(szVar.data(),szVal.data());
+/*#endif*/
+ }
+ return true;
+}
+
+/*
+ @doc: system.call
+ @keyterms:
+ call plugin
+ @type:
+ function
+ @title:
+ $system.call
+ @short:
+ Allows to call functions of a plugin
+ @syntax:
+ <string> $system.call(<plugin:string>, <function:string>[,<parameters:string>,...])
+ @description:
+ This function allows you to call simple functions of "easyplugins" (dll/so) and
+ get the result of this function. The easyplugins have to be coded in a special way.
+ If you want to write your own easyplugins, have a look on the easyplugins documentation.
+ [br]
+ [br]
+ The function needs a minimum of 2 parameters. The others are optional and not limited.[br]
+ The first one is the complete name like "example.dll" or "example.so"
+ If you have a relative path or only the filename KVIrc looks for the easyplugins in the following dirs:[br]
+ In a subdir called "easyplugins" in the local and global KVIrc directory.
+ If you give an absolute path KVIrc will load it directly.
+ [br]
+ [br]
+ You are free to add more parameters, they will be given to the easyplugin.[br]
+ The easyplugin decides how much parameters you need in addition to the first 2.
+ [br]
+ [br]
+ [b]Warning: Only use easyplugins of known and trustable sources![/b]
+ @examples:
+ [example]
+ echo $system.call("my.dll","myfunction")
+ echo $system.call("my.dll","myfunction","parameter1","parameter2")
+ echo $system.call("c:/my.dll","myfunction")
+ echo $system.call("my.so","myfunction","parameter1")
+ [/example]
+*/
+
+
+static bool system_kvs_fnc_plugin_call(KviKvsModuleFunctionCall *c)
+{
+ return g_pPluginManager->pluginCall(c);
+}
+
+static bool system_module_init(KviModule * m)
+{
+ KVSM_REGISTER_FUNCTION(m,"ostype",system_kvs_fnc_ostype);
+ KVSM_REGISTER_FUNCTION(m,"osname",system_kvs_fnc_osname);
+ KVSM_REGISTER_FUNCTION(m,"osversion",system_kvs_fnc_osversion);
+ KVSM_REGISTER_FUNCTION(m,"osrelease",system_kvs_fnc_osrelease);
+ KVSM_REGISTER_FUNCTION(m,"osmachine",system_kvs_fnc_osmachine);
+ KVSM_REGISTER_FUNCTION(m,"osnodename",system_kvs_fnc_osnodename);
+ KVSM_REGISTER_FUNCTION(m,"getenv",system_kvs_fnc_getenv);
+ KVSM_REGISTER_FUNCTION(m,"hostname",system_kvs_fnc_hostname);
+ KVSM_REGISTER_FUNCTION(m,"dcop",system_kvs_fnc_dcop);
+ KVSM_REGISTER_FUNCTION(m,"clipboard",system_kvs_fnc_clipboard);
+ KVSM_REGISTER_FUNCTION(m,"selection",system_kvs_fnc_selection);
+ KVSM_REGISTER_FUNCTION(m,"checkModule",system_kvs_fnc_checkModule);
+ KVSM_REGISTER_FUNCTION(m,"call",system_kvs_fnc_plugin_call);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setenv",system_kvs_cmd_setenv);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setClipboard",system_kvs_cmd_setClipboard);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setSelection",system_kvs_cmd_setSelection);
+
+ g_pPluginManager = new(KviPluginManager);
+
+ return true;
+}
+
+static bool system_module_cleanup(KviModule *m)
+{
+ g_pPluginManager->unloadAll();
+ delete g_pPluginManager;
+ return true;
+}
+
+static bool system_module_can_unload(KviModule *m)
+{
+ if(!g_pPluginManager->checkUnload()) return false;
+ return true;
+}
+
+KVIRC_MODULE(
+ "System", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)" \
+ " (C) 2005 Tonino Imbesi (grifisx at barmes dot org)"\
+ " (C) 2005 Alessandro Carbone (noldor at barmes dot org)",// author & (C)
+ "System informations module",
+ system_module_init,
+ system_module_can_unload,
+ 0,
+ system_module_cleanup
+)
diff --git a/src/modules/system/plugin.cpp b/src/modules/system/plugin.cpp
new file mode 100644
index 00000000..b14b18c0
--- /dev/null
+++ b/src/modules/system/plugin.cpp
@@ -0,0 +1,427 @@
+//=============================================================================
+//
+// File : plugin.cpp
+// Creation date : Wed Apr 11 04 2007 00:54:00 GMT+1 by TheXception
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2007 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 "plugin.h"
+
+#include "kvi_module.h"
+#include "kvi_string.h"
+#include "kvi_library.h"
+#include "kvi_thread.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_fileutils.h"
+
+#include <qdir.h>
+#include <qfileinfo.h>
+/*
+ @doc: easyplugins
+ @type:
+ generic
+ @keyterms:
+ easyplugins
+ @title:
+ Easyplugins
+ @short:
+ Small plugins which can be called in scripts
+ @body:
+ If you want to know how to call easyplugins please have a look at: $system.call()[br]
+ This part of the documentation handles only the way how to write an easyplugin. An easyplugin is simply a dll/so. You can create one like you normally make such so/dll files. The important thing is that these so/dll-files export some of the following functions.
+ [br][br]
+ [b]Exported functions by easyplugin (C/C++-Examples):[/b][br]
+ [br][b]_free function[/b] [i] (needed)[/i][br]
+ This function is important! Since KVIrc can not free directly the memory of the dll, the plugins need the _free function so that the memory can be freed by the plugin to prevent memory-leaks.[br]
+ [example]
+ int _free(void * p)[br]
+ {[br]
+ // Always free the memory here![br]
+ free(p);[br]
+ return 0;[br]
+ }[br]
+ [/example]
+
+ [br][b]_load function[/b] [i](optional)[/i][br]
+ After the plugin has be loaded, KVIrc will call the _load-function. Here you can prepare your plugin stuff.
+ [example]
+ int _load()[br]
+ {[br]
+ return 0;[br]
+ }[br]
+ [/example]
+
+ [br][b]_unload function[/b] [i]((optional)[/i][br]
+ This function will be called before the plugins is unloaded. In this function you can clean up memory or other things.
+ After this call there is no guarantee that the plugin will be kept in memory.[br]
+ [example]
+ int _unload()[br]
+ {[br]
+ return 0;[br]
+ }[br]
+ [/example]
+
+ [br][b]_canunload function[/b] [i](optional)[/i][br]
+ The _canunload-function will be called by KVIrc to check if it may unload the plugin.
+ If return value is true KVIrc will unload the plugin, false means he will try unloading it at the next check.[br]
+ Important: KVIrc will ignore this if unload of plugins will be forced! So you have to be sure that the _unload function of your plugins cleans up![br]
+ [example]
+ int _canunload()[br]
+ {[br]
+ return 0; [br]
+ }[br]
+ [/example]
+
+ [br][b]user function[/b][br]
+ This is the general structure of a user function call.[br]
+ The important thing here is the handling of return values. To return a value to KVIrc you have to allocate memory and write the pointer to it into pBuffer. Have a look at the example for more details.[br]
+ [example]
+ int about(int argc, char * argv[], char ** pBuffer)[br]
+ {[br]
+ *pBuffer = (char*)malloc(1024);[br]
+ sprintf((char*)*pBuffer, "Hello World"); [br]
+ return 1;[br]
+ }[br]
+ [/example]
+*/
+
+KviPlugin::KviPlugin(kvi_library_t pLib, const QString& name)
+{
+ m_Plugin = pLib;
+ m_szName = name;
+}
+
+KviPlugin::~KviPlugin()
+{
+}
+
+KviPlugin* KviPlugin::load(const QString& szFileName)
+{
+ kvi_library_t pLibrary = kvi_library_open(szFileName.local8Bit());
+ if (!pLibrary)
+ {
+ return 0;
+ }
+
+ KviPlugin* pPlugin = new KviPlugin(pLibrary,KviFileUtils::extractFileName(szFileName));
+
+ plugin_load function_load;
+
+ function_load = (plugin_unload)kvi_library_symbol(pLibrary,"_load");
+ if (function_load)
+ {
+ //TODO: THREAD
+ function_load();
+ }
+ return pPlugin;
+}
+
+bool KviPlugin::pfree(char * pBuffer)
+{
+ plugin_free function_free;
+
+ function_free = (plugin_free)kvi_library_symbol(m_Plugin,"_free");
+ if (function_free)
+ {
+ //TODO: THREAD
+ if(pBuffer) function_free(pBuffer);
+ return true;
+ }
+ return false;
+}
+
+bool KviPlugin::unload()
+{
+ plugin_unload function_unload;
+
+ function_unload = (plugin_unload)kvi_library_symbol(m_Plugin,"_unload");
+ if (function_unload)
+ {
+ //TODO: THREAD
+ function_unload();
+ }
+
+ if(m_Plugin)
+ {
+ kvi_library_close(m_Plugin);
+ }
+
+ return true;
+}
+
+bool KviPlugin::canunload()
+{
+ plugin_canunload function_canunload;
+
+ function_canunload = (plugin_canunload)kvi_library_symbol(m_Plugin,"_canunload");
+ if (function_canunload)
+ {
+ //TODO: THREAD
+ if(!function_canunload())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+int KviPlugin::call(const QString& pszFunctionName, int argc, char * argv[], char ** pBuffer)
+{
+ int r;
+ plugin_function function_call;
+ function_call = (plugin_function)kvi_library_symbol(m_Plugin,pszFunctionName.local8Bit());
+ if (!function_call)
+ {
+ return -1;
+ } else {
+ //TODO: THREAD
+ r = function_call(argc,argv,pBuffer);
+ }
+ if (r < 0) r = 0; // negative numbers are for error handling.
+ return r;
+}
+
+QString KviPlugin::name()
+{
+ return m_szName;
+}
+
+void KviPlugin::setName(const QString& Name)
+{
+ m_szName = Name;
+}
+
+
+KviPluginManager::KviPluginManager()
+{
+ m_pPluginDict = new KviPointerHashTable<QString,KviPlugin>(5,false);
+ m_pPluginDict->setAutoDelete(false);
+
+ m_bCanUnload = true;
+}
+
+KviPluginManager::~KviPluginManager()
+{
+ delete m_pPluginDict;
+}
+
+bool KviPluginManager::pluginCall(KviKvsModuleFunctionCall *c)
+{
+ // /echo $system.call("traffic.dll",about)
+ QString szPluginPath; //contains full path and plugin name like "c:/plugin.dll"
+ QString szFunctionName;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("plugin_path",KVS_PT_NONEMPTYSTRING,0,szPluginPath)
+ KVSM_PARAMETER("function",KVS_PT_NONEMPTYSTRING,0,szFunctionName)
+ KVSM_PARAMETERS_END(c)
+
+ //Check if there is such a plugin
+ if(!findPlugin(szPluginPath))
+ {
+ c->error(__tr2qs("Plugin not found. Please check the plugin-name and path."));
+ return true;
+ }
+
+ //Load plugin or check it in cache
+ if(!loadPlugin(szPluginPath))
+ {
+ c->error(__tr2qs("Error while loading plugin."));
+ return true;
+ }
+
+ //Parsing more Parameters
+ int iArgc = 0;
+ char ** ppArgv;
+ char * pArgvBuffer;
+
+ //Preparing argv buffer
+ if(c->parameterCount() > 2)
+ {
+ iArgc = c->parameterCount() - 2;
+ }
+
+ if (iArgc > 0)
+ {
+ int i = 2;
+ QString tmp;
+ int iSize = 0;
+
+ //Calculate buffer size
+ while (i < (iArgc + 2) )
+ {
+ c->params()->at(i)->asString(tmp);
+ iSize += tmp.length()+1; //+1 for the \0 characters
+ i++;
+ }
+
+ //Allocate buffer
+ ppArgv = (char**)malloc(iArgc*sizeof(char*));
+ pArgvBuffer = (char*)malloc(iSize);
+
+ i = 2;
+ char * x = 0;
+ x = pArgvBuffer;
+ while (i < (iArgc + 2) )
+ {
+ ppArgv[i-2] = x;
+ c->params()->at(i)->asString(tmp);
+ strcpy(x,tmp.local8Bit());
+ x += tmp.length();
+
+ *x = 0;
+ x++;
+ i++;
+ }
+
+ } else {
+ //Avoid using unfilled variables
+ ppArgv = 0;
+ pArgvBuffer = 0;
+ iArgc = 0;
+ }
+
+ //Preparing return buffer
+ char * returnBuffer;
+ KviPlugin * plugin;
+
+ plugin = getPlugin(szPluginPath);
+ int r = plugin->call(szFunctionName,iArgc,ppArgv,&returnBuffer);
+
+ if(r == -1)
+ {
+ c->error(__tr2qs("This plugin does not export the desired function."));
+ return true;
+ }
+ if (r > 0)
+ {
+ c->returnValue()->setString(QString::fromLocal8Bit(returnBuffer));
+ }
+
+
+ //Clean up
+ if(pArgvBuffer) free(pArgvBuffer);
+ if(ppArgv) free(ppArgv);
+ if(returnBuffer)
+ {
+ if (!plugin->pfree(returnBuffer))
+ {
+ c->warning(__tr2qs("The plugin has no function to free memory. This can result in Memory Leaks!"));
+ }
+ }
+
+
+
+ return true;
+}
+
+bool KviPluginManager::checkUnload()
+{
+ /*
+ Always called when system module should be unloaded
+ Checking here if all small "modules" can be unloaded
+ */
+ KviPointerHashTableIterator<QString,KviPlugin> it(*m_pPluginDict);
+
+ m_bCanUnload = true;
+
+ while(it.current())
+ {
+ if(it.current()->canunload())
+ {
+ it.current()->unload();
+ m_pPluginDict->remove(it.currentKey());
+ } else {
+ m_pPluginDict++;
+ m_bCanUnload = false;
+ }
+ }
+
+ return m_bCanUnload;
+}
+
+void KviPluginManager::unloadAll()
+{
+ KviPointerHashTableIterator<QString,KviPlugin> it(*m_pPluginDict);
+
+ while(it.current())
+ {
+ it.current()->unload();
+ m_pPluginDict->remove(it.currentKey());
+ }
+}
+
+bool KviPluginManager::findPlugin(QString& szPath)
+{
+ QString szFileName(KviFileUtils::extractFileName(szPath));
+// szFileName.detach();
+ if(KviFileUtils::isAbsolutePath(szPath) && KviFileUtils::fileExists(szPath))
+ {
+ // Ok,
+ return true;
+ } else {
+ //Plugin not found in direct way. Looking in kvirc local dir
+ g_pApp->getGlobalKvircDirectory(szPath,KviApp::EasyPlugins,szFileName);
+
+ if(!KviFileUtils::fileExists(szPath))
+ {
+ //Plugin not found in kvirc local dir. Looking in kvirc global dir
+ g_pApp->getLocalKvircDirectory(szPath,KviApp::EasyPlugins,szFileName);
+
+ if(!KviFileUtils::fileExists(szPath))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool KviPluginManager::isPluginLoaded(const QString& pSingleName)
+{
+ KviPlugin * p = m_pPluginDict->find(pSingleName);
+ if (!p)
+ return false;
+ else
+ return true;
+}
+
+bool KviPluginManager::loadPlugin(const QString& szPluginPath)
+{
+ if(isPluginLoaded(szPluginPath))
+ {
+ return getPlugin(szPluginPath)!=0;
+ } else {
+ KviPlugin * plugin = KviPlugin::load(szPluginPath);
+ if(plugin)
+ {
+ m_pPluginDict->insert(szPluginPath,plugin);
+ return true;
+ }
+ }
+ return false;
+}
+
+KviPlugin * KviPluginManager::getPlugin(const QString& szPluginPath)
+{
+ KviPlugin * p = m_pPluginDict->find(szPluginPath);
+ return p;
+} \ No newline at end of file
diff --git a/src/modules/system/plugin.h b/src/modules/system/plugin.h
new file mode 100644
index 00000000..64b1723a
--- /dev/null
+++ b/src/modules/system/plugin.h
@@ -0,0 +1,80 @@
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+//=============================================================================
+//
+// File : plugin.h
+// Creation date : Wed Apr 11 04 2007 00:54:00 GMT+1 by TheXception
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2007 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_module.h"
+#include "kvi_pointerhashtable.h"
+
+typedef int (*plugin_function)(int argc, char* argv[], char ** buffer);
+typedef int (*plugin_unload)();
+typedef int (*plugin_canunload)();
+typedef int (*plugin_load)();
+typedef int (*plugin_free)(char * pBuffer);
+
+class KviPlugin
+{
+protected:
+ // You have to create plugin instance by calling KviPlugin::load()
+ KviPlugin(kvi_library_t pLib, const QString& name);
+public:
+ ~KviPlugin();
+private:
+ // shared
+ // internal
+ kvi_library_t m_Plugin;
+ QString m_szName;
+public:
+ static KviPlugin* load(const QString& szFileName);
+ bool pfree(char * pBuffer);
+ bool unload();
+ bool canunload();
+ int call(const QString& szFunctionName, int argc, char * argv[], char ** pBuffer);
+ QString name();
+ void setName(const QString& szName);
+protected:
+};
+
+class KviPluginManager
+{
+ public:
+ KviPluginManager();
+ ~KviPluginManager();
+ private:
+ // shared
+ bool m_bCanUnload;
+ // internal
+ KviPointerHashTable<QString,KviPlugin> * m_pPluginDict;
+ public:
+ bool pluginCall(KviKvsModuleFunctionCall *c);
+ bool checkUnload();
+ void unloadAll();
+ protected:
+ bool findPlugin(QString& szName);
+ bool isPluginLoaded(const QString& szFileNameOrPathToLoad);
+ bool loadPlugin(const QString& szPluginPath);
+ KviPlugin * getPlugin(const QString& szPluginPath);
+};
+
+#endif //_PLUGIN_H_ \ No newline at end of file
diff --git a/src/modules/term/Makefile.am b/src/modules/term/Makefile.am
new file mode 100644
index 00000000..1567e615
--- /dev/null
+++ b/src/modules/term/Makefile.am
@@ -0,0 +1,21 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviterm.la
+
+libkviterm_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviterm_la_SOURCES = libkviterm.cpp termwidget.cpp termwindow.cpp
+libkviterm_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= termwidget.h termwindow.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+termwidget.cpp: termwidget.moc
+termwindow.cpp: termwindow.moc
diff --git a/src/modules/term/libkviterm.cpp b/src/modules/term/libkviterm.cpp
new file mode 100644
index 00000000..742aaa62
--- /dev/null
+++ b/src/modules/term/libkviterm.cpp
@@ -0,0 +1,167 @@
+//
+// File : libkviterm.cpp
+// Creation date : Wed Aug 30 2000 15:29:02 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 "kvi_module.h"
+
+#include "kvi_window.h"
+
+#include "kvi_frame.h"
+
+#include <qsplitter.h>
+#include "kvi_pointerlist.h"
+
+#ifdef COMPILE_KDE_SUPPORT
+
+ #include "termwidget.h"
+ #include "termwindow.h"
+
+ #include "ktrader.h"
+
+// #include "kparts/part.h"
+// #include "kparts/factory.h"
+// #include "klibloader.h"
+
+#endif
+
+KviModule * g_pTermModule = 0;
+
+#ifdef COMPILE_KDE_SUPPORT
+ KviPointerList<KviTermWidget> * g_pTermWidgetList = 0;
+ KviPointerList<KviTermWindow> * g_pTermWindowList = 0;
+ KviStr g_szKonsoleLibraryName = "";
+#endif
+
+/*
+ @doc: term.open
+ @type:
+ command
+ @title:
+ term.open
+ @short:
+ Shows a terminal emulator
+ @syntax:
+ term.open [-m]
+ @switches:
+ !sw: -m | --mdi
+ creates terminal as a MDI window
+ @description:
+ Opens a new terminal window (If the service is available).
+ if the -m switch is present, the created terminal as a MDI window,
+ otherwise it is a static window.[br]
+ This command is exported by the "term" module.[br]
+ Note: At the time that this module was written, the
+ KDE terminal emulator module was quite unstable; no extensive
+ testings have been made on this.
+*/
+
+static bool term_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+#ifdef COMPILE_KDE_SUPPORT
+ if(g_szKonsoleLibraryName.hasData())
+ {
+ c->module()->lock(); // multiple locks are allowed
+ if(c->hasSwitch('m',"mdi"))
+ {
+ KviTermWindow *w = new KviTermWindow(c->window()->frame(),"Terminal emulator");
+ c->window()->frame()->addWindow(w);
+ } else {
+ KviTermWidget *w = new KviTermWidget(c->window()->frame()->splitter(),
+ c->window()->frame(),true);
+ w->show();
+ }
+ } else {
+ c->warning("No terminal emulation service available");
+ }
+#else
+ c->warning("Terminal emulation service not supported (non-KDE compilation)");
+#endif
+ return true;
+}
+
+static bool term_module_init(KviModule * m)
+{
+ g_pTermModule = m;
+
+#ifdef COMPILE_KDE_SUPPORT
+ g_pTermWidgetList = new KviPointerList<KviTermWidget>;
+ g_pTermWidgetList->setAutoDelete(false);
+ g_pTermWindowList = new KviPointerList<KviTermWindow>;
+ g_pTermWindowList->setAutoDelete(false);
+
+// KTrader::OfferList offers = KTrader::self()->query("Browser/View","KonsolePart");
+// KTrader::OfferList offers = KTrader::self()->query("Browser/View","");
+// if(offers.count() > 0)
+// {
+// KTrader::OfferList::Iterator it = offers.begin();
+// while(it != offers.end())
+// {
+// KviStr tmp = (*it)->name();
+// KviStr tmp2 = (*it)->type();
+// KviStr tmp3 = (*it)->library();
+// debug("Got Service name:%s type:%s library:%s",tmp.ptr(),tmp2.ptr(),tmp3.ptr());
+// ++it;
+// }
+// }
+// KService::Ptr service = *offers.begin();
+ KService::Ptr pKonsoleService = KService::serviceByName("Terminal Emulator");
+ if(!pKonsoleService)pKonsoleService = KService::serviceByName("KonsolePart");
+ if(!pKonsoleService)pKonsoleService = KService::serviceByName("Terminal *");
+ if(pKonsoleService)
+ {
+ g_szKonsoleLibraryName = pKonsoleService->library();
+// debug("KONSOLE LIB %s",g_szKonsoleLibraryName.ptr());
+ }
+// delete pKonsoleService;
+#endif
+
+// m->registerCommand("open",term_module_cmd_open);
+#ifdef COMPILE_NEW_KVS
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",term_kvs_cmd_open);
+#endif
+ return true;
+}
+
+static bool term_module_cleanup(KviModule *m)
+{
+#ifdef COMPILE_KDE_SUPPORT
+ while(g_pTermWidgetList->first())delete g_pTermWidgetList->first();
+ delete g_pTermWidgetList;
+ g_pTermWidgetList = 0;
+ while(g_pTermWindowList->first())g_pTermWindowList->first()->close();
+ delete g_pTermWindowList;
+ g_pTermWindowList = 0;
+#endif
+ return true;
+}
+
+KVIRC_MODULE(
+ "Term", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Terminal emulator extension based on the KonsolePart KDE class",
+ term_module_init,
+ 0,
+ 0,
+ term_module_cleanup
+)
diff --git a/src/modules/term/termwidget.cpp b/src/modules/term/termwidget.cpp
new file mode 100644
index 00000000..45bf63a0
--- /dev/null
+++ b/src/modules/term/termwidget.cpp
@@ -0,0 +1,179 @@
+//
+// File : termwidget.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-2005 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 "termwidget.h"
+#include "termwindow.h"
+
+#include "kvi_module.h"
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+
+#include <qlabel.h>
+#include "kvi_pointerlist.h"
+#include <qtooltip.h>
+#include <qtimer.h>
+
+#ifdef COMPILE_KDE_SUPPORT
+
+#include "klibloader.h"
+#include "kparts/part.h"
+#include "kparts/factory.h"
+
+extern KviModule * g_pTermModule;
+extern KviPointerList<KviTermWidget> * g_pTermWidgetList;
+extern KviPointerList<KviTermWindow> * g_pTermWindowList;
+extern KviStr g_szKonsoleLibraryName;
+
+KviTermWidget::KviTermWidget(QWidget * par,KviFrame * lpFrm,bool bIsStandalone)
+: QFrame(par,"term_widget")
+{
+ if(bIsStandalone)g_pTermWidgetList->append(this);
+ m_bIsStandalone = bIsStandalone;
+
+ m_pKonsolePart = 0;
+ m_pKonsoleWidget = 0;
+
+ if(bIsStandalone)
+ {
+ m_pHBox = new KviTalHBox(this);
+ m_pTitleLabel = new QLabel(__tr2qs("Terminal emulator"),m_pHBox);
+ m_pTitleLabel->setFrameStyle(QFrame::Raised | QFrame::WinPanel);
+ m_pCloseButton = new QPushButton("",m_pHBox);
+ m_pCloseButton->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)));
+ QToolTip::add(m_pCloseButton,__tr2qs("Close this window"));
+ m_pHBox->setStretchFactor(m_pTitleLabel,2);
+ connect(m_pCloseButton,SIGNAL(clicked()),this,SLOT(closeClicked()));
+ } else {
+ m_pHBox = 0;
+ m_pTitleLabel = 0;
+ m_pCloseButton = 0;
+ }
+
+ setFrameStyle(QFrame::Sunken | QFrame::Panel);
+
+ KParts::Factory * pKonsoleFactory = static_cast<KParts::Factory *>(
+ KLibLoader::self()->factory(g_szKonsoleLibraryName.ptr()));
+
+ if(pKonsoleFactory)
+ {
+// debug("FACTORY %d",pKonsoleFactory);
+ m_pKonsolePart = static_cast<KParts::Part *>(pKonsoleFactory->createPart(
+ this,"terminal emulator",this,"the konsole part"));
+
+ if(m_pKonsolePart)
+ {
+// debug("PART %d",m_pKonsolePart);
+ m_pKonsoleWidget = m_pKonsolePart->widget();
+ connect(m_pKonsoleWidget,SIGNAL(destroyed()),this,SLOT(konsoleDestroyed()));
+// debug("Widget %d",m_pKonsoleWidget);
+ } else {
+ m_pKonsoleWidget = new QLabel(this,
+ __tr2qs("Can't create the terminal emulation part"));
+ }
+
+ } else {
+ m_pKonsoleWidget = new QLabel(this,
+ __tr2qs("Can't retrieve the terminal emulation factory"));
+ }
+}
+
+KviTermWidget::~KviTermWidget()
+{
+ if(m_pKonsoleWidget)
+ disconnect(m_pKonsoleWidget,SIGNAL(destroyed()),this,SLOT(konsoleDestroyed()));
+
+ if(m_bIsStandalone)g_pTermWidgetList->removeRef(this);
+ if(g_pTermWindowList->isEmpty() && g_pTermWidgetList->isEmpty())g_pTermModule->unlock();
+
+// debug("DELETING KONSOLE WIDGET");
+// if(m_pKonsoleWidget)delete m_pKonsoleWidget; <--// Qt will delete it
+// debug("DELETING KONSOLE PART");
+// if(m_pKonsolePart)delete m_pKonsolePart; <--// the part will delete self when the widget will die
+// debug("KONSOLE PART DELETED");
+}
+
+void KviTermWidget::resizeEvent(QResizeEvent *e)
+{
+ int hght = 0;
+ if(m_bIsStandalone)
+ {
+ hght = m_pCloseButton->sizeHint().height();
+ m_pHBox->setGeometry(1,1,width() - 2,hght + 1);
+
+ }
+ if(m_pKonsoleWidget)m_pKonsoleWidget->setGeometry(1,hght + 1,width() - 2,height() - (hght + 2));
+}
+
+void KviTermWidget::closeClicked()
+{
+ // this is called only in standalone mode
+ delete this;
+}
+
+void KviTermWidget::konsoleDestroyed()
+{
+ m_pKonsoleWidget = 0;
+ m_pKonsolePart = 0;
+ hide();
+ QTimer::singleShot(0,this,SLOT(autoClose()));
+}
+
+void KviTermWidget::autoClose()
+{
+ if(m_bIsStandalone)delete this;
+ else ((KviWindow *)parent())->close();
+}
+
+void KviTermWidget::changeTitle(int i,const QString& str)
+{
+ if(m_bIsStandalone)m_pTitleLabel->setText(str);
+}
+
+void KviTermWidget::notifySize(int,int)
+{
+}
+
+void KviTermWidget::changeColumns(int)
+{
+}
+
+QSize KviTermWidget::sizeHint() const
+{
+ int hght = 0;
+ int wdth = 0;
+ if(m_pKonsoleWidget)
+ {
+ hght += m_pKonsoleWidget->sizeHint().height();
+ wdth = m_pKonsoleWidget->sizeHint().width();
+ }
+ if(m_pCloseButton)
+ {
+ hght += m_pCloseButton->sizeHint().height();
+ }
+
+ return QSize(wdth + 2,hght + 2);
+}
+
+#include "termwidget.moc"
+
+#endif //COMPILE_KDE_SUPPORT
diff --git a/src/modules/term/termwidget.h b/src/modules/term/termwidget.h
new file mode 100644
index 00000000..88e9d9a7
--- /dev/null
+++ b/src/modules/term/termwidget.h
@@ -0,0 +1,72 @@
+#ifndef _HELPWIDGET_H_
+#define _HELPWIDGET_H_
+//
+// File : termwidget.h
+// Creation date : Wed Aug 30 2000 15:34:20 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_KDE_SUPPORT
+
+#include <qframe.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include "kvi_tal_hbox.h"
+
+#include "kparts/part.h"
+
+
+class KviFrame;
+
+class KviTermWidget : public QFrame
+{
+ Q_OBJECT
+ Q_PROPERTY( int KviProperty_ChildFocusOwner READ dummy )
+public:
+ KviTermWidget(QWidget * par,KviFrame * lpFrm,bool bIsStandalone = false);
+ ~KviTermWidget();
+private:
+ KviTalHBox * m_pHBox;
+ QLabel * m_pTitleLabel;
+ QPushButton * m_pCloseButton;
+ KParts::Part * m_pKonsolePart;
+ bool m_bIsStandalone;
+ QWidget * m_pKonsoleWidget;
+protected:
+ virtual void resizeEvent(QResizeEvent *e);
+protected slots:
+ void closeClicked();
+ void changeTitle(int i,const QString& str);
+ void notifySize(int,int);
+ void changeColumns(int);
+public:
+ QWidget * konsoleWidget(){ return m_pKonsoleWidget ? m_pKonsoleWidget : this; };
+ virtual QSize sizeHint() const;
+ int dummy() const { return 0; };
+protected slots:
+ void konsoleDestroyed();
+ void autoClose();
+};
+
+#endif
+
+
+#endif //_HELPWIDGET_H_
diff --git a/src/modules/term/termwindow.cpp b/src/modules/term/termwindow.cpp
new file mode 100644
index 00000000..39b6cc1a
--- /dev/null
+++ b/src/modules/term/termwindow.cpp
@@ -0,0 +1,84 @@
+//
+// File : termwindow.cpp
+// Creation date : Thu Aug 31 2000 15:02:22 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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 "termwindow.h"
+#include "termwidget.h"
+
+#ifdef COMPILE_KDE_SUPPORT
+
+
+#include "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_module.h"
+
+extern KviModule * g_pTermModule;
+extern KviPointerList<KviTermWindow> * g_pTermWindowList;
+extern KviPointerList<KviTermWidget> * g_pTermWidgetList;
+
+KviTermWindow::KviTermWindow(KviFrame * lpFrm,const char * name)
+: KviWindow(KVI_WINDOW_TYPE_TERM,lpFrm,name)
+{
+ g_pTermWindowList->append(this);
+ m_pTermWidget = 0;
+ m_pTermWidget = new KviTermWidget(this,lpFrm);
+ // Ensure proper focusing
+// setFocusHandler(m_pTermWidget->konsoleWidget(),this);
+}
+
+KviTermWindow::~KviTermWindow()
+{
+ g_pTermWindowList->removeRef(this);
+ if(g_pTermWindowList->isEmpty() && g_pTermWidgetList->isEmpty())g_pTermModule->unlock();
+}
+
+QPixmap * KviTermWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_RAW);
+}
+
+void KviTermWindow::resizeEvent(QResizeEvent *e)
+{
+ if(m_pTermWidget)m_pTermWidget->setGeometry(0,0,width(),height());
+}
+
+QSize KviTermWindow::sizeHint() const
+{
+ return m_pTermWidget ? m_pTermWidget->sizeHint() : KviWindow::sizeHint();
+}
+
+void KviTermWindow::fillCaptionBuffers()
+{
+ m_szPlainTextCaption.sprintf(__tr("Terminal"));
+
+ m_szHtmlActiveCaption.sprintf(
+ __tr("<nobr><font color=\"%s\"><b>Terminal</b></font></nobr>"),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name().ascii());
+ m_szHtmlInactiveCaption.sprintf(
+ __tr("<nobr><font color=\"%s\"><b>Terminal</b></font></nobr>"),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(),
+ KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name().ascii());
+}
+
+#include "termwindow.moc"
+
+#endif
diff --git a/src/modules/term/termwindow.h b/src/modules/term/termwindow.h
new file mode 100644
index 00000000..e3a9d556
--- /dev/null
+++ b/src/modules/term/termwindow.h
@@ -0,0 +1,54 @@
+#ifndef _TERMWINDOW_H_
+#define _TERMWINDOW_H_
+//
+// File : termwindow.h
+// Creation date : Thu Aug 31 2000 15:00:00 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 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_KDE_SUPPORT
+
+
+#include "kvi_window.h"
+#include "kvi_string.h"
+
+class KviTermWidget;
+
+class KviTermWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviTermWindow(KviFrame * lpFrm,const char * name);
+ ~KviTermWindow();
+protected:
+ KviTermWidget * m_pTermWidget;
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+public:
+ virtual QSize sizeHint() const;
+};
+
+
+#endif
+
+#endif //_KVI_HELPWINDOW_H_
diff --git a/src/modules/texticons/Makefile.am b/src/modules/texticons/Makefile.am
new file mode 100644
index 00000000..77646abd
--- /dev/null
+++ b/src/modules/texticons/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makemath - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvitexticons.la
+
+libkvitexticons_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvitexticons_la_SOURCES = libkvitexticons.cpp
+libkvitexticons_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/texticons/libkvitexticons.cpp b/src/modules/texticons/libkvitexticons.cpp
new file mode 100644
index 00000000..2179bf41
--- /dev/null
+++ b/src/modules/texticons/libkvitexticons.cpp
@@ -0,0 +1,161 @@
+//=============================================================================
+//
+// File : libkvitexticons.cpp
+// Creation date : Wed May 10 14:00:12 2006 GMT by Alexey Uzhva
+//
+// This math is part of the KVirc irc client distribution
+// Copyright (C) 2006 Alexey Uzhva (wizard at opendoor dot ru)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under 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_module.h"
+#include "kvi_texticonmanager.h"
+
+/*
+ @doc: texticons.get
+ @type:
+ function
+ @title:
+ $texticons.get
+ @short:
+ Retreives texticon data
+ @syntax:
+ <hash> $texticons.get()
+ <string> $texticons.get(<iconName:string>)
+ <integer> $texticons.get(<iconName:string>)
+ @description:
+ if <iconName:string> is setted returns integer icon id or string filename, associciated with <iconName:string>[br]
+ if <iconName:string> isn't set returns hash where keys are the icon names, and values are the icon id's or filenames
+ @seealso:
+ [fnc]$texticons.get[/fnc]
+*/
+
+static bool texticons_kvs_fnc_get(KviKvsModuleFunctionCall * c)
+{
+ QString szIcon;
+ KviTextIcon* pIcon=0;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("iconName",KVS_PT_NONEMPTYSTRING,KVS_PF_OPTIONAL,szIcon)
+ KVSM_PARAMETERS_END(c)
+ if(!szIcon.isNull())
+ {
+ pIcon=g_pTextIconManager->lookupTextIcon(szIcon);
+ if(!pIcon)
+ {
+ c->warning("Icon '%s' not found",szIcon.utf8().data());
+ } else {
+ if(pIcon->id()!=-1)
+ c->returnValue()->setInteger(pIcon->id());
+ else
+ c->returnValue()->setString(pIcon->filename());
+ }
+ } else {
+ KviKvsHash* hash = new KviKvsHash();
+
+ KviPointerHashTableIterator<QString,KviTextIcon> it(*(g_pTextIconManager->textIconDict()));
+
+ while(KviTextIcon * i = it.current())
+ {
+ if(i->id()!=-1)
+ hash->set(it.currentKey(),new KviKvsVariant( (kvs_int_t)(i->id()) ));
+ else
+ hash->set(it.currentKey(),new KviKvsVariant(i->filename()));
+ ++it;
+ }
+ c->returnValue()->setHash(hash);
+ }
+ return true;
+}
+
+/*
+ @doc: texticons.set
+ @type:
+ command
+ @title:
+ $texticons.set
+ @short:
+ Sets texticon data
+ @syntax:
+ texticons.set <iconName:string>
+ texticons.set <iconName:string> <iconFile:string>
+ texticons.set <iconName:string> <iconId:integer>
+ @description:
+ if command gets only 1 argument it removes <iconName:string> from list of texticons[br]
+ if it gets an integer second parameters, command associates <iconName:string> icon with builin icon, having id <iconId:integer>[br]
+ if it gets a string second parameters, command associates <iconName:string> icon with the filename <iconFile:string>
+ @seealso:
+ [fnc]$texticons.get[/fnc]
+*/
+
+static bool texticons_kvs_cmd_set(KviKvsModuleCommandCall * c)
+{
+ QString szName,szIcon;
+ KviTextIcon* pIcon=0;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("iconName",KVS_PT_NONEMPTYSTRING,0,szName)
+ KVSM_PARAMETER("iconIdOrFile",KVS_PT_STRING,KVS_PF_OPTIONAL,szIcon)
+ KVSM_PARAMETERS_END(c)
+ if(szIcon.isNull())
+ {
+ g_pTextIconManager->textIconDict()->remove(szName);
+ } else {
+ pIcon=g_pTextIconManager->lookupTextIcon(szName);
+ if(!pIcon)
+ {
+ KviTextIcon* pTmpIcon=new KviTextIcon(-1);
+ g_pTextIconManager->insert(szName,*pTmpIcon);
+ delete pTmpIcon;
+ pIcon=g_pTextIconManager->lookupTextIcon(szName);
+ if(!pIcon) return false;
+ }
+
+ bool bOk;
+ unsigned int iResult=szIcon.toUInt(&bOk);
+ if(bOk)
+ pIcon->setId(iResult);
+ else
+ pIcon->setFilename(szIcon);
+
+ }
+ g_pTextIconManager->checkDefaultAssociations();
+ return true;
+}
+
+static bool texticons_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"set",texticons_kvs_cmd_set);
+
+ KVSM_REGISTER_FUNCTION(m,"get",texticons_kvs_fnc_get);
+ return true;
+}
+
+
+static bool texticons_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "Texticons", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2006 Alexey Uzhva (wizard at opendoor dot ru)",
+ "Texticons handling functions module",
+ texticons_module_init,
+ 0,
+ 0,
+ texticons_module_cleanup
+)
diff --git a/src/modules/theme/Makefile.am b/src/modules/theme/Makefile.am
new file mode 100644
index 00000000..5417e9e5
--- /dev/null
+++ b/src/modules/theme/Makefile.am
@@ -0,0 +1,36 @@
+###############################################################################
+# KVirc IRC client Makefile - 30.12.2006 Szymon Stefanek <pragma at kvirc dot net>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvitheme.la
+
+libkvitheme_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvitheme_la_SOURCES = libkvitheme.cpp \
+ managementdialog.cpp \
+ packthemedialog.cpp \
+ savethemedialog.cpp \
+ themefunctions.cpp
+
+nodist_libkvitheme_la_SOURCES = moc_managementdialog.cpp \
+ moc_packthemedialog.cpp \
+ moc_savethemedialog.cpp
+
+libkvitheme_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= managementdialog.h \
+ packthemedialog.h \
+ savethemedialog.h \
+ themefunctions.h
+
+moc_managementdialog.cpp: managementdialog.h
+ $(SS_QT_MOC) $< -o $@
+
+moc_packthemedialog.cpp: packthemedialog.h
+ $(SS_QT_MOC) $< -o $@
+
+moc_savethemedialog.cpp: savethemedialog.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/theme/libkvitheme.cpp b/src/modules/theme/libkvitheme.cpp
new file mode 100644
index 00000000..cba1b4e8
--- /dev/null
+++ b/src/modules/theme/libkvitheme.cpp
@@ -0,0 +1,193 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// File : libkvitheme.cpp
+// Created on Sat 30 Dec 2006 14:54:56 by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2006 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_module.h"
+#include "kvi_locale.h"
+#include "kvi_qstring.h"
+#include "kvi_parameterlist.h"
+#include "kvi_cmdformatter.h"
+#include "kvi_qstring.h"
+#include "kvi_error.h"
+#include "kvi_out.h"
+#include "kvi_iconmanager.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_config.h"
+#include "kvi_sourcesdate.h"
+#include "kvi_fileutils.h"
+#include "kvi_filedialog.h"
+
+#include "managementdialog.h"
+#include "themefunctions.h"
+
+#include <qfileinfo.h>
+
+QRect g_rectManagementDialogGeometry(0,0,0,0);
+
+
+/*
+ @doc: theme.install
+ @type:
+ command
+ @title:
+ theme.install
+ @short:
+ Shows the theme theme management editor
+ @syntax:
+ theme.install <package_path:string>
+ @description:
+ Attempts to install the themes in the package specified by <package_path>.
+*/
+
+static bool theme_kvs_cmd_install(KviKvsModuleCommandCall * c)
+{
+ QString szThemePackFile;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("package_path",KVS_PT_STRING,0,szThemePackFile)
+ KVSM_PARAMETERS_END(c)
+
+ QString szError;
+ if(!KviThemeFunctions::installThemePackage(szThemePackFile,szError))
+ {
+ c->error(__tr2qs_ctx("Error installing theme package: %Q","theme"),&szError);
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ @doc: theme.screenshot
+ @type:
+ command
+ @title:
+ theme.screenshot
+ @short:
+ Makes a screenshot of the KVIrc window
+ @syntax:
+ theme.screenshot [file_name_path:string]
+ @description:
+ Makes a screenshot of the KVIrc main window
+ and saves it in the specified file. If [file_name_path]
+ is not specified then a save file dialog is shown.
+*/
+
+static bool theme_kvs_cmd_screenshot(KviKvsModuleCommandCall * c)
+{
+ QString szFileName;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("file_name_path",KVS_PT_STRING,KVS_PF_OPTIONAL,szFileName)
+ KVSM_PARAMETERS_END(c)
+
+
+ KviFileUtils::adjustFilePath(szFileName);
+
+ QString szTmp;
+ c->enterBlockingSection();
+
+ bool bResult = KviFileDialog::askForSaveFileName(szTmp,__tr2qs_ctx("Choose a file to save the screenshot to","theme"),szFileName,"*.png");
+
+ if(!c->leaveBlockingSection())return false; // need to stop immediately
+ if(!bResult)return true;
+
+ szFileName = szTmp;
+
+ if(szFileName.isEmpty())return true; // done
+ KviFileUtils::adjustFilePath(szFileName);
+ if(QFileInfo(szFileName).extension(false)!="png")
+ szFileName+=".png";
+
+ QString szError;
+ if(!KviThemeFunctions::makeKVIrcScreenshot(szFileName))
+ {
+ c->error(__tr2qs_ctx("Error making screenshot","theme")); // FIXME: a nicer error ?
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ @doc: theme.dialog
+ @type:
+ command
+ @title:
+ theme.dialog
+ @short:
+ Shows the theme theme management editor
+ @syntax:
+ theme.dialog
+ @description:
+ Shows the theme theme management editor
+*/
+
+static bool theme_kvs_cmd_dialog(KviKvsModuleCommandCall * c)
+{
+ KviThemeManagementDialog::display();
+ return true;
+}
+
+static bool theme_module_init(KviModule *m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"dialog",theme_kvs_cmd_dialog);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"install",theme_kvs_cmd_install);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"screenshot",theme_kvs_cmd_screenshot);
+
+ QString szBuf;
+ m->getDefaultConfigFileName(szBuf);
+ KviConfig cfg(szBuf,KviConfig::Read);
+ g_rectManagementDialogGeometry = cfg.readRectEntry("EditorGeometry",QRect(10,10,390,440));
+
+ return true;
+}
+
+static bool theme_module_cleanup(KviModule *m)
+{
+ KviThemeManagementDialog::cleanup();
+
+ QString szBuf;
+ m->getDefaultConfigFileName(szBuf);
+ KviConfig cfg(szBuf,KviConfig::Write);
+ cfg.writeEntry("EditorGeometry",g_rectManagementDialogGeometry);
+
+ return true;
+}
+
+static bool theme_module_can_unload(KviModule * m)
+{
+ return (!KviThemeManagementDialog::instance());
+}
+
+
+KVIRC_MODULE(
+ "theme", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2006 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Theme management functions",
+ theme_module_init,
+ theme_module_can_unload,
+ 0,
+ theme_module_cleanup
+)
diff --git a/src/modules/theme/managementdialog.cpp b/src/modules/theme/managementdialog.cpp
new file mode 100644
index 00000000..bfd75283
--- /dev/null
+++ b/src/modules/theme/managementdialog.cpp
@@ -0,0 +1,459 @@
+//=============================================================================
+//
+// File : managementdialog.cpp
+// Created on Sat 30 Dec 2006 14:54:56 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2006 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 LVI_ICON_SIZE 32
+#define LVI_BORDER 4
+#define LVI_SPACING 8
+#define LVI_MINIMUM_TEXT_WIDTH 300
+#define LVI_MINIMUM_CELL_WIDTH (LVI_MINIMUM_TEXT_WIDTH + LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER)
+
+#include "managementdialog.h"
+#include "packthemedialog.h"
+#include "savethemedialog.h"
+#include "themefunctions.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_msgbox.h"
+
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include "kvi_tal_listbox.h"
+#include <qlineedit.h>
+#include <kvi_tal_textedit.h>
+#include <qregexp.h>
+#include <qmessagebox.h>
+#include <qdir.h>
+#include <qstringlist.h>
+#include <qdatetime.h>
+#include <qfiledialog.h>
+#include "kvi_tal_popupmenu.h"
+#include <qcombobox.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qimage.h>
+#include <kvi_tal_textedit.h>
+//#include <qmultilineedit.h>
+#ifdef COMPILE_USE_QT4
+#include <QCloseEvent>
+#endif
+#include <qbuffer.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_config.h"
+#include "kvi_fileutils.h"
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_internalcmd.h"
+#include "kvi_styled_controls.h"
+#include "kvi_doublebuffer.h"
+#include "kvi_packagefile.h"
+#include "kvi_fileextensions.h"
+#include "kvi_filedialog.h"
+#include "kvi_dynamictooltip.h"
+
+#include <stdlib.h> // rand & srand
+
+extern QRect g_rectManagementDialogGeometry;
+
+
+
+KviThemeListBoxItem::KviThemeListBoxItem(KviTalListBox * box,KviThemeInfo * inf)
+: KviTalListBoxText(box)
+{
+ m_pThemeInfo = inf;
+ QString t;
+ t = "<nobr><b>";
+ t += inf->name();
+ t += "</b>";
+
+ if(!inf->version().isEmpty()) {
+ t += "[";
+ t += inf->version();
+ t += "]";
+ }
+
+ if(!inf->author().isEmpty()) {
+ t += " <font color=\"#a0a0a0\"> ";
+ t += __tr2qs_ctx("by","theme");
+ t += " ";
+ t += inf->author();
+ t += "</font>";
+ }
+
+ t += "</nobr>";
+ t += "<br><nobr><font size=\"-1\">";
+ t += inf->description();
+ t += "</font></nobr>";
+ m_pText = new KviTalSimpleRichText(t,box->font());
+ int iWidth = box->visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ iWidth -= LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER;
+ m_pText->setWidth(iWidth);
+}
+
+KviThemeListBoxItem::~KviThemeListBoxItem()
+{
+ delete m_pThemeInfo;
+ delete m_pText;
+}
+
+void KviThemeListBoxItem::paint(QPainter * p)
+{
+ KviTalListBoxText::paint(p);
+ p->drawPixmap(LVI_BORDER,LVI_BORDER, *(g_pIconManager->getBigIcon(QString(KVI_BIGICON_THEME))) );
+ int afterIcon = LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING;
+ int www = p->window().width() - (afterIcon + LVI_BORDER);
+ m_pText->setWidth(www);
+ m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,p->window().height() - (LVI_BORDER * 2)),listBox()->viewport()->colorGroup());
+}
+
+int KviThemeListBoxItem::height(const KviTalListBox * lb) const
+{
+ int iHeight = m_pText->height() + (2 * LVI_BORDER);
+ if(iHeight < (LVI_ICON_SIZE + (2 * LVI_BORDER)))iHeight = LVI_ICON_SIZE + (2 * LVI_BORDER);
+ return iHeight;
+}
+
+KviThemeManagementDialog * KviThemeManagementDialog::m_pInstance = 0;
+
+
+KviThemeManagementDialog::KviThemeManagementDialog(QWidget * parent)
+: QDialog(parent,"theme_options_widget")
+{
+ setCaption(__tr2qs_ctx("Manage Themes - KVIrc","theme"));
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_THEME)));
+
+ setModal(true);
+
+ m_pInstance = this;
+
+ QGridLayout * g = new QGridLayout(this,3,2,4,4);
+
+ KviTalHBox *hb = new KviTalHBox(this);
+ g->addMultiCellWidget(hb,0,0,0,1);
+
+ KviStyledToolButton * tb;
+ QFrame * sep;
+
+ tb = new KviStyledToolButton(hb);
+ tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_SAVE)));
+ tb->setUsesBigPixmap(true);
+ QToolTip::add(tb,__tr2qs_ctx("Save Current Theme...","theme"));
+ connect(tb,SIGNAL(clicked()),this,SLOT(saveCurrentTheme()));
+
+ sep = new QFrame(hb);
+ sep->setFrameStyle(QFrame::VLine | QFrame::Sunken);
+ sep->setMinimumWidth(12);
+
+ m_pPackThemeButton = new KviStyledToolButton(hb);
+ m_pPackThemeButton->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_PACK)));
+ m_pPackThemeButton->setUsesBigPixmap(true);
+ QToolTip::add(m_pPackThemeButton,__tr2qs_ctx("Export Selected Themes to a Distributable Package","theme"));
+ connect(m_pPackThemeButton,SIGNAL(clicked()),this,SLOT(packTheme()));
+
+ m_pDeleteThemeButton = new KviStyledToolButton(hb);
+ m_pDeleteThemeButton->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_REMOVE)));
+ m_pDeleteThemeButton->setUsesBigPixmap(true);
+ QToolTip::add(m_pDeleteThemeButton,__tr2qs_ctx("Delete Selected Themes","theme"));
+ connect(m_pDeleteThemeButton,SIGNAL(clicked()),this,SLOT(deleteTheme()));
+
+ sep = new QFrame(hb);
+ sep->setFrameStyle(QFrame::VLine | QFrame::Sunken);
+ sep->setMinimumWidth(12);
+
+ tb = new KviStyledToolButton(hb);
+ tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_OPEN)));
+ tb->setUsesBigPixmap(true);
+ QToolTip::add(tb,__tr2qs_ctx("Install Theme Package From Disk","theme"));
+ connect(tb,SIGNAL(clicked()),this,SLOT(installFromFile()));
+
+ tb = new KviStyledToolButton(hb);
+ tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_WWW)));
+ tb->setUsesBigPixmap(true);
+ QToolTip::add(tb,__tr2qs_ctx("Get More Themes...","theme"));
+ connect(tb,SIGNAL(clicked()),this,SLOT(getMoreThemes()));
+
+ QWidget *w= new QWidget(hb);
+ w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum);
+
+ m_pListBox = new KviTalListBox(this);
+ m_pListBox->setMinimumHeight(400);
+ m_pListBox->setMinimumWidth(400);
+ m_pListBox->setSelectionMode(KviTalListBox::Extended);
+ connect(m_pListBox,SIGNAL(doubleClicked(KviTalListBoxItem *)),this,SLOT(applyTheme(KviTalListBoxItem *)));
+ connect(m_pListBox,SIGNAL(contextMenuRequested(KviTalListBoxItem *,const QPoint &)),
+ this,SLOT(contextMenuRequested(KviTalListBoxItem *,const QPoint &)));
+ connect(m_pListBox,SIGNAL(selectionChanged()),this,SLOT(enableDisableButtons()));
+ g->addMultiCellWidget(m_pListBox,1,1,0,1);
+
+ KviDynamicToolTip * tip = new KviDynamicToolTip(m_pListBox);
+ connect(tip,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &)));
+
+ QPushButton * b = new QPushButton(__tr2qs("Close"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(closeClicked()));
+ g->addWidget(b,2,1);
+
+ g->setRowStretch(1,0);
+ g->setColStretch(0,1);
+
+ fillThemeBox();
+ m_pContextPopup = new KviTalPopupMenu(this);
+
+ if(g_rectManagementDialogGeometry.y() < 5)
+ {
+ g_rectManagementDialogGeometry.setY(5);
+ }
+ resize(g_rectManagementDialogGeometry.width(),
+ g_rectManagementDialogGeometry.height());
+ move(g_rectManagementDialogGeometry.x(),
+ g_rectManagementDialogGeometry.y());
+}
+
+KviThemeManagementDialog::~KviThemeManagementDialog()
+{
+ g_rectManagementDialogGeometry = QRect(pos().x(),pos().y(),size().width(),size().height());
+ m_pInstance = 0;
+}
+
+void KviThemeManagementDialog::closeClicked()
+{
+ delete this;
+ m_pInstance = 0;
+}
+
+
+void KviThemeManagementDialog::display()
+{
+ if(!m_pInstance)
+ m_pInstance = new KviThemeManagementDialog(g_pFrame);
+ m_pInstance->show();
+}
+
+void KviThemeManagementDialog::cleanup()
+{
+ if(!m_pInstance)return;
+ delete m_pInstance;
+ m_pInstance = 0;
+}
+
+void KviThemeManagementDialog::packTheme()
+{
+ KviPointerList<KviThemeInfo> dl;
+ dl.setAutoDelete(false);
+ for(KviThemeListBoxItem * it = (KviThemeListBoxItem *)m_pListBox->firstItem();it;it = (KviThemeListBoxItem *)it->next())
+ {
+ if(it->isSelected())
+ dl.append(it->themeInfo());
+ }
+ if(dl.isEmpty())return;
+
+ KviPackThemeDialog * pDialog = new KviPackThemeDialog(this,&dl);
+ pDialog->exec();
+ delete pDialog;
+
+}
+
+void KviThemeManagementDialog::contextMenuRequested(KviTalListBoxItem * it,const QPoint & pos)
+{
+ if(it)
+ {
+ m_pListBox->setCurrentItem(it);
+ m_pContextPopup->clear();
+ m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINUS)),__tr2qs_ctx("&Remove Theme","theme"),this,SLOT(deleteTheme()));
+ m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)),__tr2qs_ctx("&Apply Theme","theme"),this,SLOT(applyCurrentTheme()));
+ m_pContextPopup->popup(pos);
+ }
+}
+
+void KviThemeManagementDialog::applyTheme ( KviTalListBoxItem * it)
+{
+ if(it)m_pListBox->setCurrentItem(it);
+ applyCurrentTheme();
+}
+
+void KviThemeManagementDialog::applyCurrentTheme()
+{
+ KviThemeListBoxItem * it = (KviThemeListBoxItem *)m_pListBox->item(m_pListBox->currentItem());
+ if(!it)return;
+
+ if(KviMessageBox::yesNo(__tr2qs_ctx("Apply theme - KVIrc","theme"),
+ __tr2qs_ctx("Do you wish to apply theme \"%Q\" (version %Q)?","theme"),
+ &(it->themeInfo()->name()),&(it->themeInfo()->version())))
+ {
+ QString szPath = it->themeInfo()->absoluteDirectory();
+ if(szPath.isEmpty())return;
+
+ KviThemeInfo out;
+ if(!KviTheme::load(szPath,out))
+ {
+ QString szErr = out.lastError();
+ QString szMsg;
+ KviQString::sprintf(szMsg,__tr2qs_ctx("Failed to apply the specified theme: %Q","theme"),&szErr);
+ QMessageBox::critical(this,__tr2qs_ctx("Apply theme - KVIrc","theme"),szMsg,
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+
+ }
+ }
+}
+
+void KviThemeManagementDialog::deleteTheme()
+{
+ for(KviThemeListBoxItem * pItem = (KviThemeListBoxItem *)m_pListBox->firstItem();pItem;pItem = (KviThemeListBoxItem *)pItem->next())
+ {
+ if(pItem->isSelected())
+ {
+ if(!KviMessageBox::yesNo(__tr2qs_ctx("Delete Theme - KVIrc","theme"),
+ __tr2qs_ctx("Do you really wish to delete theme \"%Q\" (version %Q)?","theme"),
+ &(pItem->themeInfo()->name()),&(pItem->themeInfo()->version())))goto jump_out;
+
+ KviFileUtils::deleteDir(pItem->themeInfo()->absoluteDirectory());
+ }
+ }
+jump_out:
+ fillThemeBox();
+}
+
+void KviThemeManagementDialog::installFromFile()
+{
+ int iThemeCount=0;
+ QString szFileName;
+ QString szError;
+
+ if(!KviFileDialog::askForOpenFileName(szFileName,__tr2qs_ctx("Open Theme - KVIrc","theme"),QString::null,"*.kvt"))
+ return;
+
+ if(!KviThemeFunctions::installThemePackage(szFileName,szError,this))
+ {
+ KviMessageBox::information(szError);
+ return;
+ }
+ fillThemeBox();
+}
+
+void KviThemeManagementDialog::getMoreThemes()
+{
+ if(!g_pFrame)return;
+ g_pFrame->executeInternalCommand(KVI_INTERNALCOMMAND_OPENURL_KVIRC_THEMES);
+}
+
+void KviThemeManagementDialog::saveCurrentTheme()
+{
+ KviSaveThemeDialog * pSaveThemeDialog = new KviSaveThemeDialog(this);
+ pSaveThemeDialog->exec();
+ delete pSaveThemeDialog;
+ fillThemeBox();
+}
+
+void KviThemeManagementDialog::fillThemeBox(const QString &szDir)
+{
+ QDir d(szDir);
+
+ QStringList sl = d.entryList(QDir::Dirs);
+
+ for(QStringList::Iterator it = sl.begin();it != sl.end();++it)
+ {
+ if(*it == ".")continue;
+ if(*it == "..")continue;
+
+ QString szTest = szDir;
+ szTest += KVI_PATH_SEPARATOR_CHAR;
+ szTest += *it;
+
+ KviThemeInfo * inf = new KviThemeInfo();
+ if(inf->loadFromDirectory(szTest))
+ {
+ inf->setSubdirectory(*it);
+ KviThemeListBoxItem * item = 0;
+ item = new KviThemeListBoxItem(m_pListBox,inf);
+ } else {
+ delete inf;
+ }
+ }
+}
+
+void KviThemeManagementDialog::fillThemeBox()
+{
+ m_pListBox->clear();
+
+ QString szDir;
+ g_pApp->getGlobalKvircDirectory(szDir,KviApp::Themes);
+ fillThemeBox(szDir);
+ g_pApp->getLocalKvircDirectory(szDir,KviApp::Themes);
+ fillThemeBox(szDir);
+
+ enableDisableButtons();
+}
+
+bool KviThemeManagementDialog::hasSelectedItems()
+{
+ for(KviTalListBoxItem * it = m_pListBox->firstItem();it;it = it->next())
+ {
+ if(it->isSelected())return true;
+ }
+ return false;
+}
+
+
+void KviThemeManagementDialog::enableDisableButtons()
+{
+ bool b = hasSelectedItems();
+ m_pPackThemeButton->setEnabled(b);
+ m_pDeleteThemeButton->setEnabled(b);
+}
+
+void KviThemeManagementDialog::closeEvent(QCloseEvent * e)
+{
+ e->ignore();
+ delete this;
+}
+
+void KviThemeManagementDialog::tipRequest(KviDynamicToolTip *pTip,const QPoint &pnt)
+{
+ KviThemeListBoxItem * it = (KviThemeListBoxItem *)(m_pListBox->itemAt(pnt));
+
+ if(!it)return;
+
+ KviThemeInfo * pThemeInfo = it->themeInfo();
+
+ QString szThemeDescription;
+
+ KviThemeFunctions::getThemeHtmlDescription(
+ szThemeDescription,
+ pThemeInfo->name(),
+ pThemeInfo->version(),
+ pThemeInfo->description(),
+ pThemeInfo->subdirectory(),
+ pThemeInfo->application(),
+ pThemeInfo->author(),
+ pThemeInfo->date(),
+ pThemeInfo->themeEngineVersion(),
+ pThemeInfo->mediumScreenshot(),
+ 0
+ );
+
+ pTip->tip(m_pListBox->itemRect(it),szThemeDescription);
+}
diff --git a/src/modules/theme/managementdialog.h b/src/modules/theme/managementdialog.h
new file mode 100644
index 00000000..52ae0f86
--- /dev/null
+++ b/src/modules/theme/managementdialog.h
@@ -0,0 +1,109 @@
+#ifndef _MANAGEMENTDIALOG_H_
+#define _MANAGEMENTDIALOG_H_
+//=============================================================================
+//
+// File : managementdialog.h
+// Created on Sat 30 Dec 2006 14:54:56 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2006 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_optionswidget.h"
+#include "kvi_pointerlist.h"
+#include "kvi_theme.h"
+
+#include <qdialog.h>
+#ifdef COMPILE_USE_QT4
+#include <q3simplerichtext.h>
+#define KviTalSimpleRichText Q3SimpleRichText
+#else
+#include <qsimplerichtext.h>
+#define KviTalSimpleRichText QSimpleRichText
+#endif
+#include "kvi_tal_listbox.h"
+#include <qcombobox.h>
+#include "kvi_tal_popupmenu.h"
+#include <qcursor.h>
+#include <kvi_tal_wizard.h>
+
+
+class QLineEdit;
+class KviTalTextEdit;
+class QPushButton;
+class QLabel;
+class QCheckBox;
+
+//class QMultiLineEdit;
+
+class KviDynamicToolTip;
+class KviStyledToolButton;
+
+
+class KviThemeListBoxItem : public KviTalListBoxText
+{
+public:
+ KviThemeListBoxItem(KviTalListBox * box,KviThemeInfo * inf);
+ virtual ~KviThemeListBoxItem();
+public:
+ KviThemeInfo * m_pThemeInfo;
+ KviTalSimpleRichText * m_pText;
+public:
+ KviThemeInfo * themeInfo(){ return m_pThemeInfo; };
+ virtual int height ( const KviTalListBox * lb ) const ;
+protected:
+ virtual void paint ( QPainter * painter );
+};
+
+
+class KviThemeManagementDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviThemeManagementDialog(QWidget * parent);
+ virtual ~KviThemeManagementDialog();
+protected:
+ static KviThemeManagementDialog * m_pInstance;
+ KviTalListBox * m_pListBox;
+ KviTalPopupMenu * m_pContextPopup;
+ KviStyledToolButton * m_pDeleteThemeButton;
+ KviStyledToolButton * m_pPackThemeButton;
+public:
+ static KviThemeManagementDialog * instance(){ return m_pInstance; };
+ static void display();
+ static void cleanup();
+protected:
+ void fillThemeBox(const QString &szDir);
+ bool hasSelectedItems();
+ virtual void closeEvent(QCloseEvent * e);
+protected slots:
+ void saveCurrentTheme();
+ void getMoreThemes();
+ void installFromFile();
+ void fillThemeBox();
+ void deleteTheme();
+ void closeClicked();
+ void packTheme();
+ void applyTheme(KviTalListBoxItem *);
+ void applyCurrentTheme();
+ void enableDisableButtons();
+ void contextMenuRequested(KviTalListBoxItem * item, const QPoint & pos);
+ void tipRequest(KviDynamicToolTip *pTip,const QPoint &pnt);
+};
+
+#endif //!_MANAGEMENTDIALOG_H_
diff --git a/src/modules/theme/packthemedialog.cpp b/src/modules/theme/packthemedialog.cpp
new file mode 100644
index 00000000..88b248a8
--- /dev/null
+++ b/src/modules/theme/packthemedialog.cpp
@@ -0,0 +1,489 @@
+//=============================================================================
+//
+// File : packthemedialog.cpp
+// Created on Wed 03 Jan 2007 01:11:44 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2007 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 "packthemedialog.h"
+#include "themefunctions.h"
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qregexp.h>
+#include <qmessagebox.h>
+#include <qdir.h>
+#include <qcombobox.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qimage.h>
+#include <kvi_tal_textedit.h>
+#ifdef COMPILE_USE_QT4
+#include <q3multilineedit.h>
+#include <QDateTime>
+#else
+#include <qmultilineedit.h>
+#endif
+#include <qbuffer.h>
+#include <qlabel.h>
+#include <qregexp.h>
+
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_config.h"
+#include "kvi_fileutils.h"
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_styled_controls.h"
+#include "kvi_packagefile.h"
+#include "kvi_fileextensions.h"
+#include "kvi_filedialog.h"
+#include "kvi_msgbox.h"
+#include "kvi_selectors.h"
+#include "kvi_miscutils.h"
+#include "kvi_sourcesdate.h"
+
+
+
+KviPackThemeDialog::KviPackThemeDialog(QWidget * pParent,KviPointerList<KviThemeInfo> * pThemeInfoList)
+: KviTalWizard(pParent)
+{
+ m_pThemeInfoList = pThemeInfoList;
+
+ KviThemeInfo * pThemeInfo;
+ QString szPackageName;
+ QString szPackageAuthor;
+ QString szPackageDescription;
+ QString szPackageVersion;
+
+ m_szPackagePath = QDir::homeDirPath();
+ KviQString::ensureLastCharIs(m_szPackagePath,QChar(KVI_PATH_SEPARATOR_CHAR));
+
+ bool bPackagePathSet = false;
+
+ if(m_pThemeInfoList->count() > 1)
+ {
+ szPackageName = "MyThemes";
+ szPackageAuthor = __tr2qs_ctx("Your name here","theme");
+ szPackageVersion = "1.0.0";
+ szPackageDescription = __tr2qs_ctx("Put a package description here...","theme");
+ } else {
+ if(m_pThemeInfoList->count() > 0)
+ {
+ pThemeInfo = m_pThemeInfoList->first();
+ szPackageName = pThemeInfo->subdirectory();
+ szPackageAuthor = pThemeInfo->author();
+ szPackageDescription = pThemeInfo->description();
+ szPackageVersion = pThemeInfo->version();
+
+ m_szPackagePath += pThemeInfo->subdirectory();
+ if(m_szPackagePath.find(QRegExp("[0-9]\\.[0-9]")) == -1)
+ {
+ m_szPackagePath += "-";
+ m_szPackagePath += szPackageVersion;
+ }
+ m_szPackagePath += ".";
+ m_szPackagePath += KVI_FILEEXTENSION_THEMEPACKAGE;
+
+ bPackagePathSet = true;
+ }
+ }
+
+ if(!bPackagePathSet)
+ {
+ m_szPackagePath += szPackageName;
+ m_szPackagePath += "-";
+ m_szPackagePath += szPackageVersion;
+ m_szPackagePath += ".";
+ m_szPackagePath += KVI_FILEEXTENSION_THEMEPACKAGE;
+ }
+
+ setCaption(__tr2qs_ctx("Export Theme - KVIrc","theme"));
+ setMinimumSize(400,350);
+
+ // welcome page ==================================================================================
+ QWidget * pPage = new QWidget(this);
+ QGridLayout * pLayout = new QGridLayout(pPage,2,1,4,4);
+
+ QLabel * pLabel = new QLabel(pPage);
+ QString szText = "<p>";
+ szText += __tr2qs_ctx("This procedure allows you to export the selected themes to a single package. It is useful when you want to distribute your themes to the public.","theme");
+ szText += "</p><p>";
+ szText += __tr2qs_ctx("You will be asked to provide a package name, a description and, if you want, an icon/screenshot.","theme");
+ szText += "</p><p>";
+ szText += __tr2qs_ctx("Hit the \"Next\" button to begin.","theme");
+ szText += "<p>";
+
+ pLabel->setText(szText);
+ pLayout->addWidget(pLabel,0,0);
+ pLayout->setRowStretch(1,1);
+
+ addPage(pPage,__tr2qs_ctx("Welcome","theme"));
+ setBackEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setFinishEnabled(pPage,false);
+
+ // theme data name ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,2,1,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("This is the information list for the themes you're packaging. If it looks OK press \"Next\" to continue, otherwise press \"Cancel\" and rewiew your themes first.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addWidget(pLabel,0,0);
+
+ QString szThemesDescription = "<html><body bgcolor=\"#ffffff\">";
+
+ int iIdx = 0;
+ QPixmap pixScreenshot;
+ QString szScreenshotPath;
+
+ for(pThemeInfo = m_pThemeInfoList->first();pThemeInfo;pThemeInfo = m_pThemeInfoList->next())
+ {
+ QString szThemeDescription;
+
+ if(pixScreenshot.isNull())
+ {
+ pixScreenshot = pThemeInfo->smallScreenshot();
+ if(!pixScreenshot.isNull())
+ szScreenshotPath = pThemeInfo->smallScreenshotPath();
+ }
+
+ KviThemeFunctions::getThemeHtmlDescription(
+ szThemeDescription,
+ pThemeInfo->name(),
+ pThemeInfo->version(),
+ pThemeInfo->description(),
+ pThemeInfo->subdirectory(),
+ pThemeInfo->application(),
+ pThemeInfo->author(),
+ pThemeInfo->date(),
+ pThemeInfo->themeEngineVersion(),
+ pThemeInfo->smallScreenshot(),
+ iIdx
+ );
+
+ if(iIdx > 0)
+ szThemesDescription += "<hr>";
+ szThemesDescription += szThemeDescription;
+ iIdx++;
+ }
+
+ szThemesDescription += "</body></html>";
+
+ KviTalTextEdit * pTextEdit = new KviTalTextEdit(pPage);
+ pTextEdit->setPaper(QBrush(QColor(255,255,255)));
+ pTextEdit->setReadOnly(true);
+ pTextEdit->setText(szThemesDescription);
+ pLayout->addWidget(pTextEdit,1,0);
+ pLayout->setRowStretch(1,1);
+
+ addPage(pPage,__tr2qs_ctx("Theme Data","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setFinishEnabled(pPage,false);
+
+ // packager informations ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,5,2,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Here you need to provide informations about you (the packager) and a short description of the package you're creating.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addMultiCellWidget(pLabel,0,0,0,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Package Name:","theme"));
+ pLayout->addWidget(pLabel,1,0);
+
+ m_pPackageNameEdit = new QLineEdit(pPage);
+ m_pPackageNameEdit->setText(szPackageName);
+ pLayout->addWidget(m_pPackageNameEdit,1,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Version:","theme"));
+ pLayout->addWidget(pLabel,2,0);
+
+ m_pPackageVersionEdit = new QLineEdit(pPage);
+ m_pPackageVersionEdit->setText(szPackageVersion);
+ pLayout->addWidget(m_pPackageVersionEdit,2,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Description:","theme"));
+ pLayout->addWidget(pLabel,3,0);
+
+ m_pPackageDescriptionEdit = new KviTalTextEdit(pPage);
+ m_pPackageDescriptionEdit->setText(szPackageDescription);
+ pLayout->addWidget(m_pPackageDescriptionEdit,3,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Package Author:","theme"));
+ pLayout->addWidget(pLabel,4,0);
+
+ m_pPackagerNameEdit = new QLineEdit(pPage);
+ m_pPackagerNameEdit->setText(szPackageAuthor);
+ pLayout->addWidget(m_pPackagerNameEdit,4,1);
+
+
+ pLayout->setRowStretch(3,1);
+ pLayout->setColStretch(1,1);
+
+ addPage(pPage,__tr2qs_ctx("Package Informations","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setFinishEnabled(pPage,false);
+
+ // screenshot/logo/icon ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,3,1,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Here you can choose the image that will appear in the installation dialog for your theme package. It can be an icon, a logo or a screenshot and it should be not larger than 300x225. If you don't provide an image a simple default icon will be used at installation stage.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addWidget(pLabel,0,0);
+
+ m_pImageLabel = new QLabel(pPage);
+ m_pImageLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel);
+ m_pImageLabel->setMinimumSize(300,225);
+ m_pImageLabel->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
+ pLayout->addWidget(m_pImageLabel,1,0);
+
+ QString szFilter = "*.png *.jpg *.xpm";
+ m_pImageSelector = new KviFileSelector(pPage,"",&m_szImagePath,true,0,szFilter);
+ connect(m_pImageSelector,SIGNAL(selectionChanged(const QString &)),this,SLOT(imageSelectionChanged(const QString &)));
+ pLayout->addWidget(m_pImageSelector,2,0);
+ pLayout->setRowStretch(1,1);
+
+ m_pImageSelectionPage = pPage;
+ addPage(pPage,__tr2qs_ctx("Icon/Screenshot","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setFinishEnabled(pPage,false);
+
+ // save file name ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,4,1,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Here you must choose the file name for the theme package. It should have a *.%1 extension.","theme").arg(KVI_FILEEXTENSION_THEMEPACKAGE));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addWidget(pLabel,0,0);
+
+ szFilter = "*.";
+ szFilter += KVI_FILEEXTENSION_THEMEPACKAGE;
+ m_pPathSelector = new KviFileSelector(pPage,"",&m_szPackagePath,true,KviFileSelector::ChooseSaveFileName,szFilter);
+ pLayout->addWidget(m_pPathSelector,1,0);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Finally hit the \"Finish\" button to complete the packaging operation.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addWidget(pLabel,3,0);
+
+ pLayout->setRowStretch(2,1);
+
+ addPage(pPage,__tr2qs_ctx("Package Path","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,false);
+ setFinishEnabled(pPage,true);
+
+ if(!szScreenshotPath.isEmpty())
+ {
+ m_pImageSelector->setSelection(szScreenshotPath);
+ imageSelectionChanged(szScreenshotPath);
+ }
+}
+
+KviPackThemeDialog::~KviPackThemeDialog()
+{
+}
+
+void KviPackThemeDialog::imageSelectionChanged(const QString &szImagePath)
+{
+ QImage pix(szImagePath);
+ if(!pix.isNull())
+ {
+ QPixmap out;
+ if(pix.width() > 300 || pix.height() > 225)
+#ifdef COMPILE_USE_QT4
+ out.convertFromImage(pix.scaled(300,225,Qt::KeepAspectRatio,Qt::SmoothTransformation));
+#else
+ out.convertFromImage(pix.smoothScale(300,225,QImage::ScaleMin));
+#endif
+ else
+ out.convertFromImage(pix);
+ m_pImageLabel->setPixmap(out);
+ return;
+ }
+
+ QMessageBox::critical(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),__tr2qs_ctx("Failed to load the selected image","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+
+ m_pImageSelector->setSelection("");
+ m_pImageLabel->setPixmap(QPixmap());
+}
+
+
+void KviPackThemeDialog::accept()
+{
+ if(!packTheme())return;
+ KviTalWizard::accept();
+}
+
+
+bool KviPackThemeDialog::packTheme()
+{
+ m_pImageSelector->commit();
+ m_pPathSelector->commit();
+
+ QString szPackageAuthor = m_pPackagerNameEdit->text();
+ QString szPackageName = m_pPackageNameEdit->text();
+ QString szPackageDescription = m_pPackageDescriptionEdit->text();
+ QString szPackageVersion = m_pPackageVersionEdit->text();
+
+ QImage pix(m_szImagePath);
+ QPixmap out;
+ if(!pix.isNull())
+ {
+ if(pix.width() > 300 || pix.height() > 225)
+ #ifdef COMPILE_USE_QT4
+ out.convertFromImage(pix.scaled(300,225,Qt::KeepAspectRatio));
+ #else
+ out.convertFromImage(pix.smoothScale(300,225,QImage::ScaleMin));
+#endif
+ else
+ out.convertFromImage(pix);
+ } else {
+ if(!m_szImagePath.isEmpty())
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),__tr2qs_ctx("Failed to load the selected image: please fix it","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ setCurrentPage(m_pImageSelectionPage);
+ return false;
+ }
+ }
+
+ KviPackageWriter f;
+
+ QString szTmp = QDateTime::currentDateTime().toString();
+
+ f.addInfoField("PackageType","ThemePack");
+ f.addInfoField("ThemePackVersion","1");
+ f.addInfoField("Name",szPackageName);
+ f.addInfoField("Version",szPackageVersion);
+ f.addInfoField("Author",szPackageAuthor);
+ f.addInfoField("Description",szPackageDescription);
+ f.addInfoField("Date",szTmp);
+ f.addInfoField("Application","KVIrc " KVI_VERSION "." KVI_SOURCES_DATE);
+
+ if(!out.isNull())
+ {
+ QByteArray * pba = new QByteArray();
+#ifdef COMPILE_USE_QT4
+ QBuffer buffer(pba,0);
+#else
+ QBuffer buffer(*pba);
+#endif
+ buffer.open(IO_WriteOnly);
+ out.save(&buffer,"PNG");
+ buffer.close();
+ f.addInfoField("Image",pba); // cool :) [no disk access needed]
+ }
+
+ szTmp.setNum(m_pThemeInfoList->count());
+ f.addInfoField("ThemeCount",szTmp);
+
+ int iIdx = 0;
+ for(KviThemeInfo * pInfo = m_pThemeInfoList->first();pInfo;pInfo = m_pThemeInfoList->next())
+ {
+ KviQString::sprintf(szTmp,"Theme%dName",iIdx);
+ f.addInfoField(szTmp,pInfo->name());
+ KviQString::sprintf(szTmp,"Theme%dVersion",iIdx);
+ f.addInfoField(szTmp,pInfo->version());
+ KviQString::sprintf(szTmp,"Theme%dDescription",iIdx);
+ f.addInfoField(szTmp,pInfo->description());
+ KviQString::sprintf(szTmp,"Theme%dDate",iIdx);
+ f.addInfoField(szTmp,pInfo->date());
+ KviQString::sprintf(szTmp,"Theme%dSubdirectory",iIdx);
+ f.addInfoField(szTmp,pInfo->subdirectory());
+ KviQString::sprintf(szTmp,"Theme%dAuthor",iIdx);
+ f.addInfoField(szTmp,pInfo->author());
+ KviQString::sprintf(szTmp,"Theme%dApplication",iIdx);
+ f.addInfoField(szTmp,pInfo->application());
+ KviQString::sprintf(szTmp,"Theme%dThemeEngineVersion",iIdx);
+ f.addInfoField(szTmp,pInfo->themeEngineVersion());
+ QPixmap pixScreenshot = pInfo->smallScreenshot();
+ if(!pixScreenshot.isNull())
+ {
+ KviQString::sprintf(szTmp,"Theme%dScreenshot",iIdx);
+ QByteArray * pba = new QByteArray();
+#ifdef COMPILE_USE_QT4
+ QBuffer bufferz(pba,0);
+#else
+ QBuffer bufferz(*pba);
+#endif
+ bufferz.open(IO_WriteOnly);
+ pixScreenshot.save(&bufferz,"PNG");
+ bufferz.close();
+ f.addInfoField(szTmp,pba);
+ }
+
+ if(!f.addDirectory(pInfo->absoluteDirectory(),pInfo->subdirectory()))
+ {
+ szTmp = __tr2qs_ctx("Packaging failed","theme");
+ szTmp += ": ";
+ szTmp += f.lastError();
+ QMessageBox::critical(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),szTmp,
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ }
+
+ iIdx++;
+ }
+
+ if(!f.pack(m_szPackagePath))
+ {
+ szTmp = __tr2qs_ctx("Packaging failed","theme");
+ szTmp += ": ";
+ szTmp += f.lastError();
+ QMessageBox::critical(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),szTmp,
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return false;
+ }
+
+ //KviPackageReader r;
+ //r.unpack("/root/test.kvt","/root/unpacked_test_kvt");
+
+ QMessageBox::information(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),__tr2qs("Package saved succesfully"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+
+ return true;
+}
+
diff --git a/src/modules/theme/packthemedialog.h b/src/modules/theme/packthemedialog.h
new file mode 100644
index 00000000..7731cc30
--- /dev/null
+++ b/src/modules/theme/packthemedialog.h
@@ -0,0 +1,66 @@
+#ifndef _PACKTHEMEDIALOG_H_
+#define _PACKTHEMEDIALOG_H_
+//=============================================================================
+//
+// File : packthemedialog.h
+// Created on Wed 03 Jan 2007 01:11:44 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2007 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 "kvi_pointerlist.h"
+#include "kvi_theme.h"
+
+#include <qdialog.h>
+#include <kvi_tal_wizard.h>
+
+class QLineEdit;
+class KviTalTextEdit;
+class QLabel;
+class QMultiLineEdit;
+class KviFileSelector;
+
+
+class KviPackThemeDialog : public KviTalWizard
+{
+ Q_OBJECT
+public:
+ KviPackThemeDialog(QWidget * pParent,KviPointerList<KviThemeInfo> * pThemeInfoList);
+ virtual ~KviPackThemeDialog();
+protected:
+ QString m_szImagePath;
+ KviFileSelector * m_pImageSelector;
+ QString m_szPackagePath;
+ KviFileSelector * m_pPathSelector;
+ QLabel * m_pImageLabel;
+ KviPointerList<KviThemeInfo> * m_pThemeInfoList;
+ QLineEdit * m_pPackageNameEdit;
+ KviTalTextEdit * m_pPackageDescriptionEdit;
+ QLineEdit * m_pPackageVersionEdit;
+ QLineEdit * m_pPackagerNameEdit;
+ QWidget * m_pImageSelectionPage;
+protected:
+ virtual void accept();
+ bool packTheme();
+protected slots:
+ void imageSelectionChanged(const QString &szImagePath);
+};
+
+#endif //!_PACKTHEMEDIALOG_H_
diff --git a/src/modules/theme/savethemedialog.cpp b/src/modules/theme/savethemedialog.cpp
new file mode 100644
index 00000000..79319e60
--- /dev/null
+++ b/src/modules/theme/savethemedialog.cpp
@@ -0,0 +1,301 @@
+//=============================================================================
+//
+// File : savethemedialog.cpp
+// Created on Wed 03 Jan 2007 03:01:34 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2007 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 "savethemedialog.h"
+#include "themefunctions.h"
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qregexp.h>
+#include <qmessagebox.h>
+#include <qdir.h>
+#include <qcombobox.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qimage.h>
+#include <kvi_tal_textedit.h>
+#ifdef COMPILE_USE_QT4
+#include <q3multilineedit.h>
+#include <QDateTime>
+#else
+#include <qmultilineedit.h>
+#endif
+#include <qbuffer.h>
+#include <qlabel.h>
+
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_config.h"
+#include "kvi_fileutils.h"
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_styled_controls.h"
+#include "kvi_packagefile.h"
+#include "kvi_fileextensions.h"
+#include "kvi_filedialog.h"
+#include "kvi_msgbox.h"
+#include "kvi_selectors.h"
+#include "kvi_miscutils.h"
+#include "kvi_sourcesdate.h"
+
+
+
+KviSaveThemeDialog::KviSaveThemeDialog(QWidget * pParent)
+: KviTalWizard(pParent)
+{
+ setCaption(__tr2qs_ctx("Save Current Theme - KVIrc","theme"));
+ setMinimumSize(400,350);
+
+ // welcome page ==================================================================================
+ QWidget * pPage = new QWidget(this);
+ QGridLayout * pLayout = new QGridLayout(pPage,2,1,4,4);
+
+ QLabel * pLabel = new QLabel(pPage);
+ QString szText = "<p>";
+ szText += __tr2qs_ctx("This procedure allows you to save the current theme settings to a single directory. It is useful if you want to apply other themes or play with the theme settings and later come back to this theme with a single click. It will also allow you to manually modify the theme settings and later export them to a distributable package.","theme");
+ szText += "</p><p>";
+ szText += __tr2qs_ctx("You will be asked to provide a theme name, a description and, if you want, a screenshot.","theme");
+ szText += "</p><p>";
+ szText += __tr2qs_ctx("Hit the \"Next\" button to begin.","theme");
+ szText += "<p>";
+
+ pLabel->setText(szText);
+ pLayout->addWidget(pLabel,0,0);
+ pLayout->setRowStretch(1,1);
+
+ addPage(pPage,__tr2qs_ctx("Welcome","theme"));
+ setBackEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setFinishEnabled(pPage,false);
+
+ // packager informations ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,5,2,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Here you need to provide informations about you (the author) and a short description of the theme you're creating.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addMultiCellWidget(pLabel,0,0,0,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Theme Name:","theme"));
+ pLayout->addWidget(pLabel,1,0);
+
+ m_pThemeNameEdit = new QLineEdit(pPage);
+ //m_pThemeNameEdit->setText(szThemeName);
+ pLayout->addWidget(m_pThemeNameEdit,1,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Version:","theme"));
+ pLayout->addWidget(pLabel,2,0);
+
+ m_pThemeVersionEdit = new QLineEdit(pPage);
+ //m_pThemeVersionEdit->setText(szThemeVersion);
+ pLayout->addWidget(m_pThemeVersionEdit,2,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Description:","theme"));
+ pLayout->addWidget(pLabel,3,0);
+
+ m_pThemeDescriptionEdit = new KviTalTextEdit(pPage);
+ //m_pThemeDescriptionEdit->setText(szThemeDescription);
+ pLayout->addWidget(m_pThemeDescriptionEdit,3,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Theme Author:","theme"));
+ pLayout->addWidget(pLabel,4,0);
+
+ m_pAuthorNameEdit = new QLineEdit(pPage);
+ //m_pAuthorNameEdit->setText(szThemeAuthor);
+ pLayout->addWidget(m_pAuthorNameEdit,4,1);
+
+
+ pLayout->setRowStretch(3,1);
+ pLayout->setColStretch(1,1);
+
+ addPage(pPage,__tr2qs_ctx("Theme Informations","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setFinishEnabled(pPage,false);
+
+ // screenshot/logo/icon ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,4,1,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Here you can either choose a screenshot image from disk or make one now. The screenshot will be displayed in the tooltips of the theme management dialog and will be also visible in the package installation dialog if you will export the theme to a distributable package.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addWidget(pLabel,0,0);
+
+ m_pImageLabel = new QLabel(pPage);
+ m_pImageLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel);
+ m_pImageLabel->setMinimumSize(300,225);
+ m_pImageLabel->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
+ pLayout->addWidget(m_pImageLabel,1,0);
+
+ QString szFilter = "*.png *.jpg *.xpm";
+ m_pImageSelector = new KviFileSelector(pPage,"",&m_szScreenshotPath,true,0,szFilter);
+ connect(m_pImageSelector,SIGNAL(selectionChanged(const QString &)),this,SLOT(imageSelectionChanged(const QString &)));
+ pLayout->addWidget(m_pImageSelector,2,0);
+
+ QPushButton * pButton = new QPushButton(pPage);
+ pButton->setText(__tr2qs_ctx("Make Screenshot Now","theme"));
+ connect(pButton,SIGNAL(clicked()),this,SLOT(makeScreenshot()));
+ pLayout->addWidget(pButton,3,0);
+
+ pLayout->setRowStretch(1,1);
+
+ m_pImageSelectionPage = pPage;
+ addPage(pPage,__tr2qs_ctx("Screenshot","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setFinishEnabled(pPage,true);
+}
+
+KviSaveThemeDialog::~KviSaveThemeDialog()
+{
+}
+
+void KviSaveThemeDialog::imageSelectionChanged(const QString &szImagePath)
+{
+ QImage pix(szImagePath);
+ if(!pix.isNull())
+ {
+ QPixmap out;
+ if(pix.width() > 300 || pix.height() > 225)
+ #ifdef COMPILE_USE_QT4
+ out.convertFromImage(pix.scaled(300,225,Qt::KeepAspectRatio));
+ #else
+ out.convertFromImage(pix.smoothScale(300,225,QImage::ScaleMin));
+#endif
+ else
+ out.convertFromImage(pix);
+ m_pImageLabel->setPixmap(out);
+ return;
+ }
+
+ QMessageBox::critical(this,__tr2qs_ctx("Save Current Theme - KVIrc","theme"),__tr2qs_ctx("Failed to load the selected image","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+
+ m_pImageSelector->setSelection("");
+ m_pImageLabel->setPixmap(QPixmap());
+}
+
+
+void KviSaveThemeDialog::accept()
+{
+ if(!saveTheme())return;
+ KviTalWizard::accept();
+}
+
+
+void KviSaveThemeDialog::makeScreenshot()
+{
+ QString szFileName;
+ g_pApp->getTmpFileName(szFileName,"screenshot.png");
+ if(!KviThemeFunctions::makeKVIrcScreenshot(szFileName))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Acquire Screenshot - KVIrc","theme"),__tr2qs_ctx("Failed to make screenshot","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ m_pImageSelector->setSelection(szFileName);
+ imageSelectionChanged(szFileName);
+}
+
+bool KviSaveThemeDialog::saveTheme()
+{
+ m_pImageSelector->commit();
+
+ KviThemeInfo sto;
+ sto.setName(m_pThemeNameEdit->text());
+ if(sto.name().isEmpty())
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Current Theme - KVIrc","theme"),__tr2qs_ctx("You must choose a theme name!","theme"),QMessageBox::Ok,
+ QMessageBox::NoButton,QMessageBox::NoButton);
+ return false;
+ }
+
+ sto.setAuthor(m_pAuthorNameEdit->text());
+ sto.setDescription(m_pThemeDescriptionEdit->text());
+ sto.setDate(QDateTime::currentDateTime().toString());
+ sto.setVersion(m_pThemeVersionEdit->text());
+ sto.setApplication("KVIrc " KVI_VERSION "." KVI_SOURCES_DATE);
+
+ if(sto.version().isEmpty())sto.setVersion("1.0.0");
+
+ QString szSubdir = sto.name() + QString("-") + sto.version();
+ szSubdir.replace(QRegExp("[ \\\\/:][ \\\\/:]*"),"_");
+ sto.setSubdirectory(szSubdir);
+
+ QString szAbsDir;
+ g_pApp->getLocalKvircDirectory(szAbsDir,KviApp::Themes,sto.subdirectory(),true);
+ if(!KviFileUtils::makeDir(szAbsDir))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Current Theme - KVIrc","theme"),__tr2qs_ctx("Unable to create theme directory.","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return false;
+ }
+
+ sto.setAbsoluteDirectory(szAbsDir);
+
+ if(!KviTheme::save(sto))
+ {
+ QString szMsg2;
+ QString szErr = sto.lastError();
+ KviQString::sprintf(szMsg2,__tr2qs_ctx("Unable to save theme: %Q","theme"),&szErr);
+ QMessageBox::critical(this,__tr2qs_ctx("Save Current Theme - KVIrc","theme"),szMsg2,
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return false;
+ }
+ // write down the screenshot, if needed
+
+ if(!m_szScreenshotPath.isEmpty())
+ {
+ if(!KviTheme::saveScreenshots(sto,m_szScreenshotPath))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Current Theme - KVIrc","theme"),__tr2qs_ctx("Failed to load the selected screenshot image: please fix it","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ setCurrentPage(m_pImageSelectionPage);
+ return false;
+ }
+ }
+
+ QString szMsg = __tr2qs_ctx("Theme saved successfully to ","theme");
+ szMsg += sto.absoluteDirectory();
+
+ QMessageBox::information(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),szMsg,QMessageBox::Ok,
+ QMessageBox::NoButton,QMessageBox::NoButton);
+
+ return true;
+}
+
diff --git a/src/modules/theme/savethemedialog.h b/src/modules/theme/savethemedialog.h
new file mode 100644
index 00000000..df55ee92
--- /dev/null
+++ b/src/modules/theme/savethemedialog.h
@@ -0,0 +1,71 @@
+#ifndef _SAVETHEMEDIALOG_H_
+#define _SAVETHEMEDIALOG_H_
+//=============================================================================
+//
+// File : savethemedialog.h
+// Created on Wed 03 Jan 2007 03:01:34 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2007 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 "kvi_pointerlist.h"
+#include "kvi_theme.h"
+
+#include <qdialog.h>
+#include <kvi_tal_wizard.h>
+
+
+class QLineEdit;
+class KviTalTextEdit;
+class QPushButton;
+class QCheckBox;
+class QLabel;
+class QMultiLineEdit;
+class KviFileSelector;
+
+
+class KviSaveThemeDialog : public KviTalWizard
+{
+ Q_OBJECT
+public:
+ KviSaveThemeDialog(QWidget * pParent);
+ virtual ~KviSaveThemeDialog();
+protected:
+ QString m_szScreenshotPath;
+ KviFileSelector * m_pImageSelector;
+ QLabel * m_pImageLabel;
+ QLineEdit * m_pThemeNameEdit;
+ KviTalTextEdit * m_pThemeDescriptionEdit;
+ QLineEdit * m_pThemeVersionEdit;
+ QLineEdit * m_pAuthorNameEdit;
+ QWidget * m_pImageSelectionPage;
+ QPushButton * m_pOkButton;
+protected:
+ virtual void accept();
+ bool saveTheme();
+protected slots:
+ void makeScreenshot();
+ void imageSelectionChanged(const QString &szImagePath);
+ //void themeNameChanged(const QString &txt);
+};
+
+
+
+#endif //!_SAVETHEMEDIALOG_H_
diff --git a/src/modules/theme/themefunctions.cpp b/src/modules/theme/themefunctions.cpp
new file mode 100644
index 00000000..0a011956
--- /dev/null
+++ b/src/modules/theme/themefunctions.cpp
@@ -0,0 +1,396 @@
+//=============================================================================
+//
+// File : themefunctions.cpp
+// Created on Wed 03 Jan 2007 03:14:07 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2007 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 "themefunctions.h"
+
+#include "kvi_packagefile.h"
+#include "kvi_locale.h"
+#include "kvi_msgbox.h"
+#include "kvi_app.h"
+#include "kvi_htmldialog.h"
+#include "kvi_iconmanager.h"
+#include "kvi_miscutils.h"
+#include "kvi_sourcesdate.h"
+#include "kvi_theme.h"
+#include "kvi_frame.h"
+#ifdef COMPILE_USE_QT4
+#define KviTalMimeSourceFactory Q3MimeSourceFactory
+#include <q3mimefactory.h>
+#else
+#define KviTalMimeSourceFactory QMimeSourceFactory
+#endif
+#include <qmime.h>
+
+namespace KviThemeFunctions
+{
+
+ static bool notAValidThemePackage(QString &szError)
+ {
+ KviQString::sprintf(szError,__tr2qs_ctx("The selected file does not seem to be a valid KVIrc theme package","theme"));
+ return false;
+ }
+
+ bool installThemePackage(const QString &szThemePackageFileName,QString &szError,QWidget * pDialogParent)
+ {
+ KviPointerHashTable<QString,QString> * pInfoFields;
+ QString * pValue;
+ bool bInstall;
+ QPixmap pix;
+ QByteArray * pByteArray;
+ KviHtmlDialogData hd;
+
+ const char * check_fields[] = { "Name", "Version", "Author", "Description", "Date", "Application" };
+
+ // check if it is a valid theme file
+ KviPackageReader r;
+ if(!r.readHeader(szThemePackageFileName))
+ {
+ QString szErr = r.lastError();
+ KviQString::sprintf(szError,__tr2qs_ctx("The selected file does not seem to be a valid KVIrc package: %Q","theme"),&szErr);
+ return false;
+ }
+
+ pInfoFields = r.stringInfoFields();
+
+ pValue = pInfoFields->find("PackageType");
+ if(!pValue)return notAValidThemePackage(szError);
+ if(!KviQString::equalCI(*pValue,"ThemePack"))return notAValidThemePackage(szError);
+ pValue = pInfoFields->find("ThemePackVersion");
+ if(!pValue)return notAValidThemePackage(szError);
+ if(!KviQString::equalCI(*pValue,"1"))return notAValidThemePackage(szError);
+
+ // make sure the default fields exist
+ for(int i=0;i<6;i++)
+ {
+ pValue = pInfoFields->find(check_fields[i]);
+ if(!pValue)return notAValidThemePackage(szError);
+ }
+
+ pValue = pInfoFields->find("ThemeCount");
+ if(!pValue)return notAValidThemePackage(szError);
+ bool bOk;
+ int iThemeCount = pValue->toInt(&bOk);
+ if(!bOk)return notAValidThemePackage(szError);
+ if(iThemeCount < 1)return notAValidThemePackage(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_THEME));
+ }
+
+ QString szPackageName;
+ QString szPackageVersion;
+ QString szPackageAuthor;
+ QString szPackageDescription;
+ QString szPackageDate;
+ QString szPackageThemeEngineVersion;
+ QString szPackageApplication;
+
+ QString szAuthor = __tr2qs_ctx("Author","theme");
+ QString szCreatedAt = __tr2qs_ctx("Created at","theme");
+ QString szCreatedOn = __tr2qs_ctx("Created with","theme");
+
+ r.getStringInfoField("Name",szPackageName);
+ r.getStringInfoField("Version",szPackageVersion);
+ r.getStringInfoField("Author",szPackageAuthor);
+ r.getStringInfoField("Description",szPackageDescription);
+ r.getStringInfoField("Application",szPackageApplication);
+ r.getStringInfoField("Date",szPackageDate);
+
+ QString szWarnings;
+ QString szDetails = "<html><body bgcolor=\"#ffffff\">";
+ QString szTmp;
+
+ int iIdx = 0;
+ int iValidThemeCount = iThemeCount;
+
+ while(iIdx < iThemeCount)
+ {
+ bool bValid = true;
+
+ QString szThemeName;
+ QString szThemeVersion;
+ QString szThemeDescription;
+ QString szThemeDate;
+ QString szThemeSubdirectory;
+ QString szThemeAuthor;
+ QString szThemeThemeEngineVersion;
+ QString szThemeApplication;
+
+ KviQString::sprintf(szTmp,"Theme%dName",iIdx);
+ r.getStringInfoField(szTmp,szThemeName);
+ KviQString::sprintf(szTmp,"Theme%dVersion",iIdx);
+ r.getStringInfoField(szTmp,szThemeVersion);
+ KviQString::sprintf(szTmp,"Theme%dApplication",iIdx);
+ r.getStringInfoField(szTmp,szThemeApplication);
+ KviQString::sprintf(szTmp,"Theme%dDescription",iIdx);
+ r.getStringInfoField(szTmp,szThemeDescription);
+ KviQString::sprintf(szTmp,"Theme%dDate",iIdx);
+ r.getStringInfoField(szTmp,szThemeDate);
+ KviQString::sprintf(szTmp,"Theme%dSubdirectory",iIdx);
+ r.getStringInfoField(szTmp,szThemeSubdirectory);
+ KviQString::sprintf(szTmp,"Theme%dAuthor",iIdx);
+ r.getStringInfoField(szTmp,szThemeAuthor);
+ KviQString::sprintf(szTmp,"Theme%dThemeEngineVersion",iIdx);
+ r.getStringInfoField(szTmp,szThemeThemeEngineVersion);
+ KviQString::sprintf(szTmp,"Theme%dScreenshot",iIdx);
+ QPixmap pixScreenshot;
+ pByteArray = r.binaryInfoFields()->find(szTmp);
+ if(pByteArray)
+ pixScreenshot.loadFromData(*pByteArray,0,0);
+
+ if(szThemeName.isEmpty() || szThemeVersion.isEmpty() || szThemeSubdirectory.isEmpty() || szThemeThemeEngineVersion.isEmpty())
+ bValid = false;
+ if(KviMiscUtils::compareVersions(szThemeThemeEngineVersion,KVI_CURRENT_THEME_ENGINE_VERSION) < 0)
+ bValid = false;
+
+ QString szDetailsBuffer;
+
+ getThemeHtmlDescription(
+ szDetailsBuffer,
+ szThemeName,
+ szThemeVersion,
+ szThemeDescription,
+ szThemeSubdirectory,
+ szThemeApplication,
+ szThemeAuthor,
+ szThemeDate,
+ szThemeThemeEngineVersion,
+ pixScreenshot,
+ iIdx
+ );
+
+ if(iIdx > 0)
+ szDetails += "<hr>";
+
+ szDetails += szDetailsBuffer;
+
+ if(!bValid)
+ {
+ szDetails += "<p><center><font color=\"#ff0000\"><b>";
+ szDetails += __tr2qs_ctx("Warning: The theme might be incompatible with this version of KVIrc","theme");
+ szDetails += "</b></font></center></p>";
+ iValidThemeCount--;
+ }
+
+ iIdx++;
+ }
+
+ szDetails += "<br><p><center><a href=\"theme_dialog_main\">";
+ szDetails += __tr2qs_ctx("Go Back to Package Data","theme");
+ szDetails += "</a></center></p>";
+ szDetails += "</body></html>";
+
+ if(iValidThemeCount < iThemeCount)
+ {
+ szWarnings += "<p><center><font color=\"#ff0000\"><b>";
+ szWarnings += __tr2qs_ctx("Warning: Some of the theme contained in this package might be either corrupted or incompatible with this version of KVIrc","theme");
+ szWarnings += "</b></font></center></p>";
+ }
+
+ QString szShowDetails = __tr2qs_ctx("Show Details","theme");
+
+ KviQString::sprintf(hd.szHtmlText,
+ "<html bgcolor=\"#ffffff\">" \
+ "<body bgcolor=\"#ffffff\">" \
+ "<p><center>" \
+ "<h2>%Q %Q</h2>" \
+ "</center></p>" \
+ "<p><center>" \
+ "<img src=\"theme_dialog_pack_image\">" \
+ "</center></p>" \
+ "<p><center>" \
+ "<i>%Q</i>" \
+ "</center></p>" \
+ "<p><center>" \
+ "%Q: <b>%Q</b><br>" \
+ "%Q: <b>%Q</b><br>" \
+ "</center></p>" \
+ "<p><center>" \
+ "<font color=\"#808080\">" \
+ "%Q: %Q<br>" \
+ "</font>" \
+ "</center></p>" \
+ "%Q" \
+ "<br>" \
+ "<p><center>" \
+ "<a href=\"theme_dialog_details\">%Q</a>" \
+ "</center></p>" \
+ "</body>" \
+ "</html>",
+ &szPackageName,
+ &szPackageVersion,
+ &szPackageDescription,
+ &szAuthor,
+ &szPackageAuthor,
+ &szCreatedAt,
+ &szPackageDate,
+ &szCreatedOn,
+ &szPackageApplication,
+ &szWarnings,
+ &szShowDetails
+ );
+
+
+
+ KviTalMimeSourceFactory::defaultFactory()->setPixmap("theme_dialog_pack_image",pix);
+ KviTalMimeSourceFactory::defaultFactory()->setText("theme_dialog_details",szDetails);
+ KviTalMimeSourceFactory::defaultFactory()->setText("theme_dialog_main",hd.szHtmlText);
+
+ QString beginCenter = "<center>";
+ QString endCenter = "</center>";
+
+ hd.szCaption = __tr2qs_ctx("Install Theme Pack - KVIrc","theme");
+ hd.szUpperLabelText = beginCenter + __tr2qs_ctx("You're about to install the following theme package","theme") + endCenter;
+ hd.szLowerLabelText = beginCenter + __tr2qs_ctx("Do you want to proceed with the installation ?","theme") + endCenter;
+ hd.szButton1Text = __tr2qs_ctx("Do Not Install","theme");
+ hd.szButton2Text = __tr2qs_ctx("Yes, Proceed","theme");
+ hd.iDefaultButton = 2;
+ hd.iCancelButton = 1;
+ hd.pixIcon = *(g_pIconManager->getSmallIcon(KVI_SMALLICON_THEME));
+ hd.iMinimumWidth = 350;
+ hd.iMinimumHeight = 420;
+ hd.iFlags = KviHtmlDialogData::ForceMinimumSize;
+
+ bInstall = KviHtmlDialog::display(pDialogParent,&hd) == 2;
+
+ if(bInstall)
+ {
+ QString szUnpackPath;
+ g_pApp->getLocalKvircDirectory(szUnpackPath,KviApp::Themes);
+ if(!r.unpack(szThemePackageFileName,szUnpackPath))
+ {
+ QString szErr2 = r.lastError();
+ KviQString::sprintf(szError,__tr2qs_ctx("Failed to unpack the selected file: %Q","theme"),&szErr2);
+ return true;
+ }
+ }
+
+ return true;
+ }
+
+
+ void getThemeHtmlDescription(
+ QString &szBuffer,
+ const QString &szThemeName,
+ const QString &szThemeVersion,
+ const QString &szThemeDescription,
+ const QString &szThemeSubdirectory,
+ const QString &szThemeApplication,
+ const QString &szThemeAuthor,
+ const QString &szThemeDate,
+ const QString &szThemeThemeEngineVersion,
+ const QPixmap &pixScreenshot,
+ int iUniqueIndexInDocument
+ )
+ {
+ QString szAuthor = __tr2qs_ctx("Author","theme");
+ QString szCreatedAt = __tr2qs_ctx("Created at","theme");
+ QString szCreatedOn = __tr2qs_ctx("Created with","theme");
+ QString szThemeEngineVersion = __tr2qs_ctx("Theme Engine Version","theme");
+ QString szSubdirectory = __tr2qs_ctx("Subdirectory","theme");
+
+ QString szScreenshot;
+ if(!pixScreenshot.isNull())
+ {
+ KviQString::sprintf(szScreenshot,"<p><center><img src=\"theme_shot%d\"></center></p>",iUniqueIndexInDocument);
+ QString szTmp;
+ KviQString::sprintf(szTmp,"theme_shot%d",iUniqueIndexInDocument);
+ KviTalMimeSourceFactory::defaultFactory()->setPixmap(szTmp,pixScreenshot);
+ } else {
+ szScreenshot = "";
+ }
+
+ KviQString::sprintf(
+ szBuffer,
+ "<p><center>" \
+ "<h2>%Q %Q</h2>" \
+ "</center></p>" \
+ "%Q" \
+ "<p><center>" \
+ "<i>%Q</i>" \
+ "</center></p>" \
+ "<p><center>" \
+ "%Q: <b>%Q</b><br>" \
+ "%Q: <b>%Q</b><br>" \
+ "</center></p>" \
+ "<p><center>" \
+ "<font color=\"#808080\">" \
+ "%Q: %Q<br>" \
+ "%Q: %Q<br>" \
+ "%Q: %Q<br>" \
+ "</font>" \
+ "</center></p>",
+ &szThemeName,
+ &szThemeVersion,
+ &szScreenshot,
+ &szThemeDescription,
+ &szAuthor,
+ &szThemeAuthor,
+ &szCreatedAt,
+ &szThemeDate,
+ &szCreatedOn,
+ &szThemeApplication,
+ &szThemeEngineVersion,
+ &szThemeThemeEngineVersion,
+ &szSubdirectory,
+ &szThemeSubdirectory
+ );
+ }
+
+ bool makeKVIrcScreenshot(const QString &szSavePngFilePath,bool bMaximizeFrame)
+ {
+ if(bMaximizeFrame)
+ {
+ if(g_pFrame->isMaximized())
+ bMaximizeFrame = false;
+ }
+
+ if(bMaximizeFrame)
+ g_pFrame->showMaximized();
+
+ QPixmap pix = QPixmap::grabWidget(g_pFrame);
+ bool bResult = true;
+
+ if(pix.isNull())
+ bResult = false;
+ else {
+ if(!pix.save(szSavePngFilePath,"PNG",100))
+ bResult = false;
+ }
+
+ if(bMaximizeFrame)
+ g_pFrame->showNormal();
+ return bResult;
+ }
+};
+
diff --git a/src/modules/theme/themefunctions.h b/src/modules/theme/themefunctions.h
new file mode 100644
index 00000000..124a65f6
--- /dev/null
+++ b/src/modules/theme/themefunctions.h
@@ -0,0 +1,54 @@
+#ifndef _THEMEFUNCTIONS_H_
+#define _THEMEFUNCTIONS_H_
+//=============================================================================
+//
+// File : themefunctions.h
+// Created on Wed 03 Jan 2007 03:14:07 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2007 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 "kvi_qstring.h"
+
+#include <qwidget.h>
+#include <qpixmap.h>
+
+namespace KviThemeFunctions
+{
+ bool installThemePackage(const QString &szThemePackageFileName,QString &szError,QWidget * pDialogParent = 0);
+ void getThemeHtmlDescription(
+ QString &szBuffer,
+ const QString &szThemeName,
+ const QString &szThemeVersion,
+ const QString &szThemeDescription,
+ const QString &szThemeSubdirectory,
+ const QString &szThemeApplication,
+ const QString &szThemeAuthor,
+ const QString &szThemeDate,
+ const QString &szThemeThemeEngineVersion,
+ const QPixmap &pixScreenshot,
+ int iUniqueIndexInDocument = 0
+ );
+ bool makeKVIrcScreenshot(const QString &szSavePngFilePath,bool bMaximizeFrame = false);
+};
+
+
+
+#endif //!_THEMEFUNCTIONS_H_
diff --git a/src/modules/tip/Makefile.am b/src/modules/tip/Makefile.am
new file mode 100644
index 00000000..2a9fbbcb
--- /dev/null
+++ b/src/modules/tip/Makefile.am
@@ -0,0 +1,30 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvitip.la
+
+libkvitip_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvitip_la_SOURCES = libkvitip.cpp
+libkvitip_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= libkvitip.h
+
+tmpdir = $(picsdir)
+
+tmp_DATA = kvi_tip.png
+
+confdir = $(configmodulesdir)
+
+conf_DATA = libkvitip.kvc libkvitip_it.kvc libkvitip_cs.kvc libkvitip_ru.kvc
+
+EXTRA_DIST = $(tmp_DATA) $(conf_DATA)
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkvitip.cpp: libkvitip.moc
diff --git a/src/modules/tip/kvi_tip.png b/src/modules/tip/kvi_tip.png
new file mode 100644
index 00000000..29312d4a
--- /dev/null
+++ b/src/modules/tip/kvi_tip.png
Binary files differ
diff --git a/src/modules/tip/libkvitip.cpp b/src/modules/tip/libkvitip.cpp
new file mode 100644
index 00000000..ac23d914
--- /dev/null
+++ b/src/modules/tip/libkvitip.cpp
@@ -0,0 +1,309 @@
+//
+// File : libkvitip.cpp
+// Creation date : Thu May 10 2001 13:50:11 CEST 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 "libkvitip.h"
+#include "kvi_module.h"
+#include "kvi_styled_controls.h"
+
+#include "kvi_locale.h"
+#include "kvi_app.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_fileutils.h"
+
+#include <qpushbutton.h>
+
+#ifdef COMPILE_USE_QT4
+#include <q3simplerichtext.h>
+#include <QDesktopWidget>
+#include <QCloseEvent>
+#define KviTalSimpleRichText Q3SimpleRichText
+#else
+#include <qsimplerichtext.h>
+#define KviTalSimpleRichText QSimpleRichText
+#endif
+
+#include <qfont.h>
+#include <qtextcodec.h>
+#include <qpainter.h>
+
+KviTipWindow * g_pTipWindow = 0;
+
+#define KVI_TIP_WINDOW_HEIGHT 200
+#define KVI_TIP_WINDOW_WIDTH 500
+#define KVI_TIP_WINDOW_BUTTON_WIDTH 80
+#define KVI_TIP_WINDOW_BUTTON_HEIGHT 30
+#define KVI_TIP_WINDOW_BORDER 5
+#define KVI_TIP_WINDOW_DOUBLE_BORDER 10
+#define KVI_TIP_WINDOW_SPACING 2
+
+
+KviTipFrame::KviTipFrame(QWidget * par)
+: QFrame(par)
+{
+ KviStr buffer;
+ g_pApp->findImage(buffer,"kvi_tip.png");
+ m_pTipPixmap = new QPixmap(buffer.ptr());
+#ifdef COMPILE_USE_QT4
+ setBackgroundMode(Qt::NoBackground);
+#else
+ setBackgroundMode(QWidget::NoBackground);
+#endif
+ setFrameStyle(QFrame::Sunken | QFrame::WinPanel);
+}
+
+KviTipFrame::~KviTipFrame()
+{
+ delete m_pTipPixmap;
+}
+
+void KviTipFrame::setText(const QString &text)
+{
+ m_szText = "<center><font color=\"#FFFFFF\">";
+ m_szText += text;
+ m_szText += "</font></center>";
+ update();
+}
+
+void KviTipFrame::drawContents(QPainter *p)
+{
+ p->fillRect(contentsRect(),QColor(0,0,0));
+ p->drawPixmap(5,(height() - m_pTipPixmap->height()) / 2,*m_pTipPixmap);
+
+ QFont f = QFont();
+ f.setStyleHint(QFont::SansSerif);
+ f.setPointSize(12);
+
+ KviTalSimpleRichText doc(m_szText,f);
+ doc.setWidth(width() - 80);
+
+ QRegion reg(0,0,1000,20000);
+
+#if QT_VERSION >= 300
+ doc.draw(p,70,10,reg,colorGroup());
+#else
+ doc.draw(p,70,10,reg,palette());
+#endif
+}
+
+KviTipWindow::KviTipWindow()
+: QWidget(0,"kvirc_tip_window" /*,WStyle_Customize | WStyle_Title | WStyle_DialogBorder | WStyle_StaysOnTop*/ )
+{
+ m_pConfig = 0;
+
+
+ m_pTipFrame = new KviTipFrame(this);
+ m_pTipFrame->setGeometry(
+ KVI_TIP_WINDOW_BORDER,
+ KVI_TIP_WINDOW_BORDER,
+ KVI_TIP_WINDOW_WIDTH - KVI_TIP_WINDOW_DOUBLE_BORDER,
+ KVI_TIP_WINDOW_HEIGHT - (KVI_TIP_WINDOW_DOUBLE_BORDER + KVI_TIP_WINDOW_BUTTON_HEIGHT + KVI_TIP_WINDOW_SPACING));
+
+ QPushButton * pb = new QPushButton(">>",this);
+ pb->setGeometry(
+ KVI_TIP_WINDOW_WIDTH - ((KVI_TIP_WINDOW_BUTTON_WIDTH * 2)+ KVI_TIP_WINDOW_BORDER + KVI_TIP_WINDOW_SPACING),
+ KVI_TIP_WINDOW_HEIGHT - (KVI_TIP_WINDOW_BUTTON_HEIGHT + KVI_TIP_WINDOW_BORDER),
+ KVI_TIP_WINDOW_BUTTON_WIDTH,
+ KVI_TIP_WINDOW_BUTTON_HEIGHT
+ );
+ connect(pb,SIGNAL(clicked()),this,SLOT(nextTip()));
+
+ pb = new QPushButton(__tr2qs("Close"),this);
+ pb->setGeometry(
+ KVI_TIP_WINDOW_WIDTH - (KVI_TIP_WINDOW_BUTTON_WIDTH + KVI_TIP_WINDOW_BORDER),
+ KVI_TIP_WINDOW_HEIGHT - (KVI_TIP_WINDOW_BUTTON_HEIGHT + KVI_TIP_WINDOW_BORDER),
+ KVI_TIP_WINDOW_BUTTON_WIDTH,
+ KVI_TIP_WINDOW_BUTTON_HEIGHT
+ );
+ connect(pb,SIGNAL(clicked()),this,SLOT(close()));
+ pb->setDefault(true);
+
+ m_pShowAtStartupCheck = new KviStyledCheckBox(__tr2qs("Show at startup"),this);
+ m_pShowAtStartupCheck->setChecked(KVI_OPTION_BOOL(KviOption_boolShowTipAtStartup));
+ m_pShowAtStartupCheck->setGeometry(
+ KVI_TIP_WINDOW_BORDER,
+ KVI_TIP_WINDOW_HEIGHT - (KVI_TIP_WINDOW_BUTTON_HEIGHT + KVI_TIP_WINDOW_BORDER),
+ KVI_TIP_WINDOW_WIDTH - ((KVI_TIP_WINDOW_BORDER + KVI_TIP_WINDOW_BUTTON_WIDTH + KVI_TIP_WINDOW_SPACING) * 2),
+ KVI_TIP_WINDOW_BUTTON_HEIGHT
+ );
+
+ setFixedSize(KVI_TIP_WINDOW_WIDTH,KVI_TIP_WINDOW_HEIGHT);
+
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_IDEA)));
+
+ setCaption(__tr2qs("Did you know..."));
+
+ pb->setFocus();
+
+}
+
+KviTipWindow::~KviTipWindow()
+{
+ KVI_OPTION_BOOL(KviOption_boolShowTipAtStartup) = m_pShowAtStartupCheck->isChecked();
+ if(m_pConfig)closeConfig();
+}
+
+bool KviTipWindow::openConfig(const char * filename,bool bEnsureExists)
+{
+ if(m_pConfig)closeConfig();
+
+ m_szConfigFileName = filename;
+// m_szConfigFileName.cutToLast('/');
+
+ KviStr buffer;
+ g_pApp->getReadOnlyConfigPath(buffer,m_szConfigFileName.ptr(),KviApp::ConfigPlugins,true);
+
+ if(bEnsureExists)
+ {
+ if(!KviFileUtils::fileExists(buffer.ptr()))return false;
+ }
+
+ m_pConfig = new KviConfig(buffer.ptr(),KviConfig::Read);
+
+ return true;
+}
+
+void KviTipWindow::closeConfig()
+{
+ KviStr buffer;
+ g_pApp->getLocalKvircDirectory(buffer,KviApp::ConfigPlugins,m_szConfigFileName.ptr());
+ m_pConfig->setSavePath(buffer.ptr());
+ delete m_pConfig;
+ m_pConfig = 0;
+}
+
+void KviTipWindow::nextTip()
+{
+ if(!m_pConfig)
+ {
+ KviStr szLocale = KviLocale::localeName();
+ KviStr szFile;
+ szFile.sprintf("libkvitip_%s.kvc",szLocale.ptr());
+ if(!openConfig(szFile.ptr(),true))
+ {
+ szLocale.cutFromFirst('.');
+ szLocale.cutFromFirst('_');
+ szLocale.cutFromFirst('@');
+ szFile.sprintf("libkvitip_%s.kvc",szLocale.ptr());
+ if(!openConfig(szFile.ptr(),true))
+ {
+ openConfig("libkvitip.kvc",false);
+ }
+ }
+ }
+
+ unsigned int uNumTips = m_pConfig->readUIntEntry("uNumTips",0);
+ unsigned int uNextTip = m_pConfig->readUIntEntry("uNextTip",0);
+
+
+ KviStr tmp(KviStr::Format,"%u",uNextTip);
+ QString szTip = m_pConfig->readEntry(tmp.ptr(),__tr2qs("<b>Can't find any tip... :(</b>"));
+
+ //debug("REDECODED=%s",szTip.utf8().data());
+
+ uNextTip++;
+ if(uNextTip >= uNumTips)uNextTip = 0;
+ m_pConfig->writeEntry("uNextTip",uNextTip);
+
+ m_pTipFrame->setText(szTip);
+}
+
+void KviTipWindow::showEvent(QShowEvent *e)
+{
+ resize(KVI_TIP_WINDOW_WIDTH,KVI_TIP_WINDOW_HEIGHT);
+ move((g_pApp->desktop()->width() - KVI_TIP_WINDOW_WIDTH) / 2,
+ (g_pApp->desktop()->height() - KVI_TIP_WINDOW_HEIGHT) / 2);
+ QWidget::showEvent(e);
+}
+
+void KviTipWindow::closeEvent(QCloseEvent *e)
+{
+ e->ignore();
+ delete this;
+ g_pTipWindow = 0;
+}
+
+/*
+ @doc: tip.open
+ @type:
+ command
+ @title:
+ tip.open
+ @short:
+ Opens the "did you know..." tip window
+ @syntax:
+ tip.open [tip_file_name:string]
+ @description:
+ Opens the "did you know..." tip window.<br>
+ If <tip_file_name> is specified , that tip is used instead of
+ the default tips provided with kvirc.<br>
+ <tip_file_name> must be a file name with no path and must refer to a
+ standard KVIrc configuration file found in the global or local
+ KVIrc plugin configuration directory ($KVIrcDir/config/modules).<br>
+ Once the window has been opened, the next tip avaiable in the config file is shown.<br>
+ This command works even if the tip window is already opened.<br>
+*/
+
+
+static bool tip_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ QString szTipfilename;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("filename",KVS_PT_STRING,KVS_PF_OPTIONAL,szTipfilename)
+ KVSM_PARAMETERS_END(c)
+ if(!g_pTipWindow)g_pTipWindow = new KviTipWindow();
+ if (!szTipfilename.isEmpty()) g_pTipWindow->openConfig(szTipfilename);
+ g_pTipWindow->nextTip();
+ g_pTipWindow->show();
+ return true;
+}
+
+static bool tip_module_init(KviModule *m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",tip_kvs_cmd_open);
+ return true;
+}
+
+static bool tip_module_cleanup(KviModule *m)
+{
+ if(g_pTipWindow)g_pTipWindow->close();
+ return true;
+}
+
+static bool tip_module_can_unload(KviModule *m)
+{
+ return (g_pTipWindow == 0);
+}
+
+KVIRC_MODULE(
+ "Tip", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "\"Did you know...\" tip",
+ tip_module_init,
+ tip_module_can_unload,
+ 0,
+ tip_module_cleanup
+)
+
+#include "libkvitip.moc"
diff --git a/src/modules/tip/libkvitip.h b/src/modules/tip/libkvitip.h
new file mode 100644
index 00000000..1387f8df
--- /dev/null
+++ b/src/modules/tip/libkvitip.h
@@ -0,0 +1,71 @@
+#ifndef _LIBKVITIP_H_
+#define _LIBKVITIP_H_
+
+//
+// File : kvi_tip.cpp
+// Creation date : Thu May 10 2001 13:49:12 CEST 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 <qwidget.h>
+#include <qframe.h>
+#include <qpixmap.h>
+#include <qcheckbox.h>
+
+#include "kvi_styled_controls.h"
+#include "kvi_string.h"
+#include "kvi_config.h"
+
+class KviTipFrame : public QFrame
+{
+ Q_OBJECT
+public:
+ KviTipFrame(QWidget * par);
+ ~KviTipFrame();
+protected:
+ QString m_szText;
+ QPixmap * m_pTipPixmap;
+protected:
+ virtual void drawContents(QPainter *p);
+public:
+ void setText(const QString &text);
+};
+
+class KviTipWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ KviTipWindow();
+ ~KviTipWindow();
+protected:
+ KviTipFrame * m_pTipFrame;
+ KviStyledCheckBox * m_pShowAtStartupCheck;
+ KviConfig * m_pConfig;
+ KviStr m_szConfigFileName; // no path!
+protected:
+ virtual void showEvent(QShowEvent *e);
+ virtual void closeEvent(QCloseEvent *e);
+public:
+ bool openConfig(const char * filename,bool bEnsureExists = true);
+ void closeConfig();
+public slots:
+ void nextTip();
+};
+
+#endif //_LIBKVITIP_H_
diff --git a/src/modules/tip/libkvitip.kvc b/src/modules/tip/libkvitip.kvc
new file mode 100644
index 00000000..94db1571
--- /dev/null
+++ b/src/modules/tip/libkvitip.kvc
@@ -0,0 +1,28 @@
+[KVIrc]
+uNextTip=0
+uNumTips=25
+TranslatorHint=This-file-MUST-be-encoded-in-UTF8
+0=You can open connections to multiple servers in a single KVIrc window, just select "New IRC Context" from the KVIrc menu.<br>The original style of devoting a KVIrc frame window to each connection is still supported, just select "New Frame Window" from the same menu.
+1=IPv6 is now fully supported, even for DCC transfers.<br><b>/server -i &lt;servername&gt;</b> is the command. :)
+2=KVIrc supports SSL encryption.<br>SSL encrypted IRC connections can be established by using <b>/server -s</b>, and DCC connections by using <b>/dcc.chat -s</b><br>It also works over IPv6.
+3=An <b>IRC context</b> is a set of resources dealing with a single server connection. It has an associated <b>Console</b> window that displays system and server messages.
+4=KVIrc is a highly modular application. Modules are loaded and unloaded transparently to the user (and even to the scripter!). You can also write your own modules that extend the scripting language, or add other features.
+5=The <b>gnutella</b> module has been removed from the KVIrc source tree, and is now shipped as a separate package.
+6=KVIrc supports multiple handler scripts for a single event. This allows multiple scripts to be installed at the same time, avoids handler collisions and helps in adding/removing and activating/deactivating script sections.
+7=KVIrc supports the <b>irc://</b> Uniform Resource Locator (URL). Run the command: <br><b>kvirc irc://irc.yourserver.org:6667/channel</b><br> to connect to that server.<br>The general syntax is:<br><b>irc[6]://&lt;server-name&gt;[:&lt;port&gt;][/[&lt;channel&gt;[?&lt;pass&gt;]]]</b>
+8=The KVIrc executable acts like the "netscape -remote" command, if an instance of KVIrc is already running, the command line parameters are passed to that instance via IPC. You can override this behaviour with the <b>-f</b> switch.
+9=KVIrc can be your browser's handler for <b>irc://</b> URLs. If KVIrc has KDE support, you should be able to run it by simply typing an <b>irc://</b> URL into Konqueror's Location bar.<br>Try <b>irc://irc.freenode.net/kvirc</b> :)
+10=URLs can also be made for IPv6 IRC servers, the following syntax applies in this case:<br><b>irc6://&lt;ipv6-server-name&gt;[:&lt;port&gt;][/[&lt;channel&gt;[?&lt;pass&gt;]]]</b>
+11=You can switch between windows pressing <b>Ctrl+Left/Right</b>. <b>Alt+Left/Right</b> cycles only between windows in the current context.
+12=A quick method for connecting to a server in a new IRC context is <b>/server -n &lt;servername&gt;</b>
+13=KVIrc is portable between Windows and various flavours of Unix machines. If you're a good scripter, your scripts will be portable too!
+14=Want to automatically join a channel on connect?<br>Easy!<br>Just click "Advanced" in the server settings and add the channel in the "Join Channels" tab. For something that works for all servers, try <b>/event(OnIrc,autojoin){ join #yourchannel; }</b>
+15=Do you know what an avatar is? Check out <b>/help avatar</b>
+16=The DCC settings page has a lot of options that can help you solve many common DCC connection problems. People behind firewalls might be able to send data, too. It's just a matter of setting things up. :)
+17=There is a separate OpenNap compatibility module (<b>opennap</b>) that enables OpenNap-based chatting with KVIrc.
+18=KVIrc supports many 8-bit character encodings. You can "speak" KOI8-R based Russian on one channel and Japanese on another over the same connection (with appropriate fonts). We strongly encourage you to use <b>Unicode</b> (UTF-8), which supports almost every language in the world.
+19=To avoid excessive DCC transfers, it is recommended that you make your avatars available on the Web. You can also use any existing image on the Web as an avatar.<br><b>/avatar #yourchan http://funnyhost.com/funny/funny.png</b> will work!
+20=KVIrc has a built-in HTTP client, and you can download files from the Web by using the <b>/http.get</b> command.
+21=Don't like the window tree taskbar mode? You can opt for a traditional taskbar (similar to mIRC) in the taskbar settings page under the preferences.
+22=You can copy text from the text window to the clipboard by simply selecting it with the mouse. If you also keep Shift pressed then the color codes will be copied as well.
+23=This is the last tip. You can add your own tips - Check out <b>/help tip.open</b>. Feel free to submit more tips (in any language) to <b>trisk-kvirc(at)quasarnet.org</b>.
diff --git a/src/modules/tip/libkvitip_cs.kvc b/src/modules/tip/libkvitip_cs.kvc
new file mode 100644
index 00000000..ab169fe7
--- /dev/null
+++ b/src/modules/tip/libkvitip_cs.kvc
@@ -0,0 +1,29 @@
+[KVIrc]
+uNextTip=0
+uNumTips=25
+Encoding=UTF8
+0=Můžete otevřít více spojení s více servery v jednom KVIrc okně, jen vyberte "Nový IRC Kontext" v KVIrc menu.<br>Původní styl vnořeného okna KVIrcu pro každé spojení je stále podporován, stačí vybrat "Nové okno s rámcem" ze stejné nabídky.
+1=IPv6 je nyní plně podporováno, dokonce pro DCC přenosy.<br><b>/server -i &lt;název_serveru&gt;</b> je příkaz. :)
+2=KVIrc podporuje Šifrování SSL.<br>IRC spojení šifrovaná pomocí SSL mohou být navázána příkazem <b>/server -s</b>, a DCC spojení použitím <b>/dcc.chat -s</b><br>Funguje také na IPv6.
+3=<b>IRC context</b> je soubor zdrojů patřících k jednomu spojení se serverem. Má přiřazené okno <b>Console</b> které ukazuje systémové zprávy a zprávy serveru.
+4=KVIrc je vysoce modulární aplikace. Moduly jsou načítány a vypínány transparentně pro uživatele (i pro skriptora!). Můžete také napsat vlastní moduly pro rozšíření skriptovacího jazyka, nebo rozšíření funkcí KVIrc.
+5=Modul <b>gnutella</b> byl odstraněn ze zdrojového stromu KVIrc a je dodáván jako samostatný balíček.
+6=KVIrc Podporuje několikanásobné zpracování skriptů pro jednu událost. To dovoluje mít nainstalováno více skriptů současně, aniž by spolu kolidovaly a usnadnuje přidávání/odebírání a aktivaci/deaktivaci částí skriptu.
+7=KVIrc podporuje <b>irc://</b> Uniform Resource Locator (URL). Spusťte příkaz: <br><b>kvirc irc://irc.vášserver.org:6667/kanál</b><br> pro připojení k tomuto serveru.<br>Obecná syntaxe je:<br><b>irc[6]://&lt;jméno-serveru&gt;[:&lt;port&gt;][/[&lt;kanál&gt;[?&lt;heslo&gt;]]]</b>
+8=Spuštěný soubor KVIrcu pracuje jako příkaz "netscape -remote", pokud již KVIrc běží, parametry příkazového řádku jsou předány běžícímu KVIrcu přes IPC. Můžete obejít toto chování použitím parametru <b>-f</b>.
+9=KVIrc může zpracovávat URL <b>irc://</b> z Vašeho prohlížeče. Pokud má KVIrc podporu KDE, můžete jo spustit pouhým zadáním <b>irc://</b> URL do adresního řádku Konqueroru.<br>Zkuste <b>irc://irc.freenode.net/kvirc</b> :)
+10=URL mohou být také použita pro IPv6 IRC servery, v tom připadě je syntaxe:<br><b>irc6://&lt;název-ipv6-serveru&gt;[:&lt;port&gt;][/[&lt;kanál&gt;[?&lt;heslo&gt;]]]</b>
+11=Můžete přepínat mezi okny stiskem <b>Ctrl+Vlevo/Vpravo</b>. <b>Alt+Vlevo/Vpravo</b> přepíná pouze mezi okny v aktuálním kontextu.
+12=Rychlý způsob pro připojení k serveru v novém IRC kontextu je <b>/server -n &lt;název-serveru&gt;</b>
+13=KVIrc je přenositelný mezi Windows a různými Unixovými stroji. Pokud jste dobrý skriptor, Vaše skripty budou přenositelné také!
+14=Chcete automaticky vstoupit do kanálu při připojení?<br>Snadné!<br>Stačí kliknout na "Pokročilé" v nastavení serveru a přidat kanál do "Příchod do kanálů". Pro něco co funguje na všech serverech, zkuste <b>/event(OnIrc,autojoin){ join #váškanál; }</b>
+15=Víte co je Avatar? Mrkněte na <b>/help avatar</b>
+16=Nastavení DCC má mnoho možností, které Vám pomohou vyřešit mnoho běžných problémů s DCC spojením. Lidé za firewallem mohou také posílat data. Je to jen otázka správného nastavení. :)
+17=K dispozici je samostatný OpenNap modul (<b>opennap</b>), který umožnuje chat založený na OpenNap s KVIrc.
+18=KVIrc podporuje mnoho 8-bitových znakových sad. Můžete "mluvit" KOI8-R Ruštinou na jednom kanále a Japonsky na jiném při stejném spojení (s příslušnými fonty). Doporučujeme použít <b>Unicode</b> (UTF-8), který podporuje téměř každý světový jazyk.
+19=Abyste předešli mnohým DCC přenosům, doporučuje se dát si Avatar online na Web. Můžete také použít libovolný existující obrázek na webu jako Avatar.<br><b>/avatar #váškanál http://funnyhost.com/funny/funny.png</b> funguje!
+20=KVIrc má vestavěný HTTP klient, takže můžete stahovat soubory z Webu pomocí příkazu <b>/http.get</b>.
+21=Nelíbí se vám taskbar ve stromu? Můžete si nastavit tradiční taskbar (podobný mIRC) v Nastavení taskbaru.
+22=Můžete kopírovat text z okna do schránky pouhým označením myší. Pokud podržíte Shift, budou zkopírovány i barevné kódy.
+23=Můžete zkopírovat text kanálu nebo query jen jeho pouhým vybráním. Pokud podržíte Shift, tak se zkopírují i barvy.
+24=Toto je poslední tip. Můžete přidat vlastní tipy - Mrkněte na <b>/help tip.open</b>. Klidně pošlete více tipů (v libovolném jazyce) na <b>trisk-kvirc(at)quasarnet.org</b>.
diff --git a/src/modules/tip/libkvitip_it.kvc b/src/modules/tip/libkvitip_it.kvc
new file mode 100644
index 00000000..edabad68
--- /dev/null
+++ b/src/modules/tip/libkvitip_it.kvc
@@ -0,0 +1,28 @@
+[KVIrc]
+uNextTip=0
+uNumTips=25
+TranslatorHint=This-file-MUST-be-encoded-in-UTF8
+0=Puoi aprire connessioni verso server multipli: scegli "Nuovo IRC Context" dal menu KVIrc.<br>Il vecchio metodo di una finestra per connessione ovviamente ancora supportato: scegli "Nuova finestra" dallo stesso menù
+1=IPv6 ora è supportato completamente, anche per le connessioni DCC.<br>Il comando è <b>/server -i &lt;nomeserver&gt;</b> :)
+2=KVIrc supporta crittazione SSL.<br>Le connessioni IRC crittate con SSL possono essere stabilite usando <b>/server -s</b>, e connessioni DCC usando <b>/dcc.chat -s</b><br>Funziona anche usando IPv6.
+3=Un <b>contesto IRC</b> è un set di risorse che dialogano con una singola connessione server. Ha associato una finestra <b>Console</b> che mostra i messaggi di sistema e del server.
+4=KVIrc è un'applicazione altamente modulare. I moduli sono caricati e scaricati trasparentemente all'utente (ed anche allo scripter!). Puoi anche scrivere i tuoi moduli personali che estendono il linguaggio di scripting o aggiungono altre funzionalità.
+5=Il modulo <b>gnutella</b> è stato rimosso dai sorgenti di KVIrc ed è ora distribuito in un pacchetto separato.
+6=KVIrc supporta diversi gestori per lo stesso evento. Questo permette di avere diversi script installati allo stesso momento, evitare collisioni tra gestori ed aiutare ad aggiungere/rimuovere e attivare/disattivare gli script.
+7=KVIrc supporta gli URL (Uniform Resource Locator) <b>irc://</b>. Lancia il comando:<br><b>kvirc irc://irc.tuoserver.org:6667/canale</b><br> per connettere a quel server.<br>La sintassi generale è:<br><b>irc[6]://&lt;nome-server&gt;[:&lt;porta&gt;][/[&lt;canale&gt;[?&lt;password&gt;]]]</b>
+8=L'eseguibile KVIrc agisce come il comando "netscape -remote", se c'è già un'istanza di KVIrc avviata, i parametri a linea di comando saranno passato a quell'istanza usando IPC. Puoi sovrascrivere questo comportamento con l'opzione <b>-f</b>.
+9=KVIrc può essere il tuo gestore del browser per gli URL <b>irc://</b>. Se KVIrc ha il supporto KDE, dovresti poterlo lanciare semplicemente scrivendo un URL <b>irc://</b> nella barra degli URL di Konqueror.<br>Prova <b>irc://irc.freenode.net/kvirc</b> :)
+10=Gli URL possono anche essere fatti da server IRC IPv6, la sintassi seguente funzionerà in questo caso:<br><b>irc6://&lt;nome-server-ipv6&gt;[:&lt;porta&gt;][/[&lt;canale&gt;[?&lt;password&gt;]]]</b>
+11=Puoi navigare tra le finestre premendo <b>Ctrl+Sinistra/Destra</b>. <b>Alt+Sinistra/Destra</b> cambia solo finestra nel contesto corrente.
+12=Un metodo veloce per connettere a un server in un nuovo contesto IRC è <b>/server -n &lt;nomeserver&gt;</b>
+13=KVIrc è portabile tra diverse macchine UNIX (compreso Mac) e Windows. Se sei un bravo scripter, anche i tuoi script saranno portabili!
+14=Vuoi entrare in un canale automaticamente alla connessione?<br>Facile!<br>Clicca su "Avanzate" nella configurazione del server e aggiungi il canale nella scheda "Entra nei Canali". Per qualcosa che funzioni per ogni server, prova <b>/event(OnIrc,autojoin){ join #tuocanale; }</b>
+15=Sai cos'è un avatar? Prova <b>/help avatar</b>
+16=La pagina di configurazione delle DCC ha un sacco di opzioni che possono aiutarti a risolvere i problemi di connessione più comuni. Le persone dietro un firewall potrebbero anche volere inviare dei dati. E' giusto una questione di configurazione :)
+17=C'è un modulo separato per la compatibilità con OpenNAP (<b>opennap</b>) che abiita le chat basate su OpenNAP con KVIrc.
+18=KVIrc supporta diverse codifiche a 8-bit. Puoi "parlare" russo KOI8-R su un canale e giapponese in un altro con la stessa connessione (e dei font appropriati). Noi incoraggiamo fortemente l'uso di <b>Unicode</b> (UTF-8), che supporta quasi tutte le lingue del mondo.
+19=Per evitare trasferimenti DCC eccessivi, è raccomandato che metti il tuo avatar sul Web. Puoi anche usare una qualsiasi immagine sul Web come avatar.<br><b>/avatar #tuocanale http://sito.com/immagini/immagine.png</b> funzionerà!
+20=KVIrc ha un client HTTP integrato, e puoi scaricare file dal Web usando il comando <b>/http.get</b>.
+21=Non ti piacciono le finestre disposte ad albero? Puoi optare per una visualizzazione tradizionale (simile a mIRC) nella pagina di configurazione delle finestre nelle preferenze.
+22=Puoi copiare il testo dalla finestra di chat agli appunti semplicemente selezionandolo col mouse. Se tieni anche premuto lo Shift verranno copiati anche i codici colore.
+23=Questo è l'ultimo suggerimento. Puoi aggiungere i tuoi suggerimenti personali - Prova <b>/help tip.open</b>. Sentiti libero di mandare nuovi suggerimenti (in qualsiasi lingua) a <b>trisk-kvirc(at)quasarnet.org</b>.
diff --git a/src/modules/tip/libkvitip_ru.kvc b/src/modules/tip/libkvitip_ru.kvc
new file mode 100644
index 00000000..a9f982f6
--- /dev/null
+++ b/src/modules/tip/libkvitip_ru.kvc
@@ -0,0 +1,29 @@
+[KVIrc]
+uNextTip=0
+uNumTips=25
+TranslatorHint=This-file-MUST-be-encoded-in-UTF8
+0=Вы можете скопировать текст из окна в буфер обмена просто выделив его мышью. Если удерживать нажатым Shift, то коды цветов также будут скопированы.
+1=Если вы хотите использовать озвучивание событий в KVIrc, откройте редактор событий, добавьте на нужные события обработчики и впишите в них <b>snd.play /путь/к/звуковому/файлу</b>. также для некоторых событий вы можете просто установить звук, указав звуковой файл в диалоге опций, на странице Общие настройки->Звуки.
+2=IPv6 теперь полностью поддерживается, даже для DCC передач.<br><b>/server -i &lt;servername&gt;</b> команда. :)
+3=KVIrc поддерживает SSL шифрование.<br>SSL шифрованные IRC соединения можно установить, используя <b>/server -s</b>, и DCC соединения используя <b>/dcc.chat -s</b><br>Это также работает через IPv6.
+4=<b>IRC контекст</b> это ресурсы, которые относятся только к одному соединению с сервером. У него есть связанное окно <b>Консоль</b>, которое отображает сообщения системы и сервера.
+5=KVIrc является полностью модульным приложением. Модули загружаются и выгружаются прозрачно для пользователя (даже в скриптах!). Вы можете также писать свои собственные модули, которые расширяют скриптовый язык или добавляют новые возможности.
+6=KVIrc поддерживает пространства имен (namespaces), которые позволяют скриптерам не забититься о том, что имена созданных ими команд будут конфликтовать со скриптами других авторов.
+7=KVIrc поддерживает множественные обработчики для каждого события. Это позволяет использовать множество сценариев установленных в одно и то же время, исключает конфликты обработчиков, и помогает удалять/добавлять и включать/выключать секции сценариев.
+8=KVIrc поддерживает <b>irc://</b> Uniform Resource Locator (URL). Выполните команду: <br><b>kvirc irc://irc.yourserver.org:6667/channel</b><br> для подключения к серверу. Общий синтаксис:<br><b>irc[6]://&lt;имя.сервера&gt;[:&lt;порт&gt;][/[&lt;канал&gt;[?&lt;пароль&gt;]]]</b>
+9=Запуск KVIrc действует подобно команде <br>"netscape -remote", если KVIrc уже запущен параметры командной строки передаются в запущеное приложение через IPC. Вы можете отменить это используя ключ <b>-f</b>.
+10=KVIrc может быть вашим обработчиком протокола <b>irc://</b> в КДЕ. Если KVIrc собран с поддержкой KDE, вы можете запустить его просто набрав <b>irc://</b> URL в строке адреса Конкверора.<br>Например <b>irc://irc.freenode.net/kvirc</b> :)
+11=URL-ы могут быть оформлены и для IPv6 IRC серверов с помощью следующего синтаксиса:<br><b>irc6://&lt;ipv6-сервер&gt;[:&lt;порт&gt;][/[&lt;канал&gt;[?&lt;пароль&gt;]]]</b>
+12=Вы можете переключаться между окнами с помощью <b>Ctrl+Left/Right</b>. <b>Alt+Left/Right</b> - по циклу только между окнами текущего контекста.
+13=Быстрый способ для подключения к серверу в новом контексте IRC <b>/server -n &lt;имясервера&gt;</b>
+14=KVIrc является мультиплатформеннм приложением - существуют сборки под Unix, Windows и Mac. Если вы будете правильно писать сценарии, то они тоже будут портируемы!
+15=Хотите автоматически входить на канал при коннекте? Нет ничего проще!<br>Кликните на кнопке "Дополнительно" в настройках сервера и добавьте канал к списку на вкладке "Входить на каналы"
+16=Вы не знаете как пользоваться аватаром? Наберите <b>/help avatar</b>
+17=Секция настроек DCC имеет множество опций, которые помогут вам решить разные проблемы, возникающие при использовании DCC соединений. Даже если вы находитесь за фаерволом, то тоже сможете передавать данные. Всё дело в правильных настройках. :)
+18=KVIrc поддерживает множество 8-битных кодировок. Вы можете на одном канале "разговаривать" по русски в KOI8-R, а на другом по японски (если у вас имеются соответствующие шрифты ). Мы очень рекомендуем вам использовать <b>Unicode</b> (UTF-8), который поддерживает практически все языки мира.
+19=Чтобы избежать дополнительного траффика DCC, мы рекомендуем использовать аватары, находящиеся в интернете.<br><b>/avatar #yourchan http://funnyhost.com/funny/funny.png</b> будет работать!
+20=KVIrc имеет встроенный клиент HTTP, и вы можете загрузить файлы из интернета используя команду <b>/http.get</b>.
+21=Вам не нравится окно с деревом панели задач? Вы можете выбрать традиционную панель задач (такую же как в mIRC) в секции настроек панели задач.
+22=Вы можете открыть соединения для многих серверов в одном окне KVIrc, просто выберите "Новый IRC контекст" в меню KVIrc.
+23=KVIrc имеет встроенный гибкий механизм идентификации на NickServ. Если вы заинтересованы в его использовании, но не можете настроить самостоятельно, советуем прочитать инструкции на сайте http://www.kvirc.ru в разделе статьи.
+24=Это последний совет. Вы можете добавлять свои собственные советы - наберите <b>/help tip.open</b>. Вы можете отослать свои советы (на любом языке) по адресу <b>alexey@kvirc.ru</b>.
diff --git a/src/modules/tmphighlight/Makefile.am b/src/modules/tmphighlight/Makefile.am
new file mode 100644
index 00000000..6e5a02ac
--- /dev/null
+++ b/src/modules/tmphighlight/Makefile.am
@@ -0,0 +1,22 @@
+###############################################################################
+# KVirc IRC client Makestr - 10.03.2002 Juanjo lvarez <juanjux@yahoo.es>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+-I/usr/include/kde/arts\
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+#ARTS_LD_FLAGS = -DPIC -fPIC
+#ARTS_C_FLAGS = -L/usr/lib -ldl -lartsc -lpthread
+pluglib_LTLIBRARIES = libkvitmphighlight.la
+
+libkvitmphighlight_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvitmphighlight_la_SOURCES = libkvitmphighlight.cpp
+libkvitmphighlight_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+
+#noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/tmphighlight/libkvitmphighlight.cpp b/src/modules/tmphighlight/libkvitmphighlight.cpp
new file mode 100644
index 00000000..17f4ce17
--- /dev/null
+++ b/src/modules/tmphighlight/libkvitmphighlight.cpp
@@ -0,0 +1,174 @@
+// File : libkvitmphighlight.cpp
+// Creation date : Oct 10 01:06:09 CEST 2002 by Juanjo �varez
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Juanjo �varez (juanjux@yahoo.es)
+// Copyright (C) 2002 Szymon Stefanek (kvirc@tin.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 "kvi_module.h"
+
+#include "kvi_locale.h"
+#include "kvi_channel.h"
+
+//-------------------------------------------------
+/*
+ @doc: tmphighlight.add
+ @type:
+ command
+ @title:
+ tmphighlight.add
+ @short:
+ Adds a user to the channel temporary highlight list
+ @syntax:
+ tmphighlight.add <nick:string>
+ @description:
+ This command adds a user to the channel temporary highlight list, so that user messages[br]
+ will be highlighted until you close the channel. This is useful when you are in a very crowded [br]
+ channel with lots of conversations running in parallel and you want to follow one of them.[br]
+ @seealso:
+ [fnc]$tmphighlight.remove[/fnc]
+ [fnc]$tmphighlight.ishighlighted[/fnc]
+*/
+//-------------------------------------------
+// tmphighlight.add
+//-------------------------------------------
+static bool tmphighlight_kvs_cmd_add(KviKvsModuleCommandCall * c)
+{
+
+ QString szNick;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("nick",KVS_PT_NONEMPTYSTRING,0,szNick)
+ KVSM_PARAMETERS_END(c)
+ if( ( !c->window()->console()) || c->window()->console()->isNotConnected() )return c->context()->errorNoIrcContext();
+ if(!c->window()->type() == KVI_WINDOW_TYPE_CHANNEL)
+ {
+ c->warning(__tr2qs("Current window is not a channel"));
+ return false;
+ }
+
+ ((KviChannel *)c->window())->addHighlightedUser(szNick);
+
+ return true;
+}
+//-------------------------------------------------
+/*
+ @doc: tmphighlight.remove
+ @type:
+ command
+ @title:
+ tmphighlight.remove
+ @short:
+ Remove a user from the channel temporary highlight list
+ @syntax:
+ tmphighlight.remove <nick:string>
+ @description:
+ This command remove a user from the channel temporary highlight list, so that user messages[br]
+ stop being highlighted.
+ @seealso:
+ [fnc]$tmphighlight.add[/fnc]
+ [fnc]$tmphighlight.ishighlighted[/fnc]
+*/
+//-------------------------------------------
+// tmphighlight.remove
+//-------------------------------------------
+
+static bool tmphighlight_kvs_cmd_remove(KviKvsModuleCommandCall * c)
+{
+ QString szNick;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("nick",KVS_PT_NONEMPTYSTRING,0,szNick)
+ KVSM_PARAMETERS_END(c)
+ if( ( !c->window()->console()) || c->window()->console()->isNotConnected() )return c->context()->errorNoIrcContext();
+ if(!c->window()->type() == KVI_WINDOW_TYPE_CHANNEL)
+ {
+ c->warning(__tr2qs("Current window is not a channel"));
+ return false;
+ }
+
+ ((KviChannel *)c->window())->removeHighlightedUser(szNick);
+ return true;
+}
+//-------------------------------------------------
+/*
+ @doc: tmphighlight.ishighlighted
+ @type:
+ function
+ @title:
+ $tmphighlight.ishighlighted
+ @short:
+ Returns 1 if the user is highlighted on this channel, 0 otherwise
+ @syntax:
+ <boolean> $tmphighlight.ishighlighted <nick:string>
+ @description:
+ This command returns 1 if the user is highlighted on this channel and on this session of 0 otherwise.
+ @seealso:
+ [fnc]$tmphighlight.add[/fnc]
+ [fnc]$tmphighlight.remove[/fnc]
+
+*/
+//-------------------------------------------
+// tmphighlight.ishighlighted
+//-------------------------------------------
+
+static bool tmphighlight_kvs_fnc_ishighlighted(KviKvsModuleFunctionCall * c)
+{
+ QString szNick;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("nick",KVS_PT_NONEMPTYSTRING,0,szNick)
+ KVSM_PARAMETERS_END(c)
+ if( ( !c->window()->console()) || c->window()->console()->isNotConnected() )return c->context()->errorNoIrcContext();
+ if(!c->window()->type() == KVI_WINDOW_TYPE_CHANNEL)
+ {
+ c->warning(__tr2qs("Current window is not a channel"));
+ return false;
+ }
+ c->returnValue()->setBoolean(((KviChannel *)c->window())->isHighlightedUser(szNick));
+ return true;
+}
+
+//-------------------------------------------------
+static bool tmphighlight_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"add",tmphighlight_kvs_cmd_add);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"remove",tmphighlight_kvs_cmd_remove);
+ KVSM_REGISTER_FUNCTION(m,"isHighVisible",tmphighlight_kvs_fnc_ishighlighted);
+ KVSM_REGISTER_FUNCTION(m,"isHighLighted",tmphighlight_kvs_fnc_ishighlighted);
+ return true;
+}
+//-------------------------------------------------
+static bool tmphighlight_module_cleanup(KviModule *m)
+{
+ return true;
+}
+//-------------------------------------------------
+static bool tmphighlight_module_can_unload(KviModule *m)
+{
+ return true;
+}
+//-------------------------------------------------
+KVIRC_MODULE(
+ "TmpHighlight", // module name
+ "1.0.0", // module version
+ " (C) 2002 Juanjo Alvarez (juanjux@yahoo.es)", // author & (C)
+ "Temporal Highlightining of channel users",
+ tmphighlight_module_init,
+ tmphighlight_module_can_unload,
+ 0,
+ tmphighlight_module_cleanup
+)
diff --git a/src/modules/toolbar/Makefile.am b/src/modules/toolbar/Makefile.am
new file mode 100644
index 00000000..e009e306
--- /dev/null
+++ b/src/modules/toolbar/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Maketoolbar - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvitoolbar.la
+
+libkvitoolbar_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvitoolbar_la_SOURCES = libkvitoolbar.cpp
+libkvitoolbar_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+# noinst_HEADERS=
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/toolbar/libkvitoolbar.cpp b/src/modules/toolbar/libkvitoolbar.cpp
new file mode 100644
index 00000000..a72949ca
--- /dev/null
+++ b/src/modules/toolbar/libkvitoolbar.cpp
@@ -0,0 +1,602 @@
+//=============================================================================//
+//
+// File : libkvitoolbar.cpp
+// Creation date : Wed 6 Nov 22:51:59 2002 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2002-2004 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_module.h"
+
+#include "kvi_locale.h"
+
+#include "kvi_window.h"
+#include "kvi_app.h"
+#include "kvi_error.h"
+#include "kvi_cmdformatter.h"
+#include "kvi_customtoolbar.h"
+#include "kvi_customtoolbardescriptor.h"
+#include "kvi_customtoolbarmanager.h"
+#include "kvi_actionmanager.h"
+#include "kvi_kvs_useraction.h"
+
+/*
+ @doc: toolbar.create
+ @type:
+ command
+ @title:
+ toolbar.create
+ @keyterms:
+ Creating toolbars
+ @short:
+ Creates a toolbar
+ @syntax:
+ toolbar.create [-p] <id:string> <label:string> [icon_id:string]
+ @switches:
+ !sw: -p | --preserve
+ Preserve the existing toolbar, if any
+ @description:
+ Creates a toolbar with the specified <id> and with the visible <label> (caption).[br]
+ If a toolbar with the same <id> already exists then this command is equivalent to the
+ sequence of [cmd]toolbar.hide[/cmd], [cmd]toolbar.clear[/cmd] and [cmd]toolbar.setlabel[/cmd] unless the -p
+ switch is specified that causes the [cmd]toolbar.clear[/cmd] call to be skipped (contents preserved).[br]
+ This command doesn't show the toolbar (you need to use [cmd]toolbar.show[/cmd]).[br]
+ Toolbars are saved and preserved across KVIrc sessions thus you don't need to create them
+ on application startup: you only create them once.
+ If [icon_id] is specified then it is interpreted as an [doc:image_id]image identifier[/doc]
+ for the small (16x16) icon that will be put in the toolbar listing popup menu.
+ The toolbar will exist until [cmd]toolbar.destroy[/cmd] is called (you might want to add
+ an "uninstall" feature to your script).[br]
+ @seealso:
+ [fnc]$toolbar.exists[/fnc],
+ [cmd]toolbar.remove[/cmd],
+ [cmd]toolbar.show[/cmd],
+ [cmd]toolbar.destroy[/cmd]
+*/
+
+static bool toolbar_kvs_cmd_create(KviKvsModuleCommandCall * c)
+{
+ QString szId,szLabel,szIconId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETER("label",KVS_PT_STRING,KVS_PF_OPTIONAL,szLabel)
+ KVSM_PARAMETER("icon_id",KVS_PT_NONEMPTYSTRING,KVS_PF_OPTIONAL,szIconId)
+ KVSM_PARAMETERS_END(c)
+
+/* if(!c->getParameterCode(1,szLabel))
+ {
+ c->error(__tr2qs("Internal error: call a head-shrinker"));
+ return false;
+ }
+*/
+ if(szLabel.isEmpty())szLabel = "$tr(Unnamed)";
+
+ KviCustomToolBarDescriptor * d = KviCustomToolBarManager::instance()->find(szId);
+ if(d)
+ {
+ if(!c->switches()->find('p',"preserve"))d->clear();
+ d->rename(szLabel);
+ } else {
+ d = KviCustomToolBarManager::instance()->create(szId,szLabel);
+ }
+
+ if(!szIconId.isEmpty())
+ d->setIconId(szIconId);
+
+ return true;
+}
+
+/*
+ @doc: toolbar.clear
+ @type:
+ command
+ @title:
+ toolbar.clear
+ @short:
+ Clears a toolbar
+ @syntax:
+ toolbar.clear [-q] <id:string>
+ @switches:
+ !sw: -q | --quiet
+ Run quietly
+ @description:
+ Clears the contents of the toolbar specified by <id>. If the
+ toolbar does not exist then a warning is printed unless the -q switch is used.[br]
+ @seealso:
+ [fnc]$toolbar.exists[/fnc],
+ [cmd]toolbar.remove[/cmd],
+ [cmd]toolbar.show[/cmd],
+ [cmd]toolbar.destroy[/cmd]
+*/
+
+static bool toolbar_kvs_cmd_clear(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviCustomToolBarDescriptor * d = KviCustomToolBarManager::instance()->find(szId);
+ if(d)d->clear();
+ else {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The specified toolbar doesn't exist"));
+ }
+
+ return true;
+}
+
+
+/*
+ @doc: toolbar.destroy
+ @type:
+ command
+ @title:
+ toolbar.destroy
+ @keyterms:
+ Destroying a toolbar
+ @short:
+ Destroys a toolbar
+ @syntax:
+ toolbar.destroy [-q] <id:string>
+ @switches:
+ !sw: -q | --quiet
+ Run quietly
+ @description:
+ Destroys the toolbar with the specified <id>.[br]
+ The toolbar definition is definitively destroyed with all the items contained.[br]
+ If the -q switch is specified then this command runs in quiet mode and
+ does not warn if the toolbar was not existing.
+ @seealso:
+ [fnc]$toolbar.exists[/fnc],
+ [cmd]toolbar.create[/cmd]
+*/
+
+
+static bool toolbar_kvs_cmd_destroy(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ if(!KviCustomToolBarManager::instance()->destroyDescriptor(szId))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The specified toolbar doesn't exist"));
+ }
+
+ return true;
+}
+
+
+/*
+ @doc: toolbar.show
+ @type:
+ command
+ @title:
+ toolbar.show
+ @short:
+ Shows a toolbar
+ @syntax:
+ toolbar.show [-q] <id:string>
+ @switches:
+ !sw: -q | --quiet
+ Run quietly
+ @description:
+ Shows the toolbar with the specified <id>.[br]
+ If -q is specified the command runs in quiet mode and does not complain if the
+ specified toolbar doesn't exist.[br]
+ Please note that you don't need to show the toolbar at application startup: KVIrc will
+ take care of this for you (if the user chooses to keep the toolbar visible).[br]
+ You should execute this command only if you create the toolbar after KVIrc has been
+ started.[br]
+ @seealso:
+ [fnc]$toolbar.exists[/fnc],
+ [cmd]toolbar.create[/cmd]
+*/
+
+static bool toolbar_kvs_cmd_show(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviCustomToolBarDescriptor * d = KviCustomToolBarManager::instance()->find(szId);
+
+ if(!d)
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The specified toolbar doesn't exist"));
+ return true;
+ }
+
+ if(!d->toolBar())
+ d->createToolBar();
+
+ return true;
+}
+
+/*
+ @doc: toolbar.hide
+ @type:
+ command
+ @title:
+ toolbar.hide
+ @short:
+ Hides a toolbar
+ @syntax:
+ toolbar.hide [-q] <id:string>
+ @switches:
+ !sw: -q | --quiet
+ Run quietly
+ @description:
+ Hides the toolbar with the specified <id>.[br]
+ If -q is specified the command runs in quiet mode and does not complain if the
+ specified toolbar doesn't exist.[br]
+ Please note that this command doesn't destroy the toolbar definition: the toolbar
+ can be shown again by using [cmd]toolbar.show[/cmd].[br]
+ If you want to completely remove the toolbar definition use [cmd]toolbar.destroy[/cmd].[br]
+ @seealso:
+ [fnc]$toolbar.exists[/fnc],
+ [cmd]toolbar.create[/cmd],
+ [cmd]toolbar.destroy[/cmd]
+*/
+
+
+static bool toolbar_kvs_cmd_hide(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviCustomToolBarDescriptor * d = KviCustomToolBarManager::instance()->find(szId);
+
+ if(!d)
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The specified toolbar doesn't exist"));
+ return true;
+ }
+
+ if(d->toolBar()) KviCustomToolBarManager::instance()->destroyDescriptor(d->id());
+
+ return true;
+}
+
+/*
+ @doc: toolbar.exists
+ @type:
+ function
+ @title:
+ $toolbar.exists
+ @short:
+ Checks if a toolbar exists
+ @syntax:
+ <boolean> $toolbar.exists(<id:string>)
+ @description:
+ Returns 1 if the toolbar with the specified <id> has been defined.[br]
+ Note that this doesn't mean that the toolbar is visible!
+ @seealso:
+ [cmd]toolbar.create[/cmd]
+*/
+
+
+static bool toolbar_kvs_fnc_exists(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ c->returnValue()->setBoolean(KviCustomToolBarManager::instance()->find(szId) ? true : false);
+ return true;
+}
+
+/*
+ @doc: toolbar.isVisible
+ @type:
+ function
+ @title:
+ $toolbar.isVisible
+ @short:
+ Checks if a toolbar is visible
+ @syntax:
+ <boolean> $toolbar.isVisible(<id:string>)
+ @description:
+ Returns 1 if the toolbar with the specified <id> is actually visible and 0 otherwise.[br]
+ If the toolbar is not defined at all this function still returns 0.[br]
+ @seealso:
+ [cmd]toolbar.show[/cmd]
+*/
+
+static bool toolbar_kvs_fnc_isVisible(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+ KviCustomToolBarDescriptor * d = KviCustomToolBarManager::instance()->find(szId);
+ c->returnValue()->setBoolean(d ? (d->toolBar() ? true : false) : false);
+ return true;
+}
+
+/*
+ @doc: toolbar.list
+ @type:
+ function
+ @title:
+ $toolbar.list
+ @short:
+ Returns a list of defined toolbars
+ @syntax:
+ <array> $toolbar.list()
+ @description:
+ Returns a list of defined toolbar identifiers.[br]
+ You can use this function to loop thru all the toolbar definitions.[br]
+ @seealso:
+*/
+
+static bool toolbar_kvs_fnc_list(KviKvsModuleFunctionCall * c)
+{
+ KviKvsArray * a = new KviKvsArray();
+
+ KviPointerHashTableIterator<QString,KviCustomToolBarDescriptor> it(*(KviCustomToolBarManager::instance()->descriptors()));
+
+ kvs_uint_t id = 0;
+
+ while(KviCustomToolBarDescriptor * d = it.current())
+ {
+ a->set(id,new KviKvsVariant(d->id()));
+ id++;
+ ++it;
+ }
+
+ c->returnValue()->setArray(a);
+ return true;
+}
+
+
+
+/*
+ @doc: toolbar.remove
+ @type:
+ command
+ @title:
+ toolbar.remove
+ @keyterms:
+ Removing toolbar items
+ @short:
+ Removes a toolbar item
+ @syntax:
+ toolbar.remove [-q] [-i] <toolbarid:string> <action:variant>
+ @switches:
+ !sw: -q | --quiet
+ Run quietly
+ !sw: -i | --index
+ Treat <action> as the zero-based index of the action to be removed
+ instead of the action name.
+ @description:
+ Removes the specified <action> from the toolbar with the specified <toolbarid>.[br]
+ If no such item exists in the specified toolbar this command does nothing.[br]
+ If the <toolbar> parameter doesn't identify an existing toolbar then
+ a warning is printed unless the -q switch is used.[br]
+ If the -i switch is specified the <action> is interpreted as zero based
+ index of the action to be removed (instead of the action name).[br]
+ Please note that this is an expensive operation if the toolbar is visible (basically
+ the toolbar needs to be cleared and filled back again). It is a good idea to hide
+ the toolbar before removing items.[br]
+ @seealso:
+*/
+
+static bool toolbar_kvs_cmd_removeitem(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ KviKvsVariant * pvAction;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETER("action",KVS_PT_VARIANT,0,pvAction)
+ KVSM_PARAMETERS_END(c)
+
+ KviCustomToolBarDescriptor * d = KviCustomToolBarManager::instance()->find(szId);
+
+ if(!pvAction)
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->error(__tr2qs("No action name/index specified")); // syntax error
+ return false;
+ }
+
+ if(!d)
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The specified toolbar doesn't exist"));
+ return true;
+ }
+
+ if(c->switches()->find('i',"index"))
+ {
+ kvs_int_t iAction;
+ if(!pvAction->asInteger(iAction))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The action parameter didn't evaluate to an index"));
+ } else {
+ if(!d->removeAction(iAction))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The toolbar does not contain the specified item"));
+ }
+ }
+ } else {
+ QString szAction;
+ pvAction->asString(szAction);
+ if(!d->removeAction(szAction))
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The toolbar does not contain the specified item"));
+ }
+ }
+
+ return true;
+}
+
+/*
+ @doc: toolbar.additem
+ @type:
+ command
+ @title:
+ toolbar.additem
+ @keyterms:
+ Adding toolbar items
+ @short:
+ Adds a new item to a toolbar
+ @syntax:
+ toolbar.additem [-q] <toolbarid:string> <action:string>
+ @switches:
+ !sw: -q | --quiet
+ Run quietly
+ @description:
+ Adds the specified <action> from the toolbar with the specified <toolbarid>.[br]
+ If no such action exists this command does nothing (beside printing a warning unless -q is used).[br]
+ If the <toolbar> parameter doesn't identify an existing toolbar then
+ a warning is printed unless the -q switch is used.[br]
+ @examples:
+ [example]
+ toolbar.create test $tr("My Toolbar")
+ toolbar.additem test connect
+ toolbar.additem test separator
+ toolbar.additem test optionsdialog
+ toolbar.show test
+ [/example]
+ @seealso:
+*/
+
+static bool toolbar_kvs_cmd_additem(KviKvsModuleCommandCall * c)
+{
+ QString szId;
+ QString szAction;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETER("action",KVS_PT_NONEMPTYSTRING,0,szAction)
+ KVSM_PARAMETERS_END(c)
+
+ KviCustomToolBarDescriptor * d = KviCustomToolBarManager::instance()->find(szId);
+
+ if(!d)
+ {
+ if(!c->switches()->find('q',"quiet"))
+ c->warning(__tr2qs("The specified toolbar doesn't exist"));
+ return true;
+ }
+
+ if(!d->addAction(szAction))
+ {
+ if(!c->switches()->find('q',"quiet"))c->warning(__tr2qs("The action \"%Q\" doesn't exist"),&szAction);
+ }
+
+ return true;
+}
+
+
+/*
+ @doc: toolbar.items
+ @type:
+ function
+ @title:
+ $toolbar.items
+ @short:
+ Returns the list of items in a specified toolbar
+ @syntax:
+ <array> $toolbar.items(<toolbarid:string>)
+ @description:
+ Returns the array of items in the specified toolbar.
+ If the toolbar doesn't exist then an empty list is returned.
+ @seealso:
+*/
+
+static bool toolbar_kvs_fnc_items(KviKvsModuleFunctionCall * c)
+{
+ QString szId;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("id",KVS_PT_NONEMPTYSTRING,0,szId)
+ KVSM_PARAMETERS_END(c)
+
+ KviCustomToolBarDescriptor * d = KviCustomToolBarManager::instance()->find(szId);
+
+ if(!d)
+ {
+ c->warning(__tr2qs("The specified toolbar doesn't exist"));
+ return true;
+ }
+
+ KviKvsArray * a = new KviKvsArray();
+
+ KviPointerHashTableIterator<QString,KviCustomToolBarDescriptor> it(*(KviCustomToolBarManager::instance()->descriptors()));
+
+ kvs_uint_t id = 0;
+
+ for(QString * s = d->actions()->first();s;s = d->actions()->next())
+ {
+ a->set(id,new KviKvsVariant(*s));
+ id++;
+ ++it;
+ }
+
+ c->returnValue()->setArray(a);
+ return true;
+}
+
+
+
+static bool toolbar_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"create",toolbar_kvs_cmd_create)
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"clear",toolbar_kvs_cmd_clear)
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"destroy",toolbar_kvs_cmd_destroy)
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"additem",toolbar_kvs_cmd_additem)
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"remove",toolbar_kvs_cmd_removeitem)
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"show",toolbar_kvs_cmd_show)
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"hide",toolbar_kvs_cmd_hide)
+
+ KVSM_REGISTER_FUNCTION(m,"exists",toolbar_kvs_fnc_exists)
+ KVSM_REGISTER_FUNCTION(m,"isVisible",toolbar_kvs_fnc_isVisible)
+ KVSM_REGISTER_FUNCTION(m,"list",toolbar_kvs_fnc_list)
+ KVSM_REGISTER_FUNCTION(m,"items",toolbar_kvs_fnc_items)
+
+ return true;
+}
+
+static bool toolbar_module_cleanup(KviModule *m)
+{
+ return true;
+}
+
+KVIRC_MODULE(
+ "toolbar", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Interface to the scriptable toolbars",
+ toolbar_module_init,
+ 0,
+ 0,
+ toolbar_module_cleanup
+)
diff --git a/src/modules/toolbareditor/Makefile.am b/src/modules/toolbareditor/Makefile.am
new file mode 100644
index 00000000..a578e10c
--- /dev/null
+++ b/src/modules/toolbareditor/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Maketoolbareditor - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+
+pluglib_LTLIBRARIES = libkvitoolbareditor.la
+
+libkvitoolbareditor_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvitoolbareditor_la_SOURCES = libkvitoolbareditor.cpp toolbareditor.cpp
+nodist_libkvitoolbareditor_la_SOURCES = moc_toolbareditor.cpp
+
+noinst_HEADERS = toolbareditor.h
+libkvitoolbareditor_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+moc_toolbareditor.cpp: toolbareditor.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/toolbareditor/libkvitoolbareditor.cpp b/src/modules/toolbareditor/libkvitoolbareditor.cpp
new file mode 100644
index 00000000..b4f9e258
--- /dev/null
+++ b/src/modules/toolbareditor/libkvitoolbareditor.cpp
@@ -0,0 +1,96 @@
+//=============================================================================
+//
+// File : libkvitoolbareditor.cpp
+// Creation date : Sun 10 Nov 2002 23:25:59 2002 GMT by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2002-2004 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 "toolbareditor.h"
+#include "kvi_module.h"
+
+#include "kvi_locale.h"
+
+#include "kvi_frame.h"
+#include "kvi_actionmanager.h"
+#include "kvi_config.h"
+#include "kvi_app.h"
+
+QRect g_rectToolBarEditorDialogGeometry(0,0,0,0);
+
+/*
+ @doc: toolbareditor.open
+ @type:
+ command
+ @title:
+ toolbareditor.open
+ @short:
+ Shows the script toolbar editor
+ @syntax:
+ toolbareditor.open
+ @description:
+ Opens the script toolbar editor dialog.
+*/
+
+
+static bool toolbareditor_kvs_cmd_open(KviKvsModuleCommandCall * c)
+{
+ KviCustomizeToolBarsDialog::display();
+ return true;
+}
+
+static bool toolbareditor_module_init(KviModule * m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"open",toolbareditor_kvs_cmd_open);
+ QString szBuf;
+ m->getDefaultConfigFileName(szBuf);
+ KviConfig cfg(szBuf,KviConfig::Read);
+ g_rectToolBarEditorDialogGeometry = cfg.readRectEntry("EditorGeometry",QRect(10,10,390,440));
+
+
+ return true;
+}
+
+static bool toolbareditor_module_can_unload(KviModule * m)
+{
+ return (!KviCustomizeToolBarsDialog::instance());
+}
+
+static bool toolbareditor_module_cleanup(KviModule *m)
+{
+ KviCustomizeToolBarsDialog::cleanup();
+
+ QString szBuf;
+ m->getDefaultConfigFileName(szBuf);
+ KviConfig cfg(szBuf,KviConfig::Write);
+ cfg.writeEntry("EditorGeometry",g_rectToolBarEditorDialogGeometry);
+
+ return true;
+}
+
+KVIRC_MODULE(
+ "ToolbarEditor", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Editor for the scriptable toolbars",
+ toolbareditor_module_init,
+ toolbareditor_module_can_unload,
+ 0,
+ toolbareditor_module_cleanup
+)
diff --git a/src/modules/toolbareditor/toolbareditor.cpp b/src/modules/toolbareditor/toolbareditor.cpp
new file mode 100644
index 00000000..5b00f47a
--- /dev/null
+++ b/src/modules/toolbareditor/toolbareditor.cpp
@@ -0,0 +1,537 @@
+//=============================================================================//
+// File : toolbareditor.cpp
+// Created on Wed 01 Dec 2004 14:42:20 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2004 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 "toolbareditor.h"
+#include "kvi_actiondrawer.h"
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_actionmanager.h"
+#include "kvi_customtoolbar.h"
+#include "kvi_customtoolbarmanager.h"
+#include "kvi_customtoolbardescriptor.h"
+#include "kvi_imagedialog.h"
+#include "kvi_fileutils.h"
+#include "kvi_filedialog.h"
+#include "kvi_kvs_useraction.h"
+#include "kvi_draganddrop.h"
+
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qapplication.h>
+#include <qtooltip.h>
+
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qmessagebox.h>
+#include <qframe.h>
+#include <qdir.h>
+#include <qtimer.h>
+#include <qevent.h>
+
+KviCustomizeToolBarsDialog * KviCustomizeToolBarsDialog::m_pInstance = 0;
+extern QRect g_rectToolBarEditorDialogGeometry;
+
+
+
+KviTrashcanLabel::KviTrashcanLabel(QWidget * p)
+: QLabel(p)
+{
+ setPixmap(*(g_pIconManager->getBigIcon("kvi_bigicon_trashcan.png")));
+ QToolTip::add(this,__tr2qs("Drop here the icons from the toolbars to remove them"));
+ setFrameStyle(QFrame::Sunken | QFrame::WinPanel);
+ setAcceptDrops(true);
+ setAlignment(Qt::AlignCenter);
+ setMinimumSize(40,40);
+ m_uFlashCount = 0;
+ m_pFlashTimer = 0;
+ m_clrOriginal = paletteBackgroundColor();
+ connect(KviActionManager::instance(),SIGNAL(removeActionsHintRequest()),this,SLOT(flash()));
+}
+
+KviTrashcanLabel::~KviTrashcanLabel()
+{
+ if(m_pFlashTimer)
+ {
+ m_pFlashTimer->stop();
+ delete m_pFlashTimer;
+ }
+}
+
+void KviTrashcanLabel::flash()
+{
+ m_uFlashCount = 0;
+ if(m_pFlashTimer)return;
+ m_pFlashTimer = new QTimer();
+ connect(m_pFlashTimer,SIGNAL(timeout()),this,SLOT(heartbeat()));
+ m_pFlashTimer->start(200);
+}
+
+void KviTrashcanLabel::heartbeat()
+{
+ m_uFlashCount++;
+ if(m_uFlashCount % 2)
+ setPaletteBackgroundColor(QColor(0,0,0));
+ else
+ setPaletteBackgroundColor(m_clrOriginal);
+ update();
+ if(m_uFlashCount == 8)
+ {
+ m_pFlashTimer->stop();
+ delete m_pFlashTimer;
+ m_pFlashTimer = 0;
+ }
+}
+
+void KviTrashcanLabel::dropEvent(QDropEvent * e)
+{
+ if(KviTextDrag::canDecode(e))
+ e->accept();
+}
+
+void KviTrashcanLabel::dragEnterEvent(QDragEnterEvent * e)
+{
+ QString s;
+ if(KviTextDrag::decode(e,s))
+ e->accept();
+}
+
+
+
+KviCustomToolBarPropertiesDialog::KviCustomToolBarPropertiesDialog(QWidget * p,const QString &szText,const QString &szId,const QString &szLabel,const QString &szIconId)
+: QDialog(p)
+{
+ m_szId = szId;
+ m_szOriginalId = szId;
+ m_szLabel = szLabel;
+
+ setCaption(__tr2qs("ToolBar Properties"));
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TOOLBAR)));
+
+ QGridLayout * g = new QGridLayout(this,5,6,5,3);
+
+ QLabel * l = new QLabel(szText,this);
+ g->addMultiCellWidget(l,0,0,0,5);
+
+ l = new QLabel(__tr2qs("Label") + ":",this);
+ g->addWidget(l,1,0);
+
+ m_pLabelEdit = new QLineEdit(this);
+ g->addMultiCellWidget(m_pLabelEdit,1,1,1,5);
+ m_pLabelEdit->setText(szLabel);
+ connect(m_pLabelEdit,SIGNAL(textChanged(const QString &)),this,SLOT(labelTextChanged(const QString &)));
+
+ l = new QLabel(__tr2qs("Icon") + ":",this);
+ g->addWidget(l,2,0);
+
+ m_pIconEdit = new QLineEdit(this);
+ m_pIconEdit->setReadOnly(true);
+ g->addMultiCellWidget(m_pIconEdit,2,2,1,4);
+
+ m_pIconButton = new QPushButton(this);
+ g->addMultiCellWidget(m_pIconButton,2,2,5,5);
+ connect(m_pIconButton,SIGNAL(clicked()),this,SLOT(iconButtonClicked()));
+
+ iconSelected(szIconId);
+
+ m_pAdvanced = new QWidget(this);
+ QGridLayout * ag = new QGridLayout(m_pAdvanced,1,2,0,3);
+
+ l = new QLabel(__tr2qs("Id") + ":",m_pAdvanced);
+ l->setMinimumWidth(100);
+ ag->addWidget(l,0,0);
+
+ m_pIdEdit = new QLineEdit(m_pAdvanced);
+ ag->addWidget(m_pIdEdit,0,1);
+ ag->setRowStretch(0,1);
+
+ m_pIdEdit->setText(szId);
+
+ g->addMultiCellWidget(m_pAdvanced,3,3,0,5);
+ m_pAdvanced->hide();
+
+ m_pLabelEdit->setFocus();
+
+ QPushButton * pb = new QPushButton(__tr2qs("OK"),this);
+ connect(pb,SIGNAL(clicked()),this,SLOT(okClicked()));
+ pb->setMinimumWidth(80);
+ g->addMultiCellWidget(pb,4,4,4,5);
+
+ pb = new QPushButton(__tr2qs("Cancel"),this);
+ connect(pb,SIGNAL(clicked()),this,SLOT(reject()));
+ pb->setMinimumWidth(80);
+ g->addWidget(pb,4,3);
+
+ m_pAdvancedButton = new QPushButton(__tr2qs("Advanced..."),this);
+ connect(m_pAdvancedButton,SIGNAL(clicked()),this,SLOT(advancedClicked()));
+ m_pAdvancedButton->setMinimumWidth(100);
+ g->addMultiCellWidget(m_pAdvancedButton,4,4,0,1);
+
+ g->setRowStretch(0,1);
+ g->setColStretch(2,1);
+
+
+}
+
+KviCustomToolBarPropertiesDialog::~KviCustomToolBarPropertiesDialog()
+{
+}
+
+void KviCustomToolBarPropertiesDialog::iconSelected(const QString &szIconId)
+{
+ QPixmap * p = g_pIconManager->getImage(szIconId.utf8().data());
+ if(p)
+ {
+ m_pIconButton->setPixmap(*p);
+ m_szIconId = szIconId;
+ m_pIconEdit->setText(szIconId);
+ } else {
+ m_pIconButton->setText("...");
+ m_szIconId = "";
+ m_pIconEdit->setText("");
+ }
+}
+
+void KviCustomToolBarPropertiesDialog::iconButtonClicked()
+{
+ KviImageDialog * dlg = new KviImageDialog(this,__tr2qs("Please choose the icon for the ToolBar"));
+ if(dlg->exec() != QDialog::Accepted)
+ {
+ delete dlg;
+ return;
+ }
+ QString s = dlg->selectedImage();
+ delete dlg;
+ iconSelected(s);
+}
+
+
+void KviCustomToolBarPropertiesDialog::labelTextChanged(const QString &s)
+{
+ if(m_szOriginalId.isEmpty())
+ {
+ QString szId = KviCustomToolBarManager::instance()->idForNewToolBar(s);
+ m_pIdEdit->setText(szId);
+ }
+}
+
+
+void KviCustomToolBarPropertiesDialog::okClicked()
+{
+ if(m_szLabel.isEmpty())
+ {
+ QMessageBox::information(this,__tr2qs("Invalid ToolBar Label"),__tr2qs("The ToolBar Label can't be empty!"),__tr2qs("OK"));
+ return;
+ }
+
+ if(m_szId.isEmpty())
+ {
+ m_szId = KviCustomToolBarManager::instance()->idForNewToolBar(m_szLabel);
+ }
+
+ if(KviCustomToolBarManager::instance()->find(m_szId))
+ {
+ if(m_szId != m_szOriginalId)
+ {
+ if(QMessageBox::information(this,__tr2qs("Duplicate ToolBar Id"),
+ __tr2qs("The specified ToolBar Id already exists.<br>" \
+ "Would you like KVIrc to assign it automatically (so it doesn't "
+ "collide with any other toolbar) or you prefer to do it manually ?"),
+ __tr2qs("Manually"),__tr2qs("Automatically")) == 0)return;
+ m_szId = KviCustomToolBarManager::instance()->idForNewToolBar(m_szLabel);
+ }
+ }
+
+ m_szId = m_pIdEdit->text();
+ m_szLabel = m_pLabelEdit->text();
+ accept();
+}
+
+void KviCustomToolBarPropertiesDialog::advancedClicked()
+{
+ if(m_pAdvanced->isVisible())
+ {
+ m_pAdvanced->hide();
+ m_pAdvancedButton->setText(__tr2qs("Advanced..."));
+ } else {
+ m_pAdvanced->show();
+ m_pAdvancedButton->setText(__tr2qs("Hide Advanced"));
+ }
+
+}
+
+
+KviCustomizeToolBarsDialog::KviCustomizeToolBarsDialog(QWidget * p)
+: QDialog(p,"" /*,WType_TopLevel | WStyle_Customize | WStyle_Title | WStyle_StaysOnTop | WStyle_DialogBorder*/)
+{
+ setCaption(__tr2qs("Customize Toolbars"));
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TOOLBAR)));
+
+ m_pInstance = this;
+
+ QGridLayout * g = new QGridLayout(this,8,2,4,5);
+ m_pDrawer = new KviActionDrawer(this);
+ g->addMultiCellWidget(m_pDrawer,0,6,0,0);
+
+ QPushButton * b = new QPushButton(__tr2qs("New ToolBar"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(newToolBar()));
+ g->addWidget(b,0,1);
+
+ m_pDeleteToolBarButton = new QPushButton(__tr2qs("Delete ToolBar"),this);
+ connect(m_pDeleteToolBarButton,SIGNAL(clicked()),this,SLOT(deleteToolBar()));
+ g->addWidget(m_pDeleteToolBarButton,1,1);
+
+ m_pRenameToolBarButton = new QPushButton(__tr2qs("Edit ToolBar"),this);
+ connect(m_pRenameToolBarButton,SIGNAL(clicked()),this,SLOT(renameToolBar()));
+ g->addWidget(m_pRenameToolBarButton,2,1);
+
+ QFrame * f = new QFrame(this);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ g->addWidget(f,3,1);
+
+ m_pExportToolBarButton = new QPushButton(__tr2qs("Export ToolBar"),this);
+ connect(m_pExportToolBarButton,SIGNAL(clicked()),this,SLOT(exportToolBar()));
+ g->addWidget(m_pExportToolBarButton,4,1);
+
+ KviTrashcanLabel * t = new KviTrashcanLabel(this);
+ g->addWidget(t,6,1);
+
+ b = new QPushButton(__tr2qs("Close"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(closeClicked()));
+ g->addWidget(b,7,1);
+
+ g->setRowStretch(5,1);
+ g->setColStretch(0,1);
+
+ m_pDrawer->fill();
+
+ connect(KviActionManager::instance(),SIGNAL(currentToolBarChanged()),this,SLOT(currentToolBarChanged()));
+ KviActionManager::instance()->customizeToolBarsDialogCreated();
+
+ currentToolBarChanged();
+
+ if(g_rectToolBarEditorDialogGeometry.y() < 5)
+ {
+ g_rectToolBarEditorDialogGeometry.setY(5);
+ }
+ //setGeometry(KVI_OPTION_RECT(KviOption_rectRegisteredUsersDialogGeometry));
+ resize(g_rectToolBarEditorDialogGeometry.width(),
+ g_rectToolBarEditorDialogGeometry.height());
+ move(g_rectToolBarEditorDialogGeometry.x(),
+ g_rectToolBarEditorDialogGeometry.y());
+}
+
+KviCustomizeToolBarsDialog::~KviCustomizeToolBarsDialog()
+{
+ g_rectToolBarEditorDialogGeometry = QRect(pos().x(),pos().y(),size().width(),size().height());
+
+ KviActionManager::instance()->customizeToolBarsDialogDestroyed();
+ m_pInstance = 0;
+}
+
+void KviCustomizeToolBarsDialog::currentToolBarChanged()
+{
+ m_pDeleteToolBarButton->setEnabled(KviActionManager::instance()->currentToolBar());
+ m_pRenameToolBarButton->setEnabled(KviActionManager::instance()->currentToolBar());
+}
+
+void KviCustomizeToolBarsDialog::showEvent(QShowEvent * e)
+{
+// repaintContents();
+// QRect r = parentWidget() ? parentWidget()->rect() : QApplication::desktop()->rect();
+// int x = (r.width() - width()) / 2;
+// int y = (r.height() - height()) / 2;
+// move(x,y);
+}
+
+
+void KviCustomizeToolBarsDialog::deleteToolBar()
+{
+ KviCustomToolBar * t = KviActionManager::currentToolBar();
+ if(!t)return;
+ if(QMessageBox::question(this,
+ __tr2qs("Confirm ToolBar Deletion"),
+ __tr2qs("Do you really want to delete toolbar \"%1\" ?").arg(t->label()),
+ __tr2qs("No"),
+ __tr2qs("Yes")) == 0)return;
+ KviCustomToolBarManager::instance()->destroyDescriptor(t->descriptor()->id());
+}
+
+void KviCustomizeToolBarsDialog::exportToolBar()
+{
+ KviCustomToolBar * t = KviActionManager::currentToolBar();
+ if(!t)return;
+
+ QString szName = QDir::homeDirPath();
+ if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR;
+ szName += t->descriptor()->id();
+ szName += ".kvs";
+
+ QString szFile;
+
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose a Filename - KVIrc"),szName,"*.kvs",true,true,true))return;
+
+ QString szCode;
+
+ int ret = QMessageBox::question(this,
+ __tr2qs("ToolBar Export"),
+ __tr2qs("Do you want the associated actions to be exported with the toolbar ?"),
+ __tr2qs("Yes"),
+ __tr2qs("No"),
+ __tr2qs("Cancel"));
+
+ if(ret == 2)return;
+
+ bool bExportActions = ret == 0;
+
+ if(bExportActions)
+ {
+ KviPointerList<QString> * a = t->descriptor()->actions();
+ if(a)
+ {
+ for(QString * s = a->first();s;s = a->next())
+ {
+ KviAction * act = KviActionManager::instance()->getAction(*s);
+ if(act)
+ {
+ if(act->isKviUserActionNeverOverrideThis())
+ {
+ ((KviKvsUserAction *)act)->exportToKvs(szCode);
+ szCode += "\n\n";
+ }
+ }
+ }
+ }
+ }
+
+ szCode += "toolbar.create ";
+ szCode += t->descriptor()->id();
+ szCode += " ";
+ szCode += t->descriptor()->labelCode();
+ szCode += " ";
+ szCode += t->descriptor()->iconId();
+ szCode += "\n";
+
+ KviPointerList<QString> * aa = t->descriptor()->actions();
+ if(aa)
+ {
+ for(QString * ss = aa->first();ss;ss = aa->next())
+ {
+ szCode += "toolbar.additem ";
+ szCode += t->descriptor()->id();
+ szCode += " ";
+ szCode += *ss;
+ szCode += "\n";
+ }
+ }
+
+ szCode += "toolbar.show ";
+ szCode += t->descriptor()->id();
+ szCode += "\n";
+
+ if(!KviFileUtils::writeFile(szFile,szCode))
+ {
+ QMessageBox::warning(this,__tr2qs("Write Failed - KVIrc"),__tr2qs("Unable to write to the toolbar file."),__tr2qs("OK"));
+ }
+
+}
+
+void KviCustomizeToolBarsDialog::renameToolBar()
+{
+ KviCustomToolBar * t = KviActionManager::currentToolBar();
+ if(!t)return;
+
+ KviCustomToolBarPropertiesDialog * dlg = new KviCustomToolBarPropertiesDialog(this,
+ __tr2qs("Please specify the properties for the toolbar \"%1\"").arg(t->label()),
+ t->descriptor()->id(),
+ t->descriptor()->labelCode(),
+ t->descriptor()->iconId());
+
+ dlg->show();
+ if(dlg->exec() != QDialog::Accepted)
+ {
+ delete dlg;
+ return;
+ }
+
+ QString id = dlg->id();
+ QString label = dlg->label();
+ QString icon = dlg->iconId();
+ delete dlg;
+
+ if((id == t->descriptor()->id()) && (label == t->descriptor()->labelCode()) && (icon == t->descriptor()->iconId()))return;
+
+ KviCustomToolBarManager::instance()->renameDescriptor(t->descriptor()->id(),id,label);
+ t->descriptor()->setIconId(icon);
+}
+
+void KviCustomizeToolBarsDialog::newToolBar()
+{
+ KviCustomToolBarPropertiesDialog * dlg = new KviCustomToolBarPropertiesDialog(this,
+ __tr2qs("Please specify the properties for the new toolbar"),
+ KviCustomToolBarManager::instance()->idForNewToolBar(__tr2qs("My ToolBar")),
+ __tr2qs("My ToolBar"));
+
+ dlg->show();
+ if(dlg->exec() != QDialog::Accepted)
+ {
+ delete dlg;
+ return;
+ }
+
+ QString id = dlg->id();
+ QString label = dlg->label();
+ QString icon = dlg->iconId();
+ delete dlg;
+
+ KviCustomToolBarDescriptor * d = KviCustomToolBarManager::instance()->create(id,label);
+ d->setIconId(icon);
+ KviCustomToolBar * t = d->createToolBar();
+ KviActionManager::instance()->setCurrentToolBar(t);
+}
+
+void KviCustomizeToolBarsDialog::closeClicked()
+{
+ delete this;
+}
+
+void KviCustomizeToolBarsDialog::cleanup()
+{
+ if(!m_pInstance)return;
+ delete m_pInstance;
+ m_pInstance = 0;
+}
+
+void KviCustomizeToolBarsDialog::display()
+{
+ if(m_pInstance)return;
+ m_pInstance = new KviCustomizeToolBarsDialog(g_pFrame);
+ m_pInstance->show();
+}
+
+void KviCustomizeToolBarsDialog::closeEvent(QCloseEvent * e)
+{
+ e->ignore();
+ delete this;
+}
+
diff --git a/src/modules/toolbareditor/toolbareditor.h b/src/modules/toolbareditor/toolbareditor.h
new file mode 100644
index 00000000..2c44178c
--- /dev/null
+++ b/src/modules/toolbareditor/toolbareditor.h
@@ -0,0 +1,119 @@
+#ifndef _TOOLBAREDITOR_H_
+#define _TOOLBAREDITOR_H_
+//=============================================================================
+//
+// File : toolbareditor.h
+// Created on Wed 01 Dec 2004 14:42:20 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2004 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 <qwidget.h>
+#include <qlabel.h>
+#include <qdialog.h>
+#include <qcolor.h>
+
+class QPushButton;
+class KviActionDrawer;
+
+class KviCustomizeToolBarsDialog : public QDialog
+{
+ Q_OBJECT
+protected:
+ KviCustomizeToolBarsDialog(QWidget * p);
+public:
+ ~KviCustomizeToolBarsDialog();
+protected:
+ KviActionDrawer * m_pDrawer;
+ static KviCustomizeToolBarsDialog * m_pInstance;
+ QPushButton * m_pDeleteToolBarButton;
+ QPushButton * m_pRenameToolBarButton;
+ QPushButton * m_pExportToolBarButton;
+public:
+ static KviCustomizeToolBarsDialog * instance(){ return m_pInstance; };
+ static void display();
+ static void cleanup();
+protected:
+ virtual void showEvent(QShowEvent * e);
+ virtual void closeEvent(QCloseEvent *e);
+protected slots:
+ void closeClicked();
+ void newToolBar();
+ void deleteToolBar();
+ void renameToolBar();
+ void exportToolBar();
+ void currentToolBarChanged();
+};
+
+class QLineEdit;
+class QPushButton;
+
+class KviCustomToolBarPropertiesDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviCustomToolBarPropertiesDialog(QWidget * p,const QString &szText,const QString &szId = QString::null,const QString &szLabel = QString::null,const QString &szIconId = QString::null);
+ ~KviCustomToolBarPropertiesDialog();
+protected:
+ QString m_szId;
+ QString m_szOriginalId;
+ QString m_szLabel;
+ QString m_szIconId;
+ QWidget * m_pAdvanced;
+ QLineEdit * m_pIdEdit;
+ QLineEdit * m_pLabelEdit;
+ QLineEdit * m_pIconEdit;
+ QPushButton * m_pIconButton;
+ QPushButton * m_pAdvancedButton;
+public:
+ const QString &id(){ return m_szId; };
+ const QString &label(){ return m_szLabel; };
+ const QString &iconId(){ return m_szIconId; };
+protected slots:
+ void okClicked();
+ void advancedClicked();
+ void iconButtonClicked();
+ void labelTextChanged(const QString &s);
+protected:
+ void iconSelected(const QString &szIconId);
+};
+
+class QTimer;
+
+class KviTrashcanLabel : public QLabel
+{
+ Q_OBJECT
+public:
+ KviTrashcanLabel(QWidget * p);
+ virtual ~KviTrashcanLabel();
+protected:
+ unsigned int m_uFlashCount;
+ QTimer * m_pFlashTimer;
+ QColor m_clrOriginal;
+protected:
+ virtual void dragEnterEvent(QDragEnterEvent * e);
+ virtual void dropEvent(QDropEvent * e);
+public slots:
+ void flash();
+protected slots:
+ void heartbeat();
+};
+
+#endif //!_TOOLBAREDITOR_H_
diff --git a/src/modules/torrent/Makefile.am b/src/modules/torrent/Makefile.am
new file mode 100644
index 00000000..ab0d80cb
--- /dev/null
+++ b/src/modules/torrent/Makefile.am
@@ -0,0 +1,30 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvitorrent.la
+
+#%.moc: %.h
+# $(SS_QT_MOC) $< -o $@
+
+libkvitorrent_la_LDFLAGS = -avoid-version -module
+
+libkvitorrent_la_SOURCES = libkvitorrent.cpp \
+ tc_interface.cpp \
+ tc_ktorrentdcopinterface.cpp \
+ tc_statusbarapplet.cpp
+
+libkvitorrent_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS = tc_interface.h \
+ tc_ktorrentdcopinterface.h \
+ tc_statusbarapplet.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+tc_ktorrentdcopinterface.cpp: tc_ktorrentdcopinterface.moc
+tc_statusbarapplet.cpp: tc_statusbarapplet.moc
diff --git a/src/modules/torrent/libkvitorrent.cpp b/src/modules/torrent/libkvitorrent.cpp
new file mode 100644
index 00000000..9a929483
--- /dev/null
+++ b/src/modules/torrent/libkvitorrent.cpp
@@ -0,0 +1,904 @@
+//=============================================================================
+//
+// File : libkvitorrent.cpp
+// Creation date : Fri Jan 1 15:42:25 2007 GMT by Alexander Stillich
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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_module.h"
+#include "kvi_options.h"
+#include "kvi_frame.h"
+
+#include "tc_interface.h"
+#include "tc_ktorrentdcopinterface.h"
+#include "tc_statusbarapplet.h"
+
+#include "kvi_locale.h"
+#include "kvi_out.h"
+
+
+static KviPointerList<KviTorrentInterfaceDescriptor> * g_pDescriptorList = 0;
+
+static KviTorrentInterface *auto_detect_torrent_client(KviWindow * pOut = 0)
+{
+ int iBest = 0;
+ KviTorrentInterface * pBest = 0;
+ KviTorrentInterfaceDescriptor * d;
+ KviTorrentInterfaceDescriptor * pDBest = 0;
+
+ for (d=g_pDescriptorList->first(); d!=0; d=g_pDescriptorList->next())
+ {
+ // instance gets deleted by descriptor later
+ KviTorrentInterface *i = d->instance();
+ if (i)
+ {
+ int iScore = i->detect();
+ if(iScore > iBest)
+ {
+ iBest = iScore;
+ pBest = i;
+ pDBest = d;
+ }
+
+ if(pOut)
+ {
+ pOut->output(KVI_OUT_TORRENT,
+ __tr2qs_ctx("Trying torrent client interface \"%Q\": score %d", "torrent"),
+ &d->name(),
+ iScore);
+ }
+ }
+ }
+
+/* if(iBest < 90)
+ {
+ if(pOut)
+ pOut->outputNoFmt(KVI_OUT_MULTIMEDIA,__tr2qs_ctx("Not sure about the results, trying a second, more agressive detection pass","mediaplayer"));
+ // no sure player found... try again with a destructive test
+ for(d = g_pDescriptorList->first();d;d = g_pDescriptorList->next())
+ {
+ KviMediaPlayerInterface * i = d->instance();
+ if(i)
+ {
+ int iScore = i->detect(true);
+ if(iScore > iBest)
+ {
+ iBest = iScore;
+ pBest = i;
+ pDBest = d;
+ }
+ if(pOut)
+ {
+ QString szOut;
+ QString szNam = d->name();
+ KviQString::sprintf(szOut,__tr2qs_ctx("Trying media player interface \"%Q\": score %d","mediaplayer"),&(szNam),iScore);
+ pOut->output(KVI_OUT_MULTIMEDIA,szOut);
+ }
+ }
+ }
+ }
+*/
+ if(pDBest)
+ {
+ KVI_OPTION_STRING(KviOption_stringPreferredTorrentClient) = pDBest->name();
+ if(pOut)
+ pOut->output(KVI_OUT_TORRENT,
+ __tr2qs_ctx("Choosing torrent client interface \"%Q\"", "torrent"),
+ &pDBest->name());
+
+ } else
+ {
+ if(pOut)
+ pOut->outputNoFmt(KVI_OUT_TORRENT,
+ __tr2qs_ctx("Seems that there is no usable torrent client on this machine", "torrent"));
+ }
+
+ return pBest;
+}
+
+#define TC_KVS_FAIL_ON_NO_INTERFACE \
+ if (!KviTorrentInterface::selected()) \
+ { \
+ c->warning(__tr2qs_ctx("No torrent client interface selected. Try /torrent.detect", "torrent")); \
+ return true; \
+ }
+
+#define TC_KVS_COMMAND(__name) static bool torrent_kvs_cmd_ ## __name (KviKvsModuleCommandCall * c)
+#define TC_KVS_FUNCTION(__name) static bool torrent_kvs_fnc_ ## __name (KviKvsModuleFunctionCall * c)
+
+#define TC_KVS_COMMAND_ERROR \
+ if (!c->hasSwitch('q',"quiet")) \
+ { \
+ c->warning(__tr2qs_ctx("The selected torrent client interface failed to execute the requested function", "torrent")); \
+ QString tmp = __tr2qs_ctx("Last interface error: ", "torrent"); \
+ tmp += KviTorrentInterface::selected()->lastError(); \
+ c->warning(tmp); \
+ } \
+
+#define TC_KVS_SIMPLE_COMMAND(__name, __ifacecommand) \
+ TC_KVS_COMMAND(__name) \
+ { \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETERS_END(c) \
+ \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ \
+ if (!KviTorrentInterface::selected()->__ifacecommand()) \
+ { \
+ TC_KVS_COMMAND_ERROR \
+ } \
+ return true; \
+ }
+
+#define TC_KVS_INT_COMMAND(__name, __ifacecommand, __argname) \
+ TC_KVS_COMMAND(__name) \
+ { \
+ kvs_int_t arg; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER(__argname, KVS_PT_INT, 0, arg) \
+ KVSM_PARAMETERS_END(c) \
+ \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ \
+ if (!KviTorrentInterface::selected()->__ifacecommand(arg)) \
+ { \
+ TC_KVS_COMMAND_ERROR \
+ } \
+ return true; \
+ }
+
+#define TC_KVS_INT_INT_STRING_COMMAND(__name, __ifacecommand, __argname1, __argname2, __argname3) \
+ TC_KVS_COMMAND(__name) \
+ { \
+ kvs_int_t arg1; \
+ kvs_int_t arg2; \
+ QString arg3; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER(__argname1, KVS_PT_INT, 0, arg1) \
+ KVSM_PARAMETER(__argname2, KVS_PT_INT, 0, arg2) \
+ KVSM_PARAMETER(__argname3, KVS_PT_STRING, 0, arg3) \
+ KVSM_PARAMETERS_END(c) \
+ \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ \
+ if (!KviTorrentInterface::selected()->__ifacecommand(arg1, arg2, arg3)) \
+ { \
+ TC_KVS_COMMAND_ERROR \
+ } \
+ return true; \
+ }
+
+// TODO: error handling for functions
+
+#define TC_KVS_STRINGRET_FUNCTION(__name, __ifacecommand) \
+ TC_KVS_FUNCTION(__name) \
+ { \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ QString szRet = KviTorrentInterface::selected()->__ifacecommand(); \
+ c->returnValue()->setString(szRet); \
+ return true; \
+ }
+
+#define TC_KVS_INTRET_FUNCTION(__name, __ifacecommand) \
+ TC_KVS_FUNCTION(__name) \
+ { \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ kvs_int_t ret = KviTorrentInterface::selected()->__ifacecommand(); \
+ c->returnValue()->setInteger(ret); \
+ return true; \
+ }
+
+#define TC_KVS_FLOATRET_FUNCTION(__name, __ifacecommand) \
+ TC_KVS_FUNCTION(__name) \
+ { \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ kvs_real_t ret = KviTorrentInterface::selected()->__ifacecommand(); \
+ c->returnValue()->setReal(ret); \
+ return true; \
+ }
+
+#define TC_KVS_INTRET_INT_FUNCTION(__name, __ifacecommand, __argname) \
+ TC_KVS_FUNCTION(__name) \
+ { \
+ kvs_int_t arg; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER(__argname, KVS_PT_INT, 0, arg) \
+ KVSM_PARAMETERS_END(c) \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ kvs_int_t ret = KviTorrentInterface::selected()->__ifacecommand(arg); \
+ c->returnValue()->setInteger(ret); \
+ return true; \
+ }
+
+#define TC_KVS_STRINGRET_INT_FUNCTION(__name, __ifacecommand, __argname) \
+ TC_KVS_FUNCTION(__name) \
+ { \
+ kvs_int_t arg; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER(__argname, KVS_PT_INT, 0, arg) \
+ KVSM_PARAMETERS_END(c) \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ QString szRet = KviTorrentInterface::selected()->__ifacecommand(arg); \
+ c->returnValue()->setString(szRet); \
+ return true; \
+ }
+
+#define TC_KVS_STRINGRET_INT_INT_FUNCTION(__name, __ifacecommand, __argname1, __argname2) \
+ TC_KVS_FUNCTION(__name) \
+ { \
+ kvs_int_t arg1; \
+ kvs_int_t arg2; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER(__argname1, KVS_PT_INT, 0, arg1) \
+ KVSM_PARAMETER(__argname2, KVS_PT_INT, 0, arg2) \
+ KVSM_PARAMETERS_END(c) \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ QString szRet = KviTorrentInterface::selected()->__ifacecommand(arg1, arg2); \
+ c->returnValue()->setString(szRet); \
+ return true; \
+ }
+
+#define TC_KVS_INTRET_INT_INT_FUNCTION(__name, __ifacecommand, __argname1, __argname2) \
+ TC_KVS_FUNCTION(__name) \
+ { \
+ kvs_int_t arg1; \
+ kvs_int_t arg2; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER(__argname1, KVS_PT_INT, 0, arg1) \
+ KVSM_PARAMETER(__argname2, KVS_PT_INT, 0, arg2) \
+ KVSM_PARAMETERS_END(c) \
+ TC_KVS_FAIL_ON_NO_INTERFACE \
+ kvs_int_t ret = KviTorrentInterface::selected()->__ifacecommand(arg1, arg2); \
+ c->returnValue()->setInteger(ret); \
+ return true; \
+ }
+
+TC_KVS_COMMAND(detect)
+{
+ KviTorrentInterface::select(auto_detect_torrent_client(c->hasSwitch('q',"quiet") ? 0 : c->window()));
+ return true;
+}
+
+/*
+ @doc: torrent.maxUploadSpeed
+ @type:
+ function
+ @title:
+ $torrent.maxUploadSpeed
+ @short:
+ Returns maximum upload speed set in client.
+ @syntax:
+ $torrent.maxUploadSpeed()
+ @description:
+ Returns maximum upload speed set in client.
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_INTRET_FUNCTION(maxUploadSpeed, maxUploadSpeed)
+
+
+/*
+ @doc: torrent.maxDownloadSpeed
+ @type:
+ function
+ @title:
+ $torrent.maxDownloadSpeed
+ @short:
+ Returns maximum download speed set in client.
+ @syntax:
+ $torrent.maxDownloadSpeed()
+ @description:
+ Returns maximum download speed set in client.
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_INTRET_FUNCTION(maxDownloadSpeed, maxDownloadSpeed)
+
+/*
+ @doc: torrent.setMaxUploadSpeed
+ @type:
+ command
+ @title:
+ torrent.setMaxUploadSpeed
+ @short:
+ Sets maximum upload speed
+ @syntax:
+ torrent.setMaxUploadSpeed <kbytes_per_sec>
+ @description:
+ Sets maximum upload speed
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_INT_COMMAND(setMaxUploadSpeed, setMaxUploadSpeed, "kbytes_per_sec")
+
+/*
+ @doc: torrent.setMaxDownloadSpeed
+ @type:
+ command
+ @title:
+ torrent.setMaxDownloadSpeed
+ @short:
+ Sets maximum download speed
+ @syntax:
+ torrent.setMaxDownloadSpeed <kbytes_per_sec>
+ @description:
+ Sets maximum download speed
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_INT_COMMAND(setMaxDownloadSpeed, setMaxDownloadSpeed, "kbytes_per_sec")
+
+/*
+ @doc: torrent.speedUp
+ @type:
+ function
+ @title:
+ $torrent.speedUp
+ @short:
+ Returns current total upload speed
+ @syntax:
+ $torrent.speedUp()
+ @description:
+ Returns current total upload speed
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_FLOATRET_FUNCTION(speedUp, speedUp)
+
+/*
+ @doc: torrent.speedDown
+ @type:
+ function
+ @title:
+ $torrent.speedDown
+ @short:
+ Returns current total download speed
+ @syntax:
+ $torrent.speedDown()
+ @description:
+ Returns current total download speed
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_FLOATRET_FUNCTION(speedDown, speedDown)
+
+/*
+ @doc: torrent.trafficUp
+ @type:
+ function
+ @title:
+ $torrent.trafficUp
+ @short:
+ Returns the total number of bytes uploaded
+ @syntax:
+ $torrent.trafficUp()
+ @description:
+ Returns the total number of bytes uploaded
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_FLOATRET_FUNCTION(trafficUp, trafficUp)
+
+/*
+ @doc: torrent.trafficDown
+ @type:
+ function
+ @title:
+ $torrent.trafficDown
+ @short:
+ Returns the total number of bytes download
+ @syntax:
+ $torrent.trafficDown()
+ @description:
+ Returns the total number of bytes download
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_FLOATRET_FUNCTION(trafficDown, trafficDown)
+
+/*
+ @doc: torrent.count
+ @type:
+ function
+ @title:
+ $torrent.count
+ @short:
+ Returns number of torrents in client
+ @syntax:
+ $torrent.name()
+ @description:
+ Returns number of torrents in client
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_INTRET_FUNCTION(count, count)
+
+/*
+ @doc: torrent.name
+ @type:
+ function
+ @title:
+ $torrent.name
+ @short:
+ Returns torrent name as displayed in client
+ @syntax:
+ $torrent.name(torrent_number)
+ @description:
+ Returns torrent name as displayed in client
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_STRINGRET_INT_FUNCTION(name, name, "torrent_number")
+
+/*
+ @doc: torrent.start
+ @type:
+ command
+ @title:
+ torrent.start
+ @short:
+ Starts downloading of torrent <torrent_number>
+ @syntax:
+ torrent.start <torrent_number>
+ @description:
+ Starts downloading of torrent <torrent_number>
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+ [cmd]torrent.stop[/cmd], [cmd]torrent.stopAll[/cmd],
+ [cmd]torrent.startAll[/cmd]
+*/
+TC_KVS_INT_COMMAND(start, start, "torrent_number")
+
+/*
+ @doc: torrent.stop
+ @type:
+ command
+ @title:
+ torrent.stop
+ @short:
+ Stops downloading of torrent <torrent_number>
+ @syntax:
+ torrent.stop <torrent_number>
+ @description:
+ Stops downloading of torrent <torrent_number>
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+ [cmd]torrent.stopAll[/cmd], [cmd]torrent.startAll[/cmd],
+ [cmd]torrent.start[/cmd]
+*/
+TC_KVS_INT_COMMAND(stop, stop, "torrent_number")
+
+/*
+ @doc: torrent.announce
+ @type:
+ command
+ @title:
+ torrent.announce
+ @short:
+ Manually announces torrent to tracker
+ @syntax:
+ torrent.announce <torrent_number>
+ @description:
+ Manually announces torrent to tracker
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_INT_COMMAND(announce, announce, "torrent_number")
+
+/*
+ @doc: torrent.fileCount
+ @type:
+ function
+ @title:
+ $torrent.fileCount
+ @short:
+ Returns the number of files in a torrent.
+ @syntax:
+ $torrent.fileCount <torrent_number>
+ @description:
+ Returns the number of files in a torrent.
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_INTRET_INT_FUNCTION(fileCount, fileCount, "torrent_number")
+
+/*
+ @doc: torrent.fileName
+ @type:
+ function
+ @title:
+ $torrent.fileName
+ @short:
+ Returns the name of a file in a torrent.
+ @syntax:
+ $torrent.fileName <torrent_number> <file_number>
+ @description:
+ Returns the name of a file in a torrent.
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_STRINGRET_INT_INT_FUNCTION(fileName, fileName, "torrent_number", "file_number")
+
+/*
+ @doc: torrent.filePriority
+ @type:
+ function
+ @title:
+ $torrent.filePriority
+ @short:
+ Returns the priority of a file in a torrent.
+ @syntax:
+ $torrent.filePriority <torrent_number> <file_number>
+ @description:
+ Returns the priority of a file in a torrent.
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_STRINGRET_INT_INT_FUNCTION(filePriority, filePriority, "torrent_number", "file_number")
+
+/*
+ @doc: torrent.setFilePriority
+ @type:
+ command
+ @title:
+ torrent.setFilePriority
+ @short:
+ Sets the priority of a file in a torrent.
+ @syntax:
+ torrent.setFilePriority <torrent_number> <file_number>
+ @description:
+ Sets the priority of a file in a torrent.
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_INT_INT_STRING_COMMAND(setFilePriority, setFilePriority, "torrent_number", "file_number", "priority")
+
+/*
+ @doc: torrent.startAll
+ @type:
+ command
+ @title:
+ torrent.startAll
+ @short:
+ Starts downloading of all torrents
+ @syntax:
+ torrent.startAll
+ @description:
+ Starts downloading of all torrents
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+ [cmd]torrent.stopAll[/cmd], [cmd]torrent.start[/cmd],
+ [cmd]torrent.stop[/cmd]
+*/
+
+TC_KVS_SIMPLE_COMMAND(startAll, startAll)
+
+/*
+ @doc: torrent.stopAll
+ @type:
+ command
+ @title:
+ torrent.stopAll
+ @short:
+ Stops downloading of all torrents
+ @syntax:
+ torrent.stopAll
+ @description:
+ Stops downloading of all torrents
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+ [cmd]torrent.startAll[/cmd], [cmd]torrent.start[/cmd],
+ [cmd]torrent.stop[/cmd]
+*/
+
+TC_KVS_SIMPLE_COMMAND(stopAll, stopAll)
+
+
+/*
+ @doc: torrent.list
+ @type:
+ function
+ @title:
+ torrent.list
+ @short:
+ Returns a list of all torrents
+ @syntax:
+ $torrent.list()
+ @description:
+ Returns a list of all torrents
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+ [cmd]torrent.startAll[/cmd], [cmd]torrent.start[/cmd],
+ [cmd]torrent.stop[/cmd]
+*/
+
+//MP_KVS_SIMPLE_COMMAND(list,list)
+
+/*
+ @doc: torrent.setClient
+ @type:
+ command
+ @title:
+ torrent.setClient
+ @short:
+ Sets the torrent client interface
+ @syntax:
+ torrent.setClient <client_name>
+ @description:
+ Sets the torrent client interface to be used by the
+ torrent interface module. <interface_name> must be one
+ of the client names returned by [cmd]torrent.clientList[/cmd]
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+ [cmd]torrent.detect[/cmd], [fnc]$torrent.client[/fnc]
+*/
+
+TC_KVS_COMMAND(setClient)
+{
+ QString client;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("client", KVS_PT_STRING, 0, client)
+ KVSM_PARAMETERS_END(c)
+
+ for (KviTorrentInterfaceDescriptor *d = g_pDescriptorList->first(); d; d=g_pDescriptorList->next())
+ {
+ if (d->name() == client)
+ {
+ KviTorrentInterface::select(d->instance());
+ KVI_OPTION_STRING(KviOption_stringPreferredTorrentClient) = client;
+
+ if (!c->hasSwitch('q',"quiet"))
+ c->window()->output(KVI_OUT_TORRENT,
+ __tr2qs_ctx("Using client interface \"%Q\".", "torrent"),
+ &client);
+ return true;
+ }
+ }
+
+ if (!c->hasSwitch('q',"quiet"))
+ c->window()->output(KVI_OUT_TORRENT,
+ __tr2qs_ctx("Invalid client interface \"%Q\"!", "torrent"),
+ &client);
+
+ return false;
+}
+
+
+/*
+ @doc: torrent.client
+ @type:
+ function
+ @title:
+ $torrent.client
+ @short:
+ Returns the currently set torrent client interface
+ @syntax:
+ $torrent.client()
+ @description:
+ Returns the currently set torrent client interface.
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+ [cmd]torrent.detect[/cmd], [cmd]torrent.setClient[/cmd]
+*/
+TC_KVS_FUNCTION(client)
+{
+ c->returnValue()->setString(KVI_OPTION_STRING(KviOption_stringPreferredTorrentClient));
+ return true;
+}
+
+/*
+ @doc: torrent.clientList
+ @type:
+ function
+ @title:
+ $torrent.clientList
+ @short:
+ Returns a list of all supported clients.
+ @syntax:
+ $torrent.clientList()
+ @description:
+ Returns a list of all supported clients.
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+ [cmd]torrent.detect[/cmd], [cmd]torrent.setClient[/cmd],
+ [cmd]torrent.client[/cmd]
+*/
+TC_KVS_FUNCTION(clientList)
+{
+ KviKvsArray *pArray = new KviKvsArray();
+ int id=0;
+
+ for (KviTorrentInterfaceDescriptor *d=g_pDescriptorList->first(); d; d=g_pDescriptorList->next())
+ pArray->set(id++, new KviKvsVariant(d->name()));
+
+ c->returnValue()->setArray(pArray);
+ return true;
+}
+
+/*
+ @doc: torrent.state
+ @type:
+ function
+ @title:
+ $torrent.state
+ @short:
+ Returns state of torrent (Stopped, Stalled, Seeding, Downloading)
+ @syntax:
+ $torrent.state <torrent_number>
+ @description:
+ Returns state of torrent (Stopped, Stalled, Seeding, Downloading)
+ Take a look at the [module:torrent]torrent client documentation[/module]
+ for more details about how it works.[br]
+ @seealso:
+ [module:torrent]torrent client documentation[/module],
+*/
+TC_KVS_STRINGRET_INT_FUNCTION(state, state, "torrent_number")
+
+static bool torrent_module_init(KviModule *m)
+{
+ #define TC_KVS_REGCMD(__name,__stringname) KVSM_REGISTER_SIMPLE_COMMAND(m, __stringname, torrent_kvs_cmd_ ## __name)
+ #define TC_KVS_REGFNC(__name,__stringname) KVSM_REGISTER_FUNCTION(m, __stringname, torrent_kvs_fnc_ ## __name)
+
+ TC_KVS_REGCMD(detect, "detect");
+ TC_KVS_REGCMD(setClient, "setClient");
+ TC_KVS_REGCMD(start, "start")
+ TC_KVS_REGCMD(stop, "stop")
+ TC_KVS_REGCMD(announce, "announce")
+ TC_KVS_REGCMD(startAll, "startAll")
+ TC_KVS_REGCMD(stopAll, "stopAll")
+ TC_KVS_REGCMD(setMaxUploadSpeed, "setMaxUploadSpeed")
+ TC_KVS_REGCMD(setMaxDownloadSpeed, "setMaxDownloadSpeed")
+ TC_KVS_REGCMD(setFilePriority, "setFilePriority")
+ TC_KVS_REGFNC(client, "client")
+ TC_KVS_REGFNC(clientList, "clientList")
+ TC_KVS_REGFNC(maxUploadSpeed, "maxUploadSpeed")
+ TC_KVS_REGFNC(maxDownloadSpeed, "maxDownloadSpeed")
+ TC_KVS_REGFNC(speedUp, "speedUp")
+ TC_KVS_REGFNC(speedDown, "speedDown")
+ TC_KVS_REGFNC(trafficUp, "trafficUp")
+ TC_KVS_REGFNC(trafficDown, "trafficDown")
+ TC_KVS_REGFNC(count, "count")
+ TC_KVS_REGFNC(name, "name")
+ TC_KVS_REGFNC(state, "state")
+ TC_KVS_REGFNC(fileCount, "fileCount")
+ TC_KVS_REGFNC(fileName, "fileName")
+ TC_KVS_REGFNC(filePriority, "filePriority")
+
+ g_pDescriptorList = new KviPointerList<KviTorrentInterfaceDescriptor>;
+ g_pDescriptorList->setAutoDelete(true);
+
+#ifdef COMPILE_KDE_SUPPORT
+ g_pDescriptorList->append(new KviKTorrentDCOPInterfaceDescriptor);
+#endif // COMPILE_KDE_SUPPORT
+
+ KviTorrentInterface::select(0);
+
+ if (g_pFrame->mainStatusBar())
+ KviTorrentStatusBarApplet::selfRegister(g_pFrame->mainStatusBar());
+
+
+ if(KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer) == "auto")
+ {
+ KviTorrentInterface::select(auto_detect_torrent_client());
+
+ } else
+ {
+ for (KviTorrentInterfaceDescriptor *d=g_pDescriptorList->first(); d; d=g_pDescriptorList->next())
+ {
+ if (d->name() == KVI_OPTION_STRING(KviOption_stringPreferredTorrentClient))
+ KviTorrentInterface::select(d->instance());
+ }
+ }
+
+ return true;
+}
+
+static bool torrent_module_cleanup( KviModule * m )
+{
+ delete g_pDescriptorList;
+ return true;
+}
+
+static bool torrent_module_can_unload( KviModule * m )
+{
+ return true;
+}
+
+static bool torrent_module_ctrl(KviModule * m,const char * operation,void * param)
+{
+ debug("torrent module ctrl");
+/* if(kvi_strEqualCI(operation,"getAvailableMediaPlayers"))
+ {
+ // we expect param to be a pointer to QStringList
+ QStringList * l = (QStringList *)param;
+ for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next())
+ {
+ l->append(d->name());
+ }
+ return true;
+ }
+ if(kvi_strEqualCI(operation,"detectMediaPlayer"))
+ {
+ auto_detect_player(0);
+ return true;
+ }
+*/
+ return false;
+}
+
+
+
+KVIRC_MODULE(
+ "torrent",
+ "1.0.0",
+ "Copyright (C) 2007 Alexander Stillich (torque at pltn dot org)",
+ "Interface to various torrent clients",
+ torrent_module_init,
+ torrent_module_can_unload,
+ torrent_module_ctrl,
+ torrent_module_cleanup
+)
diff --git a/src/modules/torrent/tc_interface.cpp b/src/modules/torrent/tc_interface.cpp
new file mode 100644
index 00000000..9474a254
--- /dev/null
+++ b/src/modules/torrent/tc_interface.cpp
@@ -0,0 +1,31 @@
+//=============================================================================
+//
+// Common interface for BitTorrent clients.
+//
+// File : tc_interface.cpp
+// Creation date : Fri Jan 1 15:42:25 2007 GMT by Alexander Stillich
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 Szymon Stefanek (pragma at kvirc dot net)
+// Copyright (C) 2007 Alexander Stillich (torque at pltn 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 "tc_interface.h"
+#include "kvi_locale.h"
+
+KviTorrentInterface *KviTorrentInterface::m_selected = 0;
diff --git a/src/modules/torrent/tc_interface.h b/src/modules/torrent/tc_interface.h
new file mode 100644
index 00000000..797ea428
--- /dev/null
+++ b/src/modules/torrent/tc_interface.h
@@ -0,0 +1,164 @@
+#ifndef _TC_INTERFACE_H_
+#define _TC_INTERFACE_H_
+
+//=============================================================================
+//
+// Common interface for BitTorrent clients.
+//
+// File : tc_interface.h
+// Creation date : Fri Jan 1 15:42:25 2007 GMT by Alexander Stillich
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 Szymon Stefanek (pragma at kvirc dot net)
+// Copyright (C) 2007 Alexander Stillich (torque at pltn 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 "kvi_settings.h"
+#include "kvi_qstring.h"
+#include <qobject.h>
+
+class KviTorrentInterface : public QObject
+{
+
+public:
+
+ KviTorrentInterface() {}
+ virtual ~KviTorrentInterface() {}
+
+ virtual int detect() = 0;
+
+ // returns number of torrents in client
+ virtual int count()=0;
+
+/*
+ // path of torrent file
+ virtual QCString getTorrentFile(int i)=0;
+
+ // directory where data is downloaded to
+ virtual QCString getTorrentDataDir(int i)=0;
+*/
+ // number of files in torrent
+ virtual int fileCount(int i)=0;
+ // name of file in torrent
+ virtual QString fileName(int i, int file)=0;
+ // returns file priority (low, normal, high)
+ virtual QString filePriority(int i, int file)=0;
+ // sets file priority
+ virtual bool setFilePriority(int i, int file, const QString &prio)=0;
+
+ virtual bool start(int i)=0;
+ virtual bool stop(int i)=0;
+
+ virtual bool announce(int i)=0;
+
+ virtual bool startAll()=0;
+ virtual bool stopAll()=0;
+/*
+ // remove torrent from client
+ virtual bool removeTorrent(int i)=0;
+
+ virtual bool addTorrent(const QCString &mrl);
+*/
+ // returns state of torrent number i (Stopped, Stalled, Seeding, Downloading)
+ // this uses getTorrentInfo() to obtain the state and then
+ // returns it as string
+ virtual QString state(int i)=0;
+
+ // name of torrent as displayed in client
+ // uses getTorrentInfo()
+ virtual QString name(int i)=0;
+
+ virtual float speedUp()=0;
+ virtual float speedDown()=0;
+
+ virtual float trafficUp()=0;
+ virtual float trafficDown()=0;
+
+ virtual int maxUploadSpeed()=0;
+ virtual int maxDownloadSpeed()=0;
+
+ virtual bool setMaxUploadSpeed(int kbytes_per_sec)=0;
+ virtual bool setMaxDownloadSpeed(int kbytes_per_sec)=0;
+
+ QString lastError() { return m_lastError; }
+
+ static void select(KviTorrentInterface *i) { m_selected = i; }
+ static KviTorrentInterface *selected() { return m_selected; }
+
+protected:
+
+ QString m_lastError;
+
+ static KviTorrentInterface *m_selected;
+};
+
+class KviTorrentInterfaceDescriptor
+{
+public:
+ KviTorrentInterfaceDescriptor() {};
+ virtual ~KviTorrentInterfaceDescriptor() {};
+public:
+ virtual const QString & name() = 0;
+ virtual const QString & description() = 0;
+ virtual KviTorrentInterface * instance() = 0;
+};
+
+#define TORR_DECLARE_DESCRIPTOR(_interfaceclass) \
+ class _interfaceclass ## Descriptor : public KviTorrentInterfaceDescriptor \
+ { \
+ 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 KviTorrentInterface * instance(); \
+ };
+
+#define TORR_IMPLEMENT_DESCRIPTOR(_interfaceclass,_name,_description) \
+ _interfaceclass ## Descriptor::_interfaceclass ## Descriptor() \
+ : KviTorrentInterfaceDescriptor() \
+ { \
+ m_pInstance = 0; \
+ m_szName = _name; \
+ m_szDescription = _description; \
+ } \
+ _interfaceclass ## Descriptor::~_interfaceclass ## Descriptor() \
+ { \
+ delete m_pInstance; \
+ } \
+ const QString & _interfaceclass ## Descriptor::name() \
+ { \
+ return m_szName; \
+ } \
+ const QString & _interfaceclass ## Descriptor::description() \
+ { \
+ return m_szDescription; \
+ } \
+ KviTorrentInterface * _interfaceclass ## Descriptor::instance() \
+ { \
+ if (!m_pInstance) m_pInstance = new _interfaceclass(); \
+ return m_pInstance; \
+ }
+
+#endif // _TC_INTERFACE_H_
+
diff --git a/src/modules/torrent/tc_ktorrentdcopinterface.cpp b/src/modules/torrent/tc_ktorrentdcopinterface.cpp
new file mode 100644
index 00000000..8e770bfc
--- /dev/null
+++ b/src/modules/torrent/tc_ktorrentdcopinterface.cpp
@@ -0,0 +1,500 @@
+//=============================================================================
+//
+// Common interface for BitTorrent clients.
+//
+// File : torr_ktorrentdcopinterface.cpp
+// Creation date : Fri Jan 1 15:42:25 2007 GMT by Alexander Stillich
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 Szymon Stefanek (pragma at kvirc dot net)
+// Copyright (C) 2007 Alexander Stillich (torque at pltn 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.
+//
+//=============================================================================
+
+#ifdef COMPILE_KDE_SUPPORT
+
+#include "kvi_app.h"
+
+
+#include "dcopclient.h" // <-- this include should be hidden in kvilib
+
+#include "tc_ktorrentdcopinterface.h"
+
+
+#include "kvi_locale.h"
+#include <qtimer.h>
+
+TORR_IMPLEMENT_DESCRIPTOR(
+ KviKTorrentDCOPInterface,
+ "ktorrentdcop",
+ __tr2qs_ctx(
+ "An interface to KDE's excellent KTorrent client.\n" \
+ "Download it from http://www.ktorrent.org\n",
+ "torrent"
+ )
+)
+
+#define ERROR_MSG \
+ QCString msg; \
+ if (!findRunningApp(m_szAppId)) \
+ msg = "KTorrent's isn't running!"; \
+ else \
+ msg = "Something's wrong here! KTorrent's DCOP interface has probably changed."; \
+ m_lastError = __tr2qs_ctx(QString(msg), "torrent"); \
+ debug("%s (%s:%d): %s", __PRETTY_FUNCTION__, __FILE__, __LINE__, (const char*)msg); \
+
+#define ERROR_MSG_RANGE(I, SIZE) \
+ KviQString::sprintf(m_lastError, __tr2qs_ctx("Index out of range: %d [0-%d]!", "torrent"), I, (SIZE>0)?(SIZE-1):0); \
+ debug("%s (%s:%d): Index out of range: %d [0-%d]!", __PRETTY_FUNCTION__ , __FILE__, __LINE__, I, (SIZE>0)?(SIZE-1):0);
+
+#define ERROR_RET_BOOL \
+ { \
+ ERROR_MSG \
+ return false; \
+ }
+
+#define ERROR_RET_NUM \
+ { \
+ ERROR_MSG \
+ return -1; \
+ }
+
+// TODO: unused?
+#define ERROR_RET_STRING \
+ { \
+ ERROR_MSG \
+ return ""; \
+ }
+
+#define ERROR_RET_VOID \
+ { \
+ ERROR_MSG \
+ return; \
+ }
+
+#define CHECK_RANGE_BOOL(I, SIZE) \
+ if (I<0 || I>=SIZE) \
+ { \
+ ERROR_MSG_RANGE(I, SIZE) \
+ return false; \
+ }
+
+#define CHECK_RANGE_INT(I, SIZE) \
+ if (I<0 || I>=SIZE) \
+ { \
+ ERROR_MSG_RANGE(I, SIZE) \
+ return -1; \
+ }
+
+#define CHECK_RANGE_STRING(I, SIZE) \
+ if (I<0 || I>=SIZE) \
+ { \
+ ERROR_MSG_RANGE(I, SIZE) \
+ return ""; \
+ }
+
+KviKTorrentDCOPInterface::KviKTorrentDCOPInterface()
+ : KviDCOPHelper(false, "ktorrent")
+{
+ printf("KviKTorrentDCOPInterface\n");
+
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(slotTimer()));
+ timer->start(250, FALSE);
+
+ // make sure we have a list of files,
+ // otherwise functions dealing would
+ // fail if called the first time
+ slotTimer();
+}
+
+KviKTorrentDCOPInterface::~KviKTorrentDCOPInterface()
+{
+ printf("~KviKTorrentDCOPInterface\n");
+}
+
+void KviKTorrentDCOPInterface::slotTimer()
+{
+ if (!findRunningApp(m_szAppId))
+ return;
+
+ m_ti.clear();
+
+ KviValueList<int> ret;
+ if (!qvalueListIntRetIntDCOPCall("KTorrent", "getTorrentNumbers(int)", ret, 0))
+ ERROR_RET_VOID
+
+ for (int i=0; i<ret.size(); i++)
+ {
+ KviQCStringList info;
+ if (!qcstringListRetIntDCOPCall("KTorrent", "getTorrentInfo(int)", info, ret[i]))
+ ERROR_RET_VOID
+
+ if (info.size() == 0)
+ continue;
+
+ TorrentInfo item;
+ if (!makeTorrentInfo(item, info))
+ return;
+
+ item.num = ret[i];
+ m_ti.append(item);
+ }
+
+ qHeapSort(m_ti);
+}
+
+int KviKTorrentDCOPInterface::detect()
+{
+ if (!findRunningApp(m_szAppId))
+ return 0;
+
+ return 100;
+}
+
+bool makeSize(float &sz, const QString &s, const QString &u)
+{
+ bool ok;
+ sz = s.toFloat(&ok);
+ if (!ok)
+ return false;
+
+ if (u == "B")
+ ;
+ else
+ if (u == "KB")
+ sz = sz * 1024.0;
+ else
+ if (u == "MB")
+ sz = sz * 1024.0 * 1024.0;
+ else
+ if (u == "GB")
+ sz = sz * 1024.0 * 1024.0 * 1024.0;
+ else
+ return false;
+
+ return true;
+}
+
+bool KviKTorrentDCOPInterface::start(int i)
+{
+ CHECK_RANGE_BOOL(i, m_ti.size())
+
+ debug("starting %s [%d]", (const char*)m_ti[i].name, m_ti[i].num);
+ if (!voidRetIntDCOPCall("KTorrent", "start(int)", m_ti[i].num))
+ ERROR_RET_BOOL
+
+ return true;
+}
+
+bool KviKTorrentDCOPInterface::stop(int i)
+{
+ CHECK_RANGE_BOOL(i, m_ti.size())
+
+ debug("stopping %s [%d]", (const char*)m_ti[i].name, m_ti[i].num);
+ if (!voidRetIntBoolDCOPCall("KTorrent", "stop(int, bool)", m_ti[i].num, true))
+ ERROR_RET_BOOL
+
+ return true;
+}
+
+bool KviKTorrentDCOPInterface::announce(int i)
+{
+ CHECK_RANGE_BOOL(i, m_ti.size())
+
+ debug("announcing %s [%d]", (const char*)m_ti[i].name, m_ti[i].num);
+ if (!voidRetIntDCOPCall("KTorrent", "announce(int)", m_ti[i].num))
+ ERROR_RET_BOOL
+ return true;
+}
+
+QString KviKTorrentDCOPInterface::state(int i)
+{
+ CHECK_RANGE_STRING(i, m_ti.size())
+
+ return m_ti[i].state;
+}
+
+QString KviKTorrentDCOPInterface::name(int i)
+{
+ CHECK_RANGE_STRING(i, m_ti.size())
+
+ return m_ti[i].name;
+}
+
+int KviKTorrentDCOPInterface::fileCount(int i)
+{
+ CHECK_RANGE_INT(i, m_ti.size())
+
+ int ret;
+ if (!intRetIntDCOPCall("KTorrent", "getFileCount(int)", ret, m_ti[i].num))
+ ERROR_RET_NUM
+
+ return ret;
+}
+
+QString KviKTorrentDCOPInterface::fileName(int i, int file)
+{
+ CHECK_RANGE_STRING(i, m_ti.size())
+
+ QCStringList ret;
+ if (!qcstringListRetIntDCOPCall("KTorrent", "getFileNames(int)", ret, m_ti[i].num))
+ ERROR_RET_STRING
+
+ CHECK_RANGE_STRING(file, ret.size())
+
+ return ret[file];
+}
+
+QString KviKTorrentDCOPInterface::filePriority(int i, int file)
+{
+ CHECK_RANGE_STRING(i, m_ti.size())
+
+ QValueList<int> ret;
+ if (!qvalueListIntRetIntDCOPCall("KTorrent", "getFilePriorities(int)",ret, m_ti[i].num))
+ ERROR_RET_STRING
+
+ CHECK_RANGE_STRING(file, ret.size())
+
+ debug("prio: %d", ret[file]);
+ switch (ret[file])
+ {
+ case 1: return "low";
+ case 2: return "normal";
+ case 3: return "high";
+ }
+
+ ERROR_RET_STRING
+}
+
+bool KviKTorrentDCOPInterface::setFilePriority(int i, int file, const QString &prio)
+{
+ CHECK_RANGE_BOOL(i, m_ti.size())
+
+ int prion;
+ if (prio == "low")
+ prion = 1;
+ else
+ if (prio == "normal")
+ prion = 2;
+ else
+ if (prio == "high")
+ prion = 1;
+ else
+ ERROR_RET_BOOL
+
+ if (!voidRetIntIntIntDCOPCall("KTorrent", "setFilePriority(int,int,int)", m_ti[i].num, file, prion))
+ ERROR_RET_BOOL
+
+ return true;
+}
+
+bool KviKTorrentDCOPInterface::startAll()
+{
+ if (!voidRetIntDCOPCall("KTorrent", "startAll(int)", 3))
+ ERROR_RET_BOOL
+
+ return true;
+}
+
+bool KviKTorrentDCOPInterface::stopAll()
+{
+ if (!voidRetIntDCOPCall("KTorrent", "stopAll(int)", 3))
+ ERROR_RET_BOOL
+
+ return true;
+}
+
+int KviKTorrentDCOPInterface::count()
+{
+ return m_ti.size();
+}
+
+float KviKTorrentDCOPInterface::speedUp()
+{
+ KviQCStringList ret;
+ if (!qcstringListRetVoidDCOPCall("KTorrent", "getInfo()", ret))
+ ERROR_RET_NUM
+
+ QStringList tmp = QStringList::split(" ", ret[2]);
+ if (tmp.size() != 8)
+ ERROR_RET_NUM
+
+ bool ok;
+ float f = tmp[6].toFloat(&ok);
+ if (!ok)
+ ERROR_RET_NUM
+
+ return f;
+}
+
+float KviKTorrentDCOPInterface::speedDown()
+{
+ KviQCStringList ret;
+ if (!qcstringListRetVoidDCOPCall("KTorrent", "getInfo()", ret))
+ ERROR_RET_NUM
+
+ QStringList tmp = QStringList::split(" ", ret[2]);
+ if (tmp.size() != 8)
+ ERROR_RET_NUM
+
+ bool ok;
+ float f = tmp[2].toFloat(&ok);
+ if (!ok)
+ ERROR_RET_NUM
+
+ return f;
+}
+
+float KviKTorrentDCOPInterface::trafficUp()
+{
+ KviQCStringList ret;
+ if (!qcstringListRetVoidDCOPCall("KTorrent", "getInfo()", ret))
+ ERROR_RET_NUM
+
+ QStringList tmp = QStringList::split(" ", ret[1]);
+ if (tmp.size() != 8)
+ ERROR_RET_NUM
+
+ float f;
+ if (!makeSize(f, tmp[6], tmp[7]))
+ ERROR_RET_NUM
+
+ return f;
+}
+
+float KviKTorrentDCOPInterface::trafficDown()
+{
+ KviQCStringList ret;
+ if (!qcstringListRetVoidDCOPCall("KTorrent", "getInfo()", ret))
+ ERROR_RET_NUM
+
+ QStringList tmp = QStringList::split(" ", ret[1]);
+ if (tmp.size() != 8)
+ ERROR_RET_NUM
+
+ float f;
+ if (!makeSize(f, tmp[2], tmp[3]))
+ ERROR_RET_NUM
+
+ return f;
+}
+
+bool KviKTorrentDCOPInterface::makeTorrentInfo(TorrentInfo &ti, const KviQCStringList &ret)
+{
+ if (ret.size() != 10)
+ ERROR_RET_BOOL
+
+ ti.name = ret[0];
+ if (ret[1] == "Seeding")
+ ti.state = "Seeding";
+ else
+ if (ret[1] == "Stalled")
+ ti.state = "Stalled";
+ else
+ if (ret[1] == "Downloading")
+ ti.state = "Downloading";
+ else
+ ti.state = "Stopped";
+
+
+ QStringList tmp;
+ tmp = QStringList::split(" ", ret[2]);
+ if (tmp.size()!=2 || !makeSize(ti.trafficDown, tmp[0], tmp[1]))
+ ERROR_RET_BOOL
+
+ tmp = QStringList::split(" ", ret[3]);
+ if (tmp.size()!=2 || !makeSize(ti.size, tmp[0], tmp[1]))
+ ERROR_RET_BOOL
+
+ tmp = QStringList::split(" ", ret[4]);
+ if (tmp.size()!=2 || !makeSize(ti.trafficUp, tmp[0], tmp[1]))
+ ERROR_RET_BOOL
+
+
+ bool ok;
+ tmp = QStringList::split(" ", ret[5]);
+ if (tmp.size()!=2)
+ ERROR_RET_BOOL
+ ti.speedDown = tmp[0].toFloat(&ok);
+ if (!ok)
+ ERROR_RET_BOOL
+
+ tmp = QStringList::split(" ", ret[6]);
+ if (tmp.size()!=2)
+ ERROR_RET_BOOL
+ ti.speedUp = tmp[0].toFloat(&ok);
+ if (!ok)
+ ERROR_RET_BOOL
+
+
+ // torrent name, status, downloaded, size, uploaded, down spd, up spd, none, peers, % complete
+ ti.peers = ret[8].toInt(&ok);
+ if (!ok)
+ ERROR_RET_BOOL
+
+ tmp = QStringList::split(" ", ret[9]);
+ if (tmp.size()!=2)
+ ERROR_RET_BOOL
+ ti.percent = tmp[0].toFloat(&ok);
+ if (!ok)
+ ERROR_RET_BOOL
+
+ return true;
+}
+
+int KviKTorrentDCOPInterface::maxUploadSpeed()
+{
+ int ret;
+ if (!intRetVoidDCOPCall("KTorrent", "maxUploadRate()", ret))
+ {
+ ERROR_MSG
+ return -1;
+ }
+ return ret;
+}
+
+int KviKTorrentDCOPInterface::maxDownloadSpeed()
+{
+ int ret;
+ if (!intRetVoidDCOPCall("KTorrent", "maxDownloadRate()", ret))
+ {
+ ERROR_MSG
+ return -1;
+ }
+ return ret;
+}
+
+bool KviKTorrentDCOPInterface::setMaxUploadSpeed(int kbytes_per_sec)
+{
+ if (!voidRetIntDCOPCall("KTorrent", "setMaxUploadSpeed(int)", kbytes_per_sec))
+ ERROR_RET_BOOL
+ return true;
+}
+
+bool KviKTorrentDCOPInterface::setMaxDownloadSpeed(int kbytes_per_sec)
+{
+ if (!voidRetIntDCOPCall("KTorrent", "setMaxDownloadSpeed(int)", kbytes_per_sec))
+ ERROR_RET_BOOL
+ return true;
+}
+
+
+#include "tc_ktorrentdcopinterface.moc"
+
+#endif // COMPILE_KDE_SUPPORT
+
diff --git a/src/modules/torrent/tc_ktorrentdcopinterface.h b/src/modules/torrent/tc_ktorrentdcopinterface.h
new file mode 100644
index 00000000..8f39810f
--- /dev/null
+++ b/src/modules/torrent/tc_ktorrentdcopinterface.h
@@ -0,0 +1,131 @@
+#ifndef _TC_KTORRENTDCOPINTERFACE_H_
+#define _TC_KTORRENTDCOPINTERFACE_H_
+
+//=============================================================================
+//
+// DCOP interface for KTorrent client.
+//
+// File : torr_ktorrentdcopinterface.h
+// Creation date : Fri Jan 1 15:42:25 2007 GMT by Alexander Stillich
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 Szymon Stefanek (pragma at kvirc dot net)
+// Copyright (C) 2007 Alexander Stillich (torque at pltn 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 "tc_interface.h"
+
+#ifdef COMPILE_KDE_SUPPORT
+
+#include <kvi_dcophelper.h>
+
+// DCOP interface to KTorrent. this has 'DCOP' in its name
+// because in kde4 there will be a D-BUS interface.
+class KviKTorrentDCOPInterface : public KviTorrentInterface,
+ private KviDCOPHelper
+{
+ Q_OBJECT
+
+public:
+
+ KviKTorrentDCOPInterface();
+ virtual ~KviKTorrentDCOPInterface();
+
+ virtual int detect();
+
+ virtual int count();
+
+ virtual bool start(int i);
+ virtual bool stop(int i);
+ virtual bool announce(int i);
+ virtual QString state(int i);
+ virtual QString name(int i);
+
+ virtual int fileCount(int i);
+ virtual QString fileName(int i, int file);
+ virtual QString filePriority(int i, int file);
+ virtual bool setFilePriority(int i, int file, const QString &prio);
+
+ virtual bool startAll();
+ virtual bool stopAll();
+
+ virtual int maxUploadSpeed();
+ virtual int maxDownloadSpeed();
+
+ virtual bool setMaxUploadSpeed(int kbytes_per_sec);
+ virtual bool setMaxDownloadSpeed(int kbytes_per_sec);
+
+ virtual float speedUp();
+ virtual float speedDown();
+
+ virtual float trafficUp();
+ virtual float trafficDown();
+
+private slots:
+
+ // polls client and extracts information.
+ // this is done because the order of torrents returned changes
+ // each time a torrent's state changes.
+ // we want to present a consistent list (in terms of indices) to
+ // the user, so we extract the info and sort it by name.
+ // otherwise the user would have a hard time figuring out what's
+ // going on. we could sort each time a function working with
+ // torrents is called, but this would be horribly slow ...
+ void slotTimer();
+
+private:
+
+ struct TorrentInfo
+ {
+ // internal number
+ int num;
+ // name displayed in ktorrent
+ QString name;
+ // state of torrent
+ QString state;
+ // bytes
+ float size;
+ // bytes
+ float trafficUp;
+ // bytes
+ float trafficDown;
+ // KB/s
+ float speedUp;
+ // KB/s
+ float speedDown;
+ // percent complete
+ float percent;
+ // number of peers
+ int peers;
+
+ bool operator<(const TorrentInfo &ti) { return name < ti.name; }
+ };
+
+ QValueList<TorrentInfo> m_ti;
+
+private:
+
+ bool makeTorrentInfo(TorrentInfo &ti, const KviQCStringList &ret);
+};
+
+TORR_DECLARE_DESCRIPTOR(KviKTorrentDCOPInterface)
+
+#endif // COMPILE_KDE_SUPPORT
+
+#endif // _TC_KTORRENTDCOPINTERFACE_H_
diff --git a/src/modules/torrent/tc_statusbarapplet.cpp b/src/modules/torrent/tc_statusbarapplet.cpp
new file mode 100644
index 00000000..5d23a299
--- /dev/null
+++ b/src/modules/torrent/tc_statusbarapplet.cpp
@@ -0,0 +1,69 @@
+#include "qtimer.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "tc_interface.h"
+#include "tc_statusbarapplet.h"
+
+KviTorrentStatusBarApplet::KviTorrentStatusBarApplet(KviStatusBar *parent, KviStatusBarAppletDescriptor *desc)
+ : KviStatusBarApplet(parent, desc)
+{
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(update()));
+ timer->start(250, FALSE);
+// updateDisplay();
+//
+ setText("torrent client");
+}
+
+KviTorrentStatusBarApplet::~KviTorrentStatusBarApplet()
+{
+}
+
+static KviStatusBarApplet *CreateTorrentClientApplet(KviStatusBar *bar, KviStatusBarAppletDescriptor *desc)
+{
+ debug("CreateTorrentClientApplet");
+ return new KviTorrentStatusBarApplet(bar, desc);
+}
+
+void KviTorrentStatusBarApplet::selfRegister(KviStatusBar *bar)
+{
+ KviStatusBarAppletDescriptor *d = new KviStatusBarAppletDescriptor(
+ __tr2qs("Torrent Client"),
+ "torrentapplet",
+ CreateTorrentClientApplet,
+ "torrent", *(g_pIconManager->getSmallIcon(KVI_SMALLICON_AWAY)));
+
+ bar->registerAppletDescriptor(d);
+}
+
+QString formatSize(float sz)
+{
+ if (sz >= 1024.0f*1024.0f*1024.0f)
+ return QString("%1 GB").arg(sz / (1024.0f*1024.0f*1024.0f), 2, 'f', 2);
+ if (sz >= 1024.0f*1024.0f)
+ return QString("%1 MB").arg(sz / (1024.0f*1024.0f), 2, 'f', 2);
+ if (sz >= 1024.0f)
+ return QString("%1 KB").arg(sz / 1024.0f, 2, 'f', 2);
+ return QString("%1 B").arg(sz, 2, 'f', 2);
+}
+
+void KviTorrentStatusBarApplet::update()
+{
+ if (KviTorrentInterface::selected())
+ {
+ QString msg = QString("up: %1 K/s (%2), dn: %3 K/s (%4)")
+ .arg(KviTorrentInterface::selected()->speedUp(), 2)
+ .arg(formatSize(KviTorrentInterface::selected()->trafficUp()))
+ .arg(KviTorrentInterface::selected()->speedDown(), 2)
+ .arg(formatSize(KviTorrentInterface::selected()->trafficDown()));
+
+ setText(msg);
+
+ } else
+ {
+ setText(__tr2qs_ctx("No client selected!", "torrent"));
+ }
+}
+
+#include "tc_statusbarapplet.moc"
+
diff --git a/src/modules/torrent/tc_statusbarapplet.h b/src/modules/torrent/tc_statusbarapplet.h
new file mode 100644
index 00000000..03dd6d0d
--- /dev/null
+++ b/src/modules/torrent/tc_statusbarapplet.h
@@ -0,0 +1,26 @@
+#ifndef _TC_STATUSBARAPPLET_H_
+#define _TC_STATUSBARAPPLET_H_
+
+#include "kvi_statusbar.h"
+#include "kvi_statusbarapplet.h"
+
+// TODO: check if it gets destroyed
+// TODO: proper icon!
+class KviTorrentStatusBarApplet : public KviStatusBarApplet
+{
+ Q_OBJECT
+
+public:
+
+ KviTorrentStatusBarApplet(KviStatusBar *parent, KviStatusBarAppletDescriptor *desc);
+ virtual ~KviTorrentStatusBarApplet();
+
+ static void selfRegister(KviStatusBar *bar);
+
+private slots:
+
+ void update();
+
+};
+
+#endif // _TC_STATUSBARAPPLET_H_
diff --git a/src/modules/url/Makefile.am b/src/modules/url/Makefile.am
new file mode 100644
index 00000000..c2d88957
--- /dev/null
+++ b/src/modules/url/Makefile.am
@@ -0,0 +1,23 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+SUBDIRS = caps
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviurl.la
+
+libkviurl_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkviurl_la_SOURCES = libkviurl.cpp
+libkviurl_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+
+noinst_HEADERS= libkviurl.h icons.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
+
+libkviurl.cpp: libkviurl.moc
diff --git a/src/modules/url/caps/Makefile.am b/src/modules/url/caps/Makefile.am
new file mode 100644
index 00000000..231fa79c
--- /dev/null
+++ b/src/modules/url/caps/Makefile.am
@@ -0,0 +1,9 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+tmpdir = $(pluglibdir)/caps/action/
+
+tmp_DATA= url
+
+EXTRA_DIST = $(tmp_DATA)
diff --git a/src/modules/url/caps/url b/src/modules/url/caps/url
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/modules/url/caps/url
diff --git a/src/modules/url/icons.h b/src/modules/url/icons.h
new file mode 100644
index 00000000..20cc7823
--- /dev/null
+++ b/src/modules/url/icons.h
@@ -0,0 +1,554 @@
+const char * url_icon_xpm[] = {
+"16 16 104 2",
+" c None",
+". c #FFFFFF",
+"+ c #F7F7F7",
+"@ c #EFEFEF",
+"# c #E7E7E7",
+"$ c #DFDFDF",
+"% c #D7D7D7",
+"& c #CFCFCF",
+"* c #C7C7C7",
+"= c #BFBFBF",
+"- c #B7B7B7",
+"; c #AFAFAF",
+"> c #A7A7A7",
+", c #9F9F9F",
+"' c #979797",
+") c #8F8F8F",
+"! c #878787",
+"~ c #000000",
+"{ c #090909",
+"] c #121212",
+"^ c #1B1B1B",
+"/ c #242424",
+"( c #2D2D2D",
+"_ c #363636",
+": c #3F3F3F",
+"< c #484848",
+"[ c #515151",
+"} c #5B5B5B",
+"| c #646464",
+"1 c #6D6D6D",
+"2 c #767676",
+"3 c #7F7F7F",
+"4 c #C0C0C0",
+"5 c #AEAEAE",
+"6 c #A5A5A5",
+"7 c #9B9B9B",
+"8 c #929292",
+"9 c #898989",
+"0 c #777777",
+"a c #A7BED2",
+"b c #97C5EC",
+"c c #95C8F4",
+"d c #96BDE0",
+"e c #929DA7",
+"f c #8B96A0",
+"g c #90B7D9",
+"h c #90BDE4",
+"i c #798FA3",
+"j c #888888",
+"k c #6F6F6F",
+"l c #8AACCA",
+"m c #738493",
+"n c #5A5A5A",
+"o c #919191",
+"p c #676767",
+"q c #A3A8AD",
+"r c #94BBDE",
+"s c #8CB3D5",
+"t c #66727B",
+"u c #9A9A9A",
+"v c #5F5F5F",
+"w c #99AAB8",
+"x c #91B3D0",
+"y c #A3A3A3",
+"z c #575757",
+"A c #94B6D3",
+"B c #8697A6",
+"C c #7EA0BD",
+"D c #3E3E3E",
+"E c #ADADAD",
+"F c #4F4F4F",
+"G c #92B9DC",
+"H c #797F83",
+"I c #636363",
+"J c #748A9E",
+"K c #728EA7",
+"L c #353535",
+"M c #B6B6B6",
+"N c #474747",
+"O c #85ADCF",
+"P c #515C65",
+"Q c #2C2C2C",
+"R c #91BEE5",
+"S c #5F6B74",
+"T c #81A9CB",
+"U c #222222",
+"V c #C8C8C8",
+"W c #373737",
+"X c #7A8B9A",
+"Y c #8FBCE3",
+"Z c #87AFD1",
+"` c #3F4549",
+" . c #191919",
+".. c #D1D1D1",
+"+. c #2F2F2F",
+"@. c #101010",
+"#. c #DADADA",
+"$. c #272727",
+"%. c #060606",
+"&. c #E3E3E3",
+"*. c #1F1F1F",
+"=. c #ECECEC",
+"-. c #171717",
+";. c #0F0F0F",
+". + @ # $ % & * = - ; > , ' ) ! ",
+"+ ~ { ] ^ / ( _ : < [ } | 1 2 3 ",
+"@ { 4 4 4 - 5 6 7 8 9 3 2 1 3 0 ",
+"# ] 4 4 a b c d e f g c h i j k ",
+"$ ^ 4 - 5 c c 8 9 3 l c m n o p ",
+"% / - 5 q c r 9 3 2 s c t [ u v ",
+"& ( 5 6 w c x 3 2 1 c c [ < y z ",
+"* _ 6 7 A c B 2 1 m c C < D E F ",
+"= : 7 8 G c H 1 I J c K D L M N ",
+"- < 8 9 c c 1 I n O c P L Q = : ",
+"; [ 9 3 R c I n S c T L Q U V W ",
+"> } 3 2 X Y Z C c T ` Q U ...+.",
+", | 2 1 I n [ < D L Q U .@.#.$.",
+"' 1 1 I n [ < D L Q U .@.%.&.*.",
+") 2 3 j o u y E M = V ..#.&.=.-.",
+"! 3 0 k p v z F N : W +.$.*.-.;."};
+
+const char * url_toolbar_xpm[] = {
+"32 32 38 1",
+" c None",
+". c #000000",
+"+ c #FFFBFF",
+"@ c #B6C3FF",
+"# c #B6C3A6",
+"$ c #FFFFFF",
+"% c #836977",
+"& c #710818",
+"* c #20000E",
+"= c #710018",
+"- c #B60818",
+"; c #710000",
+"> c #A36B7E",
+", c #20050E",
+"' c #FFDFCF",
+") c #B60018",
+"! c #B60800",
+"~ c #B60000",
+"{ c #B62018",
+"] c #B64118",
+"^ c #FF2018",
+"/ c #B62000",
+"( c #B66B7E",
+"_ c #040001",
+": c #FF4118",
+"< c #B66908",
+"[ c #58321C",
+"} c #FF6918",
+"| c #B64100",
+"1 c #FFC3A6",
+"2 c #20252F",
+"3 c #FF4100",
+"4 c #EA6B7E",
+"5 c #713051",
+"6 c #A25E06",
+"7 c #B6727E",
+"8 c #B64151",
+"9 c #4A3211",
+"................+@..............",
+"................++..............",
+"................++..............",
+"................+++.............",
+"................+++.............",
+"................+++.............",
+"................#++@...#$#......",
+"................@+++..@+++@.....",
+"................#+++..+++++.....",
+"................@++++#+++++%....",
+"................#++++++++++#....",
+"......++@.......++++++++++$.....",
+".....++++@......++++++.+++......",
+".&..@++++++....+++++++..........",
+"&&&*++++++++...+++++++..........",
+"&&=++++++++++.+++++++++.........",
+"-;>++&&.#++++++++++++++.........",
+";-+>=&&&,'+++++++++++++#........",
+");-;=;&&&*#++++++$$.#+++........",
+"!-~-)-=-&&,+++++++...+++........",
+".{{!-;);-;&=#+++++@...++#.......",
+"..]^!-~-;-=&='+++++...@++.......",
+"...{{/{~);-;=;>+++++...++.......",
+".....{/^!-~-)-=#++++@...+@......",
+"......{/^!-!-;);(++++_...+......",
+"........]:/^!-~-;#+++@,..@......",
+".........<:/{!-~);(+++&*,.......",
+"..........[}|:/^!-~1+++-&&......",
+"............}|:/^!-~(++>&;&2....",
+".............[3:|:/^!4++;-=5....",
+"...............<6|:/{!7+#;-;8...",
+"................9}|}|:/1+-~-)..."};
+
+const char * urlhigh_toolbar_xpm[] = {
+"32 32 33 1",
+" c None",
+". c #000000",
+"+ c #D4FF00",
+"@ c #E1FF3A",
+"# c #710818",
+"$ c #20000E",
+"% c #710018",
+"& c #B60818",
+"* c #710000",
+"= c #20050E",
+"- c #B60018",
+"; c #B60800",
+"> c #B60000",
+", c #B62018",
+"' c #B64118",
+") c #FF2018",
+"! c #B62000",
+"~ c #A36B7E",
+"{ c #B66B7E",
+"] c #040001",
+"^ c #FF4118",
+"/ c #B66908",
+"( c #58321C",
+"_ c #FF6918",
+": c #B64100",
+"< c #20252F",
+"[ c #FF4100",
+"} c #EA6B7E",
+"| c #713051",
+"1 c #A25E06",
+"2 c #B6727E",
+"3 c #B64151",
+"4 c #4A3211",
+"................+@..............",
+"................++..............",
+"................++..............",
+"................+++.............",
+"................+++.............",
+"................+++.............",
+"................@++@...@+@......",
+"................@+++..@+++@.....",
+"................@+++..+++++.....",
+"................@++++@+++++@....",
+"................@++++++++++@....",
+"......++@.......+++++++++++.....",
+".....++++@......++++++.+++......",
+".#..@++++++....+++++++..........",
+"###$++++++++...+++++++..........",
+"##%++++++++++.+++++++++.........",
+"&*@++##.@++++++++++++++.........",
+"*&@@%###=@+++++++++++++@........",
+"-*&*%*###$@++++++++.@+++........",
+";&>&-&%&##=+++++++...+++........",
+".,,;&*-*&*#%@+++++@...++@.......",
+"..');&>&*&%#%@+++++...@++.......",
+"...,,!,>-*&*%*~+++++...++.......",
+".....,!);&>&-&%@++++@...+@......",
+"......,!);&;&*-*{++++]...@......",
+"........'^!);&>&*@@++@=..@......",
+"........./^!,;&>-*{+++#$=.......",
+"..........(_:^!);&>@+++&##......",
+"............_:^!);&>{++~#*#<....",
+".............([^:^!);}++*&%|....",
+".............../1:^!,;2+@*&*3...",
+"................4_:_:^!@@&>&-..."};
+
+const char * urlconf_toolbar_xpm[] = {
+"32 32 256 2",
+" c None",
+". c #000000",
+"+ c #FFFBFF",
+"@ c #B6C3FF",
+"# c #B6C3A6",
+"$ c #FFFFFF",
+"% c #836977",
+"& c #710818",
+"* c #F8F5F8",
+"= c #212121",
+"- c #0F0F0F",
+"; c #060606",
+"> c #20000E",
+", c #EAE7EA",
+"' c #D3D2D3",
+") c #E3E1E3",
+"! c #FCF9FC",
+"~ c #BEBCBE",
+"{ c #858585",
+"] c #545454",
+"^ c #323232",
+"/ c #010101",
+"( c #710018",
+"_ c #FEFAFE",
+": c #C3C1C3",
+"< c #9E9E9E",
+"[ c #B7B7B7",
+"} c #A5A5A5",
+"| c #C0BFC0",
+"1 c #EEECEE",
+"2 c #848384",
+"3 c #757575",
+"4 c #828282",
+"5 c #4A4A4A",
+"6 c #83C6C6",
+"7 c #B60818",
+"8 c #710000",
+"9 c #A36B7E",
+"0 c #FCF8FC",
+"a c #767576",
+"b c #272727",
+"c c #3D3D3D",
+"d c #707070",
+"e c #9B9B9B",
+"f c #ABABAB",
+"g c #9D9D9D",
+"h c #8A8A8A",
+"i c #999999",
+"j c #9E9D9E",
+"k c #CDCBCD",
+"l c #FBF7FB",
+"m c #F1EEF1",
+"n c #EEEBEE",
+"o c #A46D80",
+"p c #703441",
+"q c #242020",
+"r c #353535",
+"s c #888888",
+"t c #A3A3A3",
+"u c #949494",
+"v c #959595",
+"w c #A3A1A3",
+"x c #A09FA0",
+"y c #868586",
+"z c #FAF7FA",
+"A c #B60018",
+"B c #720303",
+"C c #B91221",
+"D c #770C0C",
+"E c #883446",
+"F c #948888",
+"G c #6A6A6A",
+"H c #6D6D6D",
+"I c #9F9F9F",
+"J c #AAAAAA",
+"K c #A1A1A1",
+"L c #A4A4A4",
+"M c #A0A0A0",
+"N c #939393",
+"O c #898989",
+"P c #6B6B6B",
+"Q c #C9C9C9",
+"R c #B60800",
+"S c #B1303C",
+"T c #8B5151",
+"U c #A06D72",
+"V c #B28D91",
+"W c #B6B3B3",
+"X c #9C9C9C",
+"Y c #B1B1B1",
+"Z c #B3B3B3",
+"` c #AFAFAF",
+" . c #A6A59E",
+".. c #B5A874",
+"+. c #B3A46A",
+"@. c #949287",
+"#. c #919191",
+"$. c #939293",
+"%. c #171717",
+"&. c #A85752",
+"*. c #686463",
+"=. c #8C8C8C",
+"-. c #BBBBBB",
+";. c #C2C2C2",
+">. c #BEBEBE",
+",. c #BDBDBD",
+"'. c #ADACAC",
+"). c #8F7E3D",
+"!. c #D1B440",
+"~. c #CDAF39",
+"{. c #BDA64A",
+"]. c #9F9E98",
+"^. c #989898",
+"/. c #7F7F7F",
+"(. c #B7C2F5",
+"_. c #414141",
+":. c #525151",
+"<. c #616161",
+"[. c #7A7A7A",
+"}. c #B6B6B6",
+"|. c #C3C3C3",
+"1. c #85847F",
+"2. c #A58F3B",
+"3. c #E5C752",
+"4. c #D7BA47",
+"5. c #CBAE3C",
+"6. c #9F9981",
+"7. c #A2A2A2",
+"8. c #7E7E7E",
+"9. c #CFCDCF",
+"0. c #0D0D0D",
+"a. c #2C2C2C",
+"b. c #141414",
+"c. c #100C0C",
+"d. c #505050",
+"e. c #C6C6C6",
+"f. c #CACACA",
+"g. c #A9A9A7",
+"h. c #5A5027",
+"i. c #D4BB58",
+"j. c #E8CB57",
+"k. c #D0B651",
+"l. c #99968B",
+"m. c #979797",
+"n. c #6F6F6F",
+"o. c #070707",
+"p. c #202020",
+"q. c #2F2F2F",
+"r. c #383838",
+"s. c #585858",
+"t. c #7C7C7C",
+"u. c #969696",
+"v. c #CECECE",
+"w. c #C3C2C2",
+"x. c #888784",
+"y. c #44433C",
+"z. c #89805E",
+"A. c #8F8D83",
+"B. c #8F8F8F",
+"C. c #3A3A3A",
+"D. c #9DA4C6",
+"E. c #343434",
+"F. c #575757",
+"G. c #909090",
+"H. c #D0D0D0",
+"I. c #D5D5D5",
+"J. c #CBCBCB",
+"K. c #BFBFBF",
+"L. c #C4C4C4",
+"M. c #AEAEAE",
+"N. c #BABABA",
+"O. c #B0B0B0",
+"P. c #666666",
+"Q. c #2D2D2D",
+"R. c #C0BEC0",
+"S. c #040001",
+"T. c #020202",
+"U. c #373737",
+"V. c #363636",
+"W. c #565656",
+"X. c #D4D4D4",
+"Y. c #C1C1C1",
+"Z. c #C7C7C7",
+"`. c #C5C5C5",
+" + c #C0C0C0",
+".+ c #B2B2B2",
+"++ c #696968",
+"@+ c #B8B6B8",
+"#+ c #F2EEF2",
+"$+ c #FDF9FD",
+"%+ c #20050E",
+"&+ c #404040",
+"*+ c #4D4D4D",
+"=+ c #646464",
+"-+ c #5F5F5F",
+";+ c #5D5D5D",
+">+ c #929292",
+",+ c #8D8A8A",
+"'+ c #AA808A",
+")+ c #080808",
+"!+ c #424242",
+"~+ c #2E2E2E",
+"{+ c #1A1A1A",
+"]+ c #313131",
+"^+ c #3C3C3C",
+"/+ c #4B4B4B",
+"(+ c #C8C8C8",
+"_+ c #A6A6A6",
+":+ c #484848",
+"<+ c #633636",
+"[+ c #FFC7AB",
+"}+ c #303030",
+"|+ c #3B3B3B",
+"1+ c #1D1D1D",
+"2+ c #282828",
+"3+ c #393939",
+"4+ c #7D7D7D",
+"5+ c #262423",
+"6+ c #1B1A19",
+"7+ c #191919",
+"8+ c #4B2B2E",
+"9+ c #BC1515",
+"0+ c #B66B7E",
+"a+ c #20252F",
+"b+ c #040404",
+"c+ c #0E0E0E",
+"d+ c #0B0B0B",
+"e+ c #252525",
+"f+ c #403C3B",
+"g+ c #9F5036",
+"h+ c #743B2F",
+"i+ c #1A1918",
+"j+ c #342A28",
+"k+ c #974736",
+"l+ c #FF261E",
+"m+ c #EA6B7E",
+"n+ c #713051",
+"o+ c #030303",
+"p+ c #333333",
+"q+ c #090909",
+"r+ c #BA751F",
+"s+ c #866132",
+"t+ c #9E542B",
+"u+ c #FE4821",
+"v+ c #B62000",
+"w+ c #B62018",
+"x+ c #B6727E",
+"y+ c #B64151",
+"z+ c #242424",
+"A+ c #2A2A2A",
+"B+ c #4A3211",
+"C+ c #FF6918",
+"D+ c #B64100",
+"E+ c #FF4118",
+"F+ c #FFC3A6",
+"G+ c #B60000",
+". . . . . . . . . . . . . . . . + @ . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . + + . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . + + . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . + + + . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . + + + . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . + + + . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . # + + @ . . . # $ # . . . . . . ",
+". . . . . . . . . . . . . . . . @ + + + . . @ + + + @ . . . . . ",
+". . . . . . . . . . . . . . . . # + + + . . + + + + + . . . . . ",
+". . . . . . . . . . . . . . . . @ + + + + # + + + + + % . . . . ",
+". . . . . . . . . . . . . . . . # + + + + + + + + + + # . . . . ",
+". . . . . . + + @ . . . . . . . + + + + + + + + + + $ . . . . . ",
+". . . . . + + + + @ . . . . . . + + + + + + . + + + . . . . . . ",
+". & . . @ + + + + + * = - ; . + + + + + + + . . . . . . . . . . ",
+"& & & > + , ' ) ! + ~ { ] ^ / + + + + + + + . . . . . . . . . . ",
+"& & ( _ : < [ } | 1 2 3 4 5 + 6 + + + + + + + . . . . . . . . . ",
+"7 8 9 0 a b c d e f g h i j k l m n + + + + + . . . . . . . . . ",
+"8 7 + o p q r c s t u e u v 4 w x y z + + + + # . . . . . . . . ",
+"A B C D E F G H I J K L M I N h O P Q / # + + + . . . . . . . . ",
+"R S T U V W X i Y Z ` ...+.@.#.v $.%.. . + + + . . . . . . . . ",
+". &.*.=.-.;.;.>.,.,.'.).!.~.{.].^./.(.. . . + + # . . . . . . . ",
+". _.:.<.] 5 [.}.|.>.1.2.3.4.5.6.7.8.9.b 0.. @ + + . . . . . . . ",
+". a.b.c.%.d.g e.f.f.g.h.i.j.k.l.m.X ^.n.= . . + + . . . . . . . ",
+". o.p.q.r.s.t.u.f.v.w.x.y.z.A.B.J 8.C.r.D.. . . + @ . . . . . . ",
+". . . ; E.c F.G.H.I.J.K.>.L.M.N.O.P.= Q.R.S.. . . + . . . . . . ",
+". . . T.U.V.W.L X.K Y.Z.`.Q +Y..+++@+#+$+@ %+. . @ . . . . . . ",
+". . / p.&+*+=+-+;+r.F.>+Z.,.I H B.,+'++ + + & > %+. . . . . . . ",
+". . )+r ^ !+5 ~+{+]+^+/+(+_+r ~+]+:+<+[++ + + 7 & & . . . . . . ",
+". . / a.}+r |+U.%.1+2+3+4+d 5+6+7+}+8+9+0++ + 9 & 8 & a+. . . . ",
+". . . b+a.}+c+d+2+}+e+^+^+f+g+h+i+j+k+l+R m++ + 8 7 ( n+. . . . ",
+". . . . T.o+. . T.2+q.E.p+r.q+r+s+t+u+v+w+R x++ # 8 7 8 y+. . . ",
+". . . . . . . . . z+A+p.1+}+/ . B+C+D+C+D+E+v+F++ 7 G+7 A . . . "};
diff --git a/src/modules/url/libkviurl.cpp b/src/modules/url/libkviurl.cpp
new file mode 100644
index 00000000..16430c67
--- /dev/null
+++ b/src/modules/url/libkviurl.cpp
@@ -0,0 +1,910 @@
+//
+// This file is part of the KVIrc irc client distribution
+// Copyright (C) 1999-2002 Andrea Parrella (yap@kvirc.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_styled_controls.h"
+#include "kvi_module.h"
+#include "libkviurl.h"
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_kvs_eventmanager.h"
+#include "kvi_tal_popupmenu.h"
+
+#include "kvi_menubar.h"
+#include "kvi_internalcmd.h"
+#include "kvi_iconmanager.h"
+#include "kvi_action.h"
+#include "kvi_actionmanager.h"
+#include "kvi_taskbar.h"
+#include "icons.h"
+#include "kvi_pointerlist.h"
+#include <qfiledialog.h>
+#include <qmessagebox.h>
+#include <qcursor.h>
+#include <qdatetime.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <q3textstream.h>
+ #include <QTextStream>
+#endif
+
+static QPixmap * g_pUrlIconPixmap = 0;
+static KviUrlAction * g_pUrlAction = 0;
+
+typedef struct _UrlDlgList
+{
+ UrlDialog *dlg;
+ int menu_id;
+} UrlDlgList;
+
+const char *g_pUrlListFilename = "/list.kviurl";
+const char *g_pBanListFilename = "/list.kviban";
+
+KviPointerList<KviUrl> *g_pList;
+KviPointerList<UrlDlgList> *g_pUrlDlgList;
+KviPointerList<KviStr> *g_pBanList;
+ConfigDialog *g_pConfigDialog;
+
+KviStr szConfigPath;
+
+void saveUrlList();
+void loadUrlList();
+void saveBanList();
+void loadBanList();
+UrlDlgList * findFrame();
+bool urllist();
+void url_module_help();
+
+
+#define KVI_URL_EXTENSION_NAME "URL module extenstion"
+
+static KviModuleExtension * url_extension_alloc(KviModuleExtensionAllocStruct * s)
+{
+ urllist();
+ return 0;
+}
+
+
+KviUrlAction::KviUrlAction(QObject * pParent)
+: KviKvsAction(pParent,
+ "url.list",
+ "url.list",
+ __tr2qs("Show URL List"),
+ __tr2qs("Shows the URL list window"),
+ KviActionManager::categoryGeneric())
+{
+ m_pBigIcon = new QPixmap(url_toolbar_xpm);
+ m_pSmallIcon = new QPixmap(url_icon_xpm);
+}
+
+KviUrlAction::~KviUrlAction()
+{
+ delete m_pBigIcon;
+ delete m_pSmallIcon;
+}
+
+QPixmap * KviUrlAction::bigIcon()
+{
+ return m_pBigIcon;
+}
+
+QPixmap * KviUrlAction::smallIcon()
+{
+ return m_pSmallIcon;
+}
+
+// ---------------------------- CLASS URLDIALOG ------------------------begin //
+
+UrlDialog::UrlDialog(KviPointerList<KviUrl> *g_pList)
+:KviWindow(KVI_WINDOW_TYPE_TOOL,g_pFrame,"URL List")
+{
+ m_pMenuBar = new KviTalMenuBar(this,"url menu");
+ m_pUrlList = new KviTalListView(this);
+ //m_pUrlList = new KviListView(this,"list");
+ KviConfig cfg(szConfigPath.ptr(),KviConfig::Read);
+
+ KviTalPopupMenu *pop;
+
+ pop = new KviTalPopupMenu(this);
+ pop->insertItem(__tr2qs("&Configure"),this,SLOT(config()));
+ pop->insertItem(__tr2qs("&Help"),this,SLOT(help()));
+ pop->insertItem(__tr2qs("Clo&se"),this,SLOT(close_slot()));
+ m_pMenuBar->insertItem(__tr2qs("&Module"),pop);
+
+ pop = new KviTalPopupMenu(this);
+ pop->insertItem(__tr2qs("&Load"),this,SLOT(loadList()));
+ pop->insertItem(__tr2qs("&Save"),this,SLOT(saveList()));
+ pop->insertItem(__tr2qs("&Clear"),this,SLOT(clear()));
+ m_pMenuBar->insertItem(__tr2qs("&List"),pop);
+
+ m_pUrlList->setShowSortIndicator(true);
+ m_pUrlList->addColumn(__tr2qs("URL"));
+ m_pUrlList->addColumn(__tr2qs("Window"));
+ m_pUrlList->addColumn(__tr2qs("Count"));
+ m_pUrlList->addColumn(__tr2qs("Timestamp"));
+
+ cfg.setGroup("colsWidth");
+ m_pUrlList->setColumnWidth(0,cfg.readIntEntry("Url",170));
+ m_pUrlList->setColumnWidth(1,cfg.readIntEntry("Window",130));
+ m_pUrlList->setColumnWidth(2,cfg.readIntEntry("Count",70));
+ m_pUrlList->setColumnWidth(3,cfg.readIntEntry("Timestamp",70));
+
+ connect(m_pUrlList,SIGNAL(doubleClicked(KviTalListViewItem *)),SLOT(dblclk_url(KviTalListViewItem *)));
+ connect(m_pUrlList,SIGNAL(rightButtonPressed(KviTalListViewItem *, const QPoint &, int)),SLOT(popup(KviTalListViewItem *, const QPoint &, int)));
+
+// setFocusHandlerNoChildren(m_pUrlList);
+#ifdef COMPILE_USE_QT4
+ m_pUrlList->setFocusPolicy(Qt::StrongFocus);
+#else
+ m_pUrlList->setFocusPolicy(QWidget::StrongFocus);
+#endif
+ m_pUrlList->setFocus();
+}
+
+void UrlDialog::config()
+{
+ if (!g_pConfigDialog) g_pConfigDialog = new ConfigDialog();
+}
+
+void UrlDialog::help()
+{
+//#warning "help"
+// m_pFrm->requestHelpOn("doc_plugin_url.kvihelp");
+}
+
+void UrlDialog::saveList()
+{
+ saveUrlList();
+}
+
+void UrlDialog::loadList()
+{
+ loadUrlList();
+}
+
+void UrlDialog::clear()
+{
+ g_pList->clear();
+ for (UrlDlgList *tmpitem=g_pUrlDlgList->first();tmpitem;tmpitem=g_pUrlDlgList->next()) {
+ if (tmpitem->dlg) tmpitem->dlg->m_pUrlList->clear();
+ }
+}
+
+/*
+void UrlDialog::saveProperties()
+{
+
+ KviWindowProperty p;
+ p.rect = externalGeometry();
+ p.isDocked = isAttached();
+ p.splitWidth1 = 0;
+ p.splitWidth2 = 0;
+ p.timestamp = 0;
+ p.imagesVisible = 0;
+ KviWindow * w = m_pFrm->activeWindow();
+ p.isMaximized = isAttached() && w ? w->isMaximized() : isMaximized();
+ p.topSplitWidth1 = 0;
+ p.topSplitWidth2 = 0;
+ p.topSplitWidth3 = 0;
+ g_pOptions->m_pWinPropertiesList->setProperty(caption(),&p);
+}
+*/
+
+void UrlDialog::close_slot()
+{
+ close();
+}
+
+void UrlDialog::remove()
+{
+ if (!m_pUrlList->currentItem()) {
+ QMessageBox::warning(0,__tr2qs("Warning - KVIrc"),__tr2qs("Select an URL."),QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+
+ for(KviUrl *tmp=g_pList->first();tmp;tmp=g_pList->next())
+ {
+ if (tmp->url == m_pUrlList->currentItem()->text(0)) {
+ g_pList->removeRef(tmp);
+ m_pUrlList->takeItem(m_pUrlList->currentItem());
+ return;
+ }
+ }
+}
+
+void UrlDialog::findtext()
+{
+//#warning "find text"
+/*
+ if (!m_pUrlList->currentItem()) {
+ kvirc_plugin_warning_box(__tr("Select an URL"));
+ return;
+ }
+ for(KviUrl *tmp=g_pList->first();tmp;tmp=g_pList->next())
+ {
+ if (tmp->url == KviStr(m_pUrlList->currentItem()->text(0))) {
+ g_pList->find(tmp);
+ KviStr ft="findtext %";
+ ft.replaceAll('%',tmp->url.ptr());
+ KviWindow *wnd = m_pFrm->findWindow(tmp->window.ptr());
+ if (wnd) {
+ if (kvirc_plugin_execute_command(wnd,ft.ptr())) {
+ if (wnd->mdiParent()) m_pFrm->m_pMdi->setTopChild(wnd->mdiParent(),true);
+ }
+ } else kvirc_plugin_warning_box(__tr("Window not found"));
+ }
+
+ }
+*/
+}
+
+void UrlDialog::dblclk_url(KviTalListViewItem *item)
+{
+ QString cmd="openurl ";
+ cmd.append(item->text(0));
+ KviKvsScript::run(cmd,this);
+}
+
+void UrlDialog::popup(KviTalListViewItem *item, const QPoint &point, int col)
+{
+ if (col == 0) {
+ m_szUrl = item->text(0);
+ KviTalPopupMenu p(0,"menu");
+ p.insertItem(__tr2qs("&Remove"),this,SLOT(remove()));
+ p.insertItem(__tr2qs("&Find Text"),this,SLOT(findtext()));
+ p.insertSeparator();
+ m_pListPopup = new KviTalPopupMenu(0,"list");
+ int i=0;
+ for(KviWindow *w=g_pFrame->windowList()->first();w;w=g_pFrame->windowList()->next()){
+ if ((w->type() <= 2) || (w->type() == 2) || (w->type() == 6)) { // values defined in kvi_define.h (console,channel,query,chat,uwindow)
+ m_pListPopup->insertItem(QString(w->plainTextCaption()),i);
+ m_pListPopup->connectItem(i,this,SLOT(sayToWin(int)));
+ i++;
+ }
+ }
+ p.insertItem(__tr2qs("&Say to Window"),m_pListPopup);
+ p.exec(QCursor::pos());
+ }
+}
+
+void UrlDialog::sayToWin(int itemID)
+{
+ KviWindow *wnd = g_pApp->findWindowByCaption(m_pListPopup->text(itemID).utf8().data());
+ QString say=QString("PRIVMSG %1 %2").arg(wnd->windowName()).arg(m_szUrl.ptr());
+ if (wnd) {
+ KviKvsScript::run(say,wnd);
+ wnd->raise();
+ wnd->setActiveWindow();
+ wnd->setFocus();
+ } else QMessageBox::warning(0,__tr2qs("Warning - KVIrc"),__tr2qs("Window not found."),QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+}
+
+QPixmap *UrlDialog::myIconPtr()
+{
+ //QPixmap *icon = new QPixmap(url_icon_xpm);
+ //return icon;
+ return g_pUrlIconPixmap;
+}
+
+void UrlDialog::addUrl(QString url, QString window, QString count, QString timestamp)
+{
+ KviTalListViewItem *UrlItem = new KviTalListViewItem(m_pUrlList);
+
+ UrlItem->setText(0, url);
+ UrlItem->setText(1, window);
+ UrlItem->setText(2, count);
+ UrlItem->setText(3, timestamp);
+}
+
+void UrlDialog::resizeEvent(QResizeEvent *)
+{
+ int hght = m_pMenuBar->heightForWidth(width());
+ m_pMenuBar->setGeometry(0,0,width(),hght);
+ m_pUrlList->setGeometry(0,hght,width(),height() - hght);
+}
+
+UrlDialog::~UrlDialog()
+{
+ KviConfig cfg(szConfigPath.ptr(),KviConfig::Write);
+ cfg.setGroup("ConfigDialog");
+ if (cfg.readBoolEntry("SaveColumnWidthOnClose",false)) {
+ cfg.setGroup("ColsWidth");
+ cfg.writeEntry("Url",m_pUrlList->columnWidth(0));
+ cfg.writeEntry("Window",m_pUrlList->columnWidth(1));
+ cfg.writeEntry("Count",m_pUrlList->columnWidth(2));
+ cfg.writeEntry("Timestamp",m_pUrlList->columnWidth(3));
+ }
+
+ delete m_pUrlList;
+/* if (m_pListPopup) delete m_pListPopup;
+ m_pListPopup = 0;
+ if (m_pMenuBar) delete m_pMenuBar;
+ m_pMenuBar = 0;*/
+ UrlDlgList *tmpitem = findFrame();
+ tmpitem->dlg = 0;
+}
+
+// ----------------------------- CLASS URLDIALOG -------------------------end //
+
+// --------------------------- CLASS CONFIGDIALOG ----------------------begin //
+
+ConfigDialog::ConfigDialog()
+:QDialog()
+{
+ setCaption(__tr2qs("URL Module Configuration"));
+
+ QGridLayout *g = new QGridLayout(this,4,2,10,10);
+
+ KviConfig *cfg = new KviConfig(szConfigPath.ptr(),KviConfig::Read);
+ cfg->setGroup("ConfigDialog");
+
+ cb[0] = new KviStyledCheckBox(__tr2qs("Save URL list on module unload"),this);
+ cb[0]->setChecked(cfg->readBoolEntry("SaveUrlListOnUnload",false));
+ g->addMultiCellWidget(cb[0],0,0,0,1);
+
+ cb[1] = new KviStyledCheckBox(__tr2qs("Save columns width on URL list close"),this);
+ cb[1]->setChecked(cfg->readBoolEntry("SaveColumnWidthOnClose",false));
+ g->addMultiCellWidget(cb[1],1,1,0,1);
+
+ bool tmp = cfg->readBoolEntry("BanEnabled",false);
+ delete cfg;
+
+ m_pBanFrame = new BanFrame(this,"banlist",tmp);
+ g->addMultiCellWidget(m_pBanFrame,3,3,0,1);
+
+ QPushButton *b;
+ // configure buttons
+ b = new QPushButton(__tr2qs("&Cancel"),this,"discard");
+ connect(b,SIGNAL(clicked()),this,SLOT(discardbtn()));
+ g->addWidget(b,4,0);
+
+ b = new QPushButton(__tr2qs("&OK"),this,"accept");
+ connect(b,SIGNAL(clicked()),this,SLOT(acceptbtn()));
+ g->addWidget(b,4,1);
+
+ show();
+}
+
+void ConfigDialog::discardbtn()
+{
+ delete this;
+}
+
+void ConfigDialog::acceptbtn()
+{
+ if (m_pBanFrame) m_pBanFrame->saveBans();
+
+ KviConfig *cfg = new KviConfig(szConfigPath.ptr(),KviConfig::Write);
+ cfg->setGroup("ConfigDialog");
+ cfg->writeEntry("SaveUrlListOnUnload",cb[0]->isChecked());
+ cfg->writeEntry("SaveColumnWidthOnClose",cb[1]->isChecked());
+ delete cfg;
+
+ delete this;
+}
+
+void ConfigDialog::closeEvent(QCloseEvent *)
+{
+ delete this;
+}
+
+ConfigDialog::~ConfigDialog()
+{
+ for(int i=0;i<cbnum;i++) delete cb[i];
+ g_pConfigDialog = 0;
+}
+
+// --------------------------- CLASS CONFIGDIALOG ------------------------end //
+
+// ---------------------------- CLASS BANFRAME ------------------------begin //
+
+BanFrame::BanFrame(QWidget *parent, const char *name, bool banEnabled)
+:QFrame(parent,name)
+{
+ setFrameStyle(QFrame::Panel | QFrame::Raised);
+
+ QGridLayout *g = new QGridLayout(this,2,2,10,10);
+
+ m_pEnable = new KviStyledCheckBox(__tr2qs("Enable URL ban list"),this);
+ connect(m_pEnable,SIGNAL(clicked()),this,SLOT(enableClicked()));
+ m_pEnable->setChecked(banEnabled);
+ g->addMultiCellWidget(m_pEnable,0,0,0,1);
+
+ m_pBanList = new KviTalListBox(this);
+ m_pBanList->setMinimumHeight(100);
+ loadBanList();
+ for(KviStr *tmp=g_pBanList->first();tmp;tmp=g_pBanList->next()) m_pBanList->insertItem(tmp->ptr()); // load ban list into listbox
+ m_pBanList->setEnabled(m_pEnable->isChecked());
+ g->addMultiCellWidget(m_pBanList,1,1,0,1);
+
+ m_pAddBtn = new QPushButton(__tr2qs("&Add Ban"),this,"add");
+ connect(m_pAddBtn,SIGNAL(clicked()),this,SLOT(addBan()));
+ m_pAddBtn->setEnabled(m_pEnable->isChecked());
+ g->addWidget(m_pAddBtn,2,0);
+
+ m_pRemoveBtn = new QPushButton(__tr2qs("&Remove Selected"),this,"remove");
+ connect(m_pRemoveBtn,SIGNAL(clicked()),this,SLOT(removeBan()));
+ m_pRemoveBtn->setEnabled(m_pEnable->isChecked());
+ g->addWidget(m_pRemoveBtn,2,1);
+}
+
+void BanFrame::enableClicked()
+{
+ m_pBanList->setEnabled(m_pEnable->isChecked());
+ m_pAddBtn->setEnabled(m_pEnable->isChecked());
+ m_pRemoveBtn->setEnabled(m_pEnable->isChecked());
+}
+
+void BanFrame::addBan()
+{
+ bool ok = false;
+ KviStr *text = new KviStr(QInputDialog::getText(__tr2qs("URL Ban List"),__tr2qs("Add"),QLineEdit::Normal,QString::null,&ok,this));
+ if (ok && !text->isEmpty()) {
+ g_pBanList->append(text);
+ m_pBanList->insertItem(text->ptr());
+ }
+}
+
+void BanFrame::removeBan()
+{
+ uint i = 0;
+ while ((!m_pBanList->isSelected(i)) && (i < m_pBanList->count())) i++;
+ if (!m_pBanList->isSelected(i)) {
+ QMessageBox::warning(0,__tr2qs("Warning - KVIrc"),__tr2qs("Select a ban."),QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ KviStr item(m_pBanList->text(i).utf8().data());
+ for(KviStr *tmp=g_pBanList->first();tmp;tmp=g_pBanList->next())
+ {
+ if (*tmp == item)
+ {
+ g_pBanList->removeCurrent();
+ return;
+ }
+ }
+
+ m_pBanList->removeItem(i);
+
+}
+
+void BanFrame::saveBans()
+{
+ if (m_pEnable->isChecked()) saveBanList();
+ KviConfig *cfg = new KviConfig(szConfigPath.ptr(),KviConfig::Write);
+ cfg->setGroup("ConfigDialog");
+ cfg->writeEntry("BanEnabled",m_pEnable->isChecked());
+ delete cfg;
+}
+
+BanFrame::~BanFrame()
+{
+
+}
+
+// ---------------------------- CLASS URLTOOLBAR -------------------------end //
+
+void saveUrlList()
+{
+ QString urllist;
+ g_pApp->getLocalKvircDirectory(urllist,KviApp::ConfigPlugins);
+ urllist += g_pUrlListFilename;
+ QFile file;
+ file.setName(urllist);
+ file.open(IO_WriteOnly);
+
+ QTextStream stream(&file);
+
+ stream << g_pList->count() << endl;
+
+ for(KviUrl *tmp=g_pList->first();tmp;tmp=g_pList->next())
+ {
+ stream << tmp->url << endl;
+ stream << tmp->window << endl;
+ stream << tmp->count << endl;
+ stream << tmp->timestamp << endl;
+ }
+ file.flush();
+ file.close();
+}
+
+void loadUrlList()
+{
+ KviStr urllist;
+ g_pApp->getLocalKvircDirectory(urllist,KviApp::ConfigPlugins);
+ urllist += g_pUrlListFilename;
+ QFile file;
+ file.setName(QString::fromUtf8(urllist.ptr()));
+ if (!file.open(IO_ReadOnly))return;
+#ifdef COMPILE_USE_QT4
+ Q3TextStream stream(&file);
+#else
+ QTextStream stream(&file);
+#endif
+
+
+ g_pList->clear();
+
+ for (UrlDlgList *tmpitem=g_pUrlDlgList->first();tmpitem;tmpitem=g_pUrlDlgList->next()) {
+ if (tmpitem->dlg) tmpitem->dlg->m_pUrlList->clear();
+ }
+ KviUrl *tmp;
+ int i=0;
+ int num = stream.readLine().toInt();
+ while ((!stream.eof()) && (i<num)){
+ tmp = new KviUrl();
+ tmp->url = stream.readLine();
+ tmp->window = stream.readLine();
+ tmp->count = stream.readLine().toInt();
+ tmp->timestamp = stream.readLine();
+
+ g_pList->append(tmp);
+
+ for (UrlDlgList *tmpitem=g_pUrlDlgList->first();tmpitem;tmpitem=g_pUrlDlgList->next()) {
+ if (tmpitem->dlg) {
+ QString tmpCount;
+ tmpCount.setNum(tmp->count);
+ tmpitem->dlg->addUrl(QString(tmp->url), QString(tmp->window), tmpCount, QString(tmp->timestamp));
+ }
+ }
+ i++;
+ }
+ file.close();
+}
+
+void saveBanList()
+{
+ KviStr banlist;
+ g_pApp->getLocalKvircDirectory(banlist,KviApp::ConfigPlugins);
+ banlist += g_pBanListFilename;
+ QFile file;
+ file.setName(QString::fromUtf8(banlist.ptr()));
+ file.open(IO_WriteOnly);
+
+ QTextStream stream(&file);
+
+ stream << g_pBanList->count() << endl;
+ for(KviStr *tmp=g_pBanList->first();tmp;tmp=g_pBanList->next())
+ {
+ stream << tmp->ptr() << endl;
+ }
+ file.flush();
+ file.close();
+}
+
+void loadBanList()
+{
+ KviStr banlist;
+ g_pApp->getLocalKvircDirectory(banlist,KviApp::ConfigPlugins);
+ banlist += g_pBanListFilename;
+ QFile file;
+ file.setName(QString::fromUtf8(banlist.ptr()));
+ if (!file.open(IO_ReadOnly))return;
+#ifdef COMPILE_USE_QT4
+ Q3TextStream stream(&file);
+#else
+ QTextStream stream(&file);
+#endif
+ g_pBanList->clear();
+
+ int i=0;
+ int num = stream.readLine().toInt();
+ while ((!stream.eof()) && (i<num)){
+ KviStr *tmp = new KviStr(stream.readLine());
+ g_pBanList->append(tmp);
+ i++;
+ }
+ file.close();
+}
+
+
+/*
+ @doc: url.list
+ @type:
+ command
+ @title:
+ url.list
+ @short:
+ Opens url list
+ @syntax:
+ url.list
+ @description:
+ This command opens a window containing the urls' list.
+ In the list there is other information:[br]
+ [U]Window[/U] : window where the url has been shown last[br]
+ [U]Count[/U] : number of urls shown[br]
+ [U]Timestamp[/U] : date/time when the url has been shown first[br]
+ Clicking right on the url column of the list a menu will popup, through it
+ you can remove the selected item, find the url in the window it appeared last, and
+ say it to: [I]@Console, Channels, Querys, DCC Chats[/I] and [I]User windows[/I].[br]
+ The list is saved to file when you click on the menu item or when you unload the plugin
+ on condition that you have checked the relative checkbox in configuration dialog.[br]
+ You can also open the url in your web browser double clicking on it in the url list window.[br][br]
+
+ */
+
+static bool url_kvs_cmd_list(KviKvsModuleCommandCall * c)
+{
+ urllist();
+ return true;
+}
+
+
+UrlDlgList *findFrame()
+{
+ UrlDlgList *tmpitem = g_pUrlDlgList->first();
+ if (!tmpitem) {
+ UrlDlgList *udl = new UrlDlgList();
+ udl->dlg = 0;
+ udl->menu_id = -1;
+ g_pUrlDlgList->append(udl);
+ tmpitem = g_pUrlDlgList->current();
+ }
+ return tmpitem;
+}
+
+bool urllist()
+{
+ UrlDlgList *tmpitem = findFrame();
+ if (tmpitem->dlg) return false;
+
+ tmpitem->dlg = new UrlDialog(g_pList);
+ g_pFrame->addWindow(tmpitem->dlg);
+
+ for(KviUrl *tmp=g_pList->first();tmp;tmp=g_pList->next())
+ {
+ QString tmpCount;
+ tmpCount.setNum(tmp->count);
+ tmpitem->dlg->addUrl(QString(tmp->url), QString(tmp->window), tmpCount, QString(tmp->timestamp));
+ }
+ return true;
+}
+
+
+/*
+ @doc: url.config
+ @type:
+ command
+ @title:
+ url.config
+ @short:
+ Loads URL list module
+ @syntax:
+ url.config
+ @description:
+ This command opens a configuration window where it is possible
+ to setup plugin's parameters. You can also open this window by
+ using popup menu in the url list window or by clicking on the "configure plugin" button
+ in plugins options.<BR><BR>
+ <H3>Configure dialog options:</H3>
+ There is also a ban list widget, which allows to have a list of words that plugin mustn't catch.<BR><BR>
+ <I>E.g.<BR>
+ <blockquote>if the word "ftp" is inserted in the ban list and if in a window there is an output like "ftp.kvirc.net",
+ the url will not be catched.</blockquote></I>
+ <HR>
+ */
+
+static bool url_kvs_cmd_config(KviKvsModuleCommandCall * c)
+{
+ if (!g_pConfigDialog) g_pConfigDialog = new ConfigDialog();
+ return true;
+}
+
+int check_url(KviWindow *w,const QString &szUrl) // return 0 if no occurence of the url were found
+{
+ int tmp = 0;
+
+ for(KviStr *tmpi=g_pBanList->first();tmpi;tmpi=g_pBanList->next())
+ {
+ if (szUrl.find(QString(tmpi->ptr())) != -1) tmp++;
+ }
+ if (tmp > 0) return tmp;
+
+ for(KviUrl *u = g_pList->first();u;u=g_pList->next())
+ {
+ if (u->url == szUrl) {
+ u->window = w->plainTextCaption();
+ u->count++;
+ tmp++;
+ }
+ }
+
+ for (UrlDlgList *tmpitem=g_pUrlDlgList->first();tmpitem;tmpitem=g_pUrlDlgList->next()) {
+ if (tmpitem->dlg) {
+ KviTalListViewItemIterator lvi(tmpitem->dlg->m_pUrlList);
+ for(;lvi.current();++lvi)
+ {
+ if (lvi.current()->text(0) == szUrl) {
+ int tmpCount = lvi.current()->text(2).toInt();
+ tmpCount++;
+ QString tmpStr;
+ tmpStr.setNum(tmpCount);
+ lvi.current()->setText(2,tmpStr);
+ lvi.current()->setText(1,w->plainTextCaption());
+ }
+ }
+ }
+ }
+ return tmp;
+}
+
+bool urllist_module_event_onUrl(KviKvsModuleEventCall * c)
+{
+ KviKvsVariant * vUrl = c->firstParam();
+ QString szUrl;
+ if(vUrl)vUrl->asString(szUrl);
+
+ if (check_url(c->window(),szUrl) == 0)
+ {
+
+ KviUrl *tmp = new KviUrl;
+ KviStr tmpTimestamp;
+ QDate d = QDate::currentDate();
+ KviStr date(KviStr::Format,"%d-%d%d-%d%d",d.year(),d.month() / 10,d.month() % 10,d.day() / 10,d.day() % 10);
+ tmpTimestamp = "["+date+"]"+" [";
+ tmpTimestamp += QTime::currentTime().toString()+"]";
+ tmp->url = szUrl;
+ tmp->window = c->window()->plainTextCaption();
+ tmp->count = 1;
+ tmp->timestamp = tmpTimestamp;
+
+ g_pList->append(tmp);
+ for (UrlDlgList *tmpitem=g_pUrlDlgList->first();tmpitem;tmpitem=g_pUrlDlgList->next()) {
+ if (tmpitem->dlg) {
+ QString tmpCount;
+ tmpCount.setNum(tmp->count);
+ tmpitem->dlg->addUrl(QString(tmp->url), QString(tmp->window), tmpCount, QString(tmp->timestamp));
+ tmpitem->dlg->taskBarItem()->highlight(false);
+ }
+ }
+ }
+ return true;
+}
+
+
+/* @doc: url.load
+ @type:
+ command
+ @title:
+ url.load
+ @short:
+ Loads URL list module
+ @syntax:
+ url.load
+ @description:
+ Loads the URL list module which keeps track of all urls shown in kvirc windows.
+*/
+
+
+static bool url_module_init(KviModule *m)
+{
+ KviModuleExtensionDescriptor * d = m->registerExtension("tool",
+ KVI_URL_EXTENSION_NAME,
+ __tr2qs("View URL list"),
+ url_extension_alloc);
+ if(d)d->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_URL)));
+
+ g_pList = new KviPointerList<KviUrl>;
+ g_pList->setAutoDelete(true);
+
+ g_pUrlDlgList = new KviPointerList<UrlDlgList>;
+ g_pUrlDlgList->setAutoDelete(true);
+
+ g_pBanList = new KviPointerList<KviStr>;
+ g_pBanList->setAutoDelete(true);
+
+ g_pUrlIconPixmap = new QPixmap(url_icon_xpm);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"list",url_kvs_cmd_list);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"config",url_kvs_cmd_config);
+ g_pUrlAction = new KviUrlAction(KviActionManager::instance());
+ KviActionManager::instance()->registerAction(g_pUrlAction);
+
+ m->kvsRegisterAppEventHandler(KviEvent_OnUrl,urllist_module_event_onUrl);
+
+ g_pApp->getLocalKvircDirectory(szConfigPath,KviApp::ConfigPlugins,"url.conf");
+
+ loadUrlList();
+ loadBanList();
+
+ UrlDlgList *udl = new UrlDlgList();
+ udl->dlg = 0;
+ g_pUrlDlgList->append(udl);
+
+ return true;
+}
+
+static bool url_module_cleanup(KviModule *m)
+{
+ KviConfig cfg(szConfigPath.ptr(),KviConfig::Read);
+ cfg.setGroup("ConfigDialog");
+ if (cfg.readBoolEntry("SaveUrlListOnUnload",false) == true) saveUrlList();
+ for (UrlDlgList *tmpitem=g_pUrlDlgList->first();tmpitem;tmpitem=g_pUrlDlgList->next()) {
+ if (tmpitem->dlg) tmpitem->dlg->close();
+ }
+
+ delete g_pList;
+ g_pList = 0;
+ delete g_pBanList;
+ g_pBanList = 0;
+
+ delete g_pUrlDlgList;
+ g_pUrlDlgList = 0;
+ delete g_pUrlAction;
+ g_pUrlAction = 0;
+
+
+ delete g_pUrlIconPixmap;
+ g_pUrlIconPixmap = 0;
+
+ return true;
+}
+
+static bool url_module_can_unload(KviModule *m)
+{
+ // FIXME: really ugly :/
+ return false;
+}
+
+void url_module_config()
+{
+ if (!g_pConfigDialog) g_pConfigDialog = new ConfigDialog();
+}
+
+/*
+ @doc: url
+ @type:
+ module
+ @short:
+ The URL list module: keeps track of all urls shown in kvirc windows
+ @title:
+ The URL list module
+ @body:
+ This plugin keeps track of all urls shown in kvirc windows.
+ <H3>Exported commands:</H3>
+ <B>/url.list</B> : this command opens a window containing the urls' list.
+ In the list there is other information:<BR>
+ <U>Window</U> : window where the url has been shown last<BR>
+ <U>Count</U> : number of urls shown<BR>
+ <U>Timestamp</U> : date/time when the url has been shown first<BR>
+ Clicking right on the url column of the list a menu will popup, through it
+ you can remove the selected item, find the url in the window it appeared last, and
+ say it to: <I>@Console, Channels, Querys, DCC Chats</I> and <I>User windows</I>.<BR>
+ The list is saved to file when you click on the menu item or when you unload the plugin
+ on condition that you have checked the relative checkbox in configuration dialog.<BR>
+ You can also open the url in your web browser double clicking on it in the url list window.<BR><BR>
+
+ Mail me if you have any suggestion or you want to notice a bug.<BR>
+ <B>Andrea 'YaP' Parrella</B> &lt;anandrea@iname.com&gt;<BR><BR>
+ Thanks to:<BR>
+ <B>Szymon Stefanek</B> and <B>Till Bush</B> for their help.<BR>
+ <B>Ted Podgurski</B> for toolbar's icons.
+*/
+
+
+KVIRC_MODULE(
+ "URL",
+ "1.0.0" ,
+ "Copyright (C) 2002 Andrea Parrella <yap@yapsoft.it>" ,
+ "url list module for KVIrc",
+ url_module_init,
+ url_module_can_unload,
+ 0,
+ url_module_cleanup
+)
+
+#include "libkviurl.moc"
diff --git a/src/modules/url/libkviurl.h b/src/modules/url/libkviurl.h
new file mode 100644
index 00000000..05d56ce8
--- /dev/null
+++ b/src/modules/url/libkviurl.h
@@ -0,0 +1,144 @@
+#ifndef _H_URLDLG
+#define _H_URLDLG
+
+//
+// This file is part of the KVIrc irc client distribution
+// Copyright (C) 1999-2000 Andrea Parrella (anandrea@iname.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 <qdialog.h>
+#include <qlayout.h>
+#include "kvi_tal_listview.h"
+#include <qstring.h>
+#include <qpushbutton.h>
+#include <qfile.h>
+#ifdef COMPILE_USE_QT4
+ #include <q3textstream.h>
+#else
+ #include <qtextstream.h>
+#endif
+#include <qcheckbox.h>
+#include "kvi_tal_listbox.h"
+#include <qmenubar.h>
+#include <qinputdialog.h>
+#include <qtoolbutton.h>
+#include <qiconset.h>
+
+#include "kvi_locale.h"
+#include "kvi_config.h"
+#include "kvi_irctoolbar.h"
+#include "kvi_imagelib.h"
+#include "kvi_window.h"
+#include "kvi_tal_menubar.h"
+#include "kvi_mextoolbar.h"
+#include "kvi_styled_controls.h"
+
+#include <qpixmap.h>
+
+typedef struct _KviUrl
+{
+ QString url;
+ QString window;
+ int count;
+ QString timestamp;
+} KviUrl;
+
+
+class UrlDialog : public KviWindow
+{
+ Q_OBJECT
+public:
+ UrlDialog(KviPointerList<KviUrl> *g_pList);
+ ~UrlDialog();
+private:
+ KviTalMenuBar *m_pMenuBar;
+ KviTalPopupMenu *m_pListPopup; // dynamic popup menu
+ KviStr m_szUrl; // used to pass urls to sayToWin slot
+protected:
+ QPixmap *myIconPtr();
+ void resizeEvent(QResizeEvent *);
+public:
+ KviTalListView *m_pUrlList;
+ void addUrl(QString url, QString window, QString count, QString timestamp);
+// void saveProperties();
+protected slots:
+ void config();
+ void help();
+ void saveList();
+ void loadList();
+ void clear();
+ void close_slot();
+ void remove();
+ void findtext();
+ void dblclk_url(KviTalListViewItem *item);
+ void popup(KviTalListViewItem *item, const QPoint &p, int col);
+ void sayToWin(int);
+};
+
+class BanFrame : public QFrame
+{
+ Q_OBJECT
+public:
+ BanFrame(QWidget *parent=0, const char *name=0, bool banEnable = false);
+ ~BanFrame();
+ void saveBans();
+private:
+ KviStyledCheckBox *m_pEnable;
+ KviTalListBox *m_pBanList;
+ QPushButton *m_pAddBtn;
+ QPushButton *m_pRemoveBtn;
+protected slots:
+ void enableClicked();
+ void addBan();
+ void removeBan();
+};
+
+#define cbnum 2
+
+class ConfigDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ ConfigDialog();
+ ~ConfigDialog();
+private:
+ KviStyledCheckBox *cb[cbnum];
+ BanFrame *m_pBanFrame;
+ void closeEvent(QCloseEvent *);
+protected slots:
+ void acceptbtn();
+ void discardbtn();
+};
+
+#include "kvi_kvs_action.h"
+
+class KviUrlAction : public KviKvsAction
+{
+ Q_OBJECT
+public:
+ KviUrlAction(QObject * pParent);
+ ~KviUrlAction();
+protected:
+ QPixmap * m_pBigIcon;
+ QPixmap * m_pSmallIcon;
+public:
+ virtual QPixmap * bigIcon();
+ virtual QPixmap * smallIcon();
+};
+
+#endif
diff --git a/src/modules/window/Makefile.am b/src/modules/window/Makefile.am
new file mode 100644
index 00000000..52912925
--- /dev/null
+++ b/src/modules/window/Makefile.am
@@ -0,0 +1,21 @@
+###############################################################################
+# KVirc IRC client Makefile - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkviwindow.la
+
+libkviwindow_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+nodist_libkviwindow_la_SOURCES = moc_userwindow.cpp
+
+libkviwindow_la_SOURCES = libkviwindow.cpp userwindow.cpp
+
+libkviwindow_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= userwindow.h
+
+moc_%.cpp: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/window/libkviwindow.cpp b/src/modules/window/libkviwindow.cpp
new file mode 100644
index 00000000..abef0dd9
--- /dev/null
+++ b/src/modules/window/libkviwindow.cpp
@@ -0,0 +1,1547 @@
+//=================================================================================
+//
+// File : kvi_window.cpp
+// Creation date : Sat Sep 01 2001 17:13:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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_module.h"
+
+#include "kvi_console.h"
+#include "kvi_options.h"
+#include "kvi_ircsocket.h"
+#include "kvi_frame.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_error.h"
+#include "kvi_ircview.h"
+#include "kvi_input.h"
+#include "kvi_iconmanager.h"
+#include "kvi_modulemanager.h"
+#include "kvi_memmove.h"
+#include "kvi_malloc.h"
+
+#include "kvi_channel.h"
+#include "userwindow.h"
+
+#include "kvi_pointerhashtable.h"
+#include <qtimer.h>
+
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ #include "kvi_crypt.h"
+ #include "kvi_cryptcontroller.h"
+ // kvi_app.cpp
+ extern KVIRC_API KviCryptEngineManager * g_pCryptEngineManager;
+#endif
+
+
+// kvi_app.cpp
+extern KVIRC_API KviPointerHashTable<const char *,KviWindow> * g_pGlobalWindowDict;
+KviPointerList<KviUserWindow> * g_pUserWindowList = 0;
+
+// $window.caption $window.x $window.y $window.width $window.height $window.isActive $window.type
+// $window.input.text $window.input.cursorpos $window.input.textlen
+
+
+#define GET_KVS_WINDOW_ID \
+ QString szWnd; \
+ KviWindow * pWnd; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER("window_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWnd) \
+ KVSM_PARAMETERS_END(c) \
+ if(c->parameterList()->count() == 0) \
+ { \
+ pWnd = c->window(); \
+ } else { \
+ pWnd = g_pApp->findWindow(szWnd.utf8().data()); \
+ if(!pWnd) \
+ { \
+ if(!c->hasSwitch('q',"quiet")) \
+ c->warning(__tr2qs("The window with id '%s' does not exist"),szWnd.utf8().data()); \
+ return true; \
+ } \
+ }
+
+#define GET_KVS_FNC_WINDOW_ID \
+ QString szWnd; \
+ KviWindow * pWnd; \
+ KVSM_PARAMETERS_BEGIN(c) \
+ KVSM_PARAMETER("window_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWnd) \
+ KVSM_PARAMETERS_END(c) \
+ if(c->parameterList()->count() == 0) \
+ { \
+ pWnd = c->window(); \
+ } else { \
+ pWnd = g_pApp->findWindow(szWnd.utf8().data()); \
+ if(!pWnd) \
+ return true; \
+ }
+
+/*
+ @doc: window.clearOutput
+ @type:
+ command
+ @title:
+ window.clearOutput
+ @short:
+ Clears the output a window
+ @syntax:
+ window.clearOutput [-f] [-q] [window_id]
+ @switches:
+ !sw: -q | --quiet
+ Don't warn if the specified window doesn't exist. Just continue silently.
+ @description:
+ Clears the text output of the window specified by window_id. If window_id is missing then
+ the current window is used. If the window has no text output then no operation is performed.
+ If the specified window does not exist a warning is printed (unless the -q switch is used)
+ but the execution continues normally.
+ @seealso:
+ [fnc]$window.hasOutput[/fnc]
+*/
+
+static bool window_kvs_cmd_clearOutput(KviKvsModuleCommandCall * c)
+{
+ GET_KVS_WINDOW_ID
+ if(pWnd)
+ {
+ if(pWnd->view())pWnd->view()->emptyBuffer(true);
+ if(pWnd->type() == KVI_WINDOW_TYPE_CHANNEL)
+ {
+ KviChannel *chan = (KviChannel *)pWnd;
+ if(chan->messageView()) chan->messageView()->emptyBuffer(true);
+ }
+ }
+ return true;
+}
+
+/*
+ @doc: window.close
+ @type:
+ command
+ @title:
+ window.close
+ @short:
+ Closes a window
+ @syntax:
+ window.close [-q] [window_id]
+ @description:
+ Closes the window specified by window_id. If window_id is missing then
+ the current window is closed. The close operation is asynchronous: it is
+ performed immediately after the script has terminated the execution and
+ the control is returned to the main KVIrc core. If the specified window
+ does not exist a warning is printed unless the -q switch is used.
+*/
+
+static bool window_kvs_cmd_close(KviKvsModuleCommandCall * c)
+{
+ GET_KVS_WINDOW_ID
+ if(pWnd)
+ {
+ pWnd->delayedClose();
+ }
+ return true;
+}
+
+/*
+ @doc: window.dock
+ @type:
+ command
+ @title:
+ window.dock
+ @short:
+ Docks a window
+ @syntax:
+ window.dock [-q] [window_id]
+ @description:
+ Docks the window specified by window_id. If window_id is missing then
+ the current window is docked. If the specified window was already docked then
+ no operation is performed. If the specified window
+ does not exist a warning is printed unless the -q switch is used.
+ @seealso:
+ [cmd]window.undock[/cmd]
+*/
+
+static bool window_kvs_cmd_dock(KviKvsModuleCommandCall * c)
+{
+ GET_KVS_WINDOW_ID
+ if(pWnd)
+ {
+ pWnd->dock();
+ }
+ return true;
+}
+
+/*
+ @doc: window.undock
+ @type:
+ command
+ @title:
+ window.undock
+ @short:
+ Undocks a window
+ @syntax:
+ window.undock [-q] [window_id]
+ @description:
+ Undocks the window specified by window_id. If window_id is missing then
+ the current window is undocked. If the specified window was already undocked then
+ no operation is performed. If the specified window
+ does not exist a warning is printed unless the -q switch is used.
+ @seealso:
+ [cmd]window.dock[/cmd]
+*/
+
+static bool window_kvs_cmd_undock(KviKvsModuleCommandCall * c)
+{
+ GET_KVS_WINDOW_ID
+ if(pWnd)
+ {
+ pWnd->undock();
+ }
+ return true;
+}
+
+/*
+ @doc: window.maximize
+ @type:
+ command
+ @title:
+ window.maximize
+ @short:
+ Maximizes a window
+ @syntax:
+ window.maximize [-q] [window_id]
+ @description:
+ Maximizes the window specified by window_id. If window_id is missing then
+ the current window is maximized. If the specified window was already maximized then
+ no operation is performed. If the specified window
+ does not exist a warning is printed unless the -q switch is used.
+ @seealso:
+ [cmd]window.minimize[/cmd], [cmd]window.restore[/cmd], [fnc]$window.isMaxmimized[/fnc],
+ [fnc]$window.isMinimized[/fnc]
+*/
+
+static bool window_kvs_cmd_maximize(KviKvsModuleCommandCall * c)
+{
+ GET_KVS_WINDOW_ID
+ if(pWnd)
+ {
+ pWnd->maximize();
+ }
+ return true;
+}
+
+/*
+ @doc: window.minimize
+ @type:
+ command
+ @title:
+ window.minimize
+ @short:
+ Minimizes a window
+ @syntax:
+ window.minimize [-q] [window_id]
+ @description:
+ Minimizes the window specified by window_id. If window_id is missing then
+ the current window is minimized. If the specified window was already minimized then
+ no operation is performed. If the specified window
+ does not exist a warning is printed unless the -q switch is used.
+ @seealso:
+ [cmd]window.maximize[/cmd], [cmd]window.restore[/cmd], [fnc]$window.isMaxmimized[/fnc],
+ [fnc]$window.isMinimized[/fnc]
+*/
+
+static bool window_kvs_cmd_minimize(KviKvsModuleCommandCall * c)
+{
+ GET_KVS_WINDOW_ID
+ if(pWnd)
+ {
+ pWnd->minimize();
+ }
+ return true;
+}
+
+/*
+ @doc: window.restore
+ @type:
+ command
+ @title:
+ window.restore
+ @short:
+ Restores a window
+ @syntax:
+ window.restore [-q] [window_id]
+ @description:
+ Restores the window specified by window_id. If window_id is missing then
+ the current window is restored. If the specified window was already restored then
+ no operation is performed. If the specified window
+ does not exist a warning is printed unless the -q switch is used.
+ @seealso:
+ [cmd]window.maximize[/cmd], [cmd]window.minimize[/cmd], [fnc]$window.isMaxmimized[/fnc],
+ [fnc]$window.isMinimized[/fnc]
+*/
+
+static bool window_kvs_cmd_restore(KviKvsModuleCommandCall * c)
+{
+ GET_KVS_WINDOW_ID
+ if(pWnd)
+ {
+ pWnd->restore();
+ }
+ return true;
+}
+
+/*
+ @doc: window.activate
+ @type:
+ command
+ @title:
+ window.activate
+ @short:
+ Activates a window
+ @syntax:
+ window.activate [-q] [window_id]
+ @description:
+ Activates the window specified by window_id. If window_id is missing then
+ the current window is activated. If the specified window
+ does not exist a warning is printed unless the -q switch is used.
+ Please note that if the window is currently docked to a frame then this
+ command will NOT raise the frame window. If you're interested in
+ the user's attention then you might be interested in [cmd]window.demandAttention[/cmd].
+ @seealso:
+ [cmd]window.demandAttention[/cmd]
+*/
+
+static bool window_kvs_cmd_activate(KviKvsModuleCommandCall * c)
+{
+ GET_KVS_WINDOW_ID
+ if(pWnd)
+ {
+ pWnd->autoRaise();
+ }
+ return true;
+}
+
+/*
+ @doc: window.demandAttention
+ @type:
+ command
+ @title:
+ window.demandAttention
+ @short:
+ Flashes a window's system taskbar entry
+ @syntax:
+ window.demandAttention [-q] [window_id]
+ @description:
+ Flashes the system taskbar entry of the window
+ specified by the window_id. If window_id is missing then
+ the current window's system taskbar entry is flashed. If the specified window
+ does not exist a warning is printed unless the -q switch is used.
+ If the window is currently docked in a frame then the frame's
+ system taskbar entry will be flashed.
+ Please note that this command is highly system dependant:
+ on systems that do not have a system taskbar or there
+ is no way to flash an etry this command will do nothing.
+ At the time of writing this command works flawlessly on
+ Windows and in KDE compilations.
+ @seealso:
+ [cmd]window.demandAttention[/cmd]
+*/
+
+static bool window_kvs_cmd_demandAttention(KviKvsModuleCommandCall * c)
+{
+ GET_KVS_WINDOW_ID
+ if(pWnd)
+ {
+ pWnd->demandAttention();
+ }
+ return true;
+}
+
+/*
+ @doc: window.isMaximized
+ @type:
+ function
+ @title:
+ $window.isMaximized
+ @short:
+ Checks if a window is currently maximized
+ @syntax:
+ $window.isMaximized
+ $window.isMaximized(<window_id>)
+ @description:
+ Returns 1 if the window specified by <window_id> is currently maximized and 0 otherwise.
+ The form with no parameters works on the current window. If the specified window
+ doesn't exist then 0 is returned.
+ @seealso:
+ [fnc]$window.isMinimized[/fnc], [cmd]window.maximize[/cmd],
+ [cmd]window.minimize[/cmd], [cmd]window.restore[/cmd]
+*/
+
+static bool window_kvs_fnc_isMaximized(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ c->returnValue()->setBoolean(pWnd->isMaximized() ? true : false);
+ }
+ return true;
+}
+
+/*
+ @doc: window.activityLevel
+ @type:
+ function
+ @title:
+ $window.activityLevel
+ @short:
+ Returns the current activity level of a window
+ @syntax:
+ $window.activityLevel
+ $window.activityLevel(<window_id>)
+ @description:
+ Returns the current activity level of the window specified by <window_id>.
+ The form without parameters works on the current window.[br]
+ The activity level is a number describing the level of traffic in the window
+ and depends on the window type. On channels and queries it is dependant on the number
+ and frequency of actions performed by the users.
+ @seealso:
+ [fnc]$window.activityTemperature[/fnc]
+*/
+
+static bool window_kvs_fnc_activityLevel(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ unsigned int v,t;
+ pWnd->activityMeter(&v,&t);
+ c->returnValue()->setInteger(v);
+ } else {
+ c->returnValue()->setInteger(0);
+ }
+ return true;
+}
+
+/*
+ @doc: window.activityTemperature
+ @type:
+ function
+ @title:
+ $window.activityTemperature
+ @short:
+ Returns the current activity temperature of a window
+ @syntax:
+ $window.activityTemperature
+ $window.activityTemperature(<window_id>)
+ @description:
+ Returns the current activity temperature of the window specified by <window_id>.
+ The form without parameters works on the current window.[br]
+ The activity temperature describes the type of traffic in the window and is
+ strictly related to the [fnc]$window.activityLevel[/fnc].[br]
+ On channels and queries the temperature describes the type of the actions
+ performed by the users. High temperatures denote more "human" behaviour (like
+ speaking to the channel, changing the topic etc...),
+ low temperatures denote automatic behaviours (like changing the channel limit
+ or mode: actions often performed by bots).[br]
+ @seealso:
+ [fnc]$window.activityLevel[/fnc]
+*/
+
+static bool window_kvs_fnc_activityTemperature(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ unsigned int v,t;
+ pWnd->activityMeter(&v,&t);
+ c->returnValue()->setInteger(t);
+ } else {
+ c->returnValue()->setInteger(0);
+ }
+ return true;
+}
+
+/*
+ @doc: window.isMinimized
+ @type:
+ function
+ @title:
+ $window.isMinimized
+ @short:
+ Checks if a window is currently minimized
+ @syntax:
+ $window.isMinimized
+ $window.isMinimized(<window_id>)
+ @description:
+ Returns 1 if the window specified by <window_id> is currently minimized and 0 otherwise.
+ The form with no parameters works on the current window. If the specified window
+ doesn't exist then 0 is returned.
+ @seealso:
+ [fnc]$window.isMaximized[/fnc], [cmd]window.maximize[/cmd],
+ [cmd]window.minimize[/cmd], [cmd]window.restore[/cmd]
+*/
+
+static bool window_kvs_fnc_isMinimized(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ c->returnValue()->setBoolean(pWnd->isMinimized() ? true : false);
+ }
+ return true;
+}
+
+/*
+ @doc: window.hasInput
+ @type:
+ function
+ @title:
+ $window.hasInput
+ @short:
+ Checks if a window has an input field
+ @syntax:
+ $window.hasInput
+ $window.hasInput(<window_id>)
+ @description:
+ Returns 1 if the window specified by <window_id> has an input field and 0 otherwise.
+ The form with no parameters works on the current window. If the specified window
+ doesn't exist then 0 is returned.
+ @seealso:
+ [fnc]$window.hasOutput[/fnc]
+*/
+
+static bool window_kvs_fnc_hasInput(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ c->returnValue()->setBoolean(pWnd->input() ? true : false);
+ } else
+ c->returnValue()->setBoolean(false);
+ return true;
+}
+
+/*
+ @doc: window.hasUserFocus
+ @type:
+ function
+ @title:
+ $window.hasUserFocus
+ @short:
+ Checks if a window has the user focus
+ @syntax:
+ $window.hasUserFocus
+ $window.hasUserFocus(<window_id>)
+ @description:
+ Returns 1 if the window specified by <window_id> has
+ currently the user focus and 0 otherwise.
+ The form with no parameters works on the current window.
+ If the specified window doesn't exist then 0 is returned.
+ A window has the user focus if it is the KVIrc's active
+ window and has the user's input focus (i.e. typing
+ on the keyboard will write in this window).
+ @seealso:
+*/
+
+static bool window_kvs_fnc_hasUserFocus(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ bool b = (pWnd == g_pActiveWindow) && pWnd->isActiveWindow();
+ c->returnValue()->setBoolean(b ? true : false);
+ } else
+ c->returnValue()->setBoolean(false);
+ return true;
+}
+
+/*
+ @doc: window.console
+ @type:
+ function
+ @title:
+ $window.console
+ @short:
+ Returns the console that a window is attacched to
+ @syntax:
+ $window.console
+ $window.console(<window_id>)
+ @description:
+ Returns the id of the console window that the window specified by window_id is attacched to.
+ The console is the main (and only) console of the IRC context. If window_id is missing then
+ the current window is used. If this window does not belong to an irc context (and thus has
+ no attacched console) then 0 is returned.
+ @seealso:
+*/
+
+static bool window_kvs_fnc_console(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ c->returnValue()->setInteger(pWnd->console() ? QString(pWnd->console()->id()).toInt() : 0);
+ }
+ return true;
+}
+
+/*
+ @doc: window.hasOutput
+ @type:
+ function
+ @title:
+ $window.hasOutput
+ @short:
+ Checks if a window has a text output widget
+ @syntax:
+ $window.hasOutput
+ $window.hasOutput(<window_id>)
+ @description:
+ Returns 1 if the window specified by <window_id> has a text output widget and 0 otherwise.
+ The form with no parameters works on the current window. If the specified window
+ doesn't exist then 0 is returned.
+ @seealso:
+ [fnc]$window.hasInput[/fnc]
+*/
+
+static bool window_kvs_fnc_hasOutput(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ c->returnValue()->setBoolean(pWnd->view() ? true : false);
+ } else
+ c->returnValue()->setBoolean(false);
+ return true;
+}
+
+/*
+ @doc: window.exists
+ @type:
+ function
+ @title:
+ $window.exists
+ @short:
+ Checks for the existence of a window
+ @syntax:
+ $window.exists(<window_id>)
+ @description:
+ Returns 1 if a specified window exists
+ @seealso:
+*/
+
+static bool window_kvs_fnc_exists(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ c->returnValue()->setBoolean(true);
+ } else
+ c->returnValue()->setBoolean(false);
+ return true;
+}
+
+/*
+ @doc: window.type
+ @type:
+ function
+ @title:
+ $window.type
+ @short:
+ Returns the type of a window
+ @syntax:
+ $window.type
+ $window.type(<window_id>)
+ @description:
+ Returns the type of the window with <window_id>.[br]
+ The form with no parameters returns the type of the current window.[br]
+ If the window with the specified id does not exist, an empty string is returned.[br]
+ @seealso:
+*/
+
+static bool window_kvs_fnc_type(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ c->returnValue()->setString(pWnd->typeString());
+ }
+ return true;
+}
+
+/*
+ @doc: window.context
+ @type:
+ function
+ @title:
+ $window.context
+ @short:
+ Returns the IRC context of a window
+ @syntax:
+ $window.context
+ $window.context(<window_id>)
+ @description:
+ Returns the IRC context of the window with the specified <window_id>.[br]
+ The form with no parameters returns the IRC context of the current window.[br]
+ If the window with the specified id does not exist, an empty string is returned.[br]
+ @seealso:
+*/
+
+static bool window_kvs_fnc_context(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ c->returnValue()->setInteger(pWnd->console() ? pWnd->console()->ircContextId() : 0);
+ }
+ return true;
+}
+
+/*
+ @doc: window.caption
+ @type:
+ function
+ @title:
+ $window.caption
+ @short:
+ Returns the caption of a window
+ @syntax:
+ $window.caption
+ $window.caption(<window_id>)
+ @description:
+ Returns the caption of the window with <window_id>.[br]
+ The form with no parameters returns the caption of the current window.[br]
+ If the window with the specified id does not exist, an empty string is returned.[br]
+ @seealso:
+*/
+
+static bool window_kvs_fnc_caption(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ c->returnValue()->setString(pWnd->plainTextCaption());
+ }
+ return true;
+}
+
+/*
+ @doc: window.listtypes
+ @type:
+ command
+ @title:
+ window.listtypes
+ @short:
+ Lists available types of windows
+ @syntax:
+ window.listtypes
+ @description:
+ Lists the types of windows that are built in the current release of KVIrc.[br]
+ This is actually a command and not a static list just because new window
+ types may be added in subsequent releases.[br]
+ @seealso:
+ [cmd]window.listtypes[/cmd]
+*/
+
+static bool window_kvs_cmd_listtypes(KviKvsModuleCommandCall * c)
+{
+ c->window()->listWindowTypes();
+ return true;
+}
+
+/*
+ @doc: window.list
+ @type:
+ function
+ @title:
+ $window.list
+ @short:
+ Generates lists of windows
+ @syntax:
+ $window.list(<type>[,<irc_context_id>])
+ @description:
+ Returns an array of window identifiers with a speficied type and eventually belonging to a specified
+ irc context.[br]
+ <type> is a window type such as 'query' or 'channel'.[br]
+ See [cmd]window.listtypes[/cmd] for a list of available window types in this KVIrc release.[br]
+ If <type> is the special word 'all', all the window types are listed.[br]
+ <irc_context_id> specifies the irc context in which the windows are searched.[br]
+ If no <irc_context_id> is specified , the current one is used.[br]
+ If <irc_context_id> is the special word 'all', all the irc context are searched.[br]
+ If <irc_context_id> is the special word 'none' then only windows not belonging to any
+ irc context are listed.[br]
+ The special word 'any' used as <irc_context_id> merges the effects of 'all' and 'none'
+ by searching all the irc contexts AND the windows not belonging to any irc context.[br]
+ The windows that do not belong to any irc context (such as DCC windows), must be searched
+ by using 'none' or 'any' as <irc_context_id>.
+ @examples:
+ [example]
+ [comment]# List all the queries of the current irc context[/comment]
+ [cmd]echo[/cmd] $window.list(query)
+ [comment]# Equivalent to the above[/comment]
+ [cmd]echo[/cmd] $window.list(query,[fnc]$ic[/fnc])
+ [comment]# List all the channels in all the irc contexts[/comment]
+ [cmd]echo[/cmd] $window.list(channel,all)
+ [comment]# List all the windows in the current irc context[/comment]
+ [cmd]echo[/cmd] $window.list(all)
+ [comment]# List all the windows in all irc contexts[/comment]
+ [cmd]echo[/cmd] $window.list(all,all)
+ [comment]# List all the DCC Send windows: They don't belong to any irc context[/comment]
+ [cmd]echo[/cmd] $window.list(dccsend,none)
+ [comment]# List all the user windows created with $window.open[/comment]
+ [comment]# They may either belong to an irc context or not[/comment]
+ [cmd]echo[/cmd] $window.list(userwnd,any)
+ [comment]# Ok , let's use it[/comment]
+ [comment]# A nice alias that allows iterating commands through all the consoles[/comment]
+ [comment]# Note the array returned by $window.list[/comment]
+ [comment]# This is by LatinSuD :)[/comment]
+ [cmd]alias[/cmd](iterate)
+ {
+ %ctxt[]=[fnc]$window.list[/fnc](console,all)
+ [cmd]for[/cmd](%i=0;%i<%ctxt[]#;%i++)
+ {
+ [cmd]eval[/cmd] -r=%ctxt[%i] $0-
+ }
+ }
+ iterate [cmd]echo[/cmd] Hi ppl! :)
+ [comment]# The returned array works nicely also in [cmd]foreach[/cmd][/comment]
+ [comment]# Say hi to all the channels :)[/comment]
+ [cmd]alias[/cmd](sayallchans)
+ {
+ [cmd]foreach[/cmd](%x,[fnc]$window.list[/fnc](channel,all))
+ [cmd]say[/cmd] -r=%x $0-;
+ }
+ sayallchans Hi ppl :)
+ [/example]
+ @seealso:
+ [cmd]window.listtypes[/cmd]
+*/
+
+static bool window_kvs_fnc_list(KviKvsModuleFunctionCall * c)
+{
+ QString szType;
+ QString szContext;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("type",KVS_PT_STRING,0,szType)
+ KVSM_PARAMETER("irc_context_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szContext)
+ KVSM_PARAMETERS_END(c)
+ KviKvsArray* pArray = new KviKvsArray();
+ c->returnValue()->setArray(pArray);
+
+ if(szType.isEmpty())
+ {
+ c->warning(__tr2qs("Window type or 'all' expected as first parameter"));
+ return true;
+ }
+
+ int id=0;
+
+ if(KviQString::equalCI(szContext,"all"))
+ {
+ // all contexts but no "no_context" windows
+ bool bAllWindows = KviQString::equalCI(szType,"all");
+ KviPointerHashTableIterator<const char *,KviWindow> it(*g_pGlobalWindowDict);
+
+ while(KviWindow * wnd = it.current())
+ {
+ if(wnd->context())
+ {
+ if(bAllWindows)
+ {
+ pArray->set(id, new KviKvsVariant(QString(wnd->id())));
+ id++;
+ } else {
+ if(szType.lower()==wnd->typeString())
+ {
+ pArray->set(id, new KviKvsVariant(QString(wnd->id())));
+ id++;
+ }
+ }
+ }
+ ++it;
+ }
+ } else if(KviQString::equalCI(szContext,"any"))
+ {
+ // all contexts and also "no_context" windows
+ bool bAllWindows = KviQString::equalCI(szType.lower(),"all");
+ KviPointerHashTableIterator<const char *,KviWindow> it(*g_pGlobalWindowDict);
+
+ while(KviWindow * wnd = it.current())
+ {
+ if(bAllWindows)
+ {
+ pArray->set(id, new KviKvsVariant(QString(wnd->id())));
+ id++;
+ } else {
+ if(szType.lower()==wnd->typeString())
+ {
+ pArray->set(id, new KviKvsVariant(QString(wnd->id())));
+ id++;
+ }
+ }
+ ++it;
+ }
+ } else if(KviQString::equalCI(szContext,"none"))
+ {
+ // only "no_context" windows
+ bool bAllWindows = KviQString::equalCI(szType.lower(),"all");
+ KviPointerHashTableIterator<const char *,KviWindow> it(*g_pGlobalWindowDict);
+
+ while(KviWindow * wnd = it.current())
+ {
+ if(!wnd->context())
+ {
+ if(bAllWindows)
+ {
+ pArray->set(id, new KviKvsVariant(QString(wnd->id())));
+ id++;
+ } else {
+ if(szType.lower()==wnd->typeString())
+ {
+ pArray->set(id, new KviKvsVariant(QString(wnd->id())));
+ id++;
+ }
+ }
+ }
+ ++it;
+ }
+
+ } else {
+ // some specified context
+ unsigned int uId = 0;
+
+ if(!szContext.isEmpty())
+ {
+ // specific context
+ bool bOk;
+ uId = szContext.toUInt(&bOk);
+ if(!bOk)
+ {
+ c->warning(__tr2qs("Invalid IRC context id '%Q'"),&szContext);
+ return true;
+ }
+ } else {
+ // current irc context
+ if(!c->window()->console())
+ {
+ return true;
+ }
+ uId = c->window()->console()->ircContextId();
+ }
+
+ bool bAllWindows = KviQString::equalCI(szType.lower(),"all");
+ KviPointerHashTableIterator<const char *,KviWindow> it(*g_pGlobalWindowDict);
+
+ while(KviWindow * wnd = it.current())
+ {
+ if(wnd->console())
+ {
+ if(wnd->console()->ircContextId() == uId)
+ {
+ if(bAllWindows)
+ {
+ pArray->set(id, new KviKvsVariant(QString(wnd->id())));
+ id++;
+ } else {
+ if(szType.lower()==wnd->typeString())
+ {
+ pArray->set(id, new KviKvsVariant(QString(wnd->id())));
+ id++;
+ }
+ }
+ }
+ }
+ ++it;
+ }
+ }
+ return true;
+
+}
+
+/*
+ @doc: window.open
+ @type:
+ function
+ @title:
+ $window.open
+ @short:
+ Creates and opens a new window
+ @syntax:
+ $window.open([<flags:string>[,<caption:string>[,<irc_context:integer>[,<icon:integer>]]]])
+ @description:
+ Creates a new window, opens it and returns its window identifier.
+ <flags> may be any combination of the following flag characters:[br]
+ [b]i[/b]: Causes the window to have an input field in that
+ the user can type commands or text. The text typed is reported
+ by the [event:ontextinput]OnTextInput[/event] event.[br]
+ [b]m[/b]: Creates a window that is initially minimized.[br]
+ [b]q[/b]: Don't print warning messages during the creation.[br]
+ If <caption> is given then the new window will have it as the initial plain text <caption>.
+ You can change the caption later by calling [cmd]window.setCaption[/cmd].[br]
+ If <irc_context> is given then the new window is bound to the specified irc context
+ and will be destroyed when the attacched console closes.
+ If <irc_context> is omitted or is 0 then the window will be context free (not bound
+ to any context) and will exist until it is closed by the GUI, by a [cmd]window.close[/cmd]
+ call or until KVIrc terminates. When <irc_context> is given but is not valid
+ then a warning is printed (unless the q flag is used) and the created window is context free.[br]
+ You will generally use the [fnc]$context[/fnc] function to retrieve the current IRC context id.[br]
+ [br]
+ <icon> is intepreted as the index of the internal icon to be used
+ for the window. If <icon> is omitted then a default icon is used.[br]
+ @examples:
+ [example]
+ %w = $window.open()
+ [cmd]window.close[/cmd] %w
+ %w = $window.open("m","My funky window")
+ [cmd]window.close[/cmd] %w
+ %w = $window.open("im","My funky window 2",$context,10)
+ [/example]
+ @seealso:
+ [cmd]window.close[/cmd]
+*/
+
+static bool window_kvs_fnc_open(KviKvsModuleFunctionCall * c)
+{
+ QString szFlags;
+ QString szCaption;
+ kvs_uint_t uCtx;
+ kvs_int_t iIcon;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
+ KVSM_PARAMETER("caption",KVS_PT_STRING,KVS_PF_OPTIONAL,szCaption)
+ KVSM_PARAMETER("irc_context",KVS_PT_UINT,KVS_PF_OPTIONAL,uCtx)
+ KVSM_PARAMETER("icon",KVS_PT_INT,KVS_PF_OPTIONAL,iIcon)
+ KVSM_PARAMETERS_END(c)
+ iIcon = iIcon % KVI_NUM_SMALL_ICONS;
+
+ int iFlags = 0;
+ if(szFlags.contains('i'))iFlags |= KviUserWindow::HasInput;
+
+ KviConsole * pConsole = 0;
+ if(c->parameterList()->count() >= 3)
+ {
+ pConsole = g_pApp->findConsole(uCtx);
+ if(!pConsole && !szFlags.contains('q'))
+ {
+ c->warning(__tr2qs("The specified IRC context is not valid: creating a context free window"));
+ }
+ }
+
+ KviUserWindow * wnd = new KviUserWindow(
+ c->window()->frame(),
+ szCaption,
+ iIcon,
+ pConsole,
+ iFlags);
+
+ c->window()->frame()->addWindow(wnd,!szFlags.contains('m'));
+ if(szFlags.contains('m'))wnd->minimize();
+
+ c->returnValue()->setInteger(QString(wnd->id()).toUInt());
+ return true;
+}
+
+/*
+ @doc: window.setCaption
+ @type:
+ command
+ @title:
+ window.setCaption
+ @short:
+ Sets the caption of an user window
+ @syntax:
+ window.setCaption [-q] <window_id> <plain_text_caption> [html_inactive_caption] [html_active_caption]
+ @switches:
+ !sw: -q | --quiet
+ Be quiet
+ @description:
+ Sets the caption of the user window specified by <window_id> to <plain_text_caption>.[br]
+ If <window_id> is an empty string then the current window is assumed.[br]
+ The window must be of type userwnd and must have been created by [fnc]$window.open[/fnc]:
+ it is not possible to change the caption of other window types.[br]
+ If the window is not of the expected type then a warning is printed unless the -q switch is used.[br]
+ If [html_inactive_caption] and/or [html_active_caption] are given then
+ the html versions of the captions displayed in the window caption bars
+ are set too. If one of these parameters is missing then <plain_text_caption> is
+ used for the html versions too. The html captions can contain limited html code. In particular
+ you're allowed to use the &lt;nobr&gt;,&lt;font&gt;,&lt;b&gt; and &lt;i&gt; html tags.
+ It is better to avoid using colored fonts since you can't know which color scheme the
+ user will have set.[br]
+ If the specified window does not exist a warning is printed unless the -q switch is used.
+ @seealso:
+*/
+
+static bool window_kvs_cmd_setCaption(KviKvsModuleCommandCall * c)
+{
+ QString szWnd;
+ QString szPlain;
+ QString szInactive;
+ QString szActive;
+ KviWindow * pWnd;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window_id",KVS_PT_STRING,0,szWnd)
+ KVSM_PARAMETER("plain_text_caption",KVS_PT_STRING,0,szPlain)
+ KVSM_PARAMETER("html_inactive_caption",KVS_PT_STRING,KVS_PF_OPTIONAL,szInactive)
+ KVSM_PARAMETER("html_active_caption",KVS_PT_STRING,KVS_PF_OPTIONAL,szActive)
+ KVSM_PARAMETERS_END(c)
+
+ pWnd = g_pApp->findWindow(szWnd.utf8().data());
+ if(!pWnd)
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("The window with id '%s' does not exist"),szWnd.utf8().data());
+ return true;
+ }
+
+ if(pWnd->type() == KVI_WINDOW_TYPE_USERWINDOW)
+ {
+ ((KviUserWindow *)pWnd)->setCaptionStrings(szPlain,szInactive,szActive);
+ } else {
+ if(!c->hasSwitch('q',"quiet"))c->warning(__tr2qs("The specified window is not of type \"userwnd\""));
+ }
+ return true;
+}
+
+/*
+ @doc: window.setInputText
+ @type:
+ command
+ @title:
+ window.setInputText
+ @short:
+ Sets the window input text to <text>
+ @syntax:
+ window.setInputText [-q] <window_id:integer> <text:string>
+ @switches:
+ !sw: -q | --quiet
+ Be quiet
+ @description:
+ Sets the window input text to <text>
+ @seealso:
+ [cmd]window.setInputText[/cmd] [cmd]window.insertInInputText[/cmd] [fnc]$window.inputText[/fnc]
+*/
+
+static bool window_kvs_cmd_setInputText(KviKvsModuleCommandCall * c)
+{
+ QString szWnd;
+ QString szText;
+ KviWindow * pWnd;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window_id",KVS_PT_STRING,0,szWnd)
+ KVSM_PARAMETER("text",KVS_PT_STRING,0, szText)
+ KVSM_PARAMETERS_END(c)
+
+ pWnd = g_pApp->findWindow(szWnd.utf8().data());
+ if(!pWnd)
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("The window with id '%s' does not exist"),szWnd.utf8().data());
+ return true;
+ }
+ if(pWnd->input())
+ pWnd->input()->setText(szText);
+ else
+ if(!c->hasSwitch('q',"quiet")) c->warning(__tr2qs("Window doesn't have input widget"));
+
+ return true;
+}
+
+
+/*
+ @doc: window.insertInInputText
+ @type:
+ command
+ @title:
+ window.insertInInputText
+ @short:
+ Sets the window input text to <text>
+ @syntax:
+ window.insertInInputText [-q] <window_id:integer> <text:string>
+ @switches:
+ !sw: -q | --quiet
+ Be quiet
+ @description:
+ Sets the window input text to <text>
+ @seealso:
+ [cmd]window.setInputText[/cmd], [fnc]$window.inputText[/fnc]
+*/
+
+static bool window_kvs_cmd_insertInInputText(KviKvsModuleCommandCall * c)
+{
+ QString szWnd;
+ QString szText;
+ KviWindow * pWnd;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window_id",KVS_PT_STRING,0,szWnd)
+ KVSM_PARAMETER("text",KVS_PT_STRING,0, szText)
+ KVSM_PARAMETERS_END(c)
+
+ pWnd = g_pApp->findWindow(szWnd.utf8().data());
+ if(!pWnd)
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("The window with id '%s' does not exist"),szWnd.utf8().data());
+ return true;
+ }
+ if(pWnd->input())
+ pWnd->input()->insertText(szText);
+ else
+ if(!c->hasSwitch('q',"quiet")) c->warning(__tr2qs("Window doesn't have input widget"));
+
+ return true;
+}
+
+/*
+ @doc: $window.inputText
+ @type:
+ function
+ @title:
+ $window.inputText
+ @short:
+ Returns the window input line text
+ @syntax:
+ $window.inputText(<window_id:integer>)
+ @description:
+ Returns the window input line text
+ @seealso:
+ [cmd]window.setInputText[/cmd],
+ [cmd]window.insertInInputText[/cmd]
+*/
+
+static bool window_kvs_fnc_inputText(KviKvsModuleFunctionCall * c)
+{
+ GET_KVS_FNC_WINDOW_ID
+ if(pWnd)
+ {
+ if(pWnd->input())
+ c->returnValue()->setString(pWnd->input()->text());
+ }
+ return true;
+}
+
+/*
+ @doc: window.setBackground
+ @type:
+ command
+ @title:
+ window.setBackground
+ @short:
+ Sets the background image of a window
+ @syntax:
+ window.setBackground [-q] <window_id:integer> <image_id:string>
+ @switches:
+ !sw: -q | --quiet
+ Be quiet
+ @description:
+ Sets the background image of the window specified by <window_id> to <image_id>.[br]
+ If <window_id> is an empty string then the current window is assumed.[br]
+ If the specified window or the background image does not exist a warning is printed unless the -q switch is used.
+ @seealso:
+*/
+
+static bool window_kvs_cmd_setBackground(KviKvsModuleCommandCall * c)
+{
+ QString szWnd;
+ QString szBackground;
+ KviWindow * pWnd;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window_id",KVS_PT_STRING,0,szWnd)
+ KVSM_PARAMETER("plain_text_caption",KVS_PT_STRING,0, szBackground)
+ KVSM_PARAMETERS_END(c)
+
+ pWnd = g_pApp->findWindow(szWnd.utf8().data());
+ if(!pWnd)
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("The window with id '%s' does not exist"),szWnd.utf8().data());
+ return true;
+ }
+
+ /*
+ QPixmap *pix=0;
+ pix = g_pIconManager->getImage(szBackground);
+ if (!pix){
+ KviScriptObject * ob = g_pScriptObjectController->lookupObject(szBackground);
+ if(!ob){
+ if(!c->hasSwitch('q',"quiet")) c->warning(__tr2qs("Background not found %Q "),&szBackground);
+ return true;
+ }
+ if(!ob->inherits("KviScriptPixmapObject")){
+ c->warning(__tr("Pixmap objects required !"));
+ return true;
+ }
+ QVariant pix1= ob->property("pixmap");
+ if (!pix1.asPixmap().isNull()){
+ c->warning(__tr("Pixmap is null"));
+ return true;
+ }
+ pWnd->view()->setPrivateBackgroundPixmap(pix1.asPixmap());
+ return true;
+ }
+ if(pWnd)
+ pWnd->view()->setPrivateBackgroundPixmap(*pix);
+ */
+
+ //FIXME: This is broken
+
+ return true;
+}
+
+/*
+ @doc: window.setCryptEngine
+ @type:
+ command
+ @title:
+ window.setCryptEngine
+ @short:
+ Sets the crypt engine for a window that supports it
+ @syntax:
+ window.setCryptEngine [-q] [-n] [-m] <window_id:integer> <enginename:string> <hex_encrypt_key;string> [hex_decrypt_key:string]
+ @switches:
+ !sw: -q | --quiet
+ Be quiet: do echo the raw data.
+ !sw: -n | --onlydecrypt
+ Disables encryption
+ !sw: -m | --onlyencrypt
+ Disables decryption
+ @description:
+ Sets the specified [doc:crypt_engines]cryptographic engine[/doc] for the window. If <enginename> is empty
+ then any current crypting engine is removed (i.e. crypting is disabled).
+ The must be both expressed in hexadecimal notation and are internally transformed in bytes.
+ If only the encrypt key is specified then it will be used for both encrypting and
+ decrypting. This command works only if crypt support is compiled in.
+ @examples:
+ [example]
+ [comment]# This is a really lame example :D[/comment]
+ alias(saylame)
+ {
+ window.setCryptEngine $window Lamerizer
+ say $0-
+ window.setCryptEngine $window
+ }
+ saylame Hello eleet!
+ [/example]
+
+ @seealso:
+ [fnc]$asciiToHex[/fnc], [fnc]$features[/fnc]
+*/
+
+
+#ifdef COMPILE_CRYPT_SUPPORT
+static bool initializeCryptEngine(KviCryptEngine * eng,KviStr &szEncryptKey,KviStr &szDecryptKey,QString &szError)
+{
+ char * encKey = 0;
+ int encKeyLen = 0;
+
+ char * tmpKey;
+ encKeyLen = szEncryptKey.hexToBuffer(&tmpKey,false);
+ if(encKeyLen > 0)
+ {
+ encKey = (char *)kvi_malloc(encKeyLen);
+ kvi_memmove(encKey,tmpKey,encKeyLen);
+ KviStr::freeBuffer(tmpKey);
+ } else {
+ szError = __tr2qs("The encrypt key wasn't a valid hexadecimal string");
+ return false;
+ }
+
+ char * decKey = 0;
+ int decKeyLen = 0;
+
+ decKeyLen = szDecryptKey.hexToBuffer(&tmpKey,false);
+ if(decKeyLen > 0)
+ {
+ decKey = (char *)kvi_malloc(decKeyLen);
+ kvi_memmove(decKey,tmpKey,decKeyLen);
+ KviStr::freeBuffer(tmpKey);
+ } else {
+ szError = __tr2qs("The decrypt key wasn't a valid hexadecimal string");
+ return false;
+ }
+ bool bRet = eng->init(encKey,encKeyLen,decKey,decKeyLen);
+ if(!bRet)
+ szError = eng->lastError();
+ if(encKey)kvi_free(encKey);
+ if(decKey)kvi_free(decKey);
+ return bRet;
+}
+#endif
+
+static bool window_kvs_cmd_setCryptEngine(KviKvsModuleCommandCall * c)
+{
+ QString szWnd;
+ QString szEngine;
+ QString szEncryptKey;
+ QString szDecryptKey;
+ KviWindow * pWnd;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("window_id",KVS_PT_STRING,0,szWnd)
+ KVSM_PARAMETER("enginename",KVS_PT_STRING,KVS_PF_OPTIONAL,szEngine)
+ KVSM_PARAMETER("hex_encrypt_key",KVS_PT_STRING,KVS_PF_OPTIONAL,szEncryptKey)
+ KVSM_PARAMETER("hex_decrypt_key",KVS_PT_STRING,KVS_PF_OPTIONAL,szDecryptKey)
+ KVSM_PARAMETERS_END(c)
+ if(szDecryptKey.isEmpty())szDecryptKey = szEncryptKey;
+#ifdef COMPILE_CRYPT_SUPPORT
+ pWnd = g_pApp->findWindow(szWnd.utf8().data());
+ if(!pWnd)
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("The window with id '%s' does not exist"),szWnd.utf8().data());
+ return true;
+ }
+ if(c->hasSwitch('n',"onlydecrypt") && c->hasSwitch('m',"onlyencrypt"))
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("Both -n and -m switchess specified, -n takes precedence"));
+ }
+
+ if(szEngine.isEmpty())
+ {
+ pWnd->setCryptSessionInfo(0);
+ } else {
+ if(szEncryptKey.isEmpty() || szDecryptKey.isEmpty())
+ {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("No encrypt key specified: can't allocate engine"));
+ return true;
+ }
+
+ (void)g_pModuleManager->loadModulesByCaps("crypt");
+
+ KviCryptEngine * e = g_pCryptEngineManager->allocateEngine(szEngine.utf8().data());
+ if(e)
+ {
+ KviStr enc = KviStr(szEncryptKey.utf8().data());
+ KviStr dec = KviStr(szDecryptKey.utf8().data());
+ QString szError;
+ if(initializeCryptEngine(e,enc,dec,szError))
+ {
+ KviCryptSessionInfo * inf = KviCryptController::allocateCryptSessionInfo();
+ inf->pEngine = e;
+ inf->szEngineName = szEngine;
+
+ inf->bDoEncrypt = (!c->hasSwitch('n',"onlydecrypt"));
+ inf->bDoDecrypt = (!c->hasSwitch('m',"onlyencrypt")) || c->hasSwitch('n',"onlydecrypt");
+ pWnd->setCryptSessionInfo(inf);
+ } else {
+ if(szError.isEmpty())szError = __tr2qs("Unknown engine error");
+ g_pCryptEngineManager->deallocateEngine(e);
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("Failed to initialize the specified crypt engine: %Q"),&szError);
+ }
+ } else {
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("The crypt engine \"%Q\" does not exist"),&szEngine);
+ }
+ }
+#else
+ if(!c->hasSwitch('q',"quiet"))
+ c->warning(__tr2qs("This executable has been compiled without crypt support"));
+#endif
+ return true;
+}
+
+static bool window_module_init(KviModule *m)
+{
+ g_pUserWindowList = new KviPointerList<KviUserWindow>();
+ g_pUserWindowList->setAutoDelete(false);
+
+ KVSM_REGISTER_FUNCTION(m,"activityTemperature",window_kvs_fnc_activityTemperature);
+ KVSM_REGISTER_FUNCTION(m,"activityLevel",window_kvs_fnc_activityLevel);
+ KVSM_REGISTER_FUNCTION(m,"console",window_kvs_fnc_console);
+ KVSM_REGISTER_FUNCTION(m,"hasUserFocus",window_kvs_fnc_hasUserFocus);
+ KVSM_REGISTER_FUNCTION(m,"hasOutput",window_kvs_fnc_hasOutput);
+ KVSM_REGISTER_FUNCTION(m,"isMinimized",window_kvs_fnc_isMinimized);
+ KVSM_REGISTER_FUNCTION(m,"isMaximized",window_kvs_fnc_isMaximized);
+ KVSM_REGISTER_FUNCTION(m,"caption",window_kvs_fnc_caption);
+ KVSM_REGISTER_FUNCTION(m,"type",window_kvs_fnc_type);
+ KVSM_REGISTER_FUNCTION(m,"exists",window_kvs_fnc_exists);
+ KVSM_REGISTER_FUNCTION(m,"hasInput",window_kvs_fnc_hasInput);
+ KVSM_REGISTER_FUNCTION(m,"list",window_kvs_fnc_list);
+ KVSM_REGISTER_FUNCTION(m,"open",window_kvs_fnc_open);
+ KVSM_REGISTER_FUNCTION(m,"inputText",window_kvs_fnc_inputText);
+ KVSM_REGISTER_FUNCTION(m,"context",window_kvs_fnc_context);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"close",window_kvs_cmd_close);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"clearOutput",window_kvs_cmd_clearOutput);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"dock",window_kvs_cmd_dock);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"undock",window_kvs_cmd_undock);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"maximize",window_kvs_cmd_maximize);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"minimize",window_kvs_cmd_minimize);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"restore",window_kvs_cmd_restore);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"activate",window_kvs_cmd_activate);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"demandAttention",window_kvs_cmd_demandAttention);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"listtypes",window_kvs_cmd_listtypes);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setBackground",window_kvs_cmd_setBackground);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setCaption",window_kvs_cmd_setCaption);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setCryptEngine",window_kvs_cmd_setCryptEngine);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setInputText",window_kvs_cmd_setInputText);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"insertInInputText",window_kvs_cmd_insertInInputText);
+
+ // saveOutput (view()->saveBuffer())
+/*
+ m->registerFunction("geometry",window_module_fnc_geometry);
+ m->registerCommand("setGeometry",window_module_cmd_setGeometry);
+
+ m->registerFunction("isActive",window_module_fnc_isActive);
+
+
+ // Output stuff
+ m->registerFunction("outputBufferSize",window_module_fnc_outputBufferSize);
+ m->registerCommand("setOutputBufferSize",window_module_cmd_setOutputBufferSize);
+
+ m->registerFunction("outputShowsImages",window_module_fnc_outputShowsImages);
+ m->registerCommand("setOutputShowsImages",window_module_cmd_setOutputShowsImages);
+
+ m->registerFunction("outputTimestamp",window_module_fnc_outputTimestamp);
+ m->registerCommand("setOutputTimestamp",window_module_cmd_setOutputTimestamp);
+
+ m->registerFunction("hasOutputBackgroundPixmap",window_module_fnc_hasOutputBackgroundPixmap);
+ m->registerCommand("setOutputBackgroundPixmap",window_module_cmd_setOutputBackgroundPixmap);
+
+*/
+ return true;
+}
+
+static bool window_module_cleanup(KviModule *m)
+{
+ while(KviUserWindow * w = g_pUserWindowList->first())
+ w->close();
+ delete g_pUserWindowList;
+ return true;
+}
+
+static bool window_module_can_unload(KviModule *m)
+{
+ return g_pUserWindowList->isEmpty();
+}
+
+KVIRC_MODULE(
+ "Window", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2001-2004 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "KVIrc window management functions",
+ window_module_init,
+ window_module_can_unload,
+ 0,
+ window_module_cleanup
+)
diff --git a/src/modules/window/userwindow.cpp b/src/modules/window/userwindow.cpp
new file mode 100644
index 00000000..08a7405b
--- /dev/null
+++ b/src/modules/window/userwindow.cpp
@@ -0,0 +1,107 @@
+//=============================================================================
+//
+// File : userwindow.cpp
+// Created on Mon 30 Aug 2004 15:00:52 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2004 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 "userwindow.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_input.h"
+#include "kvi_ircview.h"
+#include "kvi_frame.h"
+#include "kvi_console.h"
+
+extern KviPointerList<KviUserWindow> * g_pUserWindowList;
+
+
+KviUserWindow::KviUserWindow(KviFrame * pFrm,const char * name,int iIcon,KviConsole * pConsole,int iCreationFlags)
+: KviWindow(KVI_WINDOW_TYPE_USERWINDOW,pFrm,name,pConsole)
+{
+ g_pUserWindowList->append(this);
+
+ m_iIcon = iIcon;
+
+ m_szPlainTextCaption = name;
+ m_szHtmlActiveCaption = name;
+ m_szHtmlInactiveCaption = name;
+
+ // Register ourselves
+ //connection()->registerChannel(this);
+ // Central splitter
+// m_pSplitter = new QSplitter(QSplitter::Horizontal,this,"main_splitter");
+ // Spitted vertially on the left
+// m_pVertSplitter = new QSplitter(QSplitter::Vertical,m_pSplitter,
+// "vertical_splitter");
+ // With the IRC view over
+ m_pIrcView = new KviIrcView(this,pFrm,this);
+ // connect(m_pIrcView,SIGNAL(rightClicked()),this,SLOT(textViewRightClicked()));
+ // The userlist on the right
+// m_pUserListView = new KviUserListView(m_pSplitter,connection()->userDataBase(),this,
+// AVERAGE_CHANNEL_USERS,__tr2qs("User List"),"user_list_view");
+ // And finally the input line on the bottom
+ if(iCreationFlags & HasInput)
+ m_pInput = new KviInput(this,0);
+ else
+ m_pInput = 0;
+ // applyOptions();
+
+ if(context())context()->registerContextWindow(this);
+}
+
+KviUserWindow::~KviUserWindow()
+{
+ if(context())context()->unregisterContextWindow(this);
+ g_pUserWindowList->removeRef(this);
+}
+
+QPixmap * KviUserWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(m_iIcon);
+}
+
+void KviUserWindow::resizeEvent(QResizeEvent *e)
+{
+ if(m_pInput)
+ {
+ int hght = m_pInput->heightHint();
+ m_pIrcView->setGeometry(0,0,width(),height() - hght);
+ m_pInput->setGeometry(0,height() - hght,width(),hght);
+ } else {
+ m_pIrcView->setGeometry(0,0,width(),height());
+ }
+}
+
+void KviUserWindow::fillCaptionBuffers()
+{
+ // nothing here
+}
+
+void KviUserWindow::setCaptionStrings(const QString &szPlainText,const QString &szHtmlInactive,const QString &szHtmlActive)
+{
+ m_szPlainTextCaption = szPlainText;
+ m_szHtmlActiveCaption = szHtmlActive;
+ m_szHtmlInactiveCaption = szHtmlInactive;
+ if(m_szHtmlActiveCaption.isEmpty())m_szHtmlActiveCaption = szPlainText;
+ if(m_szHtmlInactiveCaption.isEmpty())m_szHtmlInactiveCaption = szPlainText;
+ updateCaption();
+}
+
diff --git a/src/modules/window/userwindow.h b/src/modules/window/userwindow.h
new file mode 100644
index 00000000..333b7edb
--- /dev/null
+++ b/src/modules/window/userwindow.h
@@ -0,0 +1,48 @@
+#ifndef _USERWINDOW_H_
+#define _USERWINDOW_H_
+//=============================================================================
+//
+// File : userwindow.h
+// Created on Mon 30 Aug 2004 15:00:52 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2004 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 "kvi_window.h"
+
+class KviUserWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ enum CreationFlags { HasInput = 1 };
+public:
+ KviUserWindow(KviFrame * pFrm,const char * name,int iIcon,KviConsole * pConsole = 0,int iCreationFlags = 0);
+ ~KviUserWindow();
+protected:
+ int m_iIcon;
+protected:
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+public:
+ void setCaptionStrings(const QString &szPlainText,const QString &szHtmlInactive,const QString &szHtmlActive);
+};
+
+#endif //!_USERWINDOW_H_