summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-03 02:15:56 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-03 02:15:56 +0000
commit50b48aec6ddd451a6d1709c0942477b503457663 (patch)
treea9ece53ec06fd0a2819de7a2a6de997193566626 /src
downloadk3b-50b48aec6ddd451a6d1709c0942477b503457663.tar.gz
k3b-50b48aec6ddd451a6d1709c0942477b503457663.zip
Added abandoned KDE3 version of K3B
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k3b@1084400 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src')
-rw-r--r--src/IDEAS45
-rw-r--r--src/Makefile.am86
-rw-r--r--src/eventsrc333
-rw-r--r--src/fastscale/Makefile.am14
-rw-r--r--src/fastscale/README2
-rw-r--r--src/fastscale/asm_scale.S810
-rw-r--r--src/fastscale/configure.in.in63
-rw-r--r--src/fastscale/scale.cpp1975
-rw-r--r--src/fastscale/scale.h34
-rw-r--r--src/icons/Makefile.am2
-rw-r--r--src/icons/actions/Makefile.am2
-rw-r--r--src/icons/actions/cr16-action-greenled.pngbin0 -> 536 bytes
-rw-r--r--src/icons/actions/cr16-action-redled.pngbin0 -> 493 bytes
-rw-r--r--src/icons/actions/cr16-action-yellowinfo.pngbin0 -> 589 bytes
-rw-r--r--src/icons/actions/cr16-action-yellowled.pngbin0 -> 498 bytes
-rw-r--r--src/icons/actions/hi16-action-audiocd.pngbin0 -> 957 bytes
-rw-r--r--src/icons/actions/hi16-action-burn_cdimage.pngbin0 -> 908 bytes
-rw-r--r--src/icons/actions/hi16-action-burn_dvdimage.pngbin0 -> 1011 bytes
-rw-r--r--src/icons/actions/hi16-action-cdburn.pngbin0 -> 916 bytes
-rw-r--r--src/icons/actions/hi16-action-cdcopy.pngbin0 -> 951 bytes
-rw-r--r--src/icons/actions/hi16-action-cddarip.pngbin0 -> 872 bytes
-rw-r--r--src/icons/actions/hi16-action-datacd.pngbin0 -> 941 bytes
-rw-r--r--src/icons/actions/hi16-action-datadvd.pngbin0 -> 925 bytes
-rw-r--r--src/icons/actions/hi16-action-dvdcopy.pngbin0 -> 1050 bytes
-rw-r--r--src/icons/actions/hi16-action-emovix.pngbin0 -> 978 bytes
-rw-r--r--src/icons/actions/hi16-action-erasecd.pngbin0 -> 928 bytes
-rw-r--r--src/icons/actions/hi16-action-formatdvd.pngbin0 -> 1009 bytes
-rw-r--r--src/icons/actions/hi16-action-mixedcd.pngbin0 -> 969 bytes
-rw-r--r--src/icons/actions/hi16-action-mp3cd.pngbin0 -> 836 bytes
-rw-r--r--src/icons/actions/hi16-action-musicbrainz.pngbin0 -> 1850 bytes
-rw-r--r--src/icons/actions/hi16-action-videocd.pngbin0 -> 1026 bytes
-rw-r--r--src/icons/actions/hi16-action-videodvd.pngbin0 -> 1044 bytes
-rw-r--r--src/icons/actions/hi22-action-audiocd.pngbin0 -> 1410 bytes
-rw-r--r--src/icons/actions/hi22-action-burn_cdimage.pngbin0 -> 1291 bytes
-rw-r--r--src/icons/actions/hi22-action-burn_dvdimage.pngbin0 -> 1410 bytes
-rw-r--r--src/icons/actions/hi22-action-cdburn.pngbin0 -> 1450 bytes
-rw-r--r--src/icons/actions/hi22-action-cdcopy.pngbin0 -> 1389 bytes
-rw-r--r--src/icons/actions/hi22-action-cddarip.pngbin0 -> 1397 bytes
-rw-r--r--src/icons/actions/hi22-action-datacd.pngbin0 -> 1410 bytes
-rw-r--r--src/icons/actions/hi22-action-datadvd.pngbin0 -> 1410 bytes
-rw-r--r--src/icons/actions/hi22-action-dvdcopy.pngbin0 -> 1465 bytes
-rw-r--r--src/icons/actions/hi22-action-emovix.pngbin0 -> 1511 bytes
-rw-r--r--src/icons/actions/hi22-action-erasecd.pngbin0 -> 1503 bytes
-rw-r--r--src/icons/actions/hi22-action-formatdvd.pngbin0 -> 1612 bytes
-rw-r--r--src/icons/actions/hi22-action-mixedcd.pngbin0 -> 1553 bytes
-rw-r--r--src/icons/actions/hi22-action-mp3cd.pngbin0 -> 1155 bytes
-rw-r--r--src/icons/actions/hi22-action-videocd.pngbin0 -> 1627 bytes
-rw-r--r--src/icons/actions/hi22-action-videodvd.pngbin0 -> 1641 bytes
-rw-r--r--src/icons/actions/hi32-action-audiocd.pngbin0 -> 2358 bytes
-rw-r--r--src/icons/actions/hi32-action-burn_cdimage.pngbin0 -> 2355 bytes
-rw-r--r--src/icons/actions/hi32-action-burn_dvdimage.pngbin0 -> 2543 bytes
-rw-r--r--src/icons/actions/hi32-action-cdburn.pngbin0 -> 2422 bytes
-rw-r--r--src/icons/actions/hi32-action-cdcopy.pngbin0 -> 2288 bytes
-rw-r--r--src/icons/actions/hi32-action-cddarip.pngbin0 -> 2420 bytes
-rw-r--r--src/icons/actions/hi32-action-datacd.pngbin0 -> 2218 bytes
-rw-r--r--src/icons/actions/hi32-action-datadvd.pngbin0 -> 2281 bytes
-rw-r--r--src/icons/actions/hi32-action-dvdcopy.pngbin0 -> 2658 bytes
-rw-r--r--src/icons/actions/hi32-action-emovix.pngbin0 -> 2522 bytes
-rw-r--r--src/icons/actions/hi32-action-erasecd.pngbin0 -> 2599 bytes
-rw-r--r--src/icons/actions/hi32-action-formatdvd.pngbin0 -> 2905 bytes
-rw-r--r--src/icons/actions/hi32-action-mixedcd.pngbin0 -> 2490 bytes
-rw-r--r--src/icons/actions/hi32-action-mp3cd.pngbin0 -> 2512 bytes
-rw-r--r--src/icons/actions/hi32-action-videocd.pngbin0 -> 2895 bytes
-rw-r--r--src/icons/actions/hi32-action-videodvd.pngbin0 -> 2945 bytes
-rw-r--r--src/icons/actions/hi48-action-audiocd.pngbin0 -> 4033 bytes
-rw-r--r--src/icons/actions/hi48-action-burn_cdimage.pngbin0 -> 4060 bytes
-rw-r--r--src/icons/actions/hi48-action-burn_dvdimage.pngbin0 -> 4462 bytes
-rw-r--r--src/icons/actions/hi48-action-cdburn.pngbin0 -> 4366 bytes
-rw-r--r--src/icons/actions/hi48-action-cdcopy.pngbin0 -> 3945 bytes
-rw-r--r--src/icons/actions/hi48-action-cddarip.pngbin0 -> 4131 bytes
-rw-r--r--src/icons/actions/hi48-action-datacd.pngbin0 -> 3581 bytes
-rw-r--r--src/icons/actions/hi48-action-datadvd.pngbin0 -> 3853 bytes
-rw-r--r--src/icons/actions/hi48-action-dvdcopy.pngbin0 -> 4782 bytes
-rw-r--r--src/icons/actions/hi48-action-emovix.pngbin0 -> 4602 bytes
-rw-r--r--src/icons/actions/hi48-action-erasecd.pngbin0 -> 4676 bytes
-rw-r--r--src/icons/actions/hi48-action-formatdvd.pngbin0 -> 5330 bytes
-rw-r--r--src/icons/actions/hi48-action-mixedcd.pngbin0 -> 4289 bytes
-rw-r--r--src/icons/actions/hi48-action-mp3cd.pngbin0 -> 4351 bytes
-rw-r--r--src/icons/actions/hi48-action-videocd.pngbin0 -> 5594 bytes
-rw-r--r--src/icons/actions/hi48-action-videodvd.pngbin0 -> 5649 bytes
-rw-r--r--src/icons/actions/hi64-action-musicbrainz.pngbin0 -> 4807 bytes
-rw-r--r--src/icons/actions/hisc-action-audiocd.svgzbin0 -> 3370 bytes
-rw-r--r--src/icons/actions/hisc-action-burn_cdimage.svgzbin0 -> 7665 bytes
-rw-r--r--src/icons/actions/hisc-action-burn_dvdimage.svgzbin0 -> 8596 bytes
-rw-r--r--src/icons/actions/hisc-action-cdburn.svgzbin0 -> 2771 bytes
-rw-r--r--src/icons/actions/hisc-action-cdcopy.svgzbin0 -> 3097 bytes
-rw-r--r--src/icons/actions/hisc-action-cddarip.svgzbin0 -> 9363 bytes
-rw-r--r--src/icons/actions/hisc-action-datacd.svgzbin0 -> 4433 bytes
-rw-r--r--src/icons/actions/hisc-action-datadvd.svgzbin0 -> 3160 bytes
-rw-r--r--src/icons/actions/hisc-action-dvdcopy.svgzbin0 -> 4200 bytes
-rw-r--r--src/icons/actions/hisc-action-emovix.svgzbin0 -> 55745 bytes
-rw-r--r--src/icons/actions/hisc-action-erasecd.svgzbin0 -> 8251 bytes
-rw-r--r--src/icons/actions/hisc-action-formatdvd.svgzbin0 -> 9158 bytes
-rw-r--r--src/icons/actions/hisc-action-mixedcd.svgzbin0 -> 6298 bytes
-rw-r--r--src/icons/actions/hisc-action-mp3cd.svgzbin0 -> 4455 bytes
-rw-r--r--src/icons/actions/hisc-action-videocd.svgzbin0 -> 8587 bytes
-rw-r--r--src/icons/actions/hisc-action-videodvd.svgzbin0 -> 9447 bytes
-rw-r--r--src/icons/hi128-app-k3b.pngbin0 -> 5295 bytes
-rw-r--r--src/icons/hi16-app-k3b.pngbin0 -> 731 bytes
-rw-r--r--src/icons/hi22-app-k3b.pngbin0 -> 1142 bytes
-rw-r--r--src/icons/hi32-app-k3b.pngbin0 -> 1376 bytes
-rw-r--r--src/icons/hi48-app-k3b.pngbin0 -> 2067 bytes
-rw-r--r--src/icons/hi64-app-k3b.pngbin0 -> 2891 bytes
-rw-r--r--src/k3b-cue.desktop14
-rw-r--r--src/k3b-iso.desktop13
-rw-r--r--src/k3b.cpp1630
-rw-r--r--src/k3b.desktop123
-rw-r--r--src/k3b.h330
-rw-r--r--src/k3bappdevicemanager.cpp304
-rw-r--r--src/k3bappdevicemanager.h119
-rw-r--r--src/k3bapplication.cpp451
-rw-r--r--src/k3bapplication.h156
-rw-r--r--src/k3baudioplayer.cpp663
-rw-r--r--src/k3baudioplayer.h208
-rw-r--r--src/k3baudioprojectinterface.cpp92
-rw-r--r--src/k3baudioprojectinterface.h63
-rw-r--r--src/k3bburnprogressdialog.cpp134
-rw-r--r--src/k3bburnprogressdialog.h55
-rw-r--r--src/k3bcontentsview.cpp86
-rw-r--r--src/k3bcontentsview.h49
-rw-r--r--src/k3bdatamodewidget.cpp106
-rw-r--r--src/k3bdatamodewidget.h46
-rw-r--r--src/k3bdataprojectinterface.cpp128
-rw-r--r--src/k3bdataprojectinterface.h105
-rw-r--r--src/k3bdebuggingoutputdialog.cpp162
-rw-r--r--src/k3bdebuggingoutputdialog.h46
-rw-r--r--src/k3bdebuggingoutputfile.cpp75
-rw-r--r--src/k3bdebuggingoutputfile.h39
-rw-r--r--src/k3bdiroperator.cpp159
-rw-r--r--src/k3bdiroperator.h82
-rw-r--r--src/k3bdirview.cpp367
-rw-r--r--src/k3bdirview.h100
-rw-r--r--src/k3bdiskinfoview.cpp500
-rw-r--r--src/k3bdiskinfoview.h56
-rw-r--r--src/k3bemptydiscwaiter.cpp761
-rw-r--r--src/k3bemptydiscwaiter.h139
-rw-r--r--src/k3bfiletreecombobox.cpp393
-rw-r--r--src/k3bfiletreecombobox.h72
-rw-r--r--src/k3bfiletreeview.cpp728
-rw-r--r--src/k3bfiletreeview.h199
-rw-r--r--src/k3bfileview.cpp183
-rw-r--r--src/k3bfileview.h74
-rw-r--r--src/k3bfirstrun.cpp84
-rw-r--r--src/k3bfirstrun.h34
-rw-r--r--src/k3bflatbutton.cpp203
-rw-r--r--src/k3bflatbutton.h77
-rw-r--r--src/k3binteractiondialog.cpp662
-rw-r--r--src/k3binteractiondialog.h279
-rw-r--r--src/k3binterface.cpp192
-rw-r--r--src/k3binterface.h102
-rw-r--r--src/k3bjobinterface.cpp190
-rw-r--r--src/k3bjobinterface.h82
-rw-r--r--src/k3bjobprogressdialog.cpp696
-rw-r--r--src/k3bjobprogressdialog.h173
-rw-r--r--src/k3bjobprogressosd.cpp303
-rw-r--r--src/k3bjobprogressosd.h88
-rw-r--r--src/k3blsofwrapper.cpp108
-rw-r--r--src/k3blsofwrapper.h60
-rw-r--r--src/k3blsofwrapperdialog.cpp127
-rw-r--r--src/k3blsofwrapperdialog.h53
-rw-r--r--src/k3bmediacache.cpp373
-rw-r--r--src/k3bmediacache.h148
-rw-r--r--src/k3bmediacontentsview.cpp166
-rw-r--r--src/k3bmediacontentsview.h116
-rw-r--r--src/k3bmediaselectioncombobox.cpp505
-rw-r--r--src/k3bmediaselectioncombobox.h136
-rw-r--r--src/k3bmediaselectiondialog.cpp127
-rw-r--r--src/k3bmediaselectiondialog.h87
-rw-r--r--src/k3bmedium.cpp463
-rw-r--r--src/k3bmedium.h134
-rw-r--r--src/k3bminibutton.cpp77
-rw-r--r--src/k3bminibutton.h51
-rw-r--r--src/k3bmixedprojectinterface.cpp46
-rw-r--r--src/k3bmixedprojectinterface.h47
-rw-r--r--src/k3bmusicbrainz.cpp103
-rw-r--r--src/k3bmusicbrainz.h54
-rw-r--r--src/k3bpassivepopup.cpp280
-rw-r--r--src/k3bpassivepopup.h76
-rw-r--r--src/k3bprojectinterface.cpp138
-rw-r--r--src/k3bprojectinterface.h91
-rw-r--r--src/k3bprojectmanager.cpp653
-rw-r--r--src/k3bprojectmanager.h89
-rw-r--r--src/k3bprojecttabwidget.cpp216
-rw-r--r--src/k3bprojecttabwidget.h78
-rw-r--r--src/k3bservicemenuinstaller.cpp119
-rw-r--r--src/k3bservicemenuinstaller.h55
-rw-r--r--src/k3bsidepanel.cpp108
-rw-r--r--src/k3bsidepanel.h49
-rw-r--r--src/k3bsplash.cpp129
-rw-r--r--src/k3bsplash.h48
-rw-r--r--src/k3bstatusbarmanager.cpp250
-rw-r--r--src/k3bstatusbarmanager.h61
-rw-r--r--src/k3bsystemproblemdialog.cpp690
-rw-r--r--src/k3bsystemproblemdialog.h101
-rw-r--r--src/k3btempdirselectionwidget.cpp277
-rw-r--r--src/k3btempdirselectionwidget.h100
-rw-r--r--src/k3bthemedheader.cpp129
-rw-r--r--src/k3bthemedheader.h55
-rw-r--r--src/k3bthemedlabel.cpp76
-rw-r--r--src/k3bthemedlabel.h42
-rw-r--r--src/k3bthememanager.cpp324
-rw-r--r--src/k3bthememanager.h146
-rw-r--r--src/k3btimeoutwidget.cpp149
-rw-r--r--src/k3btimeoutwidget.h59
-rw-r--r--src/k3btooltip.cpp195
-rw-r--r--src/k3btooltip.h81
-rw-r--r--src/k3btrm.cpp93
-rw-r--r--src/k3btrm.h60
-rw-r--r--src/k3bui.rc78
-rw-r--r--src/k3bwelcomewidget.cpp489
-rw-r--r--src/k3bwelcomewidget.h124
-rw-r--r--src/k3bwidgetshoweffect.cpp203
-rw-r--r--src/k3bwidgetshoweffect.h115
-rw-r--r--src/k3bwriterselectionwidget.cpp607
-rw-r--r--src/k3bwriterselectionwidget.h146
-rw-r--r--src/k3bwritingmodewidget.cpp247
-rw-r--r--src/k3bwritingmodewidget.h91
-rw-r--r--src/konqi/Makefile.am16
-rw-r--r--src/konqi/k3b_audiocd_rip.desktop49
-rw-r--r--src/konqi/k3b_cd_copy.desktop52
-rw-r--r--src/konqi/k3b_create_audio_cd.desktop62
-rw-r--r--src/konqi/k3b_create_data_cd.desktop63
-rw-r--r--src/konqi/k3b_create_data_dvd.desktop57
-rw-r--r--src/konqi/k3b_create_video_cd.desktop61
-rw-r--r--src/konqi/k3b_dvd_copy.desktop52
-rw-r--r--src/konqi/k3b_handle_empty_cd.desktop120
-rw-r--r--src/konqi/k3b_handle_empty_dvd.desktop110
-rw-r--r--src/konqi/k3b_videodvd_rip.desktop48
-rw-r--r--src/konqi/k3b_write_bin_image.desktop62
-rw-r--r--src/konqi/k3b_write_iso_image.desktop55
-rw-r--r--src/main.cpp152
-rw-r--r--src/mimetypes/Makefile.am3
-rw-r--r--src/mimetypes/x-k3b.desktop65
-rw-r--r--src/misc/Makefile.am14
-rw-r--r--src/misc/k3bblankingdialog.cpp343
-rw-r--r--src/misc/k3bblankingdialog.h86
-rw-r--r--src/misc/k3bcdcopydialog.cpp556
-rw-r--r--src/misc/k3bcdcopydialog.h96
-rw-r--r--src/misc/k3bcdimagewritingdialog.cpp1049
-rw-r--r--src/misc/k3bcdimagewritingdialog.h116
-rw-r--r--src/misc/k3bdvdcopydialog.cpp455
-rw-r--r--src/misc/k3bdvdcopydialog.h79
-rw-r--r--src/misc/k3bdvdformattingdialog.cpp185
-rw-r--r--src/misc/k3bdvdformattingdialog.h55
-rw-r--r--src/misc/k3bisoimagewritingdialog.cpp580
-rw-r--r--src/misc/k3bisoimagewritingdialog.h90
-rw-r--r--src/option/Makefile.am20
-rw-r--r--src/option/base_k3bcddboptiontab.ui560
-rw-r--r--src/option/base_k3bmiscoptiontab.ui284
-rw-r--r--src/option/base_k3bpluginoptiontab.ui90
-rw-r--r--src/option/base_k3bthemeoptiontab.ui208
-rw-r--r--src/option/k3bburningoptiontab.cpp198
-rw-r--r--src/option/k3bburningoptiontab.h61
-rw-r--r--src/option/k3bcddboptiontab.cpp338
-rw-r--r--src/option/k3bcddboptiontab.h50
-rw-r--r--src/option/k3bdeviceoptiontab.cpp94
-rw-r--r--src/option/k3bdeviceoptiontab.h47
-rw-r--r--src/option/k3bdevicewidget.cpp404
-rw-r--r--src/option/k3bdevicewidget.h78
-rw-r--r--src/option/k3bexternalbinoptiontab.cpp78
-rw-r--r--src/option/k3bexternalbinoptiontab.h50
-rw-r--r--src/option/k3bexternalbinwidget.cpp318
-rw-r--r--src/option/k3bexternalbinwidget.h103
-rw-r--r--src/option/k3bmiscoptiontab.cpp187
-rw-r--r--src/option/k3bmiscoptiontab.h43
-rw-r--r--src/option/k3bnotifyoptiontab.cpp61
-rw-r--r--src/option/k3bnotifyoptiontab.h43
-rw-r--r--src/option/k3boptiondialog.cpp258
-rw-r--r--src/option/k3boptiondialog.h91
-rw-r--r--src/option/k3bpluginoptiontab.cpp137
-rw-r--r--src/option/k3bpluginoptiontab.h43
-rw-r--r--src/option/k3bthemeoptiontab.cpp234
-rw-r--r--src/option/k3bthemeoptiontab.h47
-rw-r--r--src/pics/73lab/Makefile.am23
-rw-r--r--src/pics/73lab/dialog_left.pngbin0 -> 556 bytes
-rw-r--r--src/pics/73lab/dialog_right.pngbin0 -> 5881 bytes
-rw-r--r--src/pics/73lab/k3b.theme5
-rw-r--r--src/pics/73lab/media_audio.pngbin0 -> 7487 bytes
-rw-r--r--src/pics/73lab/media_data.pngbin0 -> 8374 bytes
-rw-r--r--src/pics/73lab/media_empty.pngbin0 -> 8001 bytes
-rw-r--r--src/pics/73lab/media_left.pngbin0 -> 556 bytes
-rw-r--r--src/pics/73lab/media_mixed.pngbin0 -> 8116 bytes
-rw-r--r--src/pics/73lab/media_none.pngbin0 -> 5881 bytes
-rw-r--r--src/pics/73lab/media_video.pngbin0 -> 7157 bytes
-rw-r--r--src/pics/73lab/probing.pngbin0 -> 32980 bytes
-rw-r--r--src/pics/73lab/progress_fail.pngbin0 -> 17515 bytes
-rw-r--r--src/pics/73lab/progress_right.pngbin0 -> 1723 bytes
-rw-r--r--src/pics/73lab/progress_success.pngbin0 -> 16094 bytes
-rw-r--r--src/pics/73lab/progress_working.pngbin0 -> 13102 bytes
-rw-r--r--src/pics/73lab/project_left.pngbin0 -> 9445 bytes
-rw-r--r--src/pics/73lab/project_right.pngbin0 -> 1723 bytes
-rw-r--r--src/pics/73lab/splash.pngbin0 -> 159246 bytes
-rw-r--r--src/pics/73lab/welcome_bg.pngbin0 -> 37538 bytes
-rw-r--r--src/pics/Makefile.am1
-rw-r--r--src/pics/RobsTheme/Makefile.am23
-rw-r--r--src/pics/RobsTheme/dialog_left.pngbin0 -> 250 bytes
-rw-r--r--src/pics/RobsTheme/dialog_right.pngbin0 -> 2845 bytes
-rw-r--r--src/pics/RobsTheme/k3b.theme5
-rw-r--r--src/pics/RobsTheme/media_audio.pngbin0 -> 7422 bytes
-rw-r--r--src/pics/RobsTheme/media_data.pngbin0 -> 9382 bytes
-rw-r--r--src/pics/RobsTheme/media_empty.pngbin0 -> 4240 bytes
-rw-r--r--src/pics/RobsTheme/media_left.pngbin0 -> 250 bytes
-rw-r--r--src/pics/RobsTheme/media_mixed.pngbin0 -> 8748 bytes
-rw-r--r--src/pics/RobsTheme/media_none.pngbin0 -> 2861 bytes
-rw-r--r--src/pics/RobsTheme/media_video.pngbin0 -> 4334 bytes
-rw-r--r--src/pics/RobsTheme/progress_fail.pngbin0 -> 7390 bytes
-rw-r--r--src/pics/RobsTheme/progress_right.pngbin0 -> 2438 bytes
-rw-r--r--src/pics/RobsTheme/progress_success.pngbin0 -> 10252 bytes
-rw-r--r--src/pics/RobsTheme/progress_working.pngbin0 -> 6998 bytes
-rw-r--r--src/pics/RobsTheme/project_left.pngbin0 -> 8067 bytes
-rw-r--r--src/pics/RobsTheme/project_right.pngbin0 -> 2376 bytes
-rw-r--r--src/pics/RobsTheme/splash.pngbin0 -> 144339 bytes
-rw-r--r--src/pics/RobsTheme/welcome_bg.pngbin0 -> 75487 bytes
-rw-r--r--src/pics/crystal/Makefile.am24
-rw-r--r--src/pics/crystal/dialog_left.pngbin0 -> 1609 bytes
-rw-r--r--src/pics/crystal/dialog_right.pngbin0 -> 7376 bytes
-rw-r--r--src/pics/crystal/k3b.theme5
-rw-r--r--src/pics/crystal/media_audio.pngbin0 -> 5068 bytes
-rw-r--r--src/pics/crystal/media_data.pngbin0 -> 6870 bytes
-rw-r--r--src/pics/crystal/media_empty.pngbin0 -> 7545 bytes
-rw-r--r--src/pics/crystal/media_left.pngbin0 -> 1609 bytes
-rw-r--r--src/pics/crystal/media_mixed.pngbin0 -> 5474 bytes
-rw-r--r--src/pics/crystal/media_none.pngbin0 -> 7376 bytes
-rw-r--r--src/pics/crystal/media_video.pngbin0 -> 6794 bytes
-rw-r--r--src/pics/crystal/probing.pngbin0 -> 31970 bytes
-rw-r--r--src/pics/crystal/progress_fail.pngbin0 -> 5714 bytes
-rw-r--r--src/pics/crystal/progress_right.pngbin0 -> 1928 bytes
-rw-r--r--src/pics/crystal/progress_success.pngbin0 -> 6590 bytes
-rw-r--r--src/pics/crystal/progress_working.pngbin0 -> 7091 bytes
-rw-r--r--src/pics/crystal/project_left.pngbin0 -> 4303 bytes
-rw-r--r--src/pics/crystal/project_right.pngbin0 -> 1928 bytes
-rw-r--r--src/pics/crystal/splash.pngbin0 -> 150400 bytes
-rw-r--r--src/pics/crystal/welcome_bg.pngbin0 -> 33102 bytes
-rw-r--r--src/pics/quant/Makefile.am23
-rw-r--r--src/pics/quant/dialog_left.pngbin0 -> 3429 bytes
-rw-r--r--src/pics/quant/dialog_right.pngbin0 -> 4364 bytes
-rw-r--r--src/pics/quant/k3b.theme6
-rw-r--r--src/pics/quant/media_audio.pngbin0 -> 5120 bytes
-rw-r--r--src/pics/quant/media_data.pngbin0 -> 4352 bytes
-rw-r--r--src/pics/quant/media_empty.pngbin0 -> 1579 bytes
-rw-r--r--src/pics/quant/media_left.pngbin0 -> 3475 bytes
-rw-r--r--src/pics/quant/media_mixed.pngbin0 -> 3429 bytes
-rw-r--r--src/pics/quant/media_none.pngbin0 -> 1835 bytes
-rw-r--r--src/pics/quant/media_video.pngbin0 -> 10157 bytes
-rw-r--r--src/pics/quant/progress_fail.pngbin0 -> 14819 bytes
-rw-r--r--src/pics/quant/progress_right.pngbin0 -> 5548 bytes
-rw-r--r--src/pics/quant/progress_success.pngbin0 -> 12044 bytes
-rw-r--r--src/pics/quant/progress_working.pngbin0 -> 11647 bytes
-rw-r--r--src/pics/quant/project_left.pngbin0 -> 9454 bytes
-rw-r--r--src/pics/quant/project_right.pngbin0 -> 5628 bytes
-rw-r--r--src/pics/quant/splash.pngbin0 -> 216696 bytes
-rw-r--r--src/pics/quant/welcome_bg.pngbin0 -> 591641 bytes
-rw-r--r--src/projects/Makefile.am86
-rw-r--r--src/projects/base_k3badvanceddataimagesettings.ui193
-rw-r--r--src/projects/base_k3baudiocdtextallfieldswidget.ui275
-rw-r--r--src/projects/base_k3baudiocdtextwidget.ui222
-rw-r--r--src/projects/base_k3baudiotrackwidget.ui336
-rw-r--r--src/projects/base_k3bbootimageview.ui394
-rw-r--r--src/projects/base_k3bdataimagesettings.ui274
-rw-r--r--src/projects/base_k3bdatavolumedescwidget.ui370
-rw-r--r--src/projects/base_k3bmovixoptionswidget.ui337
-rw-r--r--src/projects/k3baudioburndialog.cpp341
-rw-r--r--src/projects/k3baudioburndialog.h81
-rw-r--r--src/projects/k3baudiocdtextwidget.cpp236
-rw-r--r--src/projects/k3baudiocdtextwidget.h55
-rw-r--r--src/projects/k3baudiodatasourceeditwidget.cpp166
-rw-r--r--src/projects/k3baudiodatasourceeditwidget.h70
-rw-r--r--src/projects/k3baudiodatasourceviewitem.cpp111
-rw-r--r--src/projects/k3baudiodatasourceviewitem.h54
-rw-r--r--src/projects/k3baudioeditorwidget.cpp877
-rw-r--r--src/projects/k3baudioeditorwidget.h220
-rw-r--r--src/projects/k3baudiotrackaddingdialog.cpp302
-rw-r--r--src/projects/k3baudiotrackaddingdialog.h106
-rw-r--r--src/projects/k3baudiotrackdialog.cpp113
-rw-r--r--src/projects/k3baudiotrackdialog.h57
-rw-r--r--src/projects/k3baudiotrackplayer.cpp365
-rw-r--r--src/projects/k3baudiotrackplayer.h87
-rw-r--r--src/projects/k3baudiotracksplitdialog.cpp232
-rw-r--r--src/projects/k3baudiotracksplitdialog.h71
-rw-r--r--src/projects/k3baudiotracktrmlookupdialog.cpp131
-rw-r--r--src/projects/k3baudiotracktrmlookupdialog.h54
-rw-r--r--src/projects/k3baudiotrackview.cpp1005
-rw-r--r--src/projects/k3baudiotrackview.h142
-rw-r--r--src/projects/k3baudiotrackviewitem.cpp229
-rw-r--r--src/projects/k3baudiotrackviewitem.h66
-rw-r--r--src/projects/k3baudiotrackwidget.cpp162
-rw-r--r--src/projects/k3baudiotrackwidget.h48
-rw-r--r--src/projects/k3baudioview.cpp136
-rw-r--r--src/projects/k3baudioview.h61
-rw-r--r--src/projects/k3bbootimagedialog.cpp45
-rw-r--r--src/projects/k3bbootimagedialog.h44
-rw-r--r--src/projects/k3bbootimageview.cpp273
-rw-r--r--src/projects/k3bbootimageview.h57
-rw-r--r--src/projects/k3bdataadvancedimagesettingswidget.cpp352
-rw-r--r--src/projects/k3bdataadvancedimagesettingswidget.h69
-rw-r--r--src/projects/k3bdataburndialog.cpp289
-rw-r--r--src/projects/k3bdataburndialog.h75
-rw-r--r--src/projects/k3bdatadirtreeview.cpp506
-rw-r--r--src/projects/k3bdatadirtreeview.h115
-rw-r--r--src/projects/k3bdatafileview.cpp483
-rw-r--r--src/projects/k3bdatafileview.h115
-rw-r--r--src/projects/k3bdataimagesettingswidget.cpp400
-rw-r--r--src/projects/k3bdataimagesettingswidget.h54
-rw-r--r--src/projects/k3bdatamultisessioncombobox.cpp177
-rw-r--r--src/projects/k3bdatamultisessioncombobox.h52
-rw-r--r--src/projects/k3bdatapropertiesdialog.cpp248
-rw-r--r--src/projects/k3bdatapropertiesdialog.h61
-rw-r--r--src/projects/k3bdatasessionimportdialog.cpp137
-rw-r--r--src/projects/k3bdatasessionimportdialog.h64
-rw-r--r--src/projects/k3bdataurladdingdialog.cpp826
-rw-r--r--src/projects/k3bdataurladdingdialog.h110
-rw-r--r--src/projects/k3bdataview.cpp196
-rw-r--r--src/projects/k3bdataview.h78
-rw-r--r--src/projects/k3bdataviewitem.cpp340
-rw-r--r--src/projects/k3bdataviewitem.h135
-rw-r--r--src/projects/k3bdatavolumedescwidget.cpp93
-rw-r--r--src/projects/k3bdatavolumedescwidget.h40
-rw-r--r--src/projects/k3bdvdburndialog.cpp300
-rw-r--r--src/projects/k3bdvdburndialog.h69
-rw-r--r--src/projects/k3bdvdview.cpp48
-rw-r--r--src/projects/k3bdvdview.h40
-rw-r--r--src/projects/k3bencodingconverter.cpp130
-rw-r--r--src/projects/k3bencodingconverter.h59
-rw-r--r--src/projects/k3bfillstatusdisplay.cpp759
-rw-r--r--src/projects/k3bfillstatusdisplay.h117
-rw-r--r--src/projects/k3bmixedburndialog.cpp353
-rw-r--r--src/projects/k3bmixedburndialog.h78
-rw-r--r--src/projects/k3bmixeddirtreeview.cpp103
-rw-r--r--src/projects/k3bmixeddirtreeview.h56
-rw-r--r--src/projects/k3bmixedview.cpp155
-rw-r--r--src/projects/k3bmixedview.h66
-rw-r--r--src/projects/k3bmovixburndialog.cpp265
-rw-r--r--src/projects/k3bmovixburndialog.h64
-rw-r--r--src/projects/k3bmovixdvdburndialog.cpp219
-rw-r--r--src/projects/k3bmovixdvdburndialog.h57
-rw-r--r--src/projects/k3bmovixdvdview.cpp48
-rw-r--r--src/projects/k3bmovixdvdview.h40
-rw-r--r--src/projects/k3bmovixlistview.cpp327
-rw-r--r--src/projects/k3bmovixlistview.h100
-rw-r--r--src/projects/k3bmovixoptionswidget.cpp243
-rw-r--r--src/projects/k3bmovixoptionswidget.h50
-rw-r--r--src/projects/k3bmovixview.cpp192
-rw-r--r--src/projects/k3bmovixview.h65
-rw-r--r--src/projects/k3bmusicbrainzjob.cpp287
-rw-r--r--src/projects/k3bmusicbrainzjob.h89
-rw-r--r--src/projects/k3bprojectburndialog.cpp413
-rw-r--r--src/projects/k3bprojectburndialog.h191
-rw-r--r--src/projects/k3bprojectplugindialog.cpp68
-rw-r--r--src/projects/k3bprojectplugindialog.h46
-rw-r--r--src/projects/k3bvcdburndialog.cpp1088
-rw-r--r--src/projects/k3bvcdburndialog.h142
-rw-r--r--src/projects/k3bvcdlistview.cpp271
-rw-r--r--src/projects/k3bvcdlistview.h90
-rw-r--r--src/projects/k3bvcdlistviewitem.cpp129
-rw-r--r--src/projects/k3bvcdlistviewitem.h50
-rw-r--r--src/projects/k3bvcdtrackdialog.cpp802
-rw-r--r--src/projects/k3bvcdtrackdialog.h123
-rw-r--r--src/projects/k3bvcdview.cpp74
-rw-r--r--src/projects/k3bvcdview.h55
-rw-r--r--src/projects/k3bvideodvdburndialog.cpp198
-rw-r--r--src/projects/k3bvideodvdburndialog.h55
-rw-r--r--src/projects/k3bvideodvdview.cpp84
-rw-r--r--src/projects/k3bvideodvdview.h48
-rw-r--r--src/projects/k3bview.cpp176
-rw-r--r--src/projects/k3bview.h112
-rw-r--r--src/projects/kostore/Makefile.am11
-rw-r--r--src/projects/kostore/README.k3b2
-rw-r--r--src/projects/kostore/SPEC122
-rw-r--r--src/projects/kostore/koStore.cc629
-rw-r--r--src/projects/kostore/koStore.h384
-rw-r--r--src/projects/kostore/koStoreBase.cc29
-rw-r--r--src/projects/kostore/koStoreBase.h51
-rw-r--r--src/projects/kostore/koStoreDevice.h88
-rw-r--r--src/projects/kostore/koZipStore.cc237
-rw-r--r--src/projects/kostore/koZipStore.h61
-rw-r--r--src/rip/Makefile.am32
-rw-r--r--src/rip/base_k3baudiorippingoptionwidget.ui282
-rw-r--r--src/rip/base_k3bcddbpatternwidget.ui180
-rw-r--r--src/rip/k3baudiocdlistview.cpp66
-rw-r--r--src/rip/k3baudiocdlistview.h45
-rw-r--r--src/rip/k3baudiocdview.cpp631
-rw-r--r--src/rip/k3baudiocdview.h107
-rw-r--r--src/rip/k3baudioconvertingoptionwidget.cpp266
-rw-r--r--src/rip/k3baudioconvertingoptionwidget.h74
-rw-r--r--src/rip/k3baudioprojectconvertingdialog.cpp371
-rw-r--r--src/rip/k3baudioprojectconvertingdialog.h78
-rw-r--r--src/rip/k3baudioprojectconvertingthread.cpp459
-rw-r--r--src/rip/k3baudioprojectconvertingthread.h101
-rw-r--r--src/rip/k3baudioripjob.cpp77
-rw-r--r--src/rip/k3baudioripjob.h71
-rw-r--r--src/rip/k3baudiorippingdialog.cpp470
-rw-r--r--src/rip/k3baudiorippingdialog.h92
-rw-r--r--src/rip/k3baudioripthread.cpp602
-rw-r--r--src/rip/k3baudioripthread.h117
-rw-r--r--src/rip/k3bcddbpatternwidget.cpp175
-rw-r--r--src/rip/k3bcddbpatternwidget.h51
-rw-r--r--src/rip/k3bcuefilewriter.cpp91
-rw-r--r--src/rip/k3bcuefilewriter.h54
-rw-r--r--src/rip/k3bpatternparser.cpp305
-rw-r--r--src/rip/k3bpatternparser.h52
-rw-r--r--src/rip/k3bvideocdinfo.cpp247
-rw-r--r--src/rip/k3bvideocdinfo.h107
-rw-r--r--src/rip/k3bvideocdrip.cpp355
-rw-r--r--src/rip/k3bvideocdrip.h74
-rw-r--r--src/rip/k3bvideocdrippingdialog.cpp260
-rw-r--r--src/rip/k3bvideocdrippingdialog.h73
-rw-r--r--src/rip/k3bvideocdrippingoptions.h74
-rw-r--r--src/rip/k3bvideocdview.cpp509
-rw-r--r--src/rip/k3bvideocdview.h105
-rw-r--r--src/rip/videodvd/Makefile.am16
-rw-r--r--src/rip/videodvd/base_k3bvideodvdrippingwidget.ui721
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingdialog.cpp634
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingdialog.h82
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingjob.cpp385
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingjob.h106
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingpreview.cpp135
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingpreview.h66
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingtitlelistview.cpp410
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingtitlelistview.h58
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingview.cpp256
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingview.h66
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingwidget.cpp375
-rw-r--r--src/rip/videodvd/k3bvideodvdrippingwidget.h67
-rw-r--r--src/sounds/Makefile.am5
-rw-r--r--src/sounds/k3b_error1.wavbin0 -> 15669 bytes
-rw-r--r--src/sounds/k3b_success1.wavbin0 -> 46657 bytes
-rw-r--r--src/sounds/k3b_wait_media1.wavbin0 -> 1940 bytes
-rw-r--r--src/sourceheader15
-rw-r--r--src/tips47
529 files changed, 68414 insertions, 0 deletions
diff --git a/src/IDEAS b/src/IDEAS
new file mode 100644
index 0000000..f8a2f9c
--- /dev/null
+++ b/src/IDEAS
@@ -0,0 +1,45 @@
+wie in KOffice K3bDoc von KParts::ReadWritePart ableiten
+in KOffice ist der view von KParts::PartBase abgeleitet. Warum das?
+alle actions, die das doc ndern, auch ins doc packen.
+alle actions, die nur fr die ansicht da sind (zb. properties dialog) in den view
+
+da wir verschiedene projekt-typen fr den gleichen mimetype haben macht ein ReadWritePartWrapper,
+der aufgrund des doctypes entscheidet, welches K3bDoc bentigt wird, mehr Sinn. Das hiee,
+dass es einen K3bPart gibt, der alle Projekte beinhaltet. Die einzelnen Projekte knnten allerdings auch wieder
+dynamisch hinzugeladen werden, so dass immer nur das gerade bentigte K3bDoc im Speicher ist.
+Der Wrapper muss dann nur den externalbin- und den devicemanager initialisieren und den kostore ffnen. Dann alle
+K3bDocFactories (wenn ein K3bDoc als eine Art plugin dynamisch hinzugeladen werden soll) fragen, ob sie
+den projekttyp untersttzen und wenn ja, eine instanz erzeugen und das dokument laden.
+Wie sieht es dann mit dem erstellen eines neuen dokumentes aus? Ev. Knnte der Wrapper hier alle Factories nach
+dem projecttyp fragen und fr jeden eine Action erstellen.
+K3b selber benutzt dann nicht den Wrapper, sondern macht alles selber. Das hiee redundanten Code in K3b und dem
+Wrapper.
+
+
+Audiodoc:
+ tracks und files.
+ ein track kann mehrere files enthalten
+ ein file kann vorne und hinten abgeschnitten werden
+ tracks knnen zusammengefhrt werden (resultiert in einem track mit den files aus den beiden quelltracks)
+ es gibt track- und filefilter; trackfilter sind das gewohnte und sollten meist benutzt werden, filefilter
+ filtern nur innerhalb eines tracks (Bsp: normalising nur ber alle files in einem track, wohingegen
+ normalising als trackfilter ber alle tracks normalisiert)
+ Das normale verhalten ist wie jetzt: Anlegen eines Tracks mit einem File. Das sollte fr die meisten
+ Anwender reichen. Wenn ctrl oder sowas gehalten wird kann man files zu einem track hinzufgen
+ (die gui knnte hier beim drcken von ctrl alle files als kindelemente der tracks anzeigen, auch bei
+ solchen tracks, die nur ein file enthalten. So wrde deutlich, dass ein file zu einem track hinzugefgt
+ werden kann.)
+
+K3bFileSystem:
+ K3bFsItem
+ -> K3bFsFile
+ -> K3bFsDirectory
+ FileSystem bietet virtuelle Funktionen newFile( filename ) und newDirectory( name ), mit welchen neue
+ Elemente von den addUrl Funktionen angelegt werden. Jedes Item hat eine size methode, welche die Gre
+ der Datei angibt. Zustzlich gibt es eine methode, welche die Gesamtgre aller Kinder und Enkel angibt
+ (nur sinnvoll fr K3bFsDirectory)
+ K3bFileSystem hat zustzlich ein caching-system, welches inode-basierte Grenberechung erlaubt.
+ K3bFsItem hat methoden wie isDir() und einen void Zeiger fr zustzliche Daten, wenn man nicht ableiten
+ mchte.
+ Von K3bFileSystem knnte man K3bIso9660FileSystem und K3bUdfFileSystem ableiten, welche zustzliche Daten
+ enthalten. \ No newline at end of file
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..be55a51
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,86 @@
+bin_PROGRAMS = k3b
+
+k3b_SOURCES = k3bwelcomewidget.cpp k3bapplication.cpp k3bdiroperator.cpp \
+ k3bfiletreeview.cpp \
+ k3bprojecttabwidget.cpp k3bsplash.cpp \
+ k3bfileview.cpp k3bdirview.cpp k3b.cpp main.cpp \
+ k3bstatusbarmanager.cpp k3bfiletreecombobox.cpp \
+ k3binterface.cpp k3binterface.skel \
+ k3bjobinterface.cpp k3bjobinterface.skel \
+ k3bprojectinterface.cpp k3bprojectinterface.skel \
+ k3bdataprojectinterface.cpp k3bdataprojectinterface.skel \
+ k3bsystemproblemdialog.cpp k3bmediacontentsview.cpp \
+ k3bsidepanel.cpp k3bcontentsview.cpp \
+ k3bjobprogressdialog.cpp k3bburnprogressdialog.cpp k3btempdirselectionwidget.cpp \
+ k3bdatamodewidget.cpp k3bwritingmodewidget.cpp k3bwriterselectionwidget.cpp \
+ k3binteractiondialog.cpp k3bthememanager.cpp \
+ k3bprojectmanager.cpp k3btrm.cpp k3bmusicbrainz.cpp \
+ k3baudioprojectinterface.cpp k3bmixedprojectinterface.cpp \
+ k3baudioprojectinterface.skel k3bmixedprojectinterface.skel k3bflatbutton.cpp \
+ k3bemptydiscwaiter.cpp k3bjobprogressosd.cpp \
+ k3bdebuggingoutputdialog.cpp k3bdebuggingoutputfile.cpp k3bappdevicemanager.cpp \
+ k3bmediacache.cpp k3bmedium.cpp k3bmediaselectioncombobox.cpp k3btooltip.cpp \
+ k3bwidgetshoweffect.cpp k3bmediaselectiondialog.cpp k3bdiskinfoview.cpp \
+ k3bpassivepopup.cpp k3btimeoutwidget.cpp k3bminibutton.cpp \
+ k3bthemedheader.cpp k3bthemedlabel.cpp k3blsofwrapper.cpp \
+ k3blsofwrapperdialog.cpp k3bservicemenuinstaller.cpp k3bfirstrun.cpp
+
+k3b_LDADD = ./option/liboption.la ./rip/librip.la \
+ ./projects/libprojects.la ../libk3bdevice/libk3bdevice.la \
+ ../libk3b/libk3b.la ./misc/libmisc.la ./fastscale/libfastscale.la \
+ -lkio -lkparts $(CAM_LIB) $(MUSICBRAINZ_LIBS)
+
+SUBDIRS = option misc rip projects fastscale pics icons konqi mimetypes sounds
+
+xdg_apps_DATA = k3b.desktop
+
+silent_DATA = k3b-iso.desktop k3b-cue.desktop
+silentdir = $(kde_appsdir)/.hidden/
+
+###################
+# this 10 paths are KDE specific. Use them:
+# kde_htmldir Where your docs should go to. (contains lang subdirs)
+# kde_appsdir Where your application file (.kdelnk) should go to.
+# kde_icondir Where your icon should go to.
+# kde_minidir Where your mini icon should go to.
+# kde_datadir Where you install application data. (Use a subdir)
+# kde_locale Where translation files should go to.(contains lang subdirs)
+# kde_cgidir Where cgi-bin executables should go to.
+# kde_confdir Where config files should go to.
+# kde_mimedir Where mimetypes should go to.
+# kde_toolbardir Where general toolbar icons should go to.
+# kde_wallpaperdir Where general wallpapers should go to.
+
+# set the include path for X, qt and KDE
+AM_CPPFLAGS = -I$(srcdir)/../libk3b/tools \
+ -I$(srcdir)/../libk3b/core \
+ -I$(srcdir)/../libk3b/cddb \
+ -I$(srcdir)/../libk3b/videodvd \
+ -I$(srcdir)/../libk3b/jobs \
+ -I$(srcdir)/../libk3bdevice \
+ -I$(srcdir)/../libk3b/projects \
+ -I$(srcdir)/../libk3b/projects/datacd \
+ -I$(srcdir)/../libk3b/projects/datadvd \
+ -I$(srcdir)/../libk3b/projects/audiocd \
+ -I$(srcdir)/../libk3b/projects/videocd \
+ -I$(srcdir)/../libk3b/projects/mixedcd \
+ -I$(srcdir)/../libk3b/projects/movixcd \
+ -I$(srcdir)/../libk3b/projects/videodvd \
+ -I$(srcdir)/../libk3b/projects/movixdvd \
+ -I$(srcdir)/../libk3b/plugin \
+ -I$(srcdir)/projects \
+ $(all_includes)
+
+METASOURCES = AUTO
+
+# the library search path.
+k3b_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+rcdir = $(kde_datadir)/k3b
+rc_DATA = k3bui.rc eventsrc tips
+
+messages: rc.cpp
+ $(EXTRACTRC) `find . -name \*.rc -o -name \*.ui` `find ../plugins -name \*.rc -o -name \*.ui`> rc.cpp
+ $(PREPARETIPS) > tips.cpp
+ $(XGETTEXT) `find . -name \*.cpp -o -name \*.h` `find ../plugins -name \*.cpp -o -name \*.h` -o $(podir)/k3b.pot
+ rm -f tips.cpp
diff --git a/src/eventsrc b/src/eventsrc
new file mode 100644
index 0000000..a577acb
--- /dev/null
+++ b/src/eventsrc
@@ -0,0 +1,333 @@
+[!Global!]
+IconName=k3b
+Comment=K3b
+Comment[ar]= K3b
+Comment[bn]=কে-থ্রি-বি
+Comment[hi]=के3बी
+
+[SuccessfullyFinished]
+Name=Process successful
+Name[af]=Proses suksesvol
+Name[ar]= تمت المعالجة بنجاح
+Name[bg]=Процесът е успешен
+Name[bn]=প্রসেস সফল
+Name[bs]=Proces je uspio
+Name[ca]=Procés correcte
+Name[cs]=Proces úspěšný
+Name[da]=Processen lykkedes
+Name[de]=Vorgang erfolgreich
+Name[el]=Διεργασία επιτυχής
+Name[eo]=Tasko sukcesa
+Name[es]=Éxito de proceso
+Name[et]=Tegevus oli edukas
+Name[fa]=فرآیند موفق
+Name[fi]=Suoritettu
+Name[fr]=Processus réussi
+Name[ga]=D'éirigh leis an bpróiseas
+Name[gl]=Proceso exitoso
+Name[he]=תהליך מוצלח
+Name[hi]=प्रक्रिया सफल
+Name[hu]=A művelet sikeresen befejeződött
+Name[is]=Velheppnað ferli
+Name[it]=Processo riuscito
+Name[ja]=プロセス成功
+Name[ka]=პროცესი წარმატებულია
+Name[km]=ដំណើរការ​បាន​ជោគជ័យ
+Name[lt]=Procesas pavyko
+Name[mk]=Процесот е успешен
+Name[ms]= Proses berjaya
+Name[nb]=Vellykket prosess
+Name[nds]=Vörgang is glückt
+Name[ne]=प्रक्रिया सफल भयो
+Name[nl]=Proces was succesvol
+Name[nn]=Vellykka prosess
+Name[pa]=ਕਾਰਵਾਈ ਸਫ਼ਲ ਹੋਈ
+Name[pl]=Proces zakończony pomyślnie
+Name[pt]=Processo com sucesso
+Name[pt_BR]=Processo bem-sucedido
+Name[ru]=Успешно завершено
+Name[sk]=Proces úspešný
+Name[sl]=Proces uspešen
+Name[sr]=Обрада је успешна
+Name[sr@Latn]=Obrada je uspešna
+Name[sv]=Processen lyckades
+Name[ta]=வெற்றிகரமான தொகுப்பு
+Name[tg]=Бомуваффақият ба анҷом расид
+Name[tr]=İşlem başarılı
+Name[uk]=Процес успішний
+Name[uz]=Muvaffaqiyatli jarayon
+Name[uz@cyrillic]=Муваффақиятли жараён
+Name[zh_CN]=处理成功
+Name[zh_TW]=處理成功
+Comment=Process successfully finished
+Comment[af]=Proses het suksesvol klaar gemaak
+Comment[ar]=نهاية المعالجة بنجاح
+Comment[bg]=Процесът завърши успешно
+Comment[bn]=প্রসেস সফলভাবে শেষ হল
+Comment[bs]=Proces je uspješno završen
+Comment[ca]=Procés finalitzat amb èxit
+Comment[cs]=Proces úspěšně dokončen
+Comment[da]=Processen afsluttedes korrekt
+Comment[de]=Vorgang erfolgreich abgeschlossen
+Comment[el]=Η διεργασία ολοκληρώθηκε επιτυχώς
+Comment[eo]=Tasko sukcese finis
+Comment[es]=Proceso terminado con éxito
+Comment[et]=Tegevus lõppes edukalt
+Comment[fa]=فرآیند با موفقیت تمام شد
+Comment[fi]=Työ on suoritettu
+Comment[fr]=Processus terminé avec succès
+Comment[gl]=O proceso terminou con éxito
+Comment[he]=התהליך הסתיים בהצלחה
+Comment[hi]=प्रक्रिया सफलतापूर्वक पूर्ण
+Comment[hu]=A művelet sikeresen befejeződött
+Comment[is]=Ferli lauk með góðum árangri
+Comment[it]=Processo riuscito e terminato
+Comment[ja]=プロセス完了
+Comment[ka]=პროცესი წარმატებით დასრულდა
+Comment[km]=បាន​បញ្ចប់​ដំណើរការ​ដោយ​ជោគជ័យ
+Comment[lt]=Procesas sėkmingai baigtas
+Comment[mk]=Процесот заврши успешно
+Comment[ms]= Proses selesai dengan jayanya
+Comment[nb]=Prosessen ble fullført vellykket
+Comment[nds]=Vörgang afslaten
+Comment[ne]=प्रक्रिया सफलतापूर्वक समाप्त भयो
+Comment[nl]=Proces met succes voltooid
+Comment[nn]=Prosessen er fullført
+Comment[pa]=ਕਾਰਵਾਈ ਸਫ਼ਲਤਾਪੂਰਕ ਪੂਰੀ ਕੀਤੀ ਗਈ
+Comment[pl]=Proces zakończył się pomyślnie
+Comment[pt]=O processo terminou com sucesso
+Comment[pt_BR]=Processo finalizado com sucesso
+Comment[ru]=Процесс завершён успешно
+Comment[sk]=Proces úspešne ukončený
+Comment[sl]=Proces je uspešno končan
+Comment[sr]=Обрада је успешно завршена
+Comment[sr@Latn]=Obrada je uspešno završena
+Comment[sv]=Processen avslutades med lyckat resultat
+Comment[ta]=வெற்றிகரமாக தொகுப்பு முடிந்தது
+Comment[tg]=Амалиёт бомуваффақият ба анҷом расид
+Comment[tr]=İşlem başarıyla sonuçlandı
+Comment[uk]=Процес успішно завершився
+Comment[uz]=Jarayon muvaffaqiyatli tugadi
+Comment[uz@cyrillic]=Жараён муваффақиятли тугади
+Comment[zh_CN]=处理成功完成
+Comment[zh_TW]=成功完成處理
+default_sound=k3b_success1.wav
+default_presentation=1
+# None = 0, Sound = 1, Messagebox = 2, Logfile = 4, Stderr = 8, PassivePopup = 16, Execute = 32
+
+[FinishedWithError]
+Name=Process error
+Name[af]=Verwerking fout
+Name[ar]= خطأ خلال المعالجة
+Name[bg]=Грешка при обработка
+Name[bn]=প্রসেস ত্রুটি
+Name[bs]=Greška u procesu
+Name[ca]=Procés amb error
+Name[cs]=Chyba procesu
+Name[da]=Procesfejl
+Name[de]=Vorgang nicht erfolgreich
+Name[el]=Σφάλμα διεργασίας
+Name[eo]=Taska eraro
+Name[es]=Error de proceso
+Name[et]=Tegevuse viga
+Name[fa]=خطای فرآیند
+Name[fi]=Virhe
+Name[fr]=Erreur du processus
+Name[gl]=Erro no proceso
+Name[he]=שגיאת תהליך
+Name[hi]=प्रक्रिया त्रुटि
+Name[hu]=A művelet során hiba történt
+Name[is]=Villa í ferli
+Name[it]=Errore di Processo
+Name[ja]=プロセスエラー
+Name[ka]=პროცესის შეცდომა
+Name[km]=ដំណើរការ​មាន​កំហុស
+Name[lt]=Proceso klaida
+Name[mk]=Грешка во процесот
+Name[ms]=Ralat proses
+Name[nb]=Prosessfeil
+Name[nds]=Perzessfehler
+Name[ne]=प्रक्रिया त्रुटि
+Name[nl]=Procesfout
+Name[nn]=Prosessfeil
+Name[pa]=ਕਾਰਜ ਗਲਤੀ
+Name[pl]=Błąd procesu
+Name[pt]=Erro no processo
+Name[pt_BR]=Erro no processo
+Name[ru]=Ошибка
+Name[sk]=Chyba procesu
+Name[sl]=Napaka procesa
+Name[sr]=Грешка у обради
+Name[sr@Latn]=Greška u obradi
+Name[sv]=Processfel
+Name[ta]=தொகுப்புப் பிழை
+Name[tg]=Хатогӣ
+Name[tr]=İşlemde hata var
+Name[uk]=Помилка процесу
+Name[uz]=Xatoli jarayon
+Name[uz@cyrillic]=Хатоли жараён
+Name[zh_CN]=处理错误
+Name[zh_TW]=處理發生錯誤
+Comment=Process finished with errors
+Comment[af]=Die proses het met foute klaar gemaak
+Comment[ar]= انتهت المعالجة على خطأ
+Comment[bg]=Процесът завърши с грешки
+Comment[bn]=প্রসেস ত্রুটিপূর্ণভাবে শেষ হল
+Comment[bs]=Proces je završen sa greškama
+Comment[ca]=Procés finalitzat amb errors
+Comment[cs]=Proces ukončen s chybami
+Comment[da]=Processen afsluttede med fejl
+Comment[de]=Vorgang wurde mit Fehlern beendet
+Comment[el]=Η διεργασία ολοκληρώθηκε με σφάλματα
+Comment[eo]=Tasko finis erare
+Comment[es]=Proceso terminado con errores
+Comment[et]=Tegevus lõppes vigadega
+Comment[fa]=فرآیند با خطاهایی تمام شد
+Comment[fi]=Työtä suoritettaessa tapahtui virheitä
+Comment[fr]=Processus terminé avec des erreurs
+Comment[gl]=O proceso terminou con erros
+Comment[he]=התהליך הסתיים עם שגיאות
+Comment[hi]=प्रक्रिया त्रुटि के साथ पूर्ण
+Comment[hu]=A művelet hibajelzéssel fejeződött be
+Comment[is]=Ferli lauk með villum
+Comment[it]=Processo terminato con errori
+Comment[ja]=プロセス未了 (エラー)
+Comment[ka]=პროცესი შეცდომებით დასრულდა
+Comment[km]=បាន​បញ្ចប់​ដំណើរការ​ដោយ​មាន​កំហុស
+Comment[lt]=Procesas baigtas su klaidomis
+Comment[mk]=Процесот заврши со грешки
+Comment[ms]= Proses selesai dengan ralat
+Comment[nb]=Prosessen ble fullført med feil
+Comment[nds]=Vörgang mit Fehlers afslaten
+Comment[ne]=प्रक्रिया त्रुटिसँग समाप्त भयो
+Comment[nl]=Proces voltooid met fouten
+Comment[nn]=Prosess vart fullført med feil
+Comment[pa]=ਕਾਰਵਾਈ ਗਲਤੀਆਂ ਨਾਲ ਪੂਰੀ
+Comment[pl]=Proces zakończył się z błędami
+Comment[pt]=O processo terminou com erros
+Comment[pt_BR]=Processo finalizado com erros
+Comment[ru]=Процесс завершён с ошибками
+Comment[sk]=Proces ukončený s chybami
+Comment[sl]=Proces je končal brez napak
+Comment[sr]=Обрада је завршена уз грешке
+Comment[sr@Latn]=Obrada je završena uz greške
+Comment[sv]=Processen avslutades med fel
+Comment[ta]=பிழையுள்ள தொகுப்பு முடிந்தது
+Comment[tg]=Амалиёт бо хатогӣ ба анҷом расид
+Comment[tr]=İşlem hatayla sonuçlandı
+Comment[uk]=Процес завершився з помилками
+Comment[uz]=Jarayon xatolar bilan tugadi
+Comment[uz@cyrillic]=Жараён хатолар билан тугади
+Comment[zh_CN]=处理完成,有错误
+Comment[zh_TW]=完成處理,但發生錯誤
+default_sound=k3b_error1.wav
+default_presentation=1
+
+[WaitingForMedium]
+Name=Waiting for medium
+Name[af]=Wag vir medium
+Name[ar]= في انتظار الواسطة
+Name[bg]=Изчакване за диск
+Name[bn]=মাধ্যমের জন্য অপেক্ষারত
+Name[br]=Emaon o c'hortoz evit ar vedium
+Name[bs]=Čekam medij
+Name[ca]=S'està esperant un suport
+Name[cs]=Čekám na médium
+Name[da]=Venter på mediet
+Name[de]=Warten auf Medium
+Name[el]=Αναμονή για μέσο
+Name[eo]=Atendante ujon
+Name[es]=Esperando medio
+Name[et]=Andmekandja ootamine
+Name[fa]=انتظار برای رسانه
+Name[fi]=Odotetaan levyä
+Name[fr]=En attente du média
+Name[gl]=Á espera do disco
+Name[he]=מצפה למדיה
+Name[hi]=साधन हेतु प्रतीक्षारत
+Name[hu]=Várakozás egy lemezre
+Name[is]=Býð eftir miðli
+Name[it]=Si è in attesa di un supporto
+Name[ja]=メディアを待っています
+Name[ka]=ველოდები მატარებელს
+Name[km]=កំពុងរង់ចាំ​មេឌៀ
+Name[lt]=Laukiama disko
+Name[mk]=Исчекување за носач
+Name[ms]= Menunggu media
+Name[nb]=Venter på medium
+Name[nds]=An't Töven op Medium
+Name[ne]=माध्यमका लागि प्रतिक्षा गर्दै
+Name[nl]=Wacht op medium
+Name[nn]=Ventar på medium
+Name[pa]=ਲਿਖਣ ਲਈ ਮੀਡਿਆ ਦੀ ਉਡੀਕ
+Name[pl]=Oczekiwanie na płytę
+Name[pt]=À espera do disco
+Name[pt_BR]=Aguardando pela mídia
+Name[ru]=Ожидание носителя
+Name[sk]=Čakám na médium
+Name[sl]=Čakanje na medij
+Name[sr]=Чекам на диск
+Name[sr@Latn]=Čekam na disk
+Name[sv]=Väntar på media
+Name[ta]=ஊடகத்திற்காக காத்திருக்கவும்
+Name[tg]=Интизори расона
+Name[tr]=Ortam bekleniyor
+Name[uk]=Очікування носія
+Name[uz]=Disk kutilmoqda
+Name[uz@cyrillic]=Диск кутилмоқда
+Name[zh_CN]=等待存储介质
+Name[zh_TW]=等待插入媒體
+Comment=The user needs to insert a medium
+Comment[af]=Die gebruiker moet 'n medium insit
+Comment[ar]= يجب على المستعمل ادخال الواسطة
+Comment[bg]=Потребителят трябва да постави диск в устройството
+Comment[bn]=ব্যবহারকারীর একটি মাধ্যম ভিতরে ঢোকানোর প্রয়োজন
+Comment[bs]=Korisnik mora ubaciti medij
+Comment[ca]=Cal que l'usuari insereixi un suport
+Comment[cs]=Uživatel musí vložit médium
+Comment[da]=Brugeren må indsætte et medie
+Comment[de]=Der Benutzer muss ein Medium einlegen
+Comment[el]=Ο χρήστης πρέπει να εισάγει ένα μέσο
+Comment[eo]=La uzanto devas enigi ujon
+Comment[es]=El usuario necesita insertar un medio
+Comment[et]=Kasutajal tuleb andmekandja sisse panna
+Comment[fa]=کاربر نیاز به درج یک رسانه دارد
+Comment[fi]=Odotetaan käyttäjän syöttävän levyn
+Comment[fr]=L'utilisateur doit insérer un média
+Comment[gl]=O usuário debe inserir un disco
+Comment[he]=המשתמש חייב להכניס מדיית צריבה
+Comment[hi]=उपयोगकर्ता को आवश्यक होगा कि साधन प्रविष्ट करे
+Comment[hu]=Be kell helyezni egy lemezt
+Comment[is]=Notandi verður að setja inn disk
+Comment[it]=L'utente deve inserire un supporto
+Comment[ja]=メディアを入れてください
+Comment[ka]=მომხმარებელს სჭირდება მატარებლის ჩადება
+Comment[km]=អ្នកប្រើ​ត្រូវ​តែ​បញ្ចូល​ឧបករណ៍​ផ្ទុក​មួយ
+Comment[lt]=Naudotojas turi įdėti diską
+Comment[mk]=Корисникот треба да внесе носач
+Comment[ms]=Pengguna perlu menyelitkan media
+Comment[nb]=Brukeren må sette inn et medium
+Comment[nds]=De Bruker mutt en Medium inleggen
+Comment[ne]=प्रयोगकर्तालाई माध्यम घुसाउँन आवश्यक पर्दछ
+Comment[nl]=De gebruiker dient een medium in te voeren
+Comment[nn]=Brukaren må setja inn eit medium
+Comment[pa]=ਉਪਭੋਗੀ ਨੂੰ ਇੱਕ ਮੀਡੀਅਮ ਪਾਉਣ ਦੀ ਲੋੜ ਹੈ
+Comment[pl]=Użytkownik musi włożyć płytę
+Comment[pt]=O utilizador tem que inserir um disco
+Comment[pt_BR]=O usuário precisa inserir uma mídia
+Comment[ru]=Необходимо вставить носитель
+Comment[sk]=Používateľ má vložiť médium
+Comment[sl]=Uporabnik mora vstaviti medij
+Comment[sr]=Корисник мора да убаци диск
+Comment[sr@Latn]=Korisnik mora da ubaci disk
+Comment[sv]=Användaren måste mata in media
+Comment[ta]=உபயோகிப்பவர் ஊடகத்தை சொருக வேண்டும்
+Comment[tg]=Истифодабаранда бояд расонаро барқарор кунад
+Comment[tr]=Kullanıcının bir ortam takması gerekiyor
+Comment[uk]=Користувач мусить вставити носій
+Comment[uz]=Foydalanuvchi diskni qoʻyishi kerak
+Comment[uz@cyrillic]=Фойдаланувчи дискни қўйиши керак
+Comment[zh_CN]=用户需要插入存储介质
+Comment[zh_TW]=使用者需要插入媒體
+default_sound=k3b_wait_media1.wav
+default_presentation=1
diff --git a/src/fastscale/Makefile.am b/src/fastscale/Makefile.am
new file mode 100644
index 0000000..2fafe00
--- /dev/null
+++ b/src/fastscale/Makefile.am
@@ -0,0 +1,14 @@
+AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. $(all_includes)
+AM_CCASFLAGS = -I$(srcdir) $(GV_ASM_DEFS)
+
+#CXXFLAGS = -fexceptions
+
+noinst_LTLIBRARIES = libfastscale.la
+
+libfastscale_la_SOURCES = \
+ scale.cpp \
+ asm_scale.S
+
+libfastscale_la_LIBADD = $(LIB_KDECORE) $(LIBQT) $(LIBJPEG)
+
+METASOURCES = AUTO
diff --git a/src/fastscale/README b/src/fastscale/README
new file mode 100644
index 0000000..13d4ccc
--- /dev/null
+++ b/src/fastscale/README
@@ -0,0 +1,2 @@
+This directory contains fast scaling algorithms from ImageMagick and Mosfet.
+They have been copied from the Gwenview source tree. \ No newline at end of file
diff --git a/src/fastscale/asm_scale.S b/src/fastscale/asm_scale.S
new file mode 100644
index 0000000..08b43da
--- /dev/null
+++ b/src/fastscale/asm_scale.S
@@ -0,0 +1,810 @@
+#ifdef HAVE_X86_MMX
+
+#ifdef __EMX__
+/* Due to strange behaviour of as.exe we use this macros */
+/* For all OS/2 coders - please use PGCC to compile this code */
+#define PR_(foo) ___##foo
+#define PT_(foo,func) ___##foo,func
+#define SIZE(sym) \
+ .___end_##sym:; \
+ .size ___##sym,.___end_##sym-___##sym; \
+ .align 8;
+#else
+#define PR_(foo) __##foo
+#define PT_(foo,func) __##foo,func
+#define SIZE(sym) \
+ .__end_##sym:; \
+ .size __##sym,.__end_##sym-__##sym; \
+ .align 8;
+#endif
+
+/*\
+|*| MMX assembly scaling routine for Imlib2
+|*| Written by Willem Monsuwe <willem@stack.nl>
+\*/
+
+.text
+ .align 8
+.globl PR_(mimageScale_mmx_AARGBA)
+/* .type PT_(mimageScale_mmx_AARGBA,@function) */
+
+
+/*\ Prototype: __mimageScale_mmx_AARGBA(ImlibScaleInfo *isi, DATA32 *dest,
+|*| int dxx, int dyy, int dx, int dy, int dw, int dh, int dow, int sow)
+\*/
+
+#define isi 8(%ebp)
+#define dest 12(%ebp)
+#define dxx 16(%ebp)
+#define dyy 20(%ebp)
+#define dx 24(%ebp)
+#define dy 28(%ebp)
+#define dw 32(%ebp)
+#define dh 36(%ebp)
+#define dow 40(%ebp)
+#define sow 44(%ebp)
+
+/*\ Local variables that didn't fit in registers \*/
+#define y -4(%ebp)
+#define yp -8(%ebp)
+#define yap -12(%ebp)
+#define xp -16(%ebp)
+#define xap -20(%ebp)
+#define Cx -24(%ebp)
+#define Mx -28(%ebp)
+#define Cy -32(%ebp)
+#define My -36(%ebp)
+#define sow_4 -40(%ebp)
+
+/*\ When %edx points to ImlibScaleInfo, these are the members \*/
+#define xpoints (%edx)
+#define ypoints 4(%edx)
+#define xapoints 8(%edx)
+#define yapoints 12(%edx)
+#define xup_yup 16(%edx)
+
+PR_(mimageScale_mmx_AARGBA):
+ pushl %ebp
+ movl %esp, %ebp
+ subl $40, %esp
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ pushl %edi
+ pushl %esi
+ movl isi, %edx
+
+ /*\ Check (dw > 0) && (dh > 0) \*/
+ cmpl $0, dw
+ jle .scale_leave
+ cmpl $0, dh
+ jle .scale_leave
+
+ /*\ X-based array pointers point to the end; we're looping up to 0 \*/
+ /*\ %edi = dest + dow * dy + dx + dw \*/
+ movl dow, %eax
+ imull dy, %eax
+ addl dx, %eax
+ addl dw, %eax
+ movl dest, %edi
+ leal (%edi, %eax, 4), %edi
+ /*\ xp = xpoints + dxx + dw \*/
+ movl dxx, %ebx
+ addl dw, %ebx
+ movl xpoints, %eax
+ leal (%eax, %ebx, 4), %eax
+ movl %eax, xp
+ /*\ xap = xapoints + dxx + dw \*/
+ movl xapoints, %eax
+ leal (%eax, %ebx, 4), %eax
+ movl %eax, xap
+ /*\ y = dh \*/
+ movl dh, %eax
+ movl %eax, y
+ /*\ yp = ypoints + dyy \*/
+ movl dyy, %ebx
+ movl ypoints, %eax
+ leal (%eax, %ebx, 4), %eax
+ movl %eax, yp
+ /*\ yap = yapoints + dyy \*/
+ movl yapoints, %eax
+ leal (%eax, %ebx, 4), %eax
+ movl %eax, yap
+
+ pxor %mm7, %mm7
+
+ /*\ Test xup bit \*/
+ movl xup_yup, %eax
+ sarl $1, %eax
+ jnc .scale_x_down
+
+.scale_x_up:
+ /*\ Test yup bit \*/
+ sarl $1, %eax
+ jnc .scale_x_up_y_down
+
+
+/*\ Scaling up both ways \*/
+
+.scale_x_up_y_up:
+ movl sow, %ebx
+
+.up_up_loop_y:
+
+ /*\ x = -dw \*/
+ movl dw, %ecx
+ negl %ecx
+
+ /*\ %eax = *yap << 4 \*/
+ movl yap, %eax
+ movl (%eax), %eax
+ sall $4, %eax
+ jz .up_up_yap_0
+ movd %eax, %mm1
+ punpcklwd %mm1, %mm1
+ punpckldq %mm1, %mm1
+
+.up_up_loop1_x:
+ /*\ %esi = *yp + xp[x] \*/
+ movl yp, %eax
+ movl (%eax), %esi
+ movl xp, %eax
+ movl (%eax, %ecx, 4), %eax
+ leal (%esi, %eax, 4), %esi
+
+ /*\ %eax = xap[x] << 4 \*/
+ movl xap, %eax
+ movl (%eax, %ecx, 4), %eax
+ sall $4, %eax
+ jz .up_up_xap_0
+
+ /*\ %mm0 = xap[x] << 4 \*/
+ movd %eax, %mm0
+ punpcklwd %mm0, %mm0
+ punpckldq %mm0, %mm0
+
+ /*\ Load and unpack four pixels in parralel
+ |*| %mm2 = ptr[0], %mm3 = ptr[1]
+ |*| %mm4 = ptr[sow], %mm5 = ptr[sow + 1]
+ \*/
+ movq (%esi), %mm2
+ movq (%esi, %ebx, 4), %mm4
+ movq %mm2, %mm3
+ movq %mm4, %mm5
+ punpcklbw %mm7, %mm2
+ punpcklbw %mm7, %mm4
+ punpckhbw %mm7, %mm3
+ punpckhbw %mm7, %mm5
+
+ /*\ X interpolation: r = l + (r - l) * xap \*/
+ psubw %mm2, %mm3
+ psubw %mm4, %mm5
+ psllw $4, %mm3
+ psllw $4, %mm5
+ pmulhw %mm0, %mm3
+ pmulhw %mm0, %mm5
+ paddw %mm2, %mm3
+ paddw %mm4, %mm5
+ /*\ Now %mm3 = I(ptr[0], ptr[1]), %mm5 = I(ptr[sow], ptr[sow + 1]) \*/
+ jmp .up_up_common
+.up_up_xap_0:
+ /*\ Load and unpack two pixels
+ |*| %mm3 = ptr[0], %mm5 = ptr[sow]
+ \*/
+ movd (%esi), %mm3
+ movd (%esi, %ebx, 4), %mm5
+ punpcklbw %mm7, %mm3
+ punpcklbw %mm7, %mm5
+.up_up_common:
+ /*\ Y interpolation: d = u + (d - u) * yap \*/
+ psubw %mm3, %mm5
+ psllw $4, %mm5
+ pmulhw %mm1, %mm5
+ paddw %mm3, %mm5
+ packuswb %mm5, %mm5
+ movd %mm5, (%edi, %ecx, 4)
+
+ /*\ while (++x) \*/
+ incl %ecx
+ jnz .up_up_loop1_x
+ jmp .up_up_yap_end
+.up_up_yap_0:
+
+.up_up_loop2_x:
+ /*\ %esi = *yp + xp[x] \*/
+ movl yp, %eax
+ movl (%eax), %esi
+ movl xp, %eax
+ movl (%eax, %ecx, 4), %eax
+ leal (%esi, %eax, 4), %esi
+
+ /*\ %eax = xap[x] << 4 \*/
+ movl xap, %eax
+ movl (%eax, %ecx, 4), %eax
+ sall $4, %eax
+ jz .up_up_0
+
+ /*\ %mm0 = xap[x] << 4 \*/
+ movd %eax, %mm0
+ punpcklwd %mm0, %mm0
+ punpckldq %mm0, %mm0
+
+ /*\ Load and unpack two pixels in parralel
+ |*| %mm2 = ptr[0], %mm3 = ptr[1]
+ \*/
+ movq (%esi), %mm2
+ movq %mm2, %mm3
+ punpcklbw %mm7, %mm2
+ punpckhbw %mm7, %mm3
+
+ /*\ X interpolation: r = l + (r - l) * xap \*/
+ psubw %mm2, %mm3
+ psllw $4, %mm3
+ pmulhw %mm0, %mm3
+ paddw %mm2, %mm3
+ packuswb %mm3, %mm3
+ movd %mm3, (%edi, %ecx, 4)
+ jmp .up_up_1
+.up_up_0:
+ /*\ dptr[x] = *sptr \*/
+ movl (%esi), %eax
+ movl %eax, (%edi, %ecx, 4)
+.up_up_1:
+ incl %ecx
+ jnz .up_up_loop2_x
+
+.up_up_yap_end:
+ /*\ dptr += dow \*/
+ movl dow, %eax
+ leal (%edi, %eax, 4), %edi
+ /*\ yap++; yp++ \*/
+ addl $4, yap
+ addl $4, yp
+ /*\ while (y--) \*/
+ decl y
+ jnz .up_up_loop_y
+
+ jmp .scale_leave
+
+
+/*\ Scaling down vertically \*/
+
+.scale_x_up_y_down:
+ /*\ sow_4 = sow * 4 \*/
+ movl sow, %eax
+ sall $2, %eax
+ movl %eax, sow_4
+
+.up_down_loop_y:
+
+ /*\ Setup My and Cy \*/
+ movl yap, %eax
+ movzwl (%eax), %ebx
+ movl %ebx, My
+ movzwl 2(%eax), %eax
+ movl %eax, Cy
+
+ /*\ mm4 = Cy \*/
+ movd %eax, %mm4
+ punpcklwd %mm4, %mm4
+ punpckldq %mm4, %mm4
+ /*\ mm5 = My \*/
+ movd %ebx, %mm5
+ punpcklwd %mm5, %mm5
+ punpckldq %mm5, %mm5
+
+ /*\ x = -dw \*/
+ movl dw, %ecx
+ negl %ecx
+.up_down_loop_x:
+ /*\ %esi = *yp + xp[x] \*/
+ movl yp, %eax
+ movl (%eax), %esi
+ movl xp, %eax
+ movl (%eax, %ecx, 4), %eax
+ leal (%esi, %eax, 4), %esi
+
+ movl %esi, %eax
+ /*\ v = (*p * My) >> 10 \*/
+ movd (%eax), %mm0
+ punpcklbw %mm7, %mm0
+ psllw $6, %mm0
+ pmulhw %mm5, %mm0
+
+ /*\ i = 0x4000 - My \*/
+ movl $0x4000, %ebx
+ subl My, %ebx
+ jbe 5f
+ jmp 2f
+1:
+ /*\ p += sow; v += (*p * Cy) >> 10 \*/
+ addl sow_4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $6, %mm1
+ pmulhw %mm4, %mm1
+ paddw %mm1, %mm0
+
+ /*\ i -= Cy; while (i > Cy) \*/
+ subl Cy, %ebx
+2:
+ cmpl Cy, %ebx
+ jg 1b
+
+ /*\ mm6 = i \*/
+ movd %ebx, %mm6
+ punpcklwd %mm6, %mm6
+ punpckldq %mm6, %mm6
+
+ /*\ p += sow; v += (*p * i) >> 10 \*/
+ addl sow_4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $6, %mm1
+ pmulhw %mm6, %mm1
+ paddw %mm1, %mm0
+5:
+ /*\ %eax = xap[x] << 5 \*/
+ movl xap, %eax
+ movl (%eax, %ecx, 4), %eax
+ sall $5, %eax
+ jz 6f
+ /*\ mm3 = xap[x] << 5 \*/
+ movd %eax, %mm3
+ punpcklwd %mm3, %mm3
+ punpckldq %mm3, %mm3
+
+ /*\ p + 1 \*/
+ movl %esi, %eax
+ addl $4, %eax
+ /*\ vv = (*p * My) >> 10 \*/
+ movd (%eax), %mm2
+ punpcklbw %mm7, %mm2
+ psllw $6, %mm2
+ pmulhw %mm5, %mm2
+
+ /*\ i = 0x4000 - My \*/
+ movl $0x4000, %ebx
+ subl My, %ebx
+ jbe 5f
+ jmp 2f
+1:
+ /*\ p += sow; vv += (*p * Cy) >> 10 \*/
+ addl sow_4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $6, %mm1
+ pmulhw %mm4, %mm1
+ paddw %mm1, %mm2
+
+ /*\ i -= Cy; while (i > Cy) \*/
+ subl Cy, %ebx
+2:
+ cmpl Cy, %ebx
+ jg 1b
+
+ /*\ p += sow; v += (*p * i) >> 10 \*/
+ addl sow_4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $6, %mm1
+ pmulhw %mm6, %mm1
+ paddw %mm1, %mm2
+5:
+ /*\ v = v + (vv - v) * xap \*/
+ psubw %mm0, %mm2
+ psllw $3, %mm2
+ pmulhw %mm3, %mm2
+ paddw %mm2, %mm0
+6:
+ /*\ dest[x] = v >> 4 \*/
+ psrlw $4, %mm0
+ packuswb %mm0, %mm0
+ movd %mm0, (%edi, %ecx, 4)
+
+ /*\ while (++x) \*/
+ incl %ecx
+ jnz .up_down_loop_x
+
+ /*\ dptr += dow \*/
+ movl dow, %eax
+ leal (%edi, %eax, 4), %edi
+ /*\ yap++; yp++ \*/
+ addl $4, yap
+ addl $4, yp
+ /*\ while (y--) \*/
+ decl y
+ jnz .up_down_loop_y
+
+ jmp .scale_leave
+
+.scale_x_down:
+ /*\ Test yup bit \*/
+ sarl $1, %eax
+ jnc .scale_x_down_y_down
+
+
+/*\ Scaling down horizontally \*/
+
+.scale_x_down_y_up:
+ /*\ sow_4 = sow * 4 \*/
+ movl sow, %eax
+ sall $2, %eax
+ movl %eax, sow_4
+
+.down_up_loop_y:
+
+ /*\ %eax = *yap << 5 \*/
+ movl yap, %eax
+ movl (%eax), %eax
+ sall $5, %eax
+ /*\ mm3 = *yap << 5 \*/
+ movd %eax, %mm3
+ punpcklwd %mm3, %mm3
+ punpckldq %mm3, %mm3
+
+ /*\ x = -dw \*/
+ movl dw, %ecx
+ negl %ecx
+.down_up_loop_x:
+ /*\ %esi = *yp + xp[x] \*/
+ movl yp, %eax
+ movl (%eax), %esi
+ movl xp, %eax
+ movl (%eax, %ecx, 4), %eax
+ leal (%esi, %eax, 4), %esi
+
+ /*\ Setup Mx and Cx \*/
+ movl xap, %eax
+ movzwl (%eax, %ecx, 4), %ebx
+ movl %ebx, Mx
+ movzwl 2(%eax, %ecx, 4), %eax
+ movl %eax, Cx
+
+ /*\ mm4 = Cx \*/
+ movd %eax, %mm4
+ punpcklwd %mm4, %mm4
+ punpckldq %mm4, %mm4
+ /*\ mm5 = Mx \*/
+ movd %ebx, %mm5
+ punpcklwd %mm5, %mm5
+ punpckldq %mm5, %mm5
+
+ movl %esi, %eax
+ /*\ v = (*p * Mx) >> 10 \*/
+ movd (%eax), %mm0
+ punpcklbw %mm7, %mm0
+ psllw $6, %mm0
+ pmulhw %mm5, %mm0
+
+ /*\ i = 0x4000 - Mx \*/
+ movl $0x4000, %ebx
+ subl Mx, %ebx
+ jbe 5f
+ jmp 2f
+1:
+ /*\ p += sow; v += (*p * Cx) >> 10 \*/
+ addl $4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $6, %mm1
+ pmulhw %mm4, %mm1
+ paddw %mm1, %mm0
+
+ /*\ i -= Cx; while (i > Cx) \*/
+ subl Cx, %ebx
+2:
+ cmpl Cx, %ebx
+ jg 1b
+
+ /*\ mm6 = i \*/
+ movd %ebx, %mm6
+ punpcklwd %mm6, %mm6
+ punpckldq %mm6, %mm6
+
+ /*\ p += sow; v += (*p * i) >> 10 \*/
+ addl $4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $6, %mm1
+ pmulhw %mm6, %mm1
+ paddw %mm1, %mm0
+5:
+ movd %mm3, %eax
+ testl %eax, %eax
+ jz 6f
+ /*\ p + sow \*/
+ movl %esi, %eax
+ addl sow_4, %eax
+ /*\ vv = (*p * Mx) >> 10 \*/
+ movd (%eax), %mm2
+ punpcklbw %mm7, %mm2
+ psllw $6, %mm2
+ pmulhw %mm5, %mm2
+
+ /*\ i = 0x4000 - Mx \*/
+ movl $0x4000, %ebx
+ subl Mx, %ebx
+ jbe 5f
+ jmp 2f
+1:
+ /*\ p += sow; vv += (*p * Cx) >> 10 \*/
+ addl $4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $6, %mm1
+ pmulhw %mm4, %mm1
+ paddw %mm1, %mm2
+
+ /*\ i -= Cx; while (i > Cx) \*/
+ subl Cx, %ebx
+2:
+ cmpl Cx, %ebx
+ jg 1b
+
+ /*\ p += sow; v += (*p * i) >> 10 \*/
+ addl $4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $6, %mm1
+ pmulhw %mm6, %mm1
+ paddw %mm1, %mm2
+5:
+ /*\ v = v + (vv - v) * yap \*/
+ psubw %mm0, %mm2
+ psllw $3, %mm2
+ pmulhw %mm3, %mm2
+ paddw %mm2, %mm0
+6:
+ /*\ dest[x] = v >> 4 \*/
+ psrlw $4, %mm0
+ packuswb %mm0, %mm0
+ movd %mm0, (%edi, %ecx, 4)
+
+ /*\ while (++x) \*/
+ incl %ecx
+ jnz .down_up_loop_x
+
+ /*\ dptr += dow \*/
+ movl dow, %eax
+ leal (%edi, %eax, 4), %edi
+ /*\ yap++; yp++ \*/
+ addl $4, yap
+ addl $4, yp
+ /*\ while (y--) \*/
+ decl y
+ jnz .down_up_loop_y
+
+ jmp .scale_leave
+
+
+/*\ Scaling down both ways \*/
+
+.scale_x_down_y_down:
+ /*\ sow_4 = sow * 4 \*/
+ movl sow, %eax
+ sall $2, %eax
+ movl %eax, sow_4
+
+.down_down_loop_y:
+
+ /*\ Setup My and Cy \*/
+ movl yap, %eax
+ movzwl (%eax), %ebx
+ movl %ebx, My
+ movzwl 2(%eax), %eax
+ movl %eax, Cy
+
+ /*\ x = -dw \*/
+ movl dw, %ecx
+ negl %ecx
+.down_down_loop_x:
+ /*\ %esi = *yp + xp[x] \*/
+ movl yp, %eax
+ movl (%eax), %esi
+ movl xp, %eax
+ movl (%eax, %ecx, 4), %eax
+ leal (%esi, %eax, 4), %esi
+
+ /*\ Setup Mx and Cx \*/
+ movl xap, %eax
+ movzwl (%eax, %ecx, 4), %ebx
+ movl %ebx, Mx
+ movzwl 2(%eax, %ecx, 4), %eax
+ movl %eax, Cx
+
+ /*\ mm3 = Cx \*/
+ movd %eax, %mm3
+ punpcklwd %mm3, %mm3
+ punpckldq %mm3, %mm3
+ /*\ mm5 = Mx \*/
+ movd %ebx, %mm5
+ punpcklwd %mm5, %mm5
+ punpckldq %mm5, %mm5
+
+ /*\ p = sptr; v = (*p * Mx) >> 9 \*/
+ movl %esi, %eax
+ movd (%eax), %mm0
+ punpcklbw %mm7, %mm0
+ psllw $7, %mm0
+ pmulhw %mm5, %mm0
+
+ /*\ i = 0x4000 - Mx \*/
+ movl $0x4000, %ebx
+ subl Mx, %ebx
+ jbe 5f
+ jmp 2f
+1:
+ /*\ v += (*++p * Cx) >> 9 \*/
+ addl $4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $7, %mm1
+ pmulhw %mm3, %mm1
+ paddw %mm1, %mm0
+
+ /*\ i -= Cx; while (i > Cx) \*/
+ subl Cx, %ebx
+2:
+ cmpl Cx, %ebx
+ jg 1b
+
+ /*\ mm6 = i \*/
+ movd %ebx, %mm6
+ punpcklwd %mm6, %mm6
+ punpckldq %mm6, %mm6
+
+ /*\ v += (*++p * i) >> 9 \*/
+ addl $4, %eax
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $7, %mm1
+ pmulhw %mm6, %mm1
+ paddw %mm1, %mm0
+5:
+ /*\ v *= My \*/
+ movd My, %mm4
+ punpcklwd %mm4, %mm4
+ punpckldq %mm4, %mm4
+ psllw $2, %mm0
+ pmulhw %mm4, %mm0
+
+ /*\ j = 0x4000 - My \*/
+ movl $0x4000, %edx
+ subl My, %edx
+ jbe 6f
+ jmp 4f
+3:
+ /*\ sptr += sow; p = sptr \*/
+ addl sow_4, %esi
+ movl %esi, %eax
+ /*\ vx = (*p * Mx) >> 9 \*/
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $7, %mm1
+ pmulhw %mm5, %mm1
+
+ /*\ i = 0x4000 - Mx \*/
+ movl $0x4000, %ebx
+ subl Mx, %ebx
+ jbe 5f
+ jmp 2f
+1:
+ /*\ vx += (*++p * Cx) >> 9 \*/
+ addl $4, %eax
+ movd (%eax), %mm2
+ punpcklbw %mm7, %mm2
+ psllw $7, %mm2
+ pmulhw %mm3, %mm2
+ paddw %mm2, %mm1
+
+ /*\ i -= Cx; while (i > Cx) \*/
+ subl Cx, %ebx
+2:
+ cmpl Cx, %ebx
+ jg 1b
+
+ /*\ vx += (*++p * i) >> 9 \*/
+ addl $4, %eax
+ movd (%eax), %mm2
+ punpcklbw %mm7, %mm2
+ psllw $7, %mm2
+ pmulhw %mm6, %mm2
+ paddw %mm2, %mm1
+5:
+ /*\ v += (vx * Cy) >> 14 \*/
+ movd Cy, %mm4
+ punpcklwd %mm4, %mm4
+ punpckldq %mm4, %mm4
+ psllw $2, %mm1
+ pmulhw %mm4, %mm1
+ paddw %mm1, %mm0
+
+ /*\ j -= Cy; while (j > Cy) \*/
+ subl Cy, %edx
+4:
+ cmpl Cy, %edx
+ jg 3b
+
+ /*\ sptr += sow; p = sptr \*/
+ addl sow_4, %esi
+ movl %esi, %eax
+ /*\ vx = (*p * Mx) >> 9 \*/
+ movd (%eax), %mm1
+ punpcklbw %mm7, %mm1
+ psllw $7, %mm1
+ pmulhw %mm5, %mm1
+
+ /*\ i = 0x4000 - Mx \*/
+ movl $0x4000, %ebx
+ subl Mx, %ebx
+ jbe 5f
+ jmp 2f
+1:
+ /*\ vx += (*++p * Cx) >> 9 \*/
+ addl $4, %eax
+ movd (%eax), %mm2
+ punpcklbw %mm7, %mm2
+ psllw $7, %mm2
+ pmulhw %mm3, %mm2
+ paddw %mm2, %mm1
+
+ /*\ i -= Cx; while (i > Cx) \*/
+ subl Cx, %ebx
+2:
+ cmpl Cx, %ebx
+ jg 1b
+
+ /*\ vx += (*++p * i) >> 9 \*/
+ addl $4, %eax
+ movd (%eax), %mm2
+ punpcklbw %mm7, %mm2
+ psllw $7, %mm2
+ pmulhw %mm6, %mm2
+ paddw %mm2, %mm1
+5:
+ /*\ v += (vx * j) >> 14 \*/
+ movd %edx, %mm4
+ punpcklwd %mm4, %mm4
+ punpckldq %mm4, %mm4
+ psllw $2, %mm1
+ pmulhw %mm4, %mm1
+ paddw %mm1, %mm0
+6:
+ /*\ dptr[x] = mm0 >> 5 \*/
+ psrlw $5, %mm0
+ packuswb %mm0, %mm0
+ movd %mm0, (%edi, %ecx, 4)
+
+ /*\ while (++x) \*/
+ incl %ecx
+ jnz .down_down_loop_x
+
+ /*\ dptr += dow \*/
+ movl dow, %eax
+ leal (%edi, %eax, 4), %edi
+ /*\ yap++; yp++ \*/
+ addl $4, yap
+ addl $4, yp
+ /*\ while (y--) \*/
+ decl y
+ jnz .down_down_loop_y
+
+ jmp .scale_leave
+
+.scale_leave:
+ emms
+ popl %esi
+ popl %edi
+ popl %edx
+ popl %ecx
+ popl %ebx
+ movl %ebp, %esp
+ popl %ebp
+ ret
+
+SIZE(mimageScale_mmx_AARGBA)
+
+#endif
+
+.section .note.GNU-stack,"",%progbits
diff --git a/src/fastscale/configure.in.in b/src/fastscale/configure.in.in
new file mode 100644
index 0000000..a1a5f28
--- /dev/null
+++ b/src/fastscale/configure.in.in
@@ -0,0 +1,63 @@
+#
+# Imlib/Mosfet scaling
+#
+AM_PROG_AS
+
+# MMX test duped from kdelibs/kdefx - it should be probably moved to admin/
+dnl -----------------------------------------------------
+dnl IA32 checks
+dnl -----------------------------------------------------
+
+gv_asm_defs=
+case $host_cpu in
+ i*86 )
+ AC_MSG_CHECKING(for assembler support for IA32 extensions)
+
+ dnl MMX check
+ AC_TRY_COMPILE(, [ __asm__("pxor %mm0, %mm0") ],
+ [
+ echo $ECHO_N "MMX yes$ECHO_C"
+ AC_DEFINE_UNQUOTED(HAVE_X86_MMX, 1, [Define to 1 if the assembler supports MMX instructions.])
+ gv_asm_defs="$gv_asm_defs -DHAVE_X86_MMX"
+ ], [ echo $ECHO_N "MMX no$ECHO_C" ])
+
+ dnl SSE check
+ AC_TRY_COMPILE(,[ __asm__("xorps %xmm0, %xmm0") ],
+ [
+ echo $ECHO_N ", SSE yes$ECHO_C"
+ AC_DEFINE_UNQUOTED(HAVE_X86_SSE, 1, [Define to 1 if the assembler supports SSE instructions.])
+ gv_asm_defs="$gv_asm_defs -DHAVE_X86_SSE"
+ ], [ echo $ECHO_N ", SSE no$ECHO_C" ])
+
+ dnl SSE2 check
+ AC_TRY_COMPILE(, [ __asm__("xorpd %xmm0, %xmm0") ],
+ [
+ echo $ECHO_N ", SSE2 yes$ECHO_C"
+ AC_DEFINE_UNQUOTED(HAVE_X86_SSE2, 1, [Define to 1 if the assembler supports SSE2 instructions.])
+ gv_asm_defs="$gv_asm_defs -DHAVE_X86_SSE2"
+ ], [ echo $ECHO_N ", SSE2 no$ECHO_C" ])
+
+ dnl 3DNOW check
+ AC_TRY_COMPILE(, [ __asm__("femms") ],
+ [
+ echo $ECHO_N ", 3DNOW yes$ECHO_C"
+ AC_DEFINE_UNQUOTED(HAVE_X86_3DNOW, 1, [Define to 1 if the assembler supports 3DNOW instructions.])
+ gv_asm_defs="$gv_asm_defs -DHAVE_X86_3DNOW"
+ ], [ echo $ECHO_N ", 3DNOW no$ECHO_C" ])
+ echo
+ ;;
+ powerpc )
+ AC_MSG_CHECKING(for assembler support for AltiVec instructions)
+ dnl AltiVec check
+ AC_TRY_COMPILE(, [ __asm__("mtspr 256, %0\n\t" "vand %%v0, %%v0, %%v0" : : "r"(-1) ) ],
+ [
+ echo $ECHO_N " yes$ECHO_C"
+ AC_DEFINE_UNQUOTED(HAVE_PPC_ALTIVEC, 1, [Define to 1 if the assembler supports AltiVec instructions.])
+ gv_asm_defs="$gv_asm_defs -DHAVE_PPC_ALTIVEC"
+ ], [ echo $ECHO_N ", AltiVec no$ECHO_C" ])
+ echo
+ ;;
+esac
+
+GV_ASM_DEFS="$gv_asm_defs"
+AC_SUBST(GV_ASM_DEFS)
diff --git a/src/fastscale/scale.cpp b/src/fastscale/scale.cpp
new file mode 100644
index 0000000..e2332fe
--- /dev/null
+++ b/src/fastscale/scale.cpp
@@ -0,0 +1,1975 @@
+// This file includes code for scaling images, in two versions.
+// One ported from ImageMagick (slower, but can achieve better quality),
+// and from Imlib2 ported by Mosfet (very fast).
+
+
+// ImageMagick code begin
+// ----------------------
+
+// This code is ImageMagick's resize code, adapted for QImage, with
+// fastfloat class added as an optimization.
+// The original license text follows.
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% RRRR EEEEE SSSSS IIIII ZZZZZ EEEEE %
+% R R E SS I ZZ E %
+% RRRR EEE SSS I ZZZ EEE %
+% R R E SS I ZZ E %
+% R R EEEEE SSSSS IIIII ZZZZZ EEEEE %
+% %
+% ImageMagick Image Resize Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% Copyright (C) 2003 ImageMagick Studio, a non-profit organization dedicated %
+% to making software imaging solutions freely available. %
+% %
+% Permission is hereby granted, free of charge, to any person obtaining a %
+% copy of this software and associated documentation files ("ImageMagick"), %
+% to deal in ImageMagick without restriction, including without limitation %
+% the rights to use, copy, modify, merge, publish, distribute, sublicense, %
+% and/or sell copies of ImageMagick, and to permit persons to whom the %
+% ImageMagick is furnished to do so, subject to the following conditions: %
+% %
+% The above copyright notice and this permission notice shall be included in %
+% all copies or substantial portions of ImageMagick. %
+% %
+% The software is provided "as is", without warranty of any kind, express or %
+% implied, including but not limited to the warranties of merchantability, %
+% fitness for a particular purpose and noninfringement. In no event shall %
+% ImageMagick Studio be liable for any claim, damages or other liability, %
+% whether in an action of contract, tort or otherwise, arising from, out of %
+% or in connection with ImageMagick or the use or other dealings in %
+% ImageMagick. %
+% %
+% Except as contained in this notice, the name of the ImageMagick Studio %
+% shall not be used in advertising or otherwise to promote the sale, use or %
+% other dealings in ImageMagick without prior written authorization from the %
+% ImageMagick Studio. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+#include "config.h"
+
+// System
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#else
+#ifdef HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif
+#endif
+
+// Qt
+#include <qimage.h>
+#include <qcolor.h>
+
+#include <kdeversion.h>
+#include <kcpuinfo.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+// Local
+#include "scale.h"
+
+// everything in namespace
+namespace ImageUtils {
+
+
+#define Max QMAX
+#define Min QMIN
+
+// mustn't be less than used precision (i.e. 1/fastfloat::RATIO)
+#define MagickEpsilon 0.0002
+
+// fastfloat begin
+// this class stores floating point numbers as integers, with BITS shift,
+// i.e. value XYZ is stored as XYZ * RATIO
+struct fastfloat
+ {
+ private:
+ enum { BITS = 12, RATIO = 4096 };
+ public:
+ fastfloat() {}
+ fastfloat( long v ) : value( v << BITS ) {}
+ fastfloat( int v ) : value( v << BITS ) {}
+ fastfloat( double v ) : value( static_cast< long >( v * RATIO + 0.5 )) {}
+ double toDouble() const { return static_cast< double >( value ) / RATIO; }
+ long toLong() const { return value >> BITS; }
+ fastfloat& operator += ( fastfloat r ) { value += r.value; return *this; }
+ fastfloat& operator -= ( fastfloat r ) { value -= r.value; return *this; }
+ fastfloat& operator *= ( fastfloat r ) { value = static_cast< long long >( value ) * r.value >> BITS; return *this; }
+ fastfloat& operator /= ( fastfloat r ) { value = ( static_cast< long long >( value ) << BITS ) / r.value; return *this; }
+ bool operator< ( fastfloat r ) const { return value < r.value; }
+ bool operator<= ( fastfloat r ) const { return value <= r.value; }
+ bool operator> ( fastfloat r ) const { return value > r.value; }
+ bool operator>= ( fastfloat r ) const { return value >= r.value; }
+ bool operator== ( fastfloat r ) const { return value == r.value; }
+ bool operator!= ( fastfloat r ) const { return value != r.value; }
+ fastfloat operator-() const { return fastfloat( -value, false ); }
+ private:
+ fastfloat( long v, bool ) : value( v ) {} // for operator-()
+ long value;
+ };
+
+inline fastfloat operator+ ( fastfloat l, fastfloat r ) { return fastfloat( l ) += r; }
+inline fastfloat operator- ( fastfloat l, fastfloat r ) { return fastfloat( l ) -= r; }
+inline fastfloat operator* ( fastfloat l, fastfloat r ) { return fastfloat( l ) *= r; }
+inline fastfloat operator/ ( fastfloat l, fastfloat r ) { return fastfloat( l ) /= r; }
+
+inline bool operator< ( fastfloat l, double r ) { return l < fastfloat( r ); }
+inline bool operator<= ( fastfloat l, double r ) { return l <= fastfloat( r ); }
+inline bool operator> ( fastfloat l, double r ) { return l > fastfloat( r ); }
+inline bool operator>= ( fastfloat l, double r ) { return l >= fastfloat( r ); }
+inline bool operator== ( fastfloat l, double r ) { return l == fastfloat( r ); }
+inline bool operator!= ( fastfloat l, double r ) { return l != fastfloat( r ); }
+
+inline bool operator< ( double l, fastfloat r ) { return fastfloat( l ) < r ; }
+inline bool operator<= ( double l, fastfloat r ) { return fastfloat( l ) <= r ; }
+inline bool operator> ( double l, fastfloat r ) { return fastfloat( l ) > r ; }
+inline bool operator>= ( double l, fastfloat r ) { return fastfloat( l ) >= r ; }
+inline bool operator== ( double l, fastfloat r ) { return fastfloat( l ) == r ; }
+inline bool operator!= ( double l, fastfloat r ) { return fastfloat( l ) != r ; }
+
+inline double fasttodouble( fastfloat v ) { return v.toDouble(); }
+inline long fasttolong( fastfloat v ) { return v.toLong(); }
+
+#if 1 // change to 0 to turn fastfloat usage off
+#else
+#define fastfloat double
+#define fasttodouble( v ) double( v )
+#define fasttolong( v ) long( v )
+#endif
+
+//fastfloat end
+
+
+typedef fastfloat (*Filter)(const fastfloat, const fastfloat);
+
+typedef struct _ContributionInfo
+{
+ fastfloat
+ weight;
+
+ long
+ pixel;
+} ContributionInfo;
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e s i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ResizeImage() scales an image to the desired dimensions with one of these
+% filters:
+%
+% Bessel Blackman Box
+% Catrom Cubic Gaussian
+% Hanning Hermite Lanczos
+% Mitchell Point Quandratic
+% Sinc Triangle
+%
+% Most of the filters are FIR (finite impulse response), however, Bessel,
+% Gaussian, and Sinc are IIR (infinite impulse response). Bessel and Sinc
+% are windowed (brought down to zero) with the Blackman filter.
+%
+% ResizeImage() was inspired by Paul Heckbert's zoom program.
+%
+% The format of the ResizeImage method is:
+%
+% Image *ResizeImage(Image *image,const unsigned long columns,
+% const unsigned long rows,const FilterTypes filter,const double blur,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o columns: The number of columns in the scaled image.
+%
+% o rows: The number of rows in the scaled image.
+%
+% o filter: Image filter to use.
+%
+% o blur: The blur factor where > 1 is blurry, < 1 is sharp.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+#if 0
+static fastfloat Bessel(const fastfloat x,const fastfloat)
+{
+ if (x == 0.0)
+ return(MagickPI/4.0);
+ return(BesselOrderOne(MagickPI*x)/(2.0*x));
+}
+
+static fastfloat Sinc(const fastfloat x,const fastfloat)
+{
+ if (x == 0.0)
+ return(1.0);
+ return(sin(MagickPI*x)/(MagickPI*x));
+}
+
+static fastfloat Blackman(const fastfloat x,const fastfloat)
+{
+ return(0.42+0.5*cos(MagickPI*x)+0.08*cos(2*MagickPI*x));
+}
+
+static fastfloat BlackmanBessel(const fastfloat x,const fastfloat)
+{
+ return(Blackman(x/support,support)*Bessel(x,support));
+}
+
+static fastfloat BlackmanSinc(const fastfloat x,const fastfloat)
+{
+ return(Blackman(x/support,support)*Sinc(x,support));
+}
+#endif
+
+static fastfloat Box(const fastfloat x,const fastfloat)
+{
+ if (x < -0.5)
+ return(0.0);
+ if (x < 0.5)
+ return(1.0);
+ return(0.0);
+}
+
+#if 0
+static fastfloat Catrom(const fastfloat x,const fastfloat)
+{
+ if (x < -2.0)
+ return(0.0);
+ if (x < -1.0)
+ return(0.5*(4.0+x*(8.0+x*(5.0+x))));
+ if (x < 0.0)
+ return(0.5*(2.0+x*x*(-5.0-3.0*x)));
+ if (x < 1.0)
+ return(0.5*(2.0+x*x*(-5.0+3.0*x)));
+ if (x < 2.0)
+ return(0.5*(4.0+x*(-8.0+x*(5.0-x))));
+ return(0.0);
+}
+
+static fastfloat Cubic(const fastfloat x,const fastfloat)
+{
+ if (x < -2.0)
+ return(0.0);
+ if (x < -1.0)
+ return((2.0+x)*(2.0+x)*(2.0+x)/6.0);
+ if (x < 0.0)
+ return((4.0+x*x*(-6.0-3.0*x))/6.0);
+ if (x < 1.0)
+ return((4.0+x*x*(-6.0+3.0*x))/6.0);
+ if (x < 2.0)
+ return((2.0-x)*(2.0-x)*(2.0-x)/6.0);
+ return(0.0);
+}
+
+static fastfloat Gaussian(const fastfloat x,const fastfloat)
+{
+ return(exp(-2.0*x*x)*sqrt(2.0/MagickPI));
+}
+
+static fastfloat Hanning(const fastfloat x,const fastfloat)
+{
+ return(0.5+0.5*cos(MagickPI*x));
+}
+
+static fastfloat Hamming(const fastfloat x,const fastfloat)
+{
+ return(0.54+0.46*cos(MagickPI*x));
+}
+
+static fastfloat Hermite(const fastfloat x,const fastfloat)
+{
+ if (x < -1.0)
+ return(0.0);
+ if (x < 0.0)
+ return((2.0*(-x)-3.0)*(-x)*(-x)+1.0);
+ if (x < 1.0)
+ return((2.0*x-3.0)*x*x+1.0);
+ return(0.0);
+}
+
+static fastfloat Lanczos(const fastfloat x,const fastfloat support)
+{
+ if (x < -3.0)
+ return(0.0);
+ if (x < 0.0)
+ return(Sinc(-x,support)*Sinc(-x/3.0,support));
+ if (x < 3.0)
+ return(Sinc(x,support)*Sinc(x/3.0,support));
+ return(0.0);
+}
+
+static fastfloat Mitchell(const fastfloat x,const fastfloat)
+{
+#define B (1.0/3.0)
+#define C (1.0/3.0)
+#define P0 (( 6.0- 2.0*B )/6.0)
+#define P2 ((-18.0+12.0*B+ 6.0*C)/6.0)
+#define P3 (( 12.0- 9.0*B- 6.0*C)/6.0)
+#define Q0 (( 8.0*B+24.0*C)/6.0)
+#define Q1 (( -12.0*B-48.0*C)/6.0)
+#define Q2 (( 6.0*B+30.0*C)/6.0)
+#define Q3 (( - 1.0*B- 6.0*C)/6.0)
+
+ if (x < -2.0)
+ return(0.0);
+ if (x < -1.0)
+ return(Q0-x*(Q1-x*(Q2-x*Q3)));
+ if (x < 0.0)
+ return(P0+x*x*(P2-x*P3));
+ if (x < 1.0)
+ return(P0+x*x*(P2+x*P3));
+ if (x < 2.0)
+ return(Q0+x*(Q1+x*(Q2+x*Q3)));
+ return(0.0);
+
+#undef B
+#undef C
+#undef P0
+#undef P2
+#undef P3
+#undef Q0
+#undef Q1
+#undef Q2
+#undef Q3
+}
+#endif
+
+// this is the same like Mitchell, but it has different values
+// for B and C, resulting in sharper images
+// http://sourceforge.net/mailarchive/forum.php?thread_id=7445822&forum_id=1210
+static fastfloat Bicubic(const fastfloat x,const fastfloat)
+{
+#define B (0.0/3.0)
+#define C (2.0/3.0)
+#define P0 (( 6.0- 2.0*B )/6.0)
+#define P2 ((-18.0+12.0*B+ 6.0*C)/6.0)
+#define P3 (( 12.0- 9.0*B- 6.0*C)/6.0)
+#define Q0 (( 8.0*B+24.0*C)/6.0)
+#define Q1 (( -12.0*B-48.0*C)/6.0)
+#define Q2 (( 6.0*B+30.0*C)/6.0)
+#define Q3 (( - 1.0*B- 6.0*C)/6.0)
+
+ if (x < -2.0)
+ return(0.0);
+ if (x < -1.0)
+ return(Q0-x*(Q1-x*(Q2-x*Q3)));
+ if (x < 0.0)
+ return(P0+x*x*(P2-x*P3));
+ if (x < 1.0)
+ return(P0+x*x*(P2+x*P3));
+ if (x < 2.0)
+ return(Q0+x*(Q1+x*(Q2+x*Q3)));
+ return(0.0);
+
+#undef B
+#undef C
+#undef P0
+#undef P2
+#undef P3
+#undef Q0
+#undef Q1
+#undef Q2
+#undef Q3
+}
+
+#if 0
+static fastfloat Quadratic(const fastfloat x,const fastfloat)
+{
+ if (x < -1.5)
+ return(0.0);
+ if (x < -0.5)
+ return(0.5*(x+1.5)*(x+1.5));
+ if (x < 0.5)
+ return(0.75-x*x);
+ if (x < 1.5)
+ return(0.5*(x-1.5)*(x-1.5));
+ return(0.0);
+}
+#endif
+
+static fastfloat Triangle(const fastfloat x,const fastfloat)
+{
+ if (x < -1.0)
+ return(0.0);
+ if (x < 0.0)
+ return(1.0+x);
+ if (x < 1.0)
+ return(1.0-x);
+ return(0.0);
+}
+
+static void HorizontalFilter(const QImage& source,QImage& destination,
+ const fastfloat x_factor,const fastfloat blur,
+ ContributionInfo *contribution, Filter filter, fastfloat filtersupport)
+{
+ fastfloat
+ center,
+ density,
+ scale,
+ support;
+
+ long
+ n,
+ start,
+ stop,
+ y;
+
+ register long
+ i,
+ x;
+
+ /*
+ Apply filter to resize horizontally from source to destination.
+ */
+ scale=blur*Max(1.0/x_factor,1.0);
+ support=scale* filtersupport;
+ if (support <= 0.5)
+ {
+ /*
+ Reduce to point sampling.
+ */
+ support=0.5+MagickEpsilon;
+ scale=1.0;
+ }
+ scale=1.0/scale;
+ for (x=0; x < (long) destination.width(); x++)
+ {
+ center=(fastfloat) (x+0.5)/x_factor;
+ start= fasttolong(Max(center-support+0.5,0));
+ stop= fasttolong(Min(center+support+0.5,source.width()));
+ density=0.0;
+ for (n=0; n < (stop-start); n++)
+ {
+ contribution[n].pixel=start+n;
+ contribution[n].weight=
+ filter (scale*(start+n-center+0.5), filtersupport );
+ density+=contribution[n].weight;
+ }
+ if ((density != 0.0) && (density != 1.0))
+ {
+ /*
+ Normalize.
+ */
+ density=1.0/density;
+ for (i=0; i < n; i++)
+ contribution[i].weight*=density;
+ }
+// p=AcquireImagePixels(source,contribution[0].pixel,0,contribution[n-1].pixel-
+// contribution[0].pixel+1,source->rows,exception);
+// q=SetImagePixels(destination,x,0,1,destination->rows);
+ for (y=0; y < (long) destination.height(); y++)
+ {
+ fastfloat red = 0;
+ fastfloat green = 0;
+ fastfloat blue = 0;
+ fastfloat alpha = 0;
+ for (i=0; i < n; i++)
+ {
+ int px = contribution[i].pixel;
+ int py = y;
+ QRgb p = reinterpret_cast< QRgb* >( source.jumpTable()[ py ])[ px ];
+ red+=contribution[i].weight*qRed(p);
+ green+=contribution[i].weight*qGreen(p);
+ blue+=contribution[i].weight*qBlue(p);
+ alpha+=contribution[i].weight*qAlpha(p);
+ }
+ QRgb pix = qRgba(
+ fasttolong( red < 0 ? 0 : red > 255 ? 255 : red + 0.5 ),
+ fasttolong( green < 0 ? 0 : green > 255 ? 255 : green + 0.5 ),
+ fasttolong( blue < 0 ? 0 : blue > 255 ? 255 : blue + 0.5 ),
+ fasttolong( alpha < 0 ? 0 : alpha > 255 ? 255 : alpha + 0.5 ));
+ reinterpret_cast< QRgb* >( destination.jumpTable()[ y ])[ x ] = pix;
+ }
+ }
+}
+
+static void VerticalFilter(const QImage& source,QImage& destination,
+ const fastfloat y_factor,const fastfloat blur,
+ ContributionInfo *contribution, Filter filter, fastfloat filtersupport )
+{
+ fastfloat
+ center,
+ density,
+ scale,
+ support;
+
+ long
+ n,
+ start,
+ stop,
+ x;
+
+ register long
+ i,
+ y;
+
+ /*
+ Apply filter to resize vertically from source to destination.
+ */
+ scale=blur*Max(1.0/y_factor,1.0);
+ support=scale* filtersupport;
+ if (support <= 0.5)
+ {
+ /*
+ Reduce to point sampling.
+ */
+ support=0.5+MagickEpsilon;
+ scale=1.0;
+ }
+ scale=1.0/scale;
+ for (y=0; y < (long) destination.height(); y++)
+ {
+ center=(fastfloat) (y+0.5)/y_factor;
+ start= fasttolong(Max(center-support+0.5,0));
+ stop= fasttolong(Min(center+support+0.5,source.height()));
+ density=0.0;
+ for (n=0; n < (stop-start); n++)
+ {
+ contribution[n].pixel=start+n;
+ contribution[n].weight=
+ filter (scale*(start+n-center+0.5), filtersupport);
+ density+=contribution[n].weight;
+ }
+ if ((density != 0.0) && (density != 1.0))
+ {
+ /*
+ Normalize.
+ */
+ density=1.0/density;
+ for (i=0; i < n; i++)
+ contribution[i].weight*=density;
+ }
+// p=AcquireImagePixels(source,0,contribution[0].pixel,source->columns,
+// contribution[n-1].pixel-contribution[0].pixel+1,exception);
+// q=SetImagePixels(destination,0,y,destination->columns,1);
+ for (x=0; x < (long) destination.width(); x++)
+ {
+ fastfloat red = 0;
+ fastfloat green = 0;
+ fastfloat blue = 0;
+ fastfloat alpha = 0;
+ for (i=0; i < n; i++)
+ {
+ int px = x;
+ int py = contribution[i].pixel;
+ QRgb p = reinterpret_cast< QRgb* >( source.jumpTable()[ py ])[ px ];
+ red+=contribution[i].weight*qRed(p);
+ green+=contribution[i].weight*qGreen(p);
+ blue+=contribution[i].weight*qBlue(p);
+ alpha+=contribution[i].weight*qAlpha(p);
+ }
+ QRgb pix = qRgba(
+ fasttolong( red < 0 ? 0 : red > 255 ? 255 : red + 0.5 ),
+ fasttolong( green < 0 ? 0 : green > 255 ? 255 : green + 0.5 ),
+ fasttolong( blue < 0 ? 0 : blue > 255 ? 255 : blue + 0.5 ),
+ fasttolong( alpha < 0 ? 0 : alpha > 255 ? 255 : alpha + 0.5 ));
+ reinterpret_cast< QRgb* >( destination.jumpTable()[ y ])[ x ] = pix;
+ }
+ }
+}
+
+static QImage ResizeImage(const QImage& image,const int columns,
+ const int rows, Filter filter, fastfloat filtersupport, double blur)
+{
+ ContributionInfo
+ *contribution;
+
+ fastfloat
+ support,
+ x_factor,
+ x_support,
+ y_factor,
+ y_support;
+
+ /*
+ Initialize resize image attributes.
+ */
+ if ((columns == image.width()) && (rows == image.height()) && (blur == 1.0))
+ return image.copy();
+ QImage resize_image( columns, rows, 32 );
+ resize_image.setAlphaBuffer( image.hasAlphaBuffer());
+ /*
+ Allocate filter contribution info.
+ */
+ x_factor=(fastfloat) resize_image.width()/image.width();
+ y_factor=(fastfloat) resize_image.height()/image.height();
+// i=(long) LanczosFilter;
+// if (image->filter != UndefinedFilter)
+// i=(long) image->filter;
+// else
+// if ((image->storage_class == PseudoClass) || image->matte ||
+// ((x_factor*y_factor) > 1.0))
+// i=(long) MitchellFilter;
+ x_support=blur*Max(1.0/x_factor,1.0)*filtersupport;
+ y_support=blur*Max(1.0/y_factor,1.0)*filtersupport;
+ support=Max(x_support,y_support);
+ if (support < filtersupport)
+ support=filtersupport;
+ contribution=new ContributionInfo[ fasttolong( 2.0*Max(support,0.5)+3 ) ];
+ Q_CHECK_PTR( contribution );
+ /*
+ Resize image.
+ */
+ if (((fastfloat) columns*(image.height()+rows)) >
+ ((fastfloat) rows*(image.width()+columns)))
+ {
+ QImage source_image( columns, image.height(), 32 );
+ source_image.setAlphaBuffer( image.hasAlphaBuffer());
+ HorizontalFilter(image,source_image,x_factor,blur,
+ contribution,filter,filtersupport);
+ VerticalFilter(source_image,resize_image,y_factor,
+ blur,contribution,filter,filtersupport);
+ }
+ else
+ {
+ QImage source_image( image.width(), rows, 32 );
+ source_image.setAlphaBuffer( image.hasAlphaBuffer());
+ VerticalFilter(image,source_image,y_factor,blur,
+ contribution,filter,filtersupport);
+ HorizontalFilter(source_image,resize_image,x_factor,
+ blur,contribution,filter,filtersupport);
+ }
+ /*
+ Free allocated memory.
+ */
+ delete[] contribution;
+ return(resize_image);
+}
+
+
+#undef Max
+#undef Min
+#undef MagickEpsilon
+
+
+// filters and their matching support values
+#if 0
+ static const FilterInfo
+ filters[SincFilter+1] =
+ {
+ { Box, 0.0 },
+ { Box, 0.0 },
+ { Box, 0.5 },
+ { Triangle, 1.0 },
+ { Hermite, 1.0 },
+ { Hanning, 1.0 },
+ { Hamming, 1.0 },
+ { Blackman, 1.0 },
+ { Gaussian, 1.25 },
+ { Quadratic, 1.5 },
+ { Cubic, 2.0 },
+ { Catrom, 2.0 },
+ { Mitchell, 2.0 },
+ { Lanczos, 3.0 },
+ { BlackmanBessel, 3.2383 },
+ { BlackmanSinc, 4.0 }
+ };
+#endif
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S a m p l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SampleImage() scales an image to the desired dimensions with pixel
+% sampling. Unlike other scaling methods, this method does not introduce
+% any additional color into the scaled image.
+%
+% The format of the SampleImage method is:
+%
+% Image *SampleImage(const Image *image,const unsigned long columns,
+% const unsigned long rows,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o columns: The number of columns in the sampled image.
+%
+% o rows: The number of rows in the sampled image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+QImage SampleImage(const QImage& image,const int columns,
+ const int rows)
+{
+ int
+ *x_offset,
+ *y_offset;
+
+ long
+ j,
+ y;
+
+ uchar
+ *pixels;
+
+ register const uchar
+ *p;
+
+ register long
+ x;
+
+ register uchar
+ *q;
+
+ /*
+ Initialize sampled image attributes.
+ */
+ if ((columns == image.width()) && (rows == image.height()))
+ return image;
+ // This function is modified to handle any image depth, not only
+ // 32bit like the ImageMagick original. This avoids the relatively
+ // expensive conversion.
+ const int d = image.depth() / 8;
+ QImage sample_image( columns, rows, image.depth());
+ sample_image.setAlphaBuffer( image.hasAlphaBuffer());
+ /*
+ Allocate scan line buffer and column offset buffers.
+ */
+ pixels= new uchar[ image.width() * d ];
+ x_offset= new int[ sample_image.width() ];
+ y_offset= new int[ sample_image.height() ];
+ /*
+ Initialize pixel offsets.
+ */
+// In the following several code 0.5 needs to be added, otherwise the image
+// would be moved by half a pixel to bottom-right, just like
+// with Qt's QImage::scale()
+ for (x=0; x < (long) sample_image.width(); x++)
+ {
+ x_offset[x]=int((x+0.5)*image.width()/sample_image.width());
+ }
+ for (y=0; y < (long) sample_image.height(); y++)
+ {
+ y_offset[y]=int((y+0.5)*image.height()/sample_image.height());
+ }
+ /*
+ Sample each row.
+ */
+ j=(-1);
+ for (y=0; y < (long) sample_image.height(); y++)
+ {
+ q= sample_image.scanLine( y );
+ if (j != y_offset[y] )
+ {
+ /*
+ Read a scan line.
+ */
+ j= y_offset[y];
+ p= image.scanLine( j );
+ (void) memcpy(pixels,p,image.width()*d);
+ }
+ /*
+ Sample each column.
+ */
+ switch( d )
+ {
+ case 1: // 8bit
+ for (x=0; x < (long) sample_image.width(); x++)
+ {
+ *q++=pixels[ x_offset[x] ];
+ }
+ break;
+ case 4: // 32bit
+ for (x=0; x < (long) sample_image.width(); x++)
+ {
+ *(QRgb*)q=((QRgb*)pixels)[ x_offset[x] ];
+ q += d;
+ }
+ break;
+ default:
+ for (x=0; x < (long) sample_image.width(); x++)
+ {
+ memcpy( q, pixels + x_offset[x] * d, d );
+ q += d;
+ }
+ break;
+ }
+ }
+ if( d != 4 ) // != 32bit
+ {
+ sample_image.setNumColors( image.numColors());
+ for( int i = 0; i < image.numColors(); ++i )
+ sample_image.setColor( i, image.color( i ));
+ }
+ delete[] y_offset;
+ delete[] x_offset;
+ delete[] pixels;
+ return sample_image;
+}
+
+
+// ImageMagick code end
+
+
+// Imlib2/Mosfet code begin
+// ------------------------
+
+// This code is Imlib2 code, additionally modified by Mosfet, and with few small
+// modifications for Gwenview. The MMX scaling code also belongs to it.
+
+// The original license texts follow.
+
+/**
+ * This is the normal smoothscale method, based on Imlib2's smoothscale.
+ *
+ * Originally I took the algorithm used in NetPBM and Qt and added MMX/3dnow
+ * optimizations. It ran in about 1/2 the time as Qt. Then I ported Imlib's
+ * C algorithm and it ran at about the same speed as my MMX optimized one...
+ * Finally I ported Imlib's MMX version and it ran in less than half the
+ * time as my MMX algorithm, (taking only a quarter of the time Qt does).
+ *
+ * Changes include formatting, namespaces and other C++'ings, removal of old
+ * #ifdef'ed code, and removal of unneeded border calculation code.
+ *
+ * Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code
+ * is by Willem Monsuwe <willem@stack.nl>. All other modifications are
+ * (C) Daniel M. Duley.
+ */
+
+/*
+ Copyright (C) 2004 Daniel M. Duley <dan.duley@verizon.net>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+/*
+Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies of the Software and its Copyright notices. In addition publicly
+documented acknowledgment must be given that this software has been used if no
+source code of this software is made available publicly. This includes
+acknowledgments in either Copyright notices, Manuals, Publicity and Marketing
+documents or any documentation provided with any product containing this
+software. This License does not apply to any software that links to the
+libraries provided by this software (statically or dynamically), but only to
+the software provided.
+
+Please see the COPYING.PLAIN for a plain-english explanation of this notice
+and it's intent.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+namespace MImageScale{
+ typedef struct __mimage_scale_info
+ {
+ int *xpoints;
+ unsigned int **ypoints;
+ int *xapoints, *yapoints;
+ int xup_yup;
+ } MImageScaleInfo;
+
+ unsigned int** mimageCalcYPoints(unsigned int *src, int sow, int sh,
+ int dh);
+ int* mimageCalcXPoints(int sw, int dw);
+ int* mimageCalcApoints(int s, int d, int up);
+ MImageScaleInfo* mimageFreeScaleInfo(MImageScaleInfo *isi);
+ MImageScaleInfo *mimageCalcScaleInfo(QImage &img, int sw, int sh,
+ int dw, int dh, char aa, int sow);
+ void mimageSampleRGBA(MImageScaleInfo *isi, unsigned int *dest, int dxx,
+ int dyy, int dx, int dy, int dw, int dh, int dow);
+ void mimageScaleAARGBA(MImageScaleInfo *isi, unsigned int *dest, int dxx,
+ int dyy, int dx, int dy, int dw, int dh, int dow,
+ int sow);
+ void mimageScaleAARGB(MImageScaleInfo *isi, unsigned int *dest, int dxx,
+ int dyy, int dx, int dy, int dw, int dh, int dow, int
+ sow);
+ QImage smoothScale(const QImage& img, int dw, int dh);
+}
+
+#ifdef HAVE_X86_MMX
+extern "C" {
+ void __mimageScale_mmx_AARGBA(MImageScale::MImageScaleInfo *isi,
+ unsigned int *dest, int dxx, int dyy,
+ int dx, int dy, int dw, int dh,
+ int dow, int sow);
+}
+#endif
+
+using namespace MImageScale;
+
+QImage MImageScale::smoothScale(const QImage& image, int dw, int dh)
+{
+ QImage img = image.depth() < 32 ? image.convertDepth( 32 ) : image;
+ int w = img.width();
+ int h = img.height();
+
+ int sow = img.bytesPerLine();
+ // handle CroppedQImage
+ if( img.height() > 1 && sow != img.scanLine( 1 ) - img.scanLine( 0 ))
+ sow = img.scanLine( 1 ) - img.scanLine( 0 );
+ sow = sow / ( img.depth() / 8 );
+
+ MImageScaleInfo *scaleinfo =
+ mimageCalcScaleInfo(img, w, h, dw, dh, true, sow);
+ if(!scaleinfo)
+ return QImage();
+
+ QImage buffer(dw, dh, 32);
+ buffer.setAlphaBuffer(img.hasAlphaBuffer());
+
+#ifdef HAVE_X86_MMX
+//#warning Using MMX Smoothscale
+ bool haveMMX = KCPUInfo::haveExtension( KCPUInfo::IntelMMX );
+ if(haveMMX){
+ __mimageScale_mmx_AARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0),
+ 0, 0, 0, 0, dw, dh, dw, sow);
+ }
+ else
+#endif
+ {
+ if(img.hasAlphaBuffer())
+ mimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), 0, 0,
+ 0, 0, dw, dh, dw, sow);
+ else
+ mimageScaleAARGB(scaleinfo, (unsigned int *)buffer.scanLine(0), 0, 0,
+ 0, 0, dw, dh, dw, sow);
+ }
+ mimageFreeScaleInfo(scaleinfo);
+ return(buffer);
+}
+
+//
+// Code ported from Imlib...
+//
+
+// FIXME: replace with mRed, etc... These work on pointers to pixels, not
+// pixel values
+#if BYTE_ORDER == BIG_ENDIAN
+#define A_VAL(p) ((unsigned char *)(p))[0]
+#define R_VAL(p) ((unsigned char *)(p))[1]
+#define G_VAL(p) ((unsigned char *)(p))[2]
+#define B_VAL(p) ((unsigned char *)(p))[3]
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define A_VAL(p) ((unsigned char *)(p))[3]
+#define R_VAL(p) ((unsigned char *)(p))[2]
+#define G_VAL(p) ((unsigned char *)(p))[1]
+#define B_VAL(p) ((unsigned char *)(p))[0]
+#else
+#error "BYTE_ORDER is not defined"
+#endif
+
+#define INV_XAP (256 - xapoints[x])
+#define XAP (xapoints[x])
+#define INV_YAP (256 - yapoints[dyy + y])
+#define YAP (yapoints[dyy + y])
+
+unsigned int** MImageScale::mimageCalcYPoints(unsigned int *src,
+ int sow, int sh, int dh)
+{
+ unsigned int **p;
+ int i, j = 0;
+ int val, inc, rv = 0;
+
+ if(dh < 0){
+ dh = -dh;
+ rv = 1;
+ }
+ p = new unsigned int* [dh+1];
+
+ val = 0;
+ inc = (sh << 16) / dh;
+ for(i = 0; i < dh; i++){
+ p[j++] = src + ((val >> 16) * sow);
+ val += inc;
+ }
+ if(rv){
+ for(i = dh / 2; --i >= 0; ){
+ unsigned int *tmp = p[i];
+ p[i] = p[dh - i - 1];
+ p[dh - i - 1] = tmp;
+ }
+ }
+ return(p);
+}
+
+int* MImageScale::mimageCalcXPoints(int sw, int dw)
+{
+ int *p, i, j = 0;
+ int val, inc, rv = 0;
+
+ if(dw < 0){
+ dw = -dw;
+ rv = 1;
+ }
+ p = new int[dw+1];
+
+ val = 0;
+ inc = (sw << 16) / dw;
+ for(i = 0; i < dw; i++){
+ p[j++] = (val >> 16);
+ val += inc;
+ }
+
+ if(rv){
+ for(i = dw / 2; --i >= 0; ){
+ int tmp = p[i];
+ p[i] = p[dw - i - 1];
+ p[dw - i - 1] = tmp;
+ }
+ }
+ return(p);
+}
+
+int* MImageScale::mimageCalcApoints(int s, int d, int up)
+{
+ int *p, i, j = 0, rv = 0;
+
+ if(d < 0){
+ rv = 1;
+ d = -d;
+ }
+ p = new int[d];
+
+ /* scaling up */
+ if(up){
+ int val, inc;
+
+ val = 0;
+ inc = (s << 16) / d;
+ for(i = 0; i < d; i++){
+ p[j++] = (val >> 8) - ((val >> 8) & 0xffffff00);
+ if((val >> 16) >= (s - 1))
+ p[j - 1] = 0;
+ val += inc;
+ }
+ }
+ /* scaling down */
+ else{
+ int val, inc, ap, Cp;
+ val = 0;
+ inc = (s << 16) / d;
+ Cp = ((d << 14) / s) + 1;
+ for(i = 0; i < d; i++){
+ ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8;
+ p[j] = ap | (Cp << 16);
+ j++;
+ val += inc;
+ }
+ }
+ if(rv){
+ int tmp;
+ for(i = d / 2; --i >= 0; ){
+ tmp = p[i];
+ p[i] = p[d - i - 1];
+ p[d - i - 1] = tmp;
+ }
+ }
+ return(p);
+}
+
+MImageScaleInfo* MImageScale::mimageFreeScaleInfo(MImageScaleInfo *isi)
+{
+ if(isi){
+ delete[] isi->xpoints;
+ delete[] isi->ypoints;
+ delete[] isi->xapoints;
+ delete[] isi->yapoints;
+ delete isi;
+ }
+ return(NULL);
+}
+
+MImageScaleInfo* MImageScale::mimageCalcScaleInfo(QImage &img, int sw, int sh,
+ int dw, int dh, char aa, int sow)
+{
+ MImageScaleInfo *isi;
+ int scw, sch;
+
+ scw = dw * img.width() / sw;
+ sch = dh * img.height() / sh;
+
+ isi = new MImageScaleInfo;
+ if(!isi)
+ return(NULL);
+ memset(isi, 0, sizeof(MImageScaleInfo));
+
+ isi->xup_yup = (abs(dw) >= sw) + ((abs(dh) >= sh) << 1);
+
+ isi->xpoints = mimageCalcXPoints(img.width(), scw);
+ if(!isi->xpoints)
+ return(mimageFreeScaleInfo(isi));
+ isi->ypoints = mimageCalcYPoints((unsigned int *)img.scanLine(0),
+ sow, img.height(), sch );
+ if (!isi->ypoints)
+ return(mimageFreeScaleInfo(isi));
+ if(aa){
+ isi->xapoints = mimageCalcApoints(img.width(), scw, isi->xup_yup & 1);
+ if(!isi->xapoints)
+ return(mimageFreeScaleInfo(isi));
+ isi->yapoints = mimageCalcApoints(img.height(), sch, isi->xup_yup & 2);
+ if(!isi->yapoints)
+ return(mimageFreeScaleInfo(isi));
+ }
+ return(isi);
+}
+
+/* scale by pixel sampling only */
+void MImageScale::mimageSampleRGBA(MImageScaleInfo *isi, unsigned int *dest,
+ int dxx, int dyy, int dx, int dy, int dw,
+ int dh, int dow)
+{
+ unsigned int *sptr, *dptr;
+ int x, y, end;
+ unsigned int **ypoints = isi->ypoints;
+ int *xpoints = isi->xpoints;
+
+ /* whats the last pixel ont he line so we stop there */
+ end = dxx + dw;
+ /* go through every scanline in the output buffer */
+ for(y = 0; y < dh; y++){
+ /* get the pointer to the start of the destination scanline */
+ dptr = dest + dx + ((y + dy) * dow);
+ /* calculate the source line we'll scan from */
+ sptr = ypoints[dyy + y];
+ /* go thru the scanline and copy across */
+ for(x = dxx; x < end; x++)
+ *dptr++ = sptr[xpoints[x]];
+ }
+}
+
+/* FIXME: NEED to optimise ScaleAARGBA - currently its "ok" but needs work*/
+
+/* scale by area sampling */
+void MImageScale::mimageScaleAARGBA(MImageScaleInfo *isi, unsigned int *dest,
+ int dxx, int dyy, int dx, int dy, int dw,
+ int dh, int dow, int sow)
+{
+ unsigned int *sptr, *dptr;
+ int x, y, end;
+ unsigned int **ypoints = isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ end = dxx + dw;
+ /* scaling up both ways */
+ if(isi->xup_yup == 3){
+ /* go through every scanline in the output buffer */
+ for(y = 0; y < dh; y++){
+ /* calculate the source line we'll scan from */
+ dptr = dest + dx + ((y + dy) * dow);
+ sptr = ypoints[dyy + y];
+ if(YAP > 0){
+ for(x = dxx; x < end; x++){
+ int r, g, b, a;
+ int rr, gg, bb, aa;
+ unsigned int *pix;
+
+ if(XAP > 0){
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = R_VAL(pix) * INV_XAP;
+ g = G_VAL(pix) * INV_XAP;
+ b = B_VAL(pix) * INV_XAP;
+ a = A_VAL(pix) * INV_XAP;
+ pix++;
+ r += R_VAL(pix) * XAP;
+ g += G_VAL(pix) * XAP;
+ b += B_VAL(pix) * XAP;
+ a += A_VAL(pix) * XAP;
+ pix += sow;
+ rr = R_VAL(pix) * XAP;
+ gg = G_VAL(pix) * XAP;
+ bb = B_VAL(pix) * XAP;
+ aa = A_VAL(pix) * XAP;
+ pix--;
+ rr += R_VAL(pix) * INV_XAP;
+ gg += G_VAL(pix) * INV_XAP;
+ bb += B_VAL(pix) * INV_XAP;
+ aa += A_VAL(pix) * INV_XAP;
+ r = ((rr * YAP) + (r * INV_YAP)) >> 16;
+ g = ((gg * YAP) + (g * INV_YAP)) >> 16;
+ b = ((bb * YAP) + (b * INV_YAP)) >> 16;
+ a = ((aa * YAP) + (a * INV_YAP)) >> 16;
+ *dptr++ = qRgba(r, g, b, a);
+ }
+ else{
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = R_VAL(pix) * INV_YAP;
+ g = G_VAL(pix) * INV_YAP;
+ b = B_VAL(pix) * INV_YAP;
+ a = A_VAL(pix) * INV_YAP;
+ pix += sow;
+ r += R_VAL(pix) * YAP;
+ g += G_VAL(pix) * YAP;
+ b += B_VAL(pix) * YAP;
+ a += A_VAL(pix) * YAP;
+ r >>= 8;
+ g >>= 8;
+ b >>= 8;
+ a >>= 8;
+ *dptr++ = qRgba(r, g, b, a);
+ }
+ }
+ }
+ else{
+ for(x = dxx; x < end; x++){
+ int r, g, b, a;
+ unsigned int *pix;
+
+ if(XAP > 0){
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = R_VAL(pix) * INV_XAP;
+ g = G_VAL(pix) * INV_XAP;
+ b = B_VAL(pix) * INV_XAP;
+ a = A_VAL(pix) * INV_XAP;
+ pix++;
+ r += R_VAL(pix) * XAP;
+ g += G_VAL(pix) * XAP;
+ b += B_VAL(pix) * XAP;
+ a += A_VAL(pix) * XAP;
+ r >>= 8;
+ g >>= 8;
+ b >>= 8;
+ a >>= 8;
+ *dptr++ = qRgba(r, g, b, a);
+ }
+ else
+ *dptr++ = sptr[xpoints[x] ];
+ }
+ }
+ }
+ }
+ /* if we're scaling down vertically */
+ else if(isi->xup_yup == 1){
+ /*\ 'Correct' version, with math units prepared for MMXification \*/
+ int Cy, j;
+ unsigned int *pix;
+ int r, g, b, a, rr, gg, bb, aa;
+ int yap;
+
+ /* go through every scanline in the output buffer */
+ for(y = 0; y < dh; y++){
+ Cy = YAP >> 16;
+ yap = YAP & 0xffff;
+
+ dptr = dest + dx + ((y + dy) * dow);
+ for(x = dxx; x < end; x++){
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = (R_VAL(pix) * yap) >> 10;
+ g = (G_VAL(pix) * yap) >> 10;
+ b = (B_VAL(pix) * yap) >> 10;
+ a = (A_VAL(pix) * yap) >> 10;
+ for(j = (1 << 14) - yap; j > Cy; j -= Cy){
+ pix += sow;
+ r += (R_VAL(pix) * Cy) >> 10;
+ g += (G_VAL(pix) * Cy) >> 10;
+ b += (B_VAL(pix) * Cy) >> 10;
+ a += (A_VAL(pix) * Cy) >> 10;
+ }
+ if(j > 0){
+ pix += sow;
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ a += (A_VAL(pix) * j) >> 10;
+ }
+ if(XAP > 0){
+ pix = ypoints[dyy + y] + xpoints[x] + 1;
+ rr = (R_VAL(pix) * yap) >> 10;
+ gg = (G_VAL(pix) * yap) >> 10;
+ bb = (B_VAL(pix) * yap) >> 10;
+ aa = (A_VAL(pix) * yap) >> 10;
+ for(j = (1 << 14) - yap; j > Cy; j -= Cy){
+ pix += sow;
+ rr += (R_VAL(pix) * Cy) >> 10;
+ gg += (G_VAL(pix) * Cy) >> 10;
+ bb += (B_VAL(pix) * Cy) >> 10;
+ aa += (A_VAL(pix) * Cy) >> 10;
+ }
+ if(j > 0){
+ pix += sow;
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ aa += (A_VAL(pix) * j) >> 10;
+ }
+ r = r * INV_XAP;
+ g = g * INV_XAP;
+ b = b * INV_XAP;
+ a = a * INV_XAP;
+ r = (r + ((rr * XAP))) >> 12;
+ g = (g + ((gg * XAP))) >> 12;
+ b = (b + ((bb * XAP))) >> 12;
+ a = (a + ((aa * XAP))) >> 12;
+ }
+ else{
+ r >>= 4;
+ g >>= 4;
+ b >>= 4;
+ a >>= 4;
+ }
+ *dptr = qRgba(r, g, b, a);
+ dptr++;
+ }
+ }
+ }
+ /* if we're scaling down horizontally */
+ else if(isi->xup_yup == 2){
+ /*\ 'Correct' version, with math units prepared for MMXification \*/
+ int Cx, j;
+ unsigned int *pix;
+ int r, g, b, a, rr, gg, bb, aa;
+ int xap;
+
+ /* go through every scanline in the output buffer */
+ for(y = 0; y < dh; y++){
+ dptr = dest + dx + ((y + dy) * dow);
+ for(x = dxx; x < end; x++){
+ Cx = XAP >> 16;
+ xap = XAP & 0xffff;
+
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = (R_VAL(pix) * xap) >> 10;
+ g = (G_VAL(pix) * xap) >> 10;
+ b = (B_VAL(pix) * xap) >> 10;
+ a = (A_VAL(pix) * xap) >> 10;
+ for(j = (1 << 14) - xap; j > Cx; j -= Cx){
+ pix++;
+ r += (R_VAL(pix) * Cx) >> 10;
+ g += (G_VAL(pix) * Cx) >> 10;
+ b += (B_VAL(pix) * Cx) >> 10;
+ a += (A_VAL(pix) * Cx) >> 10;
+ }
+ if(j > 0){
+ pix++;
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ a += (A_VAL(pix) * j) >> 10;
+ }
+ if(YAP > 0){
+ pix = ypoints[dyy + y] + xpoints[x] + sow;
+ rr = (R_VAL(pix) * xap) >> 10;
+ gg = (G_VAL(pix) * xap) >> 10;
+ bb = (B_VAL(pix) * xap) >> 10;
+ aa = (A_VAL(pix) * xap) >> 10;
+ for(j = (1 << 14) - xap; j > Cx; j -= Cx){
+ pix++;
+ rr += (R_VAL(pix) * Cx) >> 10;
+ gg += (G_VAL(pix) * Cx) >> 10;
+ bb += (B_VAL(pix) * Cx) >> 10;
+ aa += (A_VAL(pix) * Cx) >> 10;
+ }
+ if(j > 0){
+ pix++;
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ aa += (A_VAL(pix) * j) >> 10;
+ }
+ r = r * INV_YAP;
+ g = g * INV_YAP;
+ b = b * INV_YAP;
+ a = a * INV_YAP;
+ r = (r + ((rr * YAP))) >> 12;
+ g = (g + ((gg * YAP))) >> 12;
+ b = (b + ((bb * YAP))) >> 12;
+ a = (a + ((aa * YAP))) >> 12;
+ }
+ else{
+ r >>= 4;
+ g >>= 4;
+ b >>= 4;
+ a >>= 4;
+ }
+ *dptr = qRgba(r, g, b, a);
+ dptr++;
+ }
+ }
+ }
+ /* if we're scaling down horizontally & vertically */
+ else{
+ /*\ 'Correct' version, with math units prepared for MMXification:
+ |*| The operation 'b = (b * c) >> 16' translates to pmulhw,
+ |*| so the operation 'b = (b * c) >> d' would translate to
+ |*| psllw (16 - d), %mmb; pmulh %mmc, %mmb
+ \*/
+ int Cx, Cy, i, j;
+ unsigned int *pix;
+ int a, r, g, b, ax, rx, gx, bx;
+ int xap, yap;
+
+ for(y = 0; y < dh; y++){
+ Cy = YAP >> 16;
+ yap = YAP & 0xffff;
+
+ dptr = dest + dx + ((y + dy) * dow);
+ for(x = dxx; x < end; x++){
+ Cx = XAP >> 16;
+ xap = XAP & 0xffff;
+
+ sptr = ypoints[dyy + y] + xpoints[x];
+ pix = sptr;
+ sptr += sow;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ ax = (A_VAL(pix) * xap) >> 9;
+ pix++;
+ for(i = (1 << 14) - xap; i > Cx; i -= Cx){
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ ax += (A_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if(i > 0){
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ ax += (A_VAL(pix) * i) >> 9;
+ }
+
+ r = (rx * yap) >> 14;
+ g = (gx * yap) >> 14;
+ b = (bx * yap) >> 14;
+ a = (ax * yap) >> 14;
+
+ for(j = (1 << 14) - yap; j > Cy; j -= Cy){
+ pix = sptr;
+ sptr += sow;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ ax = (A_VAL(pix) * xap) >> 9;
+ pix++;
+ for(i = (1 << 14) - xap; i > Cx; i -= Cx){
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ ax += (A_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if(i > 0){
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ ax += (A_VAL(pix) * i) >> 9;
+ }
+
+ r += (rx * Cy) >> 14;
+ g += (gx * Cy) >> 14;
+ b += (bx * Cy) >> 14;
+ a += (ax * Cy) >> 14;
+ }
+ if(j > 0){
+ pix = sptr;
+ sptr += sow;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ ax = (A_VAL(pix) * xap) >> 9;
+ pix++;
+ for(i = (1 << 14) - xap; i > Cx; i -= Cx){
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ ax += (A_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if(i > 0){
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ ax += (A_VAL(pix) * i) >> 9;
+ }
+
+ r += (rx * j) >> 14;
+ g += (gx * j) >> 14;
+ b += (bx * j) >> 14;
+ a += (ax * j) >> 14;
+ }
+
+ R_VAL(dptr) = r >> 5;
+ G_VAL(dptr) = g >> 5;
+ B_VAL(dptr) = b >> 5;
+ A_VAL(dptr) = a >> 5;
+ dptr++;
+ }
+ }
+ }
+}
+
+/* scale by area sampling - IGNORE the ALPHA byte*/
+void MImageScale::mimageScaleAARGB(MImageScaleInfo *isi, unsigned int *dest,
+ int dxx, int dyy, int dx, int dy, int dw,
+ int dh, int dow, int sow)
+{
+ unsigned int *sptr, *dptr;
+ int x, y, end;
+ unsigned int **ypoints = isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ end = dxx + dw;
+ /* scaling up both ways */
+ if(isi->xup_yup == 3){
+ /* go through every scanline in the output buffer */
+ for(y = 0; y < dh; y++){
+ /* calculate the source line we'll scan from */
+ dptr = dest + dx + ((y + dy) * dow);
+ sptr = ypoints[dyy + y];
+ if(YAP > 0){
+ for(x = dxx; x < end; x++){
+ int r = 0, g = 0, b = 0;
+ int rr = 0, gg = 0, bb = 0;
+ unsigned int *pix;
+
+ if(XAP > 0){
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = R_VAL(pix) * INV_XAP;
+ g = G_VAL(pix) * INV_XAP;
+ b = B_VAL(pix) * INV_XAP;
+ pix++;
+ r += R_VAL(pix) * XAP;
+ g += G_VAL(pix) * XAP;
+ b += B_VAL(pix) * XAP;
+ pix += sow;
+ rr = R_VAL(pix) * XAP;
+ gg = G_VAL(pix) * XAP;
+ bb = B_VAL(pix) * XAP;
+ pix --;
+ rr += R_VAL(pix) * INV_XAP;
+ gg += G_VAL(pix) * INV_XAP;
+ bb += B_VAL(pix) * INV_XAP;
+ r = ((rr * YAP) + (r * INV_YAP)) >> 16;
+ g = ((gg * YAP) + (g * INV_YAP)) >> 16;
+ b = ((bb * YAP) + (b * INV_YAP)) >> 16;
+ *dptr++ = qRgba(r, g, b, 0xff);
+ }
+ else{
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = R_VAL(pix) * INV_YAP;
+ g = G_VAL(pix) * INV_YAP;
+ b = B_VAL(pix) * INV_YAP;
+ pix += sow;
+ r += R_VAL(pix) * YAP;
+ g += G_VAL(pix) * YAP;
+ b += B_VAL(pix) * YAP;
+ r >>= 8;
+ g >>= 8;
+ b >>= 8;
+ *dptr++ = qRgba(r, g, b, 0xff);
+ }
+ }
+ }
+ else{
+ for(x = dxx; x < end; x++){
+ int r = 0, g = 0, b = 0;
+ unsigned int *pix;
+
+ if(XAP > 0){
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = R_VAL(pix) * INV_XAP;
+ g = G_VAL(pix) * INV_XAP;
+ b = B_VAL(pix) * INV_XAP;
+ pix++;
+ r += R_VAL(pix) * XAP;
+ g += G_VAL(pix) * XAP;
+ b += B_VAL(pix) * XAP;
+ r >>= 8;
+ g >>= 8;
+ b >>= 8;
+ *dptr++ = qRgba(r, g, b, 0xff);
+ }
+ else
+ *dptr++ = sptr[xpoints[x] ];
+ }
+ }
+ }
+ }
+ /* if we're scaling down vertically */
+ else if(isi->xup_yup == 1){
+ /*\ 'Correct' version, with math units prepared for MMXification \*/
+ int Cy, j;
+ unsigned int *pix;
+ int r, g, b, rr, gg, bb;
+ int yap;
+
+ /* go through every scanline in the output buffer */
+ for(y = 0; y < dh; y++){
+ Cy = YAP >> 16;
+ yap = YAP & 0xffff;
+
+ dptr = dest + dx + ((y + dy) * dow);
+ for(x = dxx; x < end; x++){
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = (R_VAL(pix) * yap) >> 10;
+ g = (G_VAL(pix) * yap) >> 10;
+ b = (B_VAL(pix) * yap) >> 10;
+ pix += sow;
+ for(j = (1 << 14) - yap; j > Cy; j -= Cy){
+ r += (R_VAL(pix) * Cy) >> 10;
+ g += (G_VAL(pix) * Cy) >> 10;
+ b += (B_VAL(pix) * Cy) >> 10;
+ pix += sow;
+ }
+ if(j > 0){
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ }
+ if(XAP > 0){
+ pix = ypoints[dyy + y] + xpoints[x] + 1;
+ rr = (R_VAL(pix) * yap) >> 10;
+ gg = (G_VAL(pix) * yap) >> 10;
+ bb = (B_VAL(pix) * yap) >> 10;
+ pix += sow;
+ for(j = (1 << 14) - yap; j > Cy; j -= Cy){
+ rr += (R_VAL(pix) * Cy) >> 10;
+ gg += (G_VAL(pix) * Cy) >> 10;
+ bb += (B_VAL(pix) * Cy) >> 10;
+ pix += sow;
+ }
+ if(j > 0){
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ }
+ r = r * INV_XAP;
+ g = g * INV_XAP;
+ b = b * INV_XAP;
+ r = (r + ((rr * XAP))) >> 12;
+ g = (g + ((gg * XAP))) >> 12;
+ b = (b + ((bb * XAP))) >> 12;
+ }
+ else{
+ r >>= 4;
+ g >>= 4;
+ b >>= 4;
+ }
+ *dptr = qRgba(r, g, b, 0xff);
+ dptr++;
+ }
+ }
+ }
+ /* if we're scaling down horizontally */
+ else if(isi->xup_yup == 2){
+ /*\ 'Correct' version, with math units prepared for MMXification \*/
+ int Cx, j;
+ unsigned int *pix;
+ int r, g, b, rr, gg, bb;
+ int xap;
+
+ /* go through every scanline in the output buffer */
+ for(y = 0; y < dh; y++){
+ dptr = dest + dx + ((y + dy) * dow);
+ for(x = dxx; x < end; x++){
+ Cx = XAP >> 16;
+ xap = XAP & 0xffff;
+
+ pix = ypoints[dyy + y] + xpoints[x];
+ r = (R_VAL(pix) * xap) >> 10;
+ g = (G_VAL(pix) * xap) >> 10;
+ b = (B_VAL(pix) * xap) >> 10;
+ pix++;
+ for(j = (1 << 14) - xap; j > Cx; j -= Cx){
+ r += (R_VAL(pix) * Cx) >> 10;
+ g += (G_VAL(pix) * Cx) >> 10;
+ b += (B_VAL(pix) * Cx) >> 10;
+ pix++;
+ }
+ if(j > 0){
+ r += (R_VAL(pix) * j) >> 10;
+ g += (G_VAL(pix) * j) >> 10;
+ b += (B_VAL(pix) * j) >> 10;
+ }
+ if(YAP > 0){
+ pix = ypoints[dyy + y] + xpoints[x] + sow;
+ rr = (R_VAL(pix) * xap) >> 10;
+ gg = (G_VAL(pix) * xap) >> 10;
+ bb = (B_VAL(pix) * xap) >> 10;
+ pix++;
+ for(j = (1 << 14) - xap; j > Cx; j -= Cx){
+ rr += (R_VAL(pix) * Cx) >> 10;
+ gg += (G_VAL(pix) * Cx) >> 10;
+ bb += (B_VAL(pix) * Cx) >> 10;
+ pix++;
+ }
+ if(j > 0){
+ rr += (R_VAL(pix) * j) >> 10;
+ gg += (G_VAL(pix) * j) >> 10;
+ bb += (B_VAL(pix) * j) >> 10;
+ }
+ r = r * INV_YAP;
+ g = g * INV_YAP;
+ b = b * INV_YAP;
+ r = (r + ((rr * YAP))) >> 12;
+ g = (g + ((gg * YAP))) >> 12;
+ b = (b + ((bb * YAP))) >> 12;
+ }
+ else{
+ r >>= 4;
+ g >>= 4;
+ b >>= 4;
+ }
+ *dptr = qRgba(r, g, b, 0xff);
+ dptr++;
+ }
+ }
+ }
+ /* fully optimized (i think) - onyl change of algorithm can help */
+ /* if we're scaling down horizontally & vertically */
+ else{
+ /*\ 'Correct' version, with math units prepared for MMXification \*/
+ int Cx, Cy, i, j;
+ unsigned int *pix;
+ int r, g, b, rx, gx, bx;
+ int xap, yap;
+
+ for(y = 0; y < dh; y++){
+ Cy = YAP >> 16;
+ yap = YAP & 0xffff;
+
+ dptr = dest + dx + ((y + dy) * dow);
+ for(x = dxx; x < end; x++){
+ Cx = XAP >> 16;
+ xap = XAP & 0xffff;
+
+ sptr = ypoints[dyy + y] + xpoints[x];
+ pix = sptr;
+ sptr += sow;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for(i = (1 << 14) - xap; i > Cx; i -= Cx){
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if(i > 0){
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ r = (rx * yap) >> 14;
+ g = (gx * yap) >> 14;
+ b = (bx * yap) >> 14;
+
+ for(j = (1 << 14) - yap; j > Cy; j -= Cy){
+ pix = sptr;
+ sptr += sow;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for(i = (1 << 14) - xap; i > Cx; i -= Cx){
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if(i > 0){
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ r += (rx * Cy) >> 14;
+ g += (gx * Cy) >> 14;
+ b += (bx * Cy) >> 14;
+ }
+ if(j > 0){
+ pix = sptr;
+ sptr += sow;
+ rx = (R_VAL(pix) * xap) >> 9;
+ gx = (G_VAL(pix) * xap) >> 9;
+ bx = (B_VAL(pix) * xap) >> 9;
+ pix++;
+ for(i = (1 << 14) - xap; i > Cx; i -= Cx){
+ rx += (R_VAL(pix) * Cx) >> 9;
+ gx += (G_VAL(pix) * Cx) >> 9;
+ bx += (B_VAL(pix) * Cx) >> 9;
+ pix++;
+ }
+ if(i > 0){
+ rx += (R_VAL(pix) * i) >> 9;
+ gx += (G_VAL(pix) * i) >> 9;
+ bx += (B_VAL(pix) * i) >> 9;
+ }
+
+ r += (rx * j) >> 14;
+ g += (gx * j) >> 14;
+ b += (bx * j) >> 14;
+ }
+
+ R_VAL(dptr) = r >> 5;
+ G_VAL(dptr) = g >> 5;
+ B_VAL(dptr) = b >> 5;
+ dptr++;
+ }
+ }
+ }
+}
+
+// Imlib2/Mosfet code end
+
+
+// public functions :
+// ------------------
+
+// This function returns how many pixels around the zoomed area should be
+// included in the image. This is used when doing incremental painting, because
+// some smoothing algorithms use surrounding pixels and not including them
+// could sometimes make the edges between incremental steps visible.
+// int extraScalePixels( SmoothAlgorithm alg, double zoom, double blur )
+// {
+// double filtersupport = 0;
+// Filter filter = NULL;
+// switch( alg ) {
+// case SMOOTH_NONE:
+// filter = NULL;
+// filtersupport = 0.0;
+// break;
+// case SMOOTH_FAST:
+// filter = Box;
+// filtersupport = 0.5;
+// break;
+// case SMOOTH_NORMAL:
+// filter = Triangle;
+// filtersupport = 1.0;
+// break;
+// case SMOOTH_BEST:
+// // filter = Mitchell;
+// filter = Bicubic;
+// filtersupport = 2.0;
+// break;
+// }
+// if( zoom == 1.0 || filtersupport == 0.0 ) return 0;
+// // Imlib2/Mosfet scale - I have really no idea how many pixels it needs
+// if( filter == Box && blur == 1.0 ) return int( 3 / zoom + 1 );
+// // This is support size for ImageMagick's scaling.
+// double scale=blur*QMAX(1.0/zoom,1.0);
+// double support=scale* filtersupport;
+// if (support <= 0.5) support=0.5+0.000001;
+// return int( support + 1 );
+// }
+
+QImage scale(const QImage& image, int width, int height,
+ SmoothAlgorithm alg, QImage::ScaleMode mode, double blur )
+{
+ if( image.isNull()) return image.copy();
+
+ QSize newSize( image.size() );
+ newSize.scale( QSize( width, height ), (QSize::ScaleMode)mode ); // ### remove cast in Qt 4.0
+ newSize = newSize.expandedTo( QSize( 1, 1 )); // make sure it doesn't become null
+
+ if ( newSize == image.size() ) return image.copy();
+
+ width = newSize.width();
+ height = newSize.height();
+ Filter filter = NULL;
+ fastfloat filtersupport;
+
+ switch( alg ) {
+ case SMOOTH_NONE:
+ filter = NULL;
+ filtersupport = 0.0;
+ break;
+ case SMOOTH_FAST:
+ filter = Box;
+ filtersupport = 0.5;
+ break;
+ case SMOOTH_NORMAL:
+ default:
+ filter = Triangle;
+ filtersupport = 1.0;
+ break;
+ case SMOOTH_BEST:
+// filter = Mitchell;
+ filter = Bicubic;
+ filtersupport = 2.0;
+ break;
+ }
+
+ if( filter == Box && blur == 1.0 )
+ return MImageScale::smoothScale( image, width, height );
+
+ if( filter == Box && width > image.width() && height > image.height() && blur == 1.0 ) {
+ filter = NULL; // Box doesn't really smooth when enlarging
+ }
+
+ if( filter == NULL ) {
+ return SampleImage( image, width, height ); // doesn't need 32bit
+ }
+
+ return ResizeImage( image.convertDepth( 32 ), width, height, filter, filtersupport, blur );
+ // unlike Qt's smoothScale() this function introduces new colors to grayscale images ... oh well
+}
+
+
+} // namespace
diff --git a/src/fastscale/scale.h b/src/fastscale/scale.h
new file mode 100644
index 0000000..299ac16
--- /dev/null
+++ b/src/fastscale/scale.h
@@ -0,0 +1,34 @@
+// vim: set tabstop=4 shiftwidth=4 noexpandtab
+/*
+Gwenview - A simple image viewer for KDE
+Copyright 2000-2004 Aurlien Gteau
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+#ifndef FAST_SCALE_H
+#define FAST_SCALE_H
+
+// Qt
+#include <qimage.h>
+
+namespace ImageUtils {
+ enum SmoothAlgorithm { SMOOTH_NONE, SMOOTH_FAST, SMOOTH_NORMAL, SMOOTH_BEST };
+
+ QImage scale(const QImage& image, int width, int height,
+ SmoothAlgorithm alg, QImage::ScaleMode mode = QImage::ScaleFree, double blur = 1.0);
+}
+
+#endif
diff --git a/src/icons/Makefile.am b/src/icons/Makefile.am
new file mode 100644
index 0000000..c7abccf
--- /dev/null
+++ b/src/icons/Makefile.am
@@ -0,0 +1,2 @@
+KDE_ICON = AUTO
+SUBDIRS = actions
diff --git a/src/icons/actions/Makefile.am b/src/icons/actions/Makefile.am
new file mode 100644
index 0000000..a8f669e
--- /dev/null
+++ b/src/icons/actions/Makefile.am
@@ -0,0 +1,2 @@
+k3bicondir = $(kde_datadir)/k3b/icons
+k3bicon_ICON = AUTO
diff --git a/src/icons/actions/cr16-action-greenled.png b/src/icons/actions/cr16-action-greenled.png
new file mode 100644
index 0000000..bf2a36c
--- /dev/null
+++ b/src/icons/actions/cr16-action-greenled.png
Binary files differ
diff --git a/src/icons/actions/cr16-action-redled.png b/src/icons/actions/cr16-action-redled.png
new file mode 100644
index 0000000..04db8ff
--- /dev/null
+++ b/src/icons/actions/cr16-action-redled.png
Binary files differ
diff --git a/src/icons/actions/cr16-action-yellowinfo.png b/src/icons/actions/cr16-action-yellowinfo.png
new file mode 100644
index 0000000..5a464f3
--- /dev/null
+++ b/src/icons/actions/cr16-action-yellowinfo.png
Binary files differ
diff --git a/src/icons/actions/cr16-action-yellowled.png b/src/icons/actions/cr16-action-yellowled.png
new file mode 100644
index 0000000..a0e8f87
--- /dev/null
+++ b/src/icons/actions/cr16-action-yellowled.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-audiocd.png b/src/icons/actions/hi16-action-audiocd.png
new file mode 100644
index 0000000..d452cdc
--- /dev/null
+++ b/src/icons/actions/hi16-action-audiocd.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-burn_cdimage.png b/src/icons/actions/hi16-action-burn_cdimage.png
new file mode 100644
index 0000000..b9821b3
--- /dev/null
+++ b/src/icons/actions/hi16-action-burn_cdimage.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-burn_dvdimage.png b/src/icons/actions/hi16-action-burn_dvdimage.png
new file mode 100644
index 0000000..28a8fbc
--- /dev/null
+++ b/src/icons/actions/hi16-action-burn_dvdimage.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-cdburn.png b/src/icons/actions/hi16-action-cdburn.png
new file mode 100644
index 0000000..4e1e406
--- /dev/null
+++ b/src/icons/actions/hi16-action-cdburn.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-cdcopy.png b/src/icons/actions/hi16-action-cdcopy.png
new file mode 100644
index 0000000..49a7505
--- /dev/null
+++ b/src/icons/actions/hi16-action-cdcopy.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-cddarip.png b/src/icons/actions/hi16-action-cddarip.png
new file mode 100644
index 0000000..ab28c17
--- /dev/null
+++ b/src/icons/actions/hi16-action-cddarip.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-datacd.png b/src/icons/actions/hi16-action-datacd.png
new file mode 100644
index 0000000..a0cd3a7
--- /dev/null
+++ b/src/icons/actions/hi16-action-datacd.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-datadvd.png b/src/icons/actions/hi16-action-datadvd.png
new file mode 100644
index 0000000..78fa410
--- /dev/null
+++ b/src/icons/actions/hi16-action-datadvd.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-dvdcopy.png b/src/icons/actions/hi16-action-dvdcopy.png
new file mode 100644
index 0000000..52012d0
--- /dev/null
+++ b/src/icons/actions/hi16-action-dvdcopy.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-emovix.png b/src/icons/actions/hi16-action-emovix.png
new file mode 100644
index 0000000..5242645
--- /dev/null
+++ b/src/icons/actions/hi16-action-emovix.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-erasecd.png b/src/icons/actions/hi16-action-erasecd.png
new file mode 100644
index 0000000..1d08a42
--- /dev/null
+++ b/src/icons/actions/hi16-action-erasecd.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-formatdvd.png b/src/icons/actions/hi16-action-formatdvd.png
new file mode 100644
index 0000000..ecc8153
--- /dev/null
+++ b/src/icons/actions/hi16-action-formatdvd.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-mixedcd.png b/src/icons/actions/hi16-action-mixedcd.png
new file mode 100644
index 0000000..514bb3e
--- /dev/null
+++ b/src/icons/actions/hi16-action-mixedcd.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-mp3cd.png b/src/icons/actions/hi16-action-mp3cd.png
new file mode 100644
index 0000000..378d072
--- /dev/null
+++ b/src/icons/actions/hi16-action-mp3cd.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-musicbrainz.png b/src/icons/actions/hi16-action-musicbrainz.png
new file mode 100644
index 0000000..0608908
--- /dev/null
+++ b/src/icons/actions/hi16-action-musicbrainz.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-videocd.png b/src/icons/actions/hi16-action-videocd.png
new file mode 100644
index 0000000..b9e8c18
--- /dev/null
+++ b/src/icons/actions/hi16-action-videocd.png
Binary files differ
diff --git a/src/icons/actions/hi16-action-videodvd.png b/src/icons/actions/hi16-action-videodvd.png
new file mode 100644
index 0000000..8bb3470
--- /dev/null
+++ b/src/icons/actions/hi16-action-videodvd.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-audiocd.png b/src/icons/actions/hi22-action-audiocd.png
new file mode 100644
index 0000000..46762b4
--- /dev/null
+++ b/src/icons/actions/hi22-action-audiocd.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-burn_cdimage.png b/src/icons/actions/hi22-action-burn_cdimage.png
new file mode 100644
index 0000000..f5e1b0d
--- /dev/null
+++ b/src/icons/actions/hi22-action-burn_cdimage.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-burn_dvdimage.png b/src/icons/actions/hi22-action-burn_dvdimage.png
new file mode 100644
index 0000000..6e6b94b
--- /dev/null
+++ b/src/icons/actions/hi22-action-burn_dvdimage.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-cdburn.png b/src/icons/actions/hi22-action-cdburn.png
new file mode 100644
index 0000000..7862d9e
--- /dev/null
+++ b/src/icons/actions/hi22-action-cdburn.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-cdcopy.png b/src/icons/actions/hi22-action-cdcopy.png
new file mode 100644
index 0000000..0269b7e
--- /dev/null
+++ b/src/icons/actions/hi22-action-cdcopy.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-cddarip.png b/src/icons/actions/hi22-action-cddarip.png
new file mode 100644
index 0000000..6bbc468
--- /dev/null
+++ b/src/icons/actions/hi22-action-cddarip.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-datacd.png b/src/icons/actions/hi22-action-datacd.png
new file mode 100644
index 0000000..cfc2e69
--- /dev/null
+++ b/src/icons/actions/hi22-action-datacd.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-datadvd.png b/src/icons/actions/hi22-action-datadvd.png
new file mode 100644
index 0000000..c1cb979
--- /dev/null
+++ b/src/icons/actions/hi22-action-datadvd.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-dvdcopy.png b/src/icons/actions/hi22-action-dvdcopy.png
new file mode 100644
index 0000000..b05714c
--- /dev/null
+++ b/src/icons/actions/hi22-action-dvdcopy.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-emovix.png b/src/icons/actions/hi22-action-emovix.png
new file mode 100644
index 0000000..04f6478
--- /dev/null
+++ b/src/icons/actions/hi22-action-emovix.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-erasecd.png b/src/icons/actions/hi22-action-erasecd.png
new file mode 100644
index 0000000..6619f67
--- /dev/null
+++ b/src/icons/actions/hi22-action-erasecd.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-formatdvd.png b/src/icons/actions/hi22-action-formatdvd.png
new file mode 100644
index 0000000..8d419f4
--- /dev/null
+++ b/src/icons/actions/hi22-action-formatdvd.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-mixedcd.png b/src/icons/actions/hi22-action-mixedcd.png
new file mode 100644
index 0000000..13cbf7f
--- /dev/null
+++ b/src/icons/actions/hi22-action-mixedcd.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-mp3cd.png b/src/icons/actions/hi22-action-mp3cd.png
new file mode 100644
index 0000000..653129d
--- /dev/null
+++ b/src/icons/actions/hi22-action-mp3cd.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-videocd.png b/src/icons/actions/hi22-action-videocd.png
new file mode 100644
index 0000000..0ebe179
--- /dev/null
+++ b/src/icons/actions/hi22-action-videocd.png
Binary files differ
diff --git a/src/icons/actions/hi22-action-videodvd.png b/src/icons/actions/hi22-action-videodvd.png
new file mode 100644
index 0000000..6ca9619
--- /dev/null
+++ b/src/icons/actions/hi22-action-videodvd.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-audiocd.png b/src/icons/actions/hi32-action-audiocd.png
new file mode 100644
index 0000000..6509ef7
--- /dev/null
+++ b/src/icons/actions/hi32-action-audiocd.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-burn_cdimage.png b/src/icons/actions/hi32-action-burn_cdimage.png
new file mode 100644
index 0000000..5bdcbf0
--- /dev/null
+++ b/src/icons/actions/hi32-action-burn_cdimage.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-burn_dvdimage.png b/src/icons/actions/hi32-action-burn_dvdimage.png
new file mode 100644
index 0000000..647d9b1
--- /dev/null
+++ b/src/icons/actions/hi32-action-burn_dvdimage.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-cdburn.png b/src/icons/actions/hi32-action-cdburn.png
new file mode 100644
index 0000000..3150417
--- /dev/null
+++ b/src/icons/actions/hi32-action-cdburn.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-cdcopy.png b/src/icons/actions/hi32-action-cdcopy.png
new file mode 100644
index 0000000..4c650ce
--- /dev/null
+++ b/src/icons/actions/hi32-action-cdcopy.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-cddarip.png b/src/icons/actions/hi32-action-cddarip.png
new file mode 100644
index 0000000..e0af956
--- /dev/null
+++ b/src/icons/actions/hi32-action-cddarip.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-datacd.png b/src/icons/actions/hi32-action-datacd.png
new file mode 100644
index 0000000..fec1dd3
--- /dev/null
+++ b/src/icons/actions/hi32-action-datacd.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-datadvd.png b/src/icons/actions/hi32-action-datadvd.png
new file mode 100644
index 0000000..730fdb0
--- /dev/null
+++ b/src/icons/actions/hi32-action-datadvd.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-dvdcopy.png b/src/icons/actions/hi32-action-dvdcopy.png
new file mode 100644
index 0000000..0ffc7b9
--- /dev/null
+++ b/src/icons/actions/hi32-action-dvdcopy.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-emovix.png b/src/icons/actions/hi32-action-emovix.png
new file mode 100644
index 0000000..779159e
--- /dev/null
+++ b/src/icons/actions/hi32-action-emovix.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-erasecd.png b/src/icons/actions/hi32-action-erasecd.png
new file mode 100644
index 0000000..e699d07
--- /dev/null
+++ b/src/icons/actions/hi32-action-erasecd.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-formatdvd.png b/src/icons/actions/hi32-action-formatdvd.png
new file mode 100644
index 0000000..4e4c044
--- /dev/null
+++ b/src/icons/actions/hi32-action-formatdvd.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-mixedcd.png b/src/icons/actions/hi32-action-mixedcd.png
new file mode 100644
index 0000000..7f842c8
--- /dev/null
+++ b/src/icons/actions/hi32-action-mixedcd.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-mp3cd.png b/src/icons/actions/hi32-action-mp3cd.png
new file mode 100644
index 0000000..98a9787
--- /dev/null
+++ b/src/icons/actions/hi32-action-mp3cd.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-videocd.png b/src/icons/actions/hi32-action-videocd.png
new file mode 100644
index 0000000..93b5838
--- /dev/null
+++ b/src/icons/actions/hi32-action-videocd.png
Binary files differ
diff --git a/src/icons/actions/hi32-action-videodvd.png b/src/icons/actions/hi32-action-videodvd.png
new file mode 100644
index 0000000..3b1ed2d
--- /dev/null
+++ b/src/icons/actions/hi32-action-videodvd.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-audiocd.png b/src/icons/actions/hi48-action-audiocd.png
new file mode 100644
index 0000000..a609713
--- /dev/null
+++ b/src/icons/actions/hi48-action-audiocd.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-burn_cdimage.png b/src/icons/actions/hi48-action-burn_cdimage.png
new file mode 100644
index 0000000..1d91604
--- /dev/null
+++ b/src/icons/actions/hi48-action-burn_cdimage.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-burn_dvdimage.png b/src/icons/actions/hi48-action-burn_dvdimage.png
new file mode 100644
index 0000000..36d24a6
--- /dev/null
+++ b/src/icons/actions/hi48-action-burn_dvdimage.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-cdburn.png b/src/icons/actions/hi48-action-cdburn.png
new file mode 100644
index 0000000..d4c8c7b
--- /dev/null
+++ b/src/icons/actions/hi48-action-cdburn.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-cdcopy.png b/src/icons/actions/hi48-action-cdcopy.png
new file mode 100644
index 0000000..a2ca951
--- /dev/null
+++ b/src/icons/actions/hi48-action-cdcopy.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-cddarip.png b/src/icons/actions/hi48-action-cddarip.png
new file mode 100644
index 0000000..d21b6f0
--- /dev/null
+++ b/src/icons/actions/hi48-action-cddarip.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-datacd.png b/src/icons/actions/hi48-action-datacd.png
new file mode 100644
index 0000000..77740bb
--- /dev/null
+++ b/src/icons/actions/hi48-action-datacd.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-datadvd.png b/src/icons/actions/hi48-action-datadvd.png
new file mode 100644
index 0000000..12e2ae6
--- /dev/null
+++ b/src/icons/actions/hi48-action-datadvd.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-dvdcopy.png b/src/icons/actions/hi48-action-dvdcopy.png
new file mode 100644
index 0000000..c2b39ef
--- /dev/null
+++ b/src/icons/actions/hi48-action-dvdcopy.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-emovix.png b/src/icons/actions/hi48-action-emovix.png
new file mode 100644
index 0000000..cec838a
--- /dev/null
+++ b/src/icons/actions/hi48-action-emovix.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-erasecd.png b/src/icons/actions/hi48-action-erasecd.png
new file mode 100644
index 0000000..8a47870
--- /dev/null
+++ b/src/icons/actions/hi48-action-erasecd.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-formatdvd.png b/src/icons/actions/hi48-action-formatdvd.png
new file mode 100644
index 0000000..1f536f1
--- /dev/null
+++ b/src/icons/actions/hi48-action-formatdvd.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-mixedcd.png b/src/icons/actions/hi48-action-mixedcd.png
new file mode 100644
index 0000000..77e2202
--- /dev/null
+++ b/src/icons/actions/hi48-action-mixedcd.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-mp3cd.png b/src/icons/actions/hi48-action-mp3cd.png
new file mode 100644
index 0000000..665e431
--- /dev/null
+++ b/src/icons/actions/hi48-action-mp3cd.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-videocd.png b/src/icons/actions/hi48-action-videocd.png
new file mode 100644
index 0000000..55bccd4
--- /dev/null
+++ b/src/icons/actions/hi48-action-videocd.png
Binary files differ
diff --git a/src/icons/actions/hi48-action-videodvd.png b/src/icons/actions/hi48-action-videodvd.png
new file mode 100644
index 0000000..2078bec
--- /dev/null
+++ b/src/icons/actions/hi48-action-videodvd.png
Binary files differ
diff --git a/src/icons/actions/hi64-action-musicbrainz.png b/src/icons/actions/hi64-action-musicbrainz.png
new file mode 100644
index 0000000..f5074c6
--- /dev/null
+++ b/src/icons/actions/hi64-action-musicbrainz.png
Binary files differ
diff --git a/src/icons/actions/hisc-action-audiocd.svgz b/src/icons/actions/hisc-action-audiocd.svgz
new file mode 100644
index 0000000..cb05f70
--- /dev/null
+++ b/src/icons/actions/hisc-action-audiocd.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-burn_cdimage.svgz b/src/icons/actions/hisc-action-burn_cdimage.svgz
new file mode 100644
index 0000000..b0a8fde
--- /dev/null
+++ b/src/icons/actions/hisc-action-burn_cdimage.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-burn_dvdimage.svgz b/src/icons/actions/hisc-action-burn_dvdimage.svgz
new file mode 100644
index 0000000..b89af60
--- /dev/null
+++ b/src/icons/actions/hisc-action-burn_dvdimage.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-cdburn.svgz b/src/icons/actions/hisc-action-cdburn.svgz
new file mode 100644
index 0000000..014f1b8
--- /dev/null
+++ b/src/icons/actions/hisc-action-cdburn.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-cdcopy.svgz b/src/icons/actions/hisc-action-cdcopy.svgz
new file mode 100644
index 0000000..9143b8d
--- /dev/null
+++ b/src/icons/actions/hisc-action-cdcopy.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-cddarip.svgz b/src/icons/actions/hisc-action-cddarip.svgz
new file mode 100644
index 0000000..2a86c86
--- /dev/null
+++ b/src/icons/actions/hisc-action-cddarip.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-datacd.svgz b/src/icons/actions/hisc-action-datacd.svgz
new file mode 100644
index 0000000..e2f0f2a
--- /dev/null
+++ b/src/icons/actions/hisc-action-datacd.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-datadvd.svgz b/src/icons/actions/hisc-action-datadvd.svgz
new file mode 100644
index 0000000..332b73c
--- /dev/null
+++ b/src/icons/actions/hisc-action-datadvd.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-dvdcopy.svgz b/src/icons/actions/hisc-action-dvdcopy.svgz
new file mode 100644
index 0000000..b8efe33
--- /dev/null
+++ b/src/icons/actions/hisc-action-dvdcopy.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-emovix.svgz b/src/icons/actions/hisc-action-emovix.svgz
new file mode 100644
index 0000000..5053e3d
--- /dev/null
+++ b/src/icons/actions/hisc-action-emovix.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-erasecd.svgz b/src/icons/actions/hisc-action-erasecd.svgz
new file mode 100644
index 0000000..7a99c82
--- /dev/null
+++ b/src/icons/actions/hisc-action-erasecd.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-formatdvd.svgz b/src/icons/actions/hisc-action-formatdvd.svgz
new file mode 100644
index 0000000..33e4877
--- /dev/null
+++ b/src/icons/actions/hisc-action-formatdvd.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-mixedcd.svgz b/src/icons/actions/hisc-action-mixedcd.svgz
new file mode 100644
index 0000000..fa10365
--- /dev/null
+++ b/src/icons/actions/hisc-action-mixedcd.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-mp3cd.svgz b/src/icons/actions/hisc-action-mp3cd.svgz
new file mode 100644
index 0000000..5142c80
--- /dev/null
+++ b/src/icons/actions/hisc-action-mp3cd.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-videocd.svgz b/src/icons/actions/hisc-action-videocd.svgz
new file mode 100644
index 0000000..9af309f
--- /dev/null
+++ b/src/icons/actions/hisc-action-videocd.svgz
Binary files differ
diff --git a/src/icons/actions/hisc-action-videodvd.svgz b/src/icons/actions/hisc-action-videodvd.svgz
new file mode 100644
index 0000000..1ec5b1f
--- /dev/null
+++ b/src/icons/actions/hisc-action-videodvd.svgz
Binary files differ
diff --git a/src/icons/hi128-app-k3b.png b/src/icons/hi128-app-k3b.png
new file mode 100644
index 0000000..278d6b1
--- /dev/null
+++ b/src/icons/hi128-app-k3b.png
Binary files differ
diff --git a/src/icons/hi16-app-k3b.png b/src/icons/hi16-app-k3b.png
new file mode 100644
index 0000000..7891dc0
--- /dev/null
+++ b/src/icons/hi16-app-k3b.png
Binary files differ
diff --git a/src/icons/hi22-app-k3b.png b/src/icons/hi22-app-k3b.png
new file mode 100644
index 0000000..43bf2f2
--- /dev/null
+++ b/src/icons/hi22-app-k3b.png
Binary files differ
diff --git a/src/icons/hi32-app-k3b.png b/src/icons/hi32-app-k3b.png
new file mode 100644
index 0000000..5c1cd8e
--- /dev/null
+++ b/src/icons/hi32-app-k3b.png
Binary files differ
diff --git a/src/icons/hi48-app-k3b.png b/src/icons/hi48-app-k3b.png
new file mode 100644
index 0000000..04c40a1
--- /dev/null
+++ b/src/icons/hi48-app-k3b.png
Binary files differ
diff --git a/src/icons/hi64-app-k3b.png b/src/icons/hi64-app-k3b.png
new file mode 100644
index 0000000..f1354cb
--- /dev/null
+++ b/src/icons/hi64-app-k3b.png
Binary files differ
diff --git a/src/k3b-cue.desktop b/src/k3b-cue.desktop
new file mode 100644
index 0000000..e1743f6
--- /dev/null
+++ b/src/k3b-cue.desktop
@@ -0,0 +1,14 @@
+# KDE Config File
+[Desktop Entry]
+Type=Application
+NoDisplay=true
+Exec=k3b --cdimage %U
+Icon=k3b
+Terminal=false
+Name=K3b
+Name[ar]= K3b
+Name[bn]=কে-থ্রি-বি
+Name[hi]=के3बी
+MimeType=application/x-cue;
+
+Encoding=UTF-8
diff --git a/src/k3b-iso.desktop b/src/k3b-iso.desktop
new file mode 100644
index 0000000..ff97f3e
--- /dev/null
+++ b/src/k3b-iso.desktop
@@ -0,0 +1,13 @@
+# KDE Config File
+[Desktop Entry]
+Type=Application
+NoDisplay=true
+Exec=k3b --image %U
+Icon=k3b
+Terminal=false
+Name=K3b
+Name[ar]= K3b
+Name[bn]=কে-থ্রি-বি
+Name[hi]=के3बी
+MimeType=application/x-iso;
+Encoding=UTF-8
diff --git a/src/k3b.cpp b/src/k3b.cpp
new file mode 100644
index 0000000..23a5cd6
--- /dev/null
+++ b/src/k3b.cpp
@@ -0,0 +1,1630 @@
+/*
+ *
+ * $Id: k3b.cpp 642063 2007-03-13 09:40:13Z trueg $
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include <config.h>
+
+
+// include files for QT
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qtoolbutton.h>
+#include <qstring.h>
+#include <qsplitter.h>
+#include <qevent.h>
+#include <qvaluelist.h>
+#include <qfont.h>
+#include <qpalette.h>
+#include <qwidgetstack.h>
+#include <qtimer.h>
+
+#include <kdockwidget.h>
+#include <kkeydialog.h>
+// include files for KDE
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+#include <kmenubar.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstdaction.h>
+#include <klineeditdlg.h>
+#include <kstandarddirs.h>
+#include <kprocess.h>
+#include <kurl.h>
+#include <kurllabel.h>
+#include <ktoolbar.h>
+#include <kstatusbar.h>
+#include <kglobalsettings.h>
+#include <kdialog.h>
+#include <kedittoolbar.h>
+#include <ksystemtray.h>
+#include <kaboutdata.h>
+#include <ktip.h>
+#include <kxmlguifactory.h>
+#include <kstdguiitem.h>
+#include <kio/global.h>
+#include <kio/netaccess.h>
+#include <krecentdocument.h>
+
+#include <stdlib.h>
+
+// application specific includes
+#include "k3b.h"
+#include "k3bapplication.h"
+#include <k3bglobals.h>
+#include "k3bview.h"
+#include "k3bdirview.h"
+#include <k3baudiodoc.h>
+#include "k3baudioview.h"
+#include "k3bappdevicemanager.h"
+#include "k3baudiotrackdialog.h"
+#include "option/k3boptiondialog.h"
+#include "k3bprojectburndialog.h"
+#include <k3bdatadoc.h>
+#include "k3bdataview.h"
+#include <k3bdvddoc.h>
+#include "k3bdvdview.h"
+#include <k3bvideodvddoc.h>
+#include "k3bvideodvdview.h"
+#include <k3bmixeddoc.h>
+#include "k3bmixedview.h"
+#include <k3bvcddoc.h>
+#include "k3bvcdview.h"
+#include <k3bmovixdoc.h>
+#include "k3bmovixview.h"
+#include <k3bmovixdvddoc.h>
+#include "k3bmovixdvdview.h"
+#include "misc/k3bblankingdialog.h"
+#include "misc/k3bcdimagewritingdialog.h"
+#include "misc/k3bisoimagewritingdialog.h"
+#include <k3bexternalbinmanager.h>
+#include "k3bprojecttabwidget.h"
+#include "misc/k3bcdcopydialog.h"
+#include "k3btempdirselectionwidget.h"
+#include "k3bstatusbarmanager.h"
+#include "k3bfiletreecombobox.h"
+#include "k3bfiletreeview.h"
+#include "k3bsidepanel.h"
+#include "k3bstdguiitems.h"
+#include "misc/k3bdvdformattingdialog.h"
+#include "misc/k3bdvdcopydialog.h"
+//#include "dvdcopy/k3bvideodvdcopydialog.h"
+#include "k3bprojectmanager.h"
+#include "k3bwelcomewidget.h"
+#include <k3bpluginmanager.h>
+#include <k3bplugin.h>
+#include "k3bsystemproblemdialog.h"
+#include <k3baudiodecoder.h>
+#include <k3bthememanager.h>
+#include <k3biso9660.h>
+#include <k3bcuefileparser.h>
+#include <k3bdeviceselectiondialog.h>
+#include <k3bjob.h>
+#include <k3bsignalwaiter.h>
+#include "k3bmediaselectiondialog.h"
+#include "k3bmediacache.h"
+#include "k3bmedium.h"
+#include "projects/k3bdatasessionimportdialog.h"
+#include "k3bpassivepopup.h"
+#include "k3bthemedheader.h"
+#include <k3baudioserver.h>
+
+
+class K3bMainWindow::Private
+{
+public:
+ K3bDoc* lastDoc;
+
+ QWidgetStack* documentStack;
+ K3bWelcomeWidget* welcomeWidget;
+ QWidget* documentHull;
+
+ QLabel* leftDocPicLabel;
+ QLabel* centerDocLabel;
+ QLabel* rightDocPicLabel;
+};
+
+
+K3bMainWindow::K3bMainWindow()
+ : DockMainWindow(0,"K3bMainwindow")
+{
+ //setup splitter behavior
+ manager()->setSplitterHighResolution(true);
+ manager()->setSplitterOpaqueResize(true);
+ manager()->setSplitterKeepSize(true);
+
+ d = new Private;
+ d->lastDoc = 0;
+
+ setPlainCaption( i18n("K3b - The CD and DVD Kreator") );
+
+ m_config = kapp->config();
+
+ ///////////////////////////////////////////////////////////////////
+ // call inits to invoke all other construction parts
+ initActions();
+ initView();
+ initStatusBar();
+ createGUI(0L);
+
+ // we need the actions for the welcomewidget
+ d->welcomeWidget->loadConfig( config() );
+
+ // fill the tabs action menu
+ m_documentTab->insertAction( actionFileSave );
+ m_documentTab->insertAction( actionFileSaveAs );
+ m_documentTab->insertAction( actionFileClose );
+
+ // /////////////////////////////////////////////////////////////////
+ // disable actions at startup
+ slotStateChanged( "state_project_active", KXMLGUIClient::StateReverse );
+
+ connect( k3bappcore->projectManager(), SIGNAL(newProject(K3bDoc*)), this, SLOT(createClient(K3bDoc*)) );
+ connect( k3bcore->deviceManager(), SIGNAL(changed()), this, SLOT(slotCheckSystemTimed()) );
+ connect( K3bAudioServer::instance(), SIGNAL(error(const QString&)), this, SLOT(slotAudioServerError(const QString&)) );
+
+ // FIXME: now make sure the welcome screen is displayed completely
+ resize( 780, 550 );
+// getMainDockWidget()->resize( getMainDockWidget()->size().expandedTo( d->welcomeWidget->sizeHint() ) );
+// m_dirTreeDock->resize( QSize( m_dirTreeDock->sizeHint().width(), m_dirTreeDock->height() ) );
+
+ readOptions();
+}
+
+K3bMainWindow::~K3bMainWindow()
+{
+ delete mainDock;
+ delete m_contentsDock;
+
+ delete d;
+}
+
+
+void K3bMainWindow::showEvent( QShowEvent* e )
+{
+ slotCheckDockWidgetStatus();
+ KDockMainWindow::showEvent( e );
+}
+
+
+void K3bMainWindow::initActions()
+{
+ // merge in the device actions from the device manager
+ // operator+= is deprecated but I know no other way to do this. Why does the KDE app framework
+ // need to have all actions in the mainwindow's actioncollection anyway (or am I just to stupid to
+ // see the correct solution?)
+ *actionCollection() += *k3bappcore->appDeviceManager()->actionCollection();
+
+ actionFileOpen = KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
+ actionFileOpenRecent = KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection());
+ actionFileSave = KStdAction::save(this, SLOT(slotFileSave()), actionCollection());
+ actionFileSaveAs = KStdAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection());
+ actionFileSaveAll = new KAction( i18n("Save All"), "save_all", 0, this, SLOT(slotFileSaveAll()),
+ actionCollection(), "file_save_all" );
+ actionFileClose = KStdAction::close(this, SLOT(slotFileClose()), actionCollection());
+ actionFileCloseAll = new KAction( i18n("Close All"), 0, 0, this, SLOT(slotFileCloseAll()),
+ actionCollection(), "file_close_all" );
+ actionFileQuit = KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
+ actionViewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()), actionCollection());
+ actionSettingsConfigure = KStdAction::preferences(this, SLOT(slotSettingsConfigure()), actionCollection() );
+
+ // the tip action
+ (void)KStdAction::tipOfDay(this, SLOT(slotShowTips()), actionCollection() );
+ (void)KStdAction::keyBindings( this, SLOT( slotConfigureKeys() ), actionCollection() );
+
+ KStdAction::configureToolbars(this, SLOT(slotEditToolbars()), actionCollection());
+ setStandardToolBarMenuEnabled(true);
+ KStdAction::showMenubar( this, SLOT(slotShowMenuBar()), actionCollection() );
+
+ actionFileNewMenu = new KActionMenu( i18n("&New Project"), "filenew", actionCollection(), "file_new" );
+ actionFileNewAudio = new KAction(i18n("New &Audio CD Project"), "audiocd", 0, this, SLOT(slotNewAudioDoc()),
+ actionCollection(), "file_new_audio");
+ actionFileNewData = new KAction(i18n("New Data &CD Project"), "datacd", 0, this, SLOT(slotNewDataDoc()),
+ actionCollection(), "file_new_data");
+ actionFileNewMixed = new KAction(i18n("New &Mixed Mode CD Project"), "mixedcd", 0, this, SLOT(slotNewMixedDoc()),
+ actionCollection(), "file_new_mixed");
+ actionFileNewVcd = new KAction(i18n("New &Video CD Project"), "videocd", 0, this, SLOT(slotNewVcdDoc()),
+ actionCollection(), "file_new_vcd");
+ actionFileNewMovix = new KAction(i18n("New &eMovix CD Project"), "emovix", 0, this, SLOT(slotNewMovixDoc()),
+ actionCollection(), "file_new_movix");
+ actionFileNewMovixDvd = new KAction(i18n("New &eMovix DVD Project"), "emovix", 0, this, SLOT(slotNewMovixDvdDoc()),
+ actionCollection(), "file_new_movix_dvd");
+ actionFileNewDvd = new KAction(i18n("New Data &DVD Project"), "datadvd", 0, this, SLOT(slotNewDvdDoc()),
+ actionCollection(), "file_new_dvd");
+ actionFileNewVideoDvd = new KAction(i18n("New V&ideo DVD Project"), "videodvd", 0, this, SLOT(slotNewVideoDvdDoc()),
+ actionCollection(), "file_new_video_dvd");
+ actionFileContinueMultisession = new KAction( i18n("Continue Multisession Project"), "datacd", 0, this, SLOT(slotContinueMultisession()),
+ actionCollection(), "file_continue_multisession" );
+
+ actionFileNewMenu->setDelayed( false );
+ actionFileNewMenu->insert( actionFileNewData );
+ actionFileNewMenu->insert( actionFileNewDvd );
+ actionFileNewMenu->insert( actionFileContinueMultisession );
+ actionFileNewMenu->insert( new KActionSeparator( this ) );
+ actionFileNewMenu->insert( actionFileNewAudio );
+ actionFileNewMenu->insert( new KActionSeparator( this ) );
+ actionFileNewMenu->insert( actionFileNewMixed );
+ actionFileNewMenu->insert( new KActionSeparator( this ) );
+ actionFileNewMenu->insert( actionFileNewVcd );
+ actionFileNewMenu->insert( actionFileNewVideoDvd );
+ actionFileNewMenu->insert( new KActionSeparator( this ) );
+ actionFileNewMenu->insert( actionFileNewMovix );
+ actionFileNewMenu->insert( actionFileNewMovixDvd );
+
+
+
+
+
+ actionProjectAddFiles = new KAction( i18n("&Add Files..."), "filenew", 0, this, SLOT(slotProjectAddFiles()),
+ actionCollection(), "project_add_files");
+
+ KAction* actionClearProject = new KAction( i18n("&Clear Project"), QApplication::reverseLayout() ? "clear_left" : "locationbar_erase", 0,
+ this, SLOT(slotClearProject()), actionCollection(), "project_clear_project" );
+
+ actionViewDirTreeView = new KToggleAction(i18n("Show Directories"), 0, this, SLOT(slotShowDirTreeView()),
+ actionCollection(), "view_dir_tree");
+
+ actionViewContentsView = new KToggleAction(i18n("Show Contents"), 0, this, SLOT(slotShowContentsView()),
+ actionCollection(), "view_contents");
+
+ actionViewDocumentHeader = new KToggleAction(i18n("Show Document Header"), 0, this, SLOT(slotViewDocumentHeader()),
+ actionCollection(), "view_document_header");
+
+ actionToolsBlankCdrw = new KAction( i18n("&Erase CD-RW..."), "erasecd", 0, this, SLOT(slotBlankCdrw()),
+ actionCollection(), "tools_blank_cdrw" );
+ KAction* actionToolsFormatDVD = new KAction( i18n("&Format DVD%1RW...").arg(""), "formatdvd", 0, this,
+ SLOT(slotFormatDvd()), actionCollection(), "tools_format_dvd" );
+ actionToolsWriteCdImage = new KAction(i18n("&Burn CD Image..."), "burn_cdimage", 0, this, SLOT(slotWriteCdImage()),
+ actionCollection(), "tools_write_cd_image" );
+ KAction* actionToolsWriteDvdImage = new KAction(i18n("&Burn DVD ISO Image..."), "burn_dvdimage", 0, this, SLOT(slotWriteDvdIsoImage()),
+ actionCollection(), "tools_write_dvd_iso" );
+
+ actionCdCopy = new KAction(i18n("&Copy CD..."), "cdcopy", 0, this, SLOT(slotCdCopy()),
+ actionCollection(), "tools_copy_cd" );
+
+ KAction* actionToolsDvdCopy = new KAction(i18n("Copy &DVD..."), "dvdcopy", 0, this, SLOT(slotDvdCopy()),
+ actionCollection(), "tools_copy_dvd" );
+
+ actionToolsCddaRip = new KAction( i18n("Rip Audio CD..."), "cddarip", 0, this, SLOT(slotCddaRip()),
+ actionCollection(), "tools_cdda_rip" );
+ actionToolsVideoDvdRip = new KAction( i18n("Rip Video DVD..."), "videodvd", 0, this, SLOT(slotVideoDvdRip()),
+ actionCollection(), "tools_videodvd_rip" );
+ actionToolsVideoCdRip = new KAction( i18n("Rip Video CD..."), "videocd", 0, this, SLOT(slotVideoCdRip()),
+ actionCollection(), "tools_videocd_rip" );
+
+ (void)new KAction( i18n("System Check"), 0, 0, this, SLOT(slotCheckSystem()),
+ actionCollection(), "help_check_system" );
+
+#ifdef HAVE_K3BSETUP
+ actionSettingsK3bSetup = new KAction(i18n("&Setup System Permissions..."), "configure", 0, this, SLOT(slotK3bSetup()),
+ actionCollection(), "settings_k3bsetup" );
+#endif
+
+#ifdef K3B_DEBUG
+ (void)new KAction( "Test Media Selection ComboBox", 0, 0, this,
+ SLOT(slotMediaSelectionTester()), actionCollection(),
+ "test_media_selection" );
+#endif
+
+ actionFileNewMenu->setToolTip(i18n("Creates a new project"));
+ actionFileNewData->setToolTip( i18n("Creates a new data CD project") );
+ actionFileNewAudio->setToolTip( i18n("Creates a new audio CD project") );
+ actionFileNewMovixDvd->setToolTip( i18n("Creates a new eMovix DVD project") );
+ actionFileNewDvd->setToolTip( i18n("Creates a new data DVD project") );
+ actionFileNewMovix->setToolTip( i18n("Creates a new eMovix CD project") );
+ actionFileNewVcd->setToolTip( i18n("Creates a new Video CD project") );
+ actionToolsBlankCdrw->setToolTip( i18n("Open the CD-RW erasing dialog") );
+ actionToolsFormatDVD->setToolTip( i18n("Open the DVD%1RW formatting dialog").arg("") );
+ actionCdCopy->setToolTip( i18n("Open the CD copy dialog") );
+ actionToolsWriteCdImage->setToolTip( i18n("Write an Iso9660, cue/bin, or cdrecord clone image to CD") );
+ actionToolsWriteDvdImage->setToolTip( i18n("Write an Iso9660 image to DVD") );
+ actionToolsDvdCopy->setToolTip( i18n("Open the DVD copy dialog") );
+ actionFileOpen->setToolTip(i18n("Opens an existing project"));
+ actionFileOpenRecent->setToolTip(i18n("Opens a recently used file"));
+ actionFileSave->setToolTip(i18n("Saves the current project"));
+ actionFileSaveAs->setToolTip(i18n("Saves the current project to a new url"));
+ actionFileSaveAll->setToolTip(i18n("Saves all open projects"));
+ actionFileClose->setToolTip(i18n("Closes the current project"));
+ actionFileCloseAll->setToolTip(i18n("Closes all open projects"));
+ actionFileQuit->setToolTip(i18n("Quits the application"));
+ actionSettingsConfigure->setToolTip( i18n("Configure K3b settings") );
+#ifdef HAVE_K3BSETUP
+ actionSettingsK3bSetup->setToolTip( i18n("Setup the system permissions (requires root privileges)") );
+#endif
+ actionToolsCddaRip->setToolTip( i18n("Digitally extract tracks from an audio CD") );
+ actionToolsVideoDvdRip->setToolTip( i18n("Transcode Video DVD titles") );
+ actionToolsVideoCdRip->setToolTip( i18n("Extract tracks from a Video CD") );
+ actionProjectAddFiles->setToolTip( i18n("Add files to the current project") );
+ actionClearProject->setToolTip( i18n("Clear the current project") );
+
+ // make sure the tooltips are used for the menu
+ actionCollection()->setHighlightingEnabled( true );
+}
+
+
+
+const QPtrList<K3bDoc>& K3bMainWindow::projects() const
+{
+ return k3bappcore->projectManager()->projects();
+}
+
+
+void K3bMainWindow::slotConfigureKeys()
+{
+ KKeyDialog::configure( actionCollection(), this );
+}
+
+void K3bMainWindow::initStatusBar()
+{
+ m_statusBarManager = new K3bStatusBarManager( this );
+}
+
+
+void K3bMainWindow::initView()
+{
+ // setup main docking things
+ mainDock = createDockWidget( "project_view", SmallIcon("idea"), 0,
+ kapp->makeStdCaption( i18n("Project View") ), i18n("Project View") );
+ mainDock->setDockSite( KDockWidget::DockCorner );
+ mainDock->setEnableDocking( KDockWidget::DockNone );
+ setView( mainDock );
+ setMainDockWidget( mainDock );
+
+ // --- Document Dock ----------------------------------------------------------------------------
+ d->documentStack = new QWidgetStack( mainDock );
+ mainDock->setWidget( d->documentStack );
+
+ d->documentHull = new QWidget( d->documentStack );
+ d->documentStack->addWidget( d->documentHull );
+ QGridLayout* documentHullLayout = new QGridLayout( d->documentHull );
+ documentHullLayout->setMargin( 2 );
+ documentHullLayout->setSpacing( 0 );
+
+ m_documentHeader = new K3bThemedHeader( d->documentHull );
+ m_documentHeader->setTitle( i18n("Current Projects") );
+ m_documentHeader->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
+ m_documentHeader->setLeftPixmap( K3bTheme::PROJECT_LEFT );
+ m_documentHeader->setRightPixmap( K3bTheme::PROJECT_RIGHT );
+
+ // add the document tab to the styled document box
+ m_documentTab = new K3bProjectTabWidget( d->documentHull );
+
+ documentHullLayout->addWidget( m_documentHeader, 0, 0 );
+ documentHullLayout->addWidget( m_documentTab, 1, 0 );
+
+ connect( m_documentTab, SIGNAL(currentChanged(QWidget*)), this, SLOT(slotCurrentDocChanged()) );
+
+ d->welcomeWidget = new K3bWelcomeWidget( this, m_documentTab );
+ m_documentTab->addTab( d->welcomeWidget, i18n("Quickstart") );
+
+// d->documentStack->addWidget( d->welcomeWidget );
+// d->documentStack->raiseWidget( d->welcomeWidget );
+ // ---------------------------------------------------------------------------------------------
+
+ // --- Directory Dock --------------------------------------------------------------------------
+ m_dirTreeDock = createDockWidget( "directory_tree", SmallIcon("folder"), 0,
+ kapp->makeStdCaption( i18n("Sidepanel") ), i18n("Sidepanel") );
+ m_dirTreeDock->setEnableDocking( KDockWidget::DockCorner );
+
+ K3bFileTreeView* sidePanel = new K3bFileTreeView( m_dirTreeDock );
+ //K3bSidePanel* sidePanel = new K3bSidePanel( this, m_dirTreeDock, "sidePanel" );
+
+ m_dirTreeDock->setWidget( sidePanel );
+ m_dirTreeDock->manualDock( mainDock, KDockWidget::DockTop, 4000 );
+ connect( m_dirTreeDock, SIGNAL(iMBeingClosed()), this, SLOT(slotDirTreeDockHidden()) );
+ connect( m_dirTreeDock, SIGNAL(hasUndocked()), this, SLOT(slotDirTreeDockHidden()) );
+ // ---------------------------------------------------------------------------------------------
+
+ // --- Contents Dock ---------------------------------------------------------------------------
+ m_contentsDock = createDockWidget( "contents_view", SmallIcon("idea"), 0,
+ kapp->makeStdCaption( i18n("Contents View") ), i18n("Contents View") );
+ m_contentsDock->setEnableDocking( KDockWidget::DockCorner );
+ m_dirView = new K3bDirView( sidePanel/*->fileTreeView()*/, m_contentsDock );
+ m_contentsDock->setWidget( m_dirView );
+ m_contentsDock->manualDock( m_dirTreeDock, KDockWidget::DockRight, 2000 );
+
+ connect( m_contentsDock, SIGNAL(iMBeingClosed()), this, SLOT(slotContentsDockHidden()) );
+ connect( m_contentsDock, SIGNAL(hasUndocked()), this, SLOT(slotContentsDockHidden()) );
+ // ---------------------------------------------------------------------------------------------
+
+ // --- filetreecombobox-toolbar ----------------------------------------------------------------
+ K3bFileTreeComboBox* m_fileTreeComboBox = new K3bFileTreeComboBox( 0 );
+ connect( m_fileTreeComboBox, SIGNAL(urlExecuted(const KURL&)), m_dirView, SLOT(showUrl(const KURL& )) );
+ connect( m_fileTreeComboBox, SIGNAL(deviceExecuted(K3bDevice::Device*)), m_dirView,
+ SLOT(showDevice(K3bDevice::Device* )) );
+ connect( m_dirView, SIGNAL(urlEntered(const KURL&)), m_fileTreeComboBox, SLOT(setUrl(const KURL&)) );
+ connect( m_dirView, SIGNAL(deviceSelected(K3bDevice::Device*)), m_fileTreeComboBox, SLOT(setDevice(K3bDevice::Device*)) );
+
+ KWidgetAction* fileTreeComboAction = new KWidgetAction( m_fileTreeComboBox,
+ i18n("&Quick Dir Selector"),
+ 0, 0, 0,
+ actionCollection(), "quick_dir_selector" );
+ fileTreeComboAction->setAutoSized(true);
+ (void)new KAction( i18n("Go"), "key_enter", 0, m_fileTreeComboBox, SLOT(slotGoUrl()), actionCollection(), "go_url" );
+ // ---------------------------------------------------------------------------------------------
+}
+
+
+void K3bMainWindow::createClient( K3bDoc* doc )
+{
+ // create the proper K3bView (maybe we should put this into some other class like K3bProjectManager)
+ K3bView* view = 0;
+ switch( doc->type() ) {
+ case K3bDoc::AUDIO:
+ view = new K3bAudioView( static_cast<K3bAudioDoc*>(doc), m_documentTab );
+ break;
+ case K3bDoc::DATA:
+ view = new K3bDataView( static_cast<K3bDataDoc*>(doc), m_documentTab );
+ break;
+ case K3bDoc::MIXED:
+ {
+ K3bMixedDoc* mixedDoc = static_cast<K3bMixedDoc*>(doc);
+ view = new K3bMixedView( mixedDoc, m_documentTab );
+ mixedDoc->dataDoc()->setView( view );
+ mixedDoc->audioDoc()->setView( view );
+ break;
+ }
+ case K3bDoc::VCD:
+ view = new K3bVcdView( static_cast<K3bVcdDoc*>(doc), m_documentTab );
+ break;
+ case K3bDoc::MOVIX:
+ view = new K3bMovixView( static_cast<K3bMovixDoc*>(doc), m_documentTab );
+ break;
+ case K3bDoc::MOVIX_DVD:
+ view = new K3bMovixDvdView( static_cast<K3bMovixDvdDoc*>(doc), m_documentTab );
+ break;
+ case K3bDoc::DVD:
+ view = new K3bDvdView( static_cast<K3bDvdDoc*>(doc), m_documentTab );
+ break;
+ case K3bDoc::VIDEODVD:
+ view = new K3bVideoDvdView( static_cast<K3bVideoDvdDoc*>(doc), m_documentTab );
+ break;
+ }
+
+ doc->setView( view );
+ view->setCaption( doc->URL().fileName() );
+
+ m_documentTab->insertTab( doc );
+ m_documentTab->showPage( view );
+
+ slotCurrentDocChanged();
+}
+
+
+K3bView* K3bMainWindow::activeView() const
+{
+ QWidget* w = m_documentTab->currentPage();
+ if( K3bView* view = dynamic_cast<K3bView*>(w) )
+ return view;
+ else
+ return 0;
+}
+
+
+K3bDoc* K3bMainWindow::activeDoc() const
+{
+ if( activeView() )
+ return activeView()->getDocument();
+ else
+ return 0;
+}
+
+
+K3bDoc* K3bMainWindow::openDocument(const KURL& url)
+{
+ slotStatusMsg(i18n("Opening file..."));
+
+ //
+ // First we check if this is an iso image in case someone wants to open one this way
+ //
+ if( !isCdDvdImageAndIfSoOpenDialog( url ) ) {
+
+ // see if it's an audio cue file
+ K3bCueFileParser parser( url.path() );
+ if( parser.isValid() && parser.toc().contentType() == K3bDevice::AUDIO ) {
+ K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::AUDIO );
+ doc->addUrl( url );
+ return doc;
+ }
+ else {
+ // check, if document already open. If yes, set the focus to the first view
+ K3bDoc* doc = k3bappcore->projectManager()->findByUrl( url );
+ if( doc ) {
+ doc->view()->setFocus();
+ return doc;
+ }
+
+ doc = k3bappcore->projectManager()->openProject( url );
+
+ if( doc == 0 ) {
+ KMessageBox::error (this,i18n("Could not open document!"), i18n("Error!"));
+ return 0;
+ }
+
+ actionFileOpenRecent->addURL(url);
+
+ return doc;
+ }
+ }
+ else
+ return 0;
+}
+
+
+void K3bMainWindow::saveOptions()
+{
+ actionFileOpenRecent->saveEntries( config(), "Recent Files" );
+
+ // save dock positions!
+ manager()->writeConfig( config(), "Docking Config" );
+
+ m_dirView->saveConfig( config() );
+
+ saveMainWindowSettings( config(), "main_window_settings" );
+
+ k3bcore->saveSettings( config() );
+
+ d->welcomeWidget->saveConfig( config() );
+
+ KConfigGroup grp( m_config, "General Options" );
+ grp.writeEntry( "Show Document Header", actionViewDocumentHeader->isChecked() );
+}
+
+
+void K3bMainWindow::readOptions()
+{
+ KConfigGroup grp( m_config, "General Options" );
+
+ bool bViewDocumentHeader = grp.readBoolEntry("Show Document Header", true);
+ actionViewDocumentHeader->setChecked(bViewDocumentHeader);
+
+ // initialize the recent file list
+ actionFileOpenRecent->loadEntries( config(), "Recent Files" );
+
+ // do not read dock-positions from a config that has been saved by an old version
+ K3bVersion configVersion( grp.readEntry( "config version", "0.1" ) );
+ if( configVersion >= K3bVersion("0.12") )
+ manager()->readConfig( config(), "Docking Config" );
+ else
+ kdDebug() << "(K3bMainWindow) ignoring docking config from K3b version " << configVersion << endl;
+
+ applyMainWindowSettings( config(), "main_window_settings" );
+
+ m_dirView->readConfig( config() );
+
+ slotViewDocumentHeader();
+ slotCheckDockWidgetStatus();
+}
+
+
+void K3bMainWindow::saveProperties( KConfig* c )
+{
+ // 1. put saved projects in the config
+ // 2. save every modified project in "~/.kde/share/apps/k3b/sessions/" + KApp->sessionId()
+ // 3. save the url of the project (might be something like "AudioCD1") in the config
+ // 4. save the status of every project (modified/saved)
+
+ QString saveDir = KGlobal::dirs()->saveLocation( "appdata", "sessions/" + qApp->sessionId() + "/", true );
+
+ // FIXME: for some reason the config entries are not properly stored when using the default
+ // KMainWindow session config. Since I was not able to find the bug I use another config object
+ // ----------------------------------------------------------
+ c = new KSimpleConfig( saveDir + "list", false );
+ c->setGroup( "Saved Session" );
+ // ----------------------------------------------------------
+
+ const QPtrList<K3bDoc>& docs = k3bappcore->projectManager()->projects();
+ c->writeEntry( "Number of projects", docs.count() );
+
+ int cnt = 1;
+ for( QPtrListIterator<K3bDoc> it( docs ); *it; ++it ) {
+ // the "name" of the project (or the original url if isSaved())
+ c->writePathEntry( QString("%1 url").arg(cnt), (*it)->URL().url() );
+
+ // is the doc modified
+ c->writeEntry( QString("%1 modified").arg(cnt), (*it)->isModified() );
+
+ // has the doc already been saved?
+ c->writeEntry( QString("%1 saved").arg(cnt), (*it)->isSaved() );
+
+ // where does the session management save it? If it's not modified and saved this is
+ // the same as the url
+ KURL saveUrl = (*it)->URL();
+ if( !(*it)->isSaved() || (*it)->isModified() )
+ saveUrl = KURL::fromPathOrURL( saveDir + QString::number(cnt) );
+ c->writePathEntry( QString("%1 saveurl").arg(cnt), saveUrl.url() );
+
+ // finally save it
+ k3bappcore->projectManager()->saveProject( *it, saveUrl );
+
+ ++cnt;
+ }
+
+ // FIXME: for some reason the config entries are not properly stored when using the default
+ // KMainWindow session config. Since I was not able to find the bug I use another config object
+ // ----------------------------------------------------------
+ delete c;
+ // ----------------------------------------------------------
+}
+
+
+// FIXME:move this to K3bProjectManager
+void K3bMainWindow::readProperties( KConfig* c )
+{
+ // FIXME: do not delete the files here. rather do it when the app is exited normally
+ // since that's when we can be sure we never need the session stuff again.
+
+ // 1. read all projects from the config
+ // 2. simply open all of themg
+ // 3. reset the saved urls and the modified state
+ // 4. delete "~/.kde/share/apps/k3b/sessions/" + KApp->sessionId()
+
+ QString saveDir = KGlobal::dirs()->saveLocation( "appdata", "sessions/" + qApp->sessionId() + "/", true );
+
+ // FIXME: for some reason the config entries are not properly stored when using the default
+ // KMainWindow session config. Since I was not able to find the bug I use another config object
+ // ----------------------------------------------------------
+ c = new KSimpleConfig( saveDir + "list", true );
+ c->setGroup( "Saved Session" );
+ // ----------------------------------------------------------
+
+ int cnt = c->readNumEntry( "Number of projects", 0 );
+ kdDebug() << "(K3bMainWindow::readProperties) number of projects from last session in " << saveDir << ": " << cnt << endl
+ << " read from config group " << c->group() << endl;
+
+ for( int i = 1; i <= cnt; ++i ) {
+ // in this case the constructor works since we saved as url()
+ KURL url = c->readPathEntry( QString("%1 url").arg(i) );
+
+ bool modified = c->readBoolEntry( QString("%1 modified").arg(i) );
+
+ bool saved = c->readBoolEntry( QString("%1 saved").arg(i) );
+
+ KURL saveUrl = c->readPathEntry( QString("%1 saveurl").arg(i) );
+
+ // now load the project
+ if( K3bDoc* doc = k3bappcore->projectManager()->openProject( saveUrl ) ) {
+
+ // reset the url
+ doc->setURL( url );
+ doc->setModified( modified );
+ doc->setSaved( saved );
+ }
+ else
+ kdDebug() << "(K3bMainWindow) could not open session saved doc " << url.path() << endl;
+
+ // remove the temp file
+ if( !saved || modified )
+ QFile::remove( saveUrl.path() );
+ }
+
+ // and now remove the temp dir
+ KIO::del( KURL::fromPathOrURL(saveDir), false, false );
+
+ // FIXME: for some reason the config entries are not properly stored when using the default
+ // KMainWindow session config. Since I was not able to find the bug I use another config object
+ // ----------------------------------------------------------
+ delete c;
+ // ----------------------------------------------------------
+}
+
+
+bool K3bMainWindow::queryClose()
+{
+ //
+ // Check if a job is currently running
+ // For now K3b only allows for one major job at a time which means that we only need to cancel
+ // this one job.
+ //
+ if( k3bcore->jobsRunning() ) {
+
+ // pitty, but I see no possibility to make this work. It always crashes because of the event
+ // management thing mentioned below. So until I find a solution K3b simply will refuse to close
+ // while a job i running
+ return false;
+
+// kdDebug() << "(K3bMainWindow::queryClose) jobs running." << endl;
+// K3bJob* job = k3bcore->runningJobs().getFirst();
+
+// // now search for the major job (to be on the safe side although for now no subjobs register with the k3bcore)
+// K3bJobHandler* jh = job->jobHandler();
+// while( jh->isJob() ) {
+// job = static_cast<K3bJob*>( jh );
+// jh = job->jobHandler();
+// }
+
+// kdDebug() << "(K3bMainWindow::queryClose) main job found: " << job->jobDescription() << endl;
+
+// // now job is the major job and jh should be a widget
+// QWidget* progressDialog = dynamic_cast<QWidget*>( jh );
+
+// kdDebug() << "(K3bMainWindow::queryClose) job active: " << job->active() << endl;
+
+// // now ask the user if he/she really wants to cancel this job
+// if( job->active() ) {
+// if( KMessageBox::questionYesNo( progressDialog ? progressDialog : this,
+// i18n("Do you really want to cancel?"),
+// i18n("Cancel") ) == KMessageBox::Yes ) {
+// // cancel the job
+// kdDebug() << "(K3bMainWindow::queryClose) canceling job." << endl;
+// job->cancel();
+
+// // wait for the job to finish
+// kdDebug() << "(K3bMainWindow::queryClose) waiting for job to finish." << endl;
+// K3bSignalWaiter::waitForJob( job );
+
+// // close the progress dialog
+// if( progressDialog ) {
+// kdDebug() << "(K3bMainWindow::queryClose) closing progress dialog." << endl;
+// progressDialog->close();
+// //
+// // now here we have the problem that due to the whole Qt event thing the exec call (or
+// // in this case most likely the startJob call) does not return until we leave this method.
+// // That means that the progress dialog might be deleted by it's parent below (when we
+// // close docs) before it is deleted by the creator (most likely a projectburndialog).
+// // That would result in a double deletion and thus a crash.
+// // So we just reparent the dialog to 0 here so it's (former) parent won't delete it.
+// //
+// progressDialog->reparent( 0, QPoint(0,0) );
+// }
+
+// kdDebug() << "(K3bMainWindow::queryClose) job cleanup done." << endl;
+// }
+// else
+// return false;
+// }
+ }
+
+ //
+ // if we are closed by the session manager everything is fine since we store the
+ // current state in saveProperties
+ //
+ if( kapp->sessionSaving() )
+ return true;
+
+ // FIXME: do not close the docs here. Just ask for them to be saved and return false
+ // if the user chose cancel for some doc
+
+ // ---------------------------------
+ // we need to manually close all the views to ensure that
+ // each of them receives a close-event and
+ // the user is asked for every modified doc to save the changes
+ // ---------------------------------
+
+ while( K3bView* view = activeView() ) {
+ if( !canCloseDocument(view->doc()) )
+ return false;
+ closeProject(view->doc());
+ }
+
+ return true;
+}
+
+
+bool K3bMainWindow::canCloseDocument( K3bDoc* doc )
+{
+ if( !doc->isModified() )
+ return true;
+
+ if( !KConfigGroup( config(), "General Options" ).readBoolEntry( "ask_for_saving_changes_on_exit", true ) )
+ return true;
+
+ switch ( KMessageBox::warningYesNoCancel( this,
+ i18n("%1 has unsaved data.").arg( doc->URL().fileName() ),
+ i18n("Closing Project"),
+ KStdGuiItem::save(),
+ KGuiItem( i18n("&Discard"), "editshred" ) ) )
+ {
+ case KMessageBox::Yes:
+ fileSave( doc );
+ case KMessageBox::No:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool K3bMainWindow::queryExit()
+{
+ // TODO: call this in K3bApplication somewhere
+ saveOptions();
+ return true;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATION
+/////////////////////////////////////////////////////////////////////
+
+
+void K3bMainWindow::slotFileOpen()
+{
+ slotStatusMsg(i18n("Opening file..."));
+
+ KURL::List urls = KFileDialog::getOpenURLs( ":k3b-projects-folder",
+ i18n("*.k3b|K3b Projects"),
+ this,
+ i18n("Open Files") );
+ for( KURL::List::iterator it = urls.begin(); it != urls.end(); ++it ) {
+ openDocument( *it );
+ actionFileOpenRecent->addURL( *it );
+ }
+}
+
+void K3bMainWindow::slotFileOpenRecent(const KURL& url)
+{
+ slotStatusMsg(i18n("Opening file..."));
+
+ openDocument(url);
+}
+
+
+void K3bMainWindow::slotFileSaveAll()
+{
+ for( QPtrListIterator<K3bDoc> it( k3bappcore->projectManager()->projects() );
+ *it; ++it ) {
+ fileSave( *it );
+ }
+}
+
+
+void K3bMainWindow::slotFileSave()
+{
+ if( K3bDoc* doc = activeDoc() ) {
+ fileSave( doc );
+ }
+}
+
+void K3bMainWindow::fileSave( K3bDoc* doc )
+{
+ slotStatusMsg(i18n("Saving file..."));
+
+ if( doc == 0 ) {
+ doc = activeDoc();
+ }
+ if( doc != 0 ) {
+ if( !doc->isSaved() )
+ fileSaveAs( doc );
+ else if( !k3bappcore->projectManager()->saveProject( doc, doc->URL()) )
+ KMessageBox::error (this,i18n("Could not save the current document!"), i18n("I/O Error"));
+ }
+}
+
+
+void K3bMainWindow::slotFileSaveAs()
+{
+ if( K3bDoc* doc = activeDoc() ) {
+ fileSaveAs( doc );
+ }
+}
+
+
+void K3bMainWindow::fileSaveAs( K3bDoc* doc )
+{
+ slotStatusMsg(i18n("Saving file with a new filename..."));
+
+ if( doc == 0 ) {
+ doc = activeDoc();
+ }
+
+ if( doc != 0 ) {
+ // we do not use the static KFileDialog method here to be able to specify a filename suggestion
+ KFileDialog dlg( ":k3b-projects-folder", i18n("*.k3b|K3b Projects"), this, "filedialog", true );
+ dlg.setCaption( i18n("Save As") );
+ dlg.setOperationMode( KFileDialog::Saving );
+ dlg.setSelection( doc->name() );
+ dlg.exec();
+ KURL url = dlg.selectedURL();
+
+ if( url.isValid() ) {
+ KRecentDocument::add( url );
+
+ bool exists = KIO::NetAccess::exists( url, false, 0 );
+ if( !exists ||
+ ( exists &&
+ KMessageBox::warningContinueCancel( this, i18n("Do you want to overwrite %1?").arg( url.prettyURL() ),
+ i18n("File Exists"), i18n("Overwrite") )
+ == KMessageBox::Continue ) ) {
+
+ if( !k3bappcore->projectManager()->saveProject( doc, url ) ) {
+ KMessageBox::error (this,i18n("Could not save the current document!"), i18n("I/O Error"));
+ return;
+ }
+ else
+ actionFileOpenRecent->addURL(url);
+ }
+ }
+ }
+}
+
+
+void K3bMainWindow::slotFileClose()
+{
+ slotStatusMsg(i18n("Closing file..."));
+ if( K3bView* pView = activeView() ) {
+ if( pView ) {
+ K3bDoc* pDoc = pView->doc();
+
+ if( canCloseDocument(pDoc) ) {
+ closeProject(pDoc);
+ }
+ }
+ }
+
+ slotCurrentDocChanged();
+}
+
+
+void K3bMainWindow::slotFileCloseAll()
+{
+ while( K3bView* pView = activeView() ) {
+ if( pView ) {
+ K3bDoc* pDoc = pView->doc();
+
+ if( canCloseDocument(pDoc) )
+ closeProject(pDoc);
+ else
+ break;
+ }
+ }
+
+ slotCurrentDocChanged();
+}
+
+
+void K3bMainWindow::closeProject( K3bDoc* doc )
+{
+ // unplug the actions
+ if( factory() ) {
+ if( d->lastDoc == doc ) {
+ factory()->removeClient( static_cast<K3bView*>(d->lastDoc->view()) );
+ d->lastDoc = 0;
+ }
+ }
+
+ // remove the view from the project tab
+ m_documentTab->removePage( doc->view() );
+
+ // remove the project from the manager
+ k3bappcore->projectManager()->removeProject( doc );
+
+ // delete view and doc
+ delete doc->view();
+ delete doc;
+}
+
+
+void K3bMainWindow::slotFileQuit()
+{
+ close();
+}
+
+
+void K3bMainWindow::slotViewStatusBar()
+{
+ //turn Statusbar on or off
+ if(actionViewStatusBar->isChecked()) {
+ statusBar()->show();
+ }
+ else {
+ statusBar()->hide();
+ }
+}
+
+
+void K3bMainWindow::slotStatusMsg(const QString &text)
+{
+ ///////////////////////////////////////////////////////////////////
+ // change status message permanently
+// statusBar()->clear();
+// statusBar()->changeItem(text,1);
+
+ statusBar()->message( text, 2000 );
+}
+
+
+void K3bMainWindow::slotSettingsConfigure()
+{
+ K3bOptionDialog d( this, "SettingsDialog", true );
+
+ d.exec();
+
+ // emit a changed signal every time since we do not know if the user selected
+ // "apply" and "cancel" or "ok"
+ emit configChanged( m_config );
+}
+
+
+void K3bMainWindow::showOptionDialog( int index )
+{
+ K3bOptionDialog d( this, "SettingsDialog", true );
+
+ d.showPage( index );
+
+ d.exec();
+
+ // emit a changed signal every time since we do not know if the user selected
+ // "apply" and "cancel" or "ok"
+ emit configChanged( m_config );
+}
+
+
+K3bDoc* K3bMainWindow::slotNewAudioDoc()
+{
+ slotStatusMsg(i18n("Creating new Audio CD Project."));
+
+ K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::AUDIO );
+
+ return doc;
+}
+
+K3bDoc* K3bMainWindow::slotNewDataDoc()
+{
+ slotStatusMsg(i18n("Creating new Data CD Project."));
+
+ K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::DATA );
+
+ return doc;
+}
+
+
+K3bDoc* K3bMainWindow::slotNewDvdDoc()
+{
+ slotStatusMsg(i18n("Creating new Data DVD Project."));
+
+ K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::DVD );
+
+ return doc;
+}
+
+
+K3bDoc* K3bMainWindow::slotContinueMultisession()
+{
+ return K3bDataSessionImportDialog::importSession( 0, this );
+}
+
+
+K3bDoc* K3bMainWindow::slotNewVideoDvdDoc()
+{
+ slotStatusMsg(i18n("Creating new VideoDVD Project."));
+
+ K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::VIDEODVD );
+
+ return doc;
+}
+
+
+K3bDoc* K3bMainWindow::slotNewMixedDoc()
+{
+ slotStatusMsg(i18n("Creating new Mixed Mode CD Project."));
+
+ K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::MIXED );
+
+ return doc;
+}
+
+K3bDoc* K3bMainWindow::slotNewVcdDoc()
+{
+ slotStatusMsg(i18n("Creating new Video CD Project."));
+
+ K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::VCD );
+
+ return doc;
+}
+
+
+K3bDoc* K3bMainWindow::slotNewMovixDoc()
+{
+ slotStatusMsg(i18n("Creating new eMovix CD Project."));
+
+ K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::MOVIX );
+
+ return doc;
+}
+
+
+K3bDoc* K3bMainWindow::slotNewMovixDvdDoc()
+{
+ slotStatusMsg(i18n("Creating new eMovix DVD Project."));
+
+ K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::MOVIX_DVD );
+
+ return doc;
+}
+
+
+void K3bMainWindow::slotCurrentDocChanged()
+{
+ // check the doctype
+ K3bView* v = activeView();
+ if( v ) {
+ k3bappcore->projectManager()->setActive( v->doc() );
+
+ //
+ // There are two possiblities to plug the project actions:
+ // 1. Through KXMLGUIClient::plugActionList
+ // This way we just ask the View for the actionCollection (which it should merge with
+ // the doc's) and plug it into the project menu.
+ // Advantage: easy and clear to handle
+ // Disadvantage: we may only plug all actions at once into one menu
+ //
+ // 2. Through merging the doc as a KXMLGUIClient
+ // This way every view is a KXMLGUIClient and it's GUI is just merged into the MainWindow's.
+ // Advantage: flexible
+ // Disadvantage: every view needs it's own XML file
+ //
+ //
+
+ if( factory() ) {
+ if( d->lastDoc )
+ factory()->removeClient( static_cast<K3bView*>(d->lastDoc->view()) );
+ factory()->addClient( v );
+ d->lastDoc = v->doc();
+ }
+ else
+ kdDebug() << "(K3bMainWindow) ERROR: could not get KXMLGUIFactory instance." << endl;
+ }
+ else
+ k3bappcore->projectManager()->setActive( 0L );
+
+ if( k3bappcore->projectManager()->isEmpty() ) {
+ slotStateChanged( "state_project_active", KXMLGUIClient::StateReverse );
+ }
+ else {
+ d->documentStack->raiseWidget( d->documentHull );
+ slotStateChanged( "state_project_active", KXMLGUIClient::StateNoReverse );
+ }
+
+ // make sure the document header is shown (or not)
+ slotViewDocumentHeader();
+}
+
+
+void K3bMainWindow::slotEditToolbars()
+{
+ saveMainWindowSettings( m_config, "main_window_settings" );
+ KEditToolbar dlg( factory() );
+ connect(&dlg, SIGNAL(newToolbarConfig()), SLOT(slotNewToolBarConfig()));
+ dlg.exec();
+}
+
+
+void K3bMainWindow::slotNewToolBarConfig()
+{
+ applyMainWindowSettings( m_config, "main_window_settings" );
+}
+
+
+bool K3bMainWindow::eject()
+{
+ KConfigGroup c( config(), "General Options" );
+ return !c.readBoolEntry( "No cd eject", false );
+}
+
+
+void K3bMainWindow::slotErrorMessage(const QString& message)
+{
+ KMessageBox::error( this, message );
+}
+
+
+void K3bMainWindow::slotWarningMessage(const QString& message)
+{
+ KMessageBox::sorry( this, message );
+}
+
+
+void K3bMainWindow::slotWriteCdImage()
+{
+ K3bCdImageWritingDialog d( this );
+ d.exec(false);
+}
+
+
+void K3bMainWindow::slotWriteDvdIsoImage()
+{
+ K3bIsoImageWritingDialog d( this );
+ d.exec(false);
+}
+
+
+void K3bMainWindow::slotWriteDvdIsoImage( const KURL& url )
+{
+ K3bIsoImageWritingDialog d( this );
+ d.setImage( url );
+ d.exec(false);
+}
+
+
+void K3bMainWindow::slotWriteCdImage( const KURL& url )
+{
+ K3bCdImageWritingDialog d( this );
+ d.setImage( url );
+ d.exec(false);
+}
+
+
+void K3bMainWindow::slotProjectAddFiles()
+{
+ K3bView* view = activeView();
+
+ if( view ) {
+ QStringList files = KFileDialog::getOpenFileNames( ":k3b-project-add-files",
+ i18n("*|All Files"),
+ this,
+ i18n("Select Files to Add to Project") );
+
+ KURL::List urls;
+ for( QStringList::ConstIterator it = files.begin();
+ it != files.end(); it++ ) {
+ KURL url;
+ url.setPath(*it);
+ urls.append( url );
+ }
+
+ if( !urls.isEmpty() )
+ view->addUrls( urls );
+ }
+ else
+ KMessageBox::error( this, i18n("Please create a project before adding files"), i18n("No Active Project"));
+}
+
+
+void K3bMainWindow::slotK3bSetup()
+{
+ KProcess p;
+ p << "kdesu" << "kcmshell k3bsetup2 --lang " + KGlobal::locale()->language();
+ if( !p.start( KProcess::DontCare ) )
+ KMessageBox::error( 0, i18n("Could not find kdesu to run K3bSetup with root privileges. "
+ "Please run it manually as root.") );
+}
+
+
+void K3bMainWindow::blankCdrw( K3bDevice::Device* dev )
+{
+ K3bBlankingDialog dlg( this, "blankingdialog" );
+ dlg.setDevice( dev );
+ dlg.exec(false);
+}
+
+
+void K3bMainWindow::slotBlankCdrw()
+{
+ blankCdrw( 0 );
+}
+
+
+void K3bMainWindow::formatDvd( K3bDevice::Device* dev )
+{
+ K3bDvdFormattingDialog d( this );
+ d.setDevice( dev );
+ d.exec(false);
+}
+
+
+void K3bMainWindow::slotFormatDvd()
+{
+ formatDvd( 0 );
+}
+
+
+void K3bMainWindow::cdCopy( K3bDevice::Device* dev )
+{
+ K3bCdCopyDialog d( this );
+ d.setReadingDevice( dev );
+ d.exec(false);
+}
+
+
+void K3bMainWindow::slotCdCopy()
+{
+ cdCopy( 0 );
+}
+
+
+void K3bMainWindow::dvdCopy( K3bDevice::Device* dev )
+{
+ K3bDvdCopyDialog d( this );
+ d.setReadingDevice( dev );
+ d.exec(false);
+}
+
+
+void K3bMainWindow::slotDvdCopy()
+{
+ dvdCopy( 0 );
+}
+
+
+// void K3bMainWindow::slotVideoDvdCopy()
+// {
+// K3bVideoDvdCopyDialog d( this );
+// d.exec();
+// }
+
+
+void K3bMainWindow::slotShowDirTreeView()
+{
+ m_dirTreeDock->changeHideShowState();
+ slotCheckDockWidgetStatus();
+}
+
+
+void K3bMainWindow::slotShowContentsView()
+{
+ m_contentsDock->changeHideShowState();
+ slotCheckDockWidgetStatus();
+}
+
+
+void K3bMainWindow::slotShowMenuBar()
+{
+ if( menuBar()->isVisible() )
+ menuBar()->hide();
+ else
+ menuBar()->show();
+}
+
+
+void K3bMainWindow::slotShowTips()
+{
+ KTipDialog::showTip( this, QString::null, true );
+}
+
+
+void K3bMainWindow::slotDirTreeDockHidden()
+{
+ actionViewDirTreeView->setChecked( false );
+}
+
+
+void K3bMainWindow::slotContentsDockHidden()
+{
+ actionViewContentsView->setChecked( false );
+}
+
+
+void K3bMainWindow::slotCheckDockWidgetStatus()
+{
+ actionViewContentsView->setChecked( m_contentsDock->isVisible() );
+ actionViewDirTreeView->setChecked( m_dirTreeDock->isVisible() );
+}
+
+
+void K3bMainWindow::slotViewDocumentHeader()
+{
+ if( actionViewDocumentHeader->isChecked() &&
+ !k3bappcore->projectManager()->isEmpty() ) {
+ m_documentHeader->show();
+ }
+ else {
+ m_documentHeader->hide();
+ }
+}
+
+
+K3bExternalBinManager* K3bMainWindow::externalBinManager() const
+{
+ return k3bcore->externalBinManager();
+}
+
+
+K3bDevice::DeviceManager* K3bMainWindow::deviceManager() const
+{
+ return k3bcore->deviceManager();
+}
+
+
+void K3bMainWindow::slotDataImportSession()
+{
+ if( activeView() ) {
+ if( K3bDataView* view = dynamic_cast<K3bDataView*>(activeView()) ) {
+ view->importSession();
+ }
+ }
+}
+
+
+void K3bMainWindow::slotDataClearImportedSession()
+{
+ if( activeView() ) {
+ if( K3bDataView* view = dynamic_cast<K3bDataView*>(activeView()) ) {
+ view->clearImportedSession();
+ }
+ }
+}
+
+
+void K3bMainWindow::slotEditBootImages()
+{
+ if( activeView() ) {
+ if( K3bDataView* view = dynamic_cast<K3bDataView*>(activeView()) ) {
+ view->editBootImages();
+ }
+ }
+}
+
+
+void K3bMainWindow::slotCheckSystemTimed()
+{
+ // run the system check from the event queue so we do not
+ // mess with the device state resetting throughout the app
+ // when called from K3bDeviceManager::changed
+ QTimer::singleShot( 0, this, SLOT(slotCheckSystem()) );
+}
+
+
+void K3bMainWindow::slotCheckSystem()
+{
+ K3bSystemProblemDialog::checkSystem( this );
+}
+
+
+void K3bMainWindow::addUrls( const KURL::List& urls )
+{
+ if( K3bView* view = activeView() ) {
+ view->addUrls( urls );
+ }
+ else {
+ // check if the files are all audio we can handle. If so create an audio project
+ bool audio = true;
+ QPtrList<K3bPlugin> fl = k3bcore->pluginManager()->plugins( "AudioDecoder" );
+ for( KURL::List::const_iterator it = urls.begin(); it != urls.end(); ++it ) {
+ const KURL& url = *it;
+
+ if( QFileInfo(url.path()).isDir() ) {
+ audio = false;
+ break;
+ }
+
+ bool a = false;
+ for( QPtrListIterator<K3bPlugin> it( fl ); it.current(); ++it ) {
+ if( static_cast<K3bAudioDecoderFactory*>(it.current())->canDecode( url ) ) {
+ a = true;
+ break;
+ }
+ }
+ if( !a ) {
+ audio = a;
+ break;
+ }
+ }
+
+ if( !audio && urls.count() == 1 ) {
+ // see if it's an audio cue file
+ K3bCueFileParser parser( urls.first().path() );
+ if( parser.isValid() && parser.toc().contentType() == K3bDevice::AUDIO ) {
+ audio = true;
+ }
+ }
+
+ if( audio )
+ static_cast<K3bView*>(slotNewAudioDoc()->view())->addUrls( urls );
+ else if( urls.count() > 1 || !isCdDvdImageAndIfSoOpenDialog( urls.first() ) )
+ static_cast<K3bView*>(slotNewDataDoc()->view())->addUrls( urls );
+ }
+}
+
+
+void K3bMainWindow::slotClearProject()
+{
+ K3bDoc* doc = k3bappcore->projectManager()->activeDoc();
+ if( doc ) {
+ if( KMessageBox::warningContinueCancel( this,
+ i18n("Do you really want to clear the current project?"),
+ i18n("Clear Project"),
+ i18n("Clear"),
+ "clear_current_project_dontAskAgain" ) == KMessageBox::Continue ) {
+ doc->newDocument();
+ k3bappcore->projectManager()->loadDefaults( doc );
+ }
+ }
+}
+
+
+bool K3bMainWindow::isCdDvdImageAndIfSoOpenDialog( const KURL& url )
+{
+ K3bIso9660 iso( url.path() );
+ if( iso.open() ) {
+ iso.close();
+ // very rough dvd image size test
+ if( K3b::filesize( url ) > 1000*1024*1024 )
+ slotWriteDvdIsoImage( url );
+ else
+ slotWriteCdImage( url );
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
+void K3bMainWindow::slotCddaRip()
+{
+ cddaRip( 0 );
+}
+
+
+void K3bMainWindow::cddaRip( K3bDevice::Device* dev )
+{
+ if( !dev ||
+ !(k3bappcore->mediaCache()->medium( dev ).content() & K3bMedium::CONTENT_AUDIO ) )
+ dev = K3bMediaSelectionDialog::selectMedium( K3bDevice::MEDIA_CD_ALL,
+ K3bDevice::STATE_COMPLETE|K3bDevice::STATE_INCOMPLETE,
+ K3bMedium::CONTENT_AUDIO,
+ this,
+ i18n("Audio CD Rip") );
+
+ if( dev )
+ m_dirView->showDevice( dev );
+}
+
+
+void K3bMainWindow::videoDvdRip( K3bDevice::Device* dev )
+{
+ if( !dev ||
+ !(k3bappcore->mediaCache()->medium( dev ).content() & K3bMedium::CONTENT_VIDEO_DVD ) )
+ dev = K3bMediaSelectionDialog::selectMedium( K3bDevice::MEDIA_DVD_ALL,
+ K3bDevice::STATE_COMPLETE,
+ K3bMedium::CONTENT_VIDEO_DVD,
+ this,
+ i18n("Video DVD Rip") );
+
+ if( dev )
+ m_dirView->showDevice( dev );
+}
+
+
+void K3bMainWindow::slotVideoDvdRip()
+{
+ videoDvdRip( 0 );
+}
+
+
+void K3bMainWindow::videoCdRip( K3bDevice::Device* dev )
+{
+ if( !dev ||
+ !(k3bappcore->mediaCache()->medium( dev ).content() & K3bMedium::CONTENT_VIDEO_CD ) )
+ dev = K3bMediaSelectionDialog::selectMedium( K3bDevice::MEDIA_CD_ALL,
+ K3bDevice::STATE_COMPLETE,
+ K3bMedium::CONTENT_VIDEO_CD,
+ this,
+ i18n("Video CD Rip") );
+
+ if( dev )
+ m_dirView->showDevice( dev );
+}
+
+
+void K3bMainWindow::slotVideoCdRip()
+{
+ videoCdRip( 0 );
+}
+
+
+void K3bMainWindow::slotAudioServerError( const QString& error )
+{
+ K3bPassivePopup::showPopup( error, i18n("Audio Output Problem") );
+}
+
+#include "k3b.moc"
+
diff --git a/src/k3b.desktop b/src/k3b.desktop
new file mode 100644
index 0000000..e6c107b
--- /dev/null
+++ b/src/k3b.desktop
@@ -0,0 +1,123 @@
+[Desktop Entry]
+Type=Application
+Exec=k3b %U
+Icon=k3b
+DocPath=k3b/index.html
+GenericName=CD & DVD Burning
+GenericName[af]=CD & DVD Skrywer
+GenericName[ar]= اعداد كتابة القرص المدمج(CD) و القرص المرئي الرقمي (DVD)
+GenericName[bg]=Запис на CD и DVD
+GenericName[bn]=সিডি এবং ডিভিডি লিখন
+GenericName[br]=Skrivañ CD ha DVD
+GenericName[bs]=CD & DVD prženje
+GenericName[ca]=Programa per gravar CDs i DVDs
+GenericName[cs]=Vypalování CD a DVD
+GenericName[da]=Cd & dvd-skriveprogram
+GenericName[de]=CD & DVD-Brennen
+GenericName[el]=Εγγραφή CD & DVD
+GenericName[eo]=KD & DVD enskribo
+GenericName[es]=Grabación de CD y DVD
+GenericName[et]=CD ja DVD kirjutamine
+GenericName[fa]=سوزاندن دیسک فشرده و دی وی دی
+GenericName[fi]=Poltto-ohjelma
+GenericName[fr]=Gravure de CD et DVD
+GenericName[gl]=Gravazón de CDs e DVDs
+GenericName[he]=צרינת תקליטורי CD & DVD
+GenericName[hi]=सीडी & डीवीडी बर्निंग
+GenericName[hu]=CD- és DVD-író
+GenericName[is]=CD og DVD brennsla
+GenericName[it]=Masterizzazione CD e DVD
+GenericName[ja]=CD / DVD 作成
+GenericName[ka]=CD-ის და DVD-ის ჩანაწერა
+GenericName[km]=ការ​ដុត​ស៊ីឌី & ឌីវីឌី
+GenericName[lt]=CD ir DVD kūrimas
+GenericName[mk]=Снимање на CD и DVD
+GenericName[ms]=Membakar CD & DVD
+GenericName[nb]=CD- og DVD-brenning
+GenericName[nds]=Brennen vun CD & DVD
+GenericName[ne]=सीडी र डीभीडी बर्निङ
+GenericName[nl]=CD- en dvd-brandprogramma
+GenericName[nn]=CD- og DVD-brenning
+GenericName[pa]=CD & DVD ਲਿਖਣ ਲਈ
+GenericName[pl]=Nagrywanie płyt CD i DVD
+GenericName[pt]=Gravação de CDs e DVDs
+GenericName[pt_BR]=Queima de CD & DVD
+GenericName[ru]=Запись CD и DVD
+GenericName[sk]=Napaľovanie CD & DVD
+GenericName[sl]=Pisanje CD-jev in DVD-jev
+GenericName[sr]=Резање CD-а и DVD-а
+GenericName[sr@Latn]=Rezanje CD-a i DVD-a
+GenericName[sv]=Cd och dvd-brännprogram
+GenericName[ta]=சிடி எழுதும் தகவல்
+GenericName[tg]=Сабти CD ва DVD
+GenericName[tr]=CD ve DVD Kaydedici
+GenericName[uk]=Запис КД та DVD
+GenericName[uz]=CD va DVD disklarga yozish
+GenericName[uz@cyrillic]=CD ва DVD дискларга ёзиш
+GenericName[zh_CN]=CD & DVD 烧录程序
+GenericName[zh_TW]=CD & DVD 燒錄
+Comment=CD writing program
+Comment[af]=CD skryf program
+Comment[ar]=برنامج لكتابة الاقراص المدمجة CD
+Comment[bg]=Програма за запис на CD
+Comment[bn]=সিডি লিখন প্রোগ্র্যাম
+Comment[br]=Program skriver CD
+Comment[bs]=Program za prženje CDova
+Comment[ca]=Programa gravador de CDs
+Comment[cs]=Program pro vypalování CD
+Comment[da]=Cd-skriveprogram
+Comment[de]=CD-Brennprogramm
+Comment[el]=Πρόγραμμα εγγραφής CD
+Comment[eo]=KD skribilo
+Comment[es]=Programa de grabación de CD
+Comment[et]=CD kirjutamise rakendus
+Comment[fa]=برنامۀ نوشتن دیسک فشرده
+Comment[fi]=Poltto-ohjelma
+Comment[fr]=Programme de gravure de CD
+Comment[gl]=Un programa de gravazón de CDs
+Comment[he]=תוכנית צריבת תקליטורים
+Comment[hi]=सीडी लिखने का प्रोग्राम
+Comment[hu]=CD-író program
+Comment[is]=CD skrifunarforrit
+Comment[it]=Programma di masterizzazione
+Comment[ja]=CD 書き込みプログラム
+Comment[ka]=CD-ის ჩამწერი პროგრამა
+Comment[km]=កម្មវិធី​សរសេរ​ស៊ីឌី
+Comment[lt]=CD įrašymo programa
+Comment[mk]=Програма за снимање на CD
+Comment[ms]=Program menulis CD
+Comment[nb]=CD-brenningsprogram
+Comment[nds]=CD-Schriefprogramm
+Comment[ne]=सीडी लेख्ने कार्यक्रम
+Comment[nl]=CD-brandprogramma
+Comment[nn]=CD-brenneprogram
+Comment[pa]=CD ਲਿਖਣ ਕਾਰਜ
+Comment[pl]=Program do nagrywania płyt CD
+Comment[pt]=Um programa de gravação de CDs
+Comment[pt_BR]=Programa de gravação em CD
+Comment[ru]=Программа записи на CD
+Comment[sk]=CD vypaľovací program
+Comment[sl]=Program za pisanje CD-jev
+Comment[sr]=Програм за писање CD-а
+Comment[sr@Latn]=Program za pisanje CD-a
+Comment[sv]=Cd-brännprogram
+Comment[ta]=குறுந்தகட்டில் எழுதும் நிரல்
+Comment[tg]=Барномаи сабти компакт-дискҳо
+Comment[tr]=CD yazdırma programı
+Comment[uk]=Програма запису КД
+Comment[uz]=Kompakt-diskka yozish dasturi
+Comment[uz@cyrillic]=Компакт-дискка ёзиш дастури
+Comment[xh]=Ubhalo lwe Cd lodweiso Iwenkqubo
+Comment[zh_CN]=CD 刻录程序
+Comment[zh_TW]=CD 燒錄程式
+Comment[zu]=Uhlelo lwemisebenzi olubhala i-CD
+Terminal=false
+Name=K3b
+Name[ar]= K3b
+Name[bn]=কে-থ্রি-বি
+Name[hi]=के3बी
+MimeType=application/x-k3b;application/x-iso;application/x-cue
+X-KDE-StartupNotify=true
+X-KDE-NativeMimeType=application/x-k3b;application/x-iso;application/x-cue
+Categories=KDE;Application;AudioVideo;DiscBurning;
+X-DCOP-ServiceType=Unique
diff --git a/src/k3b.h b/src/k3b.h
new file mode 100644
index 0000000..37532b0
--- /dev/null
+++ b/src/k3b.h
@@ -0,0 +1,330 @@
+/*
+ *
+ * $Id: k3b.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+
+#ifndef K3B_H
+#define K3B_H
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// include files for Qt
+#include <qstrlist.h>
+#include <qworkspace.h>
+#include <qptrlist.h>
+
+// include files for KDE
+#include <kapplication.h>
+#include <kparts/dockmainwindow.h>
+#include <kdockwidget.h>
+#include <kaction.h>
+#include <kurl.h>
+
+class QVBox;
+
+
+// forward declaration of the K3b classes
+class K3bMainWindow;
+class K3bDoc;
+class K3bView;
+class K3bDirView;
+class K3bExternalBinManager;
+class K3bOptionDialog;
+class K3bJob;
+class K3bProjectTabWidget;
+class K3bSongManager;
+class KSystemTray;
+class K3bStatusBarManager;
+class K3bProjectInterface;
+class K3bThemedHeader;
+
+namespace K3bDevice {
+ class DeviceManager;
+ class Device;
+}
+
+
+class K3bMainWindow : public KParts::DockMainWindow
+{
+ Q_OBJECT
+
+ public:
+ /** construtor of K3bMainWindow, calls all init functions to create the application.
+ * @see initMenuBar initToolBar
+ */
+ K3bMainWindow();
+ ~K3bMainWindow();
+
+ /** opens a file specified by commandline option */
+ K3bDoc* openDocument( const KURL& url = KURL() );
+
+ K3bDevice::DeviceManager* deviceManager() const;
+ K3bExternalBinManager* externalBinManager() const;
+ KConfig* config() const { return m_config; }
+ // return main window with browser/cd/dvd view, used for DND
+ K3bDirView* mainWindow() const { return m_dirView; }
+ /**
+ * @returns a pointer to the currently visible view or 0 if no project was created
+ */
+ K3bView* activeView() const;
+ /**
+ * @returns a pointer to the doc associated with the currently visible view or 0 if no project was created
+ */
+ K3bDoc* activeDoc() const;
+
+ const QPtrList<K3bDoc>& projects() const;
+
+ bool eject();
+ void showOptionDialog( int = 0 );
+
+ /** Creates the main view of the KDockMainWindow instance and initializes the MDI view area including any needed
+ * connections.
+ * must be called after construction
+ */
+ void initView();
+
+ KSystemTray* systemTray() const { return m_systemTray; }
+
+ public slots:
+ K3bDoc* slotNewAudioDoc();
+ K3bDoc* slotNewDataDoc();
+ K3bDoc* slotNewMixedDoc();
+ K3bDoc* slotNewVcdDoc();
+ K3bDoc* slotNewMovixDoc();
+ K3bDoc* slotNewMovixDvdDoc();
+ K3bDoc* slotNewDvdDoc();
+ K3bDoc* slotNewVideoDvdDoc();
+ K3bDoc* slotContinueMultisession();
+
+ void slotClearProject();
+
+ void blankCdrw( K3bDevice::Device* );
+ void slotBlankCdrw();
+ void formatDvd( K3bDevice::Device* );
+ void slotFormatDvd();
+ void slotWriteCdImage();
+ void slotWriteCdImage( const KURL& url );
+ void slotWriteDvdIsoImage();
+ void slotWriteDvdIsoImage( const KURL& url );
+ void cdCopy( K3bDevice::Device* );
+ void slotCdCopy();
+ void dvdCopy( K3bDevice::Device* );
+ void slotDvdCopy();
+ void cddaRip( K3bDevice::Device* );
+ void slotCddaRip();
+ void videoDvdRip( K3bDevice::Device* );
+ void slotVideoDvdRip();
+ void videoCdRip( K3bDevice::Device* );
+ void slotVideoCdRip();
+ void slotK3bSetup();
+
+ void slotErrorMessage(const QString&);
+ void slotWarningMessage(const QString&);
+
+ void slotConfigureKeys();
+ void slotShowTips();
+ void slotCheckSystem();
+
+ void addUrls( const KURL::List& urls );
+
+ signals:
+ void initializationInfo( const QString& );
+ void configChanged( KConfig* c );
+
+ protected:
+ /** queryClose is called by KTMainWindow on each closeEvent of a window. Against the
+ * default implementation (only returns true), this overridden function retrieves all modified documents
+ * from the open document list and asks the user to select which files to save before exiting the application.
+ * @see KTMainWindow#queryClose
+ * @see KTMainWindow#closeEvent
+ */
+ virtual bool queryClose();
+
+ /** queryExit is called by KTMainWindow when the last window of the application is going to be closed during the closeEvent().
+ * Against the default implementation that just returns true, this calls saveOptions() to save the settings of the last window's
+ * properties.
+ * @see KTMainWindow#queryExit
+ * @see KTMainWindow#closeEvent
+ */
+ virtual bool queryExit();
+
+ /** saves the window properties for each open window during session end to the session config file, including saving the currently
+ * opened file by a temporary filename provided by KApplication.
+ * @see KTMainWindow#saveProperties
+ */
+ virtual void saveProperties(KConfig *_cfg);
+
+ /** reads the session config file and restores the application's state including the last opened files and documents by reading the
+ * temporary files saved by saveProperties()
+ * @see KTMainWindow#readProperties
+ */
+ virtual void readProperties(KConfig *_cfg);
+
+ /**
+ * checks if doc is modified and asks the user for saving if so.
+ * returns false if the user chose cancel.
+ */
+ bool canCloseDocument( K3bDoc* );
+
+ virtual void showEvent( QShowEvent* e );
+
+ private slots:
+ /** open a file and load it into the document*/
+ void slotFileOpen();
+ /** opens a file from the recent files menu */
+ void slotFileOpenRecent(const KURL& url);
+ /** save a document */
+ void slotFileSave();
+ /** save a document by a new filename*/
+ void slotFileSaveAs();
+ void slotFileSaveAll();
+ /** asks for saving if the file is modified, then closes the actual file and window*/
+ void slotFileClose();
+ void slotFileCloseAll();
+
+ void slotDirTreeDockHidden();
+ void slotContentsDockHidden();
+
+ void slotSettingsConfigure();
+
+ /** checks if the currently visible tab is a k3bview
+ or not and dis- or enables some actions */
+ void slotCurrentDocChanged();
+
+ void slotFileQuit();
+
+ /** toggles the statusbar
+ */
+ void slotViewStatusBar();
+
+ void slotViewDocumentHeader();
+
+ void slotCheckDockWidgetStatus();
+
+ /** changes the statusbar contents for the standard label permanently, used to indicate current actions.
+ * @param text the text that is displayed in the statusbar
+ */
+ void slotStatusMsg(const QString &text);
+
+ void slotShowDirTreeView();
+ void slotShowContentsView();
+ void slotShowMenuBar();
+
+ void slotProjectAddFiles();
+
+ void slotEditToolbars();
+ void slotNewToolBarConfig();
+
+ void slotDataImportSession();
+ void slotDataClearImportedSession();
+ void slotEditBootImages();
+
+ void slotAudioServerError( const QString& error );
+
+ void createClient(K3bDoc* doc);
+
+ /**
+ * Run slotCheckSystem with a timer
+ */
+ void slotCheckSystemTimed();
+
+ private:
+ void fileSave( K3bDoc* doc = 0 );
+ void fileSaveAs( K3bDoc* doc = 0 );
+ void closeProject( K3bDoc* );
+
+ /** save general Options like all bar positions and status as well as the geometry and the recent file list to the configuration
+ * file
+ */
+ void saveOptions();
+ /** read general Options again and initialize all variables like the recent file list */
+ void readOptions();
+
+ /** initializes the KActions of the application */
+ void initActions();
+
+ /** sets up the statusbar for the main window by initialzing a statuslabel.
+ */
+ void initStatusBar();
+
+ bool isCdDvdImageAndIfSoOpenDialog( const KURL& url );
+
+ /** the configuration object of the application */
+ KConfig *m_config;
+
+ /** The MDI-Interface is managed by this tabbed view */
+ K3bProjectTabWidget* m_documentTab;
+
+ // KAction pointers to enable/disable actions
+ KActionMenu* actionFileNewMenu;
+ KAction* actionFileNewAudio;
+ KAction* actionFileNewData;
+ KAction* actionFileNewMixed;
+ KAction* actionFileNewVcd;
+ KAction* actionFileNewMovix;
+ KAction* actionFileNewMovixDvd;
+ KAction* actionFileNewDvd;
+ KAction* actionFileNewVideoDvd;
+ KAction* actionFileContinueMultisession;
+ KAction* actionFileOpen;
+ KRecentFilesAction* actionFileOpenRecent;
+ KAction* actionFileSave;
+ KAction* actionFileSaveAs;
+ KAction* actionFileSaveAll;
+ KAction* actionFileClose;
+ KAction* actionFileCloseAll;
+ KAction* actionFileQuit;
+ KAction* actionSettingsConfigure;
+ KAction* actionSettingsK3bSetup;
+ KAction* actionToolsBlankCdrw;
+ KAction* actionToolsWriteCdImage;
+ KAction* actionToolsCddaRip;
+ KAction* actionToolsVideoDvdRip;
+ KAction* actionToolsVideoCdRip;
+ KAction* actionCdCopy;
+ KAction* actionProjectAddFiles;
+ KToggleAction* actionViewStatusBar;
+ KToggleAction* actionViewDirTreeView;
+ KToggleAction* actionViewContentsView;
+ KToggleAction* actionViewDocumentHeader;
+
+ // project actions
+ QPtrList<KAction> m_dataProjectActions;
+
+ KDockWidget* mainDock;
+ KDockWidget* m_contentsDock;
+ KDockWidget* m_dirTreeDock;
+
+ // The K3b-specific widgets
+ K3bDirView* m_dirView;
+ K3bOptionDialog* m_optionDialog;
+
+ K3bStatusBarManager* m_statusBarManager;
+
+ KSystemTray* m_systemTray;
+
+ bool m_initialized;
+
+ // the funny header
+ K3bThemedHeader* m_documentHeader;
+
+ class Private;
+ Private* d;
+};
+
+#endif // K3B_H
diff --git a/src/k3bappdevicemanager.cpp b/src/k3bappdevicemanager.cpp
new file mode 100644
index 0000000..c21f746
--- /dev/null
+++ b/src/k3bappdevicemanager.cpp
@@ -0,0 +1,304 @@
+/*
+ *
+ * $Id: sourceheader 380067 2005-01-19 13:03:46Z trueg $
+ * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include "k3bappdevicemanager.h"
+
+#include <k3bdevice.h>
+#include <k3bdevicehandler.h>
+#include <k3bglobals.h>
+#include <k3bapplication.h>
+#include <k3bmediacache.h>
+
+#include <kaction.h>
+#include <kinputdialog.h>
+#include <kmessagebox.h>
+#include <kinputdialog.h>
+#include <kio/job.h>
+#include <klocale.h>
+#include <kio/global.h>
+#include <kpopupmenu.h>
+
+
+K3bAppDeviceManager::K3bAppDeviceManager( QObject* parent, const char* name )
+ : K3bDevice::DeviceManager( parent, name ),
+ m_currentDevice(0),
+ m_ejectRequested(false)
+{
+ // FIXME: should we pass the mainwindow as watch window here?
+ // Is there a proper way to insert this actioncollection into the mainwindow's?
+ m_actionCollection = new KActionCollection( this );
+
+ // setup actions
+ KActionMenu* devicePopupMenu = new KActionMenu( m_actionCollection, "device_popup" );
+ m_actionDiskInfo = new KAction( i18n("Media &Info"), "info", 0, this, SLOT(diskInfo()),
+ m_actionCollection, "device_diskinfo");
+ m_actionUnmount = new KAction( i18n("&Unmount"), "cdrom_unmount", 0, this, SLOT(unmountDisk()),
+ m_actionCollection, "device_unmount");
+ m_actionMount = new KAction( i18n("&Mount"), "cdrom_mount", 0, this, SLOT(mountDisk()),
+ m_actionCollection, "device_mount");
+ m_actionEject = new KAction( i18n("&Eject"), "", 0, this, SLOT(ejectDisk()),
+ m_actionCollection, "device_eject");
+ m_actionLoad = new KAction( i18n("L&oad"), "", 0, this, SLOT(loadDisk()),
+ m_actionCollection, "device_load");
+// KAction* actionUnlock = new KAction( i18n("Un&lock"), "", 0, this, SLOT(unlockDevice()),
+// m_actionCollection, "device_unlock" );
+// KAction* actionlock = new KAction( i18n("Loc&k"), "", 0, this, SLOT(lockDevice()),
+// m_actionCollection, "device_lock" );
+ m_actionSetReadSpeed = new KAction( i18n("Set Read Speed..."), "", 0, this, SLOT(setReadSpeed()),
+ m_actionCollection, "device_set_read_speed" );
+
+ m_actionDiskInfo->setToolTip( i18n("Display generic medium information") );
+ m_actionUnmount->setToolTip( i18n("Unmount the medium") );
+ m_actionMount->setToolTip( i18n("Mount the medium") );
+ m_actionEject->setToolTip( i18n("Eject the medium") );
+ m_actionLoad->setToolTip( i18n("(Re)Load the medium") );
+ m_actionSetReadSpeed->setToolTip( i18n("Force the drive's read speed") );
+
+ devicePopupMenu->insert( m_actionDiskInfo );
+ devicePopupMenu->insert( new KActionSeparator( this ) );
+ devicePopupMenu->insert( m_actionUnmount );
+ devicePopupMenu->insert( m_actionMount );
+ devicePopupMenu->insert( new KActionSeparator( this ) );
+ devicePopupMenu->insert( m_actionEject );
+ devicePopupMenu->insert( m_actionLoad );
+// devicePopupMenu->insert( new KActionSeparator( this ) );
+// devicePopupMenu->insert( actionUnlock );
+// devicePopupMenu->insert( actionlock );
+ devicePopupMenu->insert( new KActionSeparator( this ) );
+ devicePopupMenu->insert( m_actionSetReadSpeed );
+
+ setCurrentDevice( 0 );
+}
+
+
+void K3bAppDeviceManager::setMediaCache( K3bMediaCache* c )
+{
+ connect( c, SIGNAL(mediumChanged(K3bDevice::Device*)),
+ this, SLOT(slotMediumChanged(K3bDevice::Device*)) );
+}
+
+
+int K3bAppDeviceManager::scanBus()
+{
+ return K3bDevice::DeviceManager::scanBus();
+}
+
+
+K3bDevice::Device* K3bAppDeviceManager::currentDevice() const
+{
+ return m_currentDevice;
+}
+
+
+void K3bAppDeviceManager::clear()
+{
+ // make sure we do not use a deleted device
+ m_currentDevice = 0;
+ K3bDevice::DeviceManager::clear();
+}
+
+
+void K3bAppDeviceManager::removeDevice( const QString& dev )
+{
+ if( m_currentDevice == findDevice(dev) )
+ m_currentDevice = 0;
+
+ K3bDevice::DeviceManager::removeDevice( dev );
+
+ if( !m_currentDevice )
+ setCurrentDevice( allDevices().getFirst() );
+}
+
+
+K3bAppDeviceManager::~K3bAppDeviceManager()
+{
+}
+
+
+void K3bAppDeviceManager::slotMediumChanged( K3bDevice::Device* dev )
+{
+ m_actionDiskInfo->setEnabled( dev != 0 );
+ m_actionUnmount->setEnabled( dev != 0 );
+ m_actionMount->setEnabled( dev != 0 );
+ m_actionEject->setEnabled( dev != 0 );
+ m_actionLoad->setEnabled( dev != 0 );
+ m_actionSetReadSpeed->setEnabled( dev != 0 );
+
+ if( dev && dev == currentDevice() ) {
+ bool mounted = K3b::isMounted( dev );
+ bool mediumMountable = k3bappcore->mediaCache()->medium( dev ).content() & K3bMedium::CONTENT_DATA;
+ m_actionMount->setEnabled( !mounted && mediumMountable );
+ m_actionUnmount->setEnabled( mounted );
+ }
+}
+
+
+void K3bAppDeviceManager::setCurrentDevice( K3bDevice::Device* dev )
+{
+ if( dev && dev != m_currentDevice ) {
+ m_currentDevice = dev;
+ emit currentDeviceChanged( dev );
+ }
+
+ slotMediumChanged( dev );
+}
+
+
+void K3bAppDeviceManager::diskInfo()
+{
+ if( currentDevice() ) {
+ emit detectingDiskInfo( currentDevice() );
+ }
+}
+
+
+void K3bAppDeviceManager::unlockDevice()
+{
+ if( currentDevice() )
+ K3bDevice::unblock( currentDevice() );
+}
+
+
+void K3bAppDeviceManager::lockDevice()
+{
+ if( currentDevice() )
+ K3bDevice::block( currentDevice() );
+}
+
+
+void K3bAppDeviceManager::mountDisk()
+{
+ if ( currentDevice() ) {
+ // FIXME: make this non-blocking
+ if( !K3b::isMounted( currentDevice() ) )
+ K3b::mount( currentDevice() );
+
+ emit mountFinished( KIO::findDeviceMountPoint( currentDevice()->blockDeviceName() ) );
+ }
+}
+
+
+void K3bAppDeviceManager::unmountDisk()
+{
+ if ( currentDevice() ) {
+ // FIXME: make this non-blocking
+ if( K3b::isMounted( currentDevice() ) )
+ emit unmountFinished( K3b::unmount( currentDevice() ) );
+ else
+ emit unmountFinished( true );
+ }
+}
+
+
+void K3bAppDeviceManager::ejectDisk()
+{
+ // FIXME: make this non-blocking
+ if ( currentDevice() )
+ K3b::eject( currentDevice() ); // just ignore errors here
+}
+
+
+void K3bAppDeviceManager::loadDisk()
+{
+ if( currentDevice() )
+ K3bDevice::reload( currentDevice() );
+}
+
+
+void K3bAppDeviceManager::setReadSpeed()
+{
+ if( currentDevice() ) {
+ bool ok = false;
+ int s = KInputDialog::getInteger( i18n("CD Read Speed"),
+ i18n("<p>Please enter the preferred read speed for <b>%1</b>. "
+ "This speed will be used for the currently mounted "
+ "medium."
+ "<p>This is especially useful to slow down the drive when "
+ "watching movies which are read directly from the drive "
+ "and the spinning noise is intrusive."
+ "<p>Be aware that this has no influence on K3b since it will "
+ "change the reading speed again when copying CDs or DVDs.")
+ .arg(currentDevice()->vendor() + " " + currentDevice()->description()),
+ 12,
+ 1,
+ currentDevice()->maxReadSpeed(),
+ 1,
+ 10,
+ &ok,
+ 0 );
+ if( ok ) {
+ if( !currentDevice()->setSpeed( s*175, 0xFFFF ) )
+ KMessageBox::error( 0, i18n("Setting the read speed failed.") );
+ }
+ }
+}
+
+
+void K3bAppDeviceManager::diskInfo( K3bDevice::Device* dev )
+{
+ setCurrentDevice( dev );
+ diskInfo();
+}
+
+
+void K3bAppDeviceManager::unlockDevice( K3bDevice::Device* dev )
+{
+ setCurrentDevice( dev );
+ unlockDevice();
+}
+
+
+void K3bAppDeviceManager::lockDevice( K3bDevice::Device* dev )
+{
+ setCurrentDevice( dev );
+ lockDevice();
+}
+
+
+void K3bAppDeviceManager::mountDisk( K3bDevice::Device* dev )
+{
+ setCurrentDevice( dev );
+ mountDisk();
+}
+
+
+void K3bAppDeviceManager::unmountDisk( K3bDevice::Device* dev )
+{
+ setCurrentDevice( dev );
+ unmountDisk();
+}
+
+
+void K3bAppDeviceManager::ejectDisk( K3bDevice::Device* dev )
+{
+ setCurrentDevice( dev );
+ ejectDisk();
+}
+
+
+void K3bAppDeviceManager::loadDisk( K3bDevice::Device* dev )
+{
+ setCurrentDevice( dev );
+ loadDisk();
+}
+
+
+void K3bAppDeviceManager::setReadSpeed( K3bDevice::Device* dev )
+{
+ setCurrentDevice( dev );
+ setReadSpeed();
+}
+
+#include "k3bappdevicemanager.moc"
diff --git a/src/k3bappdevicemanager.h b/src/k3bappdevicemanager.h
new file mode 100644
index 0000000..419a8b3
--- /dev/null
+++ b/src/k3bappdevicemanager.h
@@ -0,0 +1,119 @@
+/*
+ *
+ * $Id: sourceheader 380067 2005-01-19 13:03:46Z trueg $
+ * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#ifndef _K3B_APP_DEVICE_MANAGER_H_
+#define _K3B_APP_DEVICE_MANAGER_H_
+
+class KActionCollection;
+class KAction;
+class K3bMediaCache;
+
+namespace K3bDevice {
+ class Device;
+ class DiskInfo;
+ class DiskInfoDetector;
+}
+
+namespace KIO {
+ class Job;
+}
+
+#include <k3bdevicemanager.h>
+
+
+/**
+ * Enhanced device manager which can do some additional actions
+ * and maintains a current device
+ */
+class K3bAppDeviceManager : public K3bDevice::DeviceManager
+{
+ Q_OBJECT
+
+ public:
+ K3bAppDeviceManager( QObject* parent = 0, const char* name = 0 );
+ ~K3bAppDeviceManager();
+
+ K3bDevice::Device* currentDevice() const;
+ KActionCollection* actionCollection() const { return m_actionCollection; }
+ void setMediaCache( K3bMediaCache* c );
+
+ signals:
+ void currentDeviceChanged( K3bDevice::Device* );
+
+ /**
+ * Emitted when starting to detect the diskinfo. This may be used to show some info
+ * to the user since deteting the diskinfo might take some time.
+ */
+ void detectingDiskInfo( K3bDevice::Device* );
+ void diskInfoReady( K3bDevice::DiskInfoDetector* );
+
+ void mountFinished( const QString& mountPoint );
+ void unmountFinished( bool success );
+
+ public slots:
+ /**
+ * \reimplemeted for internal reasons. The API is unaffected.
+ */
+ void clear();
+
+ /**
+ * \reimplemeted for internal reasons. The API is unaffected.
+ */
+ void removeDevice( const QString& );
+
+ /**
+ * \reimplemeted for internal reasons. The API is unaffected.
+ */
+ int scanBus();
+
+ void setCurrentDevice( K3bDevice::Device* );
+
+ void diskInfo();
+ void unlockDevice();
+ void lockDevice();
+ void mountDisk();
+ void unmountDisk();
+ void ejectDisk();
+ void loadDisk();
+ void setReadSpeed();
+
+ void diskInfo( K3bDevice::Device* );
+ void unlockDevice( K3bDevice::Device* );
+ void lockDevice( K3bDevice::Device* );
+ void mountDisk( K3bDevice::Device* );
+ void unmountDisk( K3bDevice::Device* );
+ void ejectDisk( K3bDevice::Device* );
+ void loadDisk( K3bDevice::Device* );
+ void setReadSpeed( K3bDevice::Device* );
+
+ private slots:
+ void slotMediumChanged( K3bDevice::Device* dev );
+
+ private:
+ KAction* m_actionDiskInfo;
+ KAction* m_actionUnmount;
+ KAction* m_actionMount;
+ KAction* m_actionEject;
+ KAction* m_actionLoad;
+ KAction* m_actionSetReadSpeed;
+
+ mutable K3bDevice::Device* m_currentDevice;
+ KActionCollection* m_actionCollection;
+ K3bDevice::DiskInfoDetector* m_diskInfoDetector;
+
+ bool m_ejectRequested;
+};
+
+#endif
diff --git a/src/k3bapplication.cpp b/src/k3bapplication.cpp
new file mode 100644
index 0000000..4b517ea
--- /dev/null
+++ b/src/k3bapplication.cpp
@@ -0,0 +1,451 @@
+/*
+ *
+ * $Id: k3bapplication.cpp 802344 2008-04-29 07:45:46Z trueg $
+ * Copyright (C) 2003-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bapplication.h"
+#include "k3b.h"
+#include "k3bsplash.h"
+#include "k3baudioserver.h"
+#include "k3binterface.h"
+#include "k3bjobinterface.h"
+#include "k3bprojectmanager.h"
+#include "k3bappdevicemanager.h"
+#include "k3bmediacache.h"
+#include "k3bpassivepopup.h"
+#include "k3blsofwrapperdialog.h"
+#include "k3bfirstrun.h"
+
+#include <k3bcore.h>
+#include <k3bdevicemanager.h>
+#include <k3bhalconnection.h>
+#include <k3bexternalbinmanager.h>
+#include <k3bdefaultexternalprograms.h>
+#include <k3bglobals.h>
+#include <k3bversion.h>
+#include <k3bdoc.h>
+#include "k3bsystemproblemdialog.h"
+#include <k3bthread.h>
+#include <k3bpluginmanager.h>
+#include <k3bthememanager.h>
+#include <k3bmsf.h>
+#include <k3bmovixprogram.h>
+#include <k3bview.h>
+#include <k3bjob.h>
+
+#include <ktip.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <dcopclient.h>
+#include <kstandarddirs.h>
+#include <kstartupinfo.h>
+#include <kmessagebox.h>
+
+#include <qguardedptr.h>
+#include <qtimer.h>
+#include <qvaluelist.h>
+#include <qcstring.h>
+
+
+K3bApplication::Core* K3bApplication::Core::s_k3bAppCore = 0;
+
+
+K3bApplication::K3bApplication()
+ : KUniqueApplication(),
+ m_mainWindow(0),
+ m_needToInit(true)
+{
+ // insert library i18n data
+ KGlobal::locale()->insertCatalogue( "libk3bdevice" );
+ KGlobal::locale()->insertCatalogue( "libk3b" );
+
+ m_core = new Core( this );
+
+ // TODO: move to K3bCore?
+ // from this point on available through K3bAudioServer::instance()
+ m_audioServer = new K3bAudioServer( this, "K3bAudioServer" );
+
+ connect( m_core, SIGNAL(initializationInfo(const QString&)),
+ SIGNAL(initializationInfo(const QString&)) );
+
+ connect( this, SIGNAL(shutDown()), SLOT(slotShutDown()) );
+}
+
+
+K3bApplication::~K3bApplication()
+{
+ // we must not delete m_mainWindow here, QApplication takes care of it
+}
+
+
+void K3bApplication::init()
+{
+ KConfigGroup generalOptions( config(), "General Options" );
+
+ QGuardedPtr<K3bSplash> splash;
+ if( !isRestored() ) {
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if( generalOptions.readBoolEntry("Show splash", true) && args->isSet( "splash" ) ) {
+ // we need the correct splash pic
+ m_core->m_themeManager->readConfig( config() );
+
+ splash = new K3bSplash( 0 );
+ splash->connect( this, SIGNAL(initializationInfo(const QString&)), SLOT(addInfo(const QString&)) );
+
+ // kill the splash after 5 seconds
+ QTimer::singleShot( 5000, splash, SLOT(close()) );
+
+ splash->show();
+ qApp->processEvents();
+ }
+ }
+
+ //
+ // Load device, external programs, and stuff.
+ //
+ m_core->init();
+ m_core->readSettings( config() );
+
+ m_core->deviceManager()->printDevices();
+
+ m_audioServer->setOutputMethod( generalOptions.readEntry( "Audio Output System", "arts" ).local8Bit() );
+
+ emit initializationInfo( i18n("Creating GUI...") );
+
+ m_mainWindow = new K3bMainWindow();
+ m_core->m_mainWindow = m_mainWindow;
+ m_core->interface()->setMainWindow( m_mainWindow );
+
+ if( isRestored() ) {
+ // we only have one single mainwindow to restore
+ m_mainWindow->restore(1);
+ }
+ else {
+ setMainWidget( m_mainWindow );
+
+ m_mainWindow->show();
+
+ emit initializationInfo( i18n("Ready.") );
+
+ emit initializationDone();
+
+ //K3bFirstRun::run( m_mainWindow );
+
+ if( K3bSystemProblemDialog::readCheckSystemConfig() ) {
+ emit initializationInfo( i18n("Checking System") );
+ K3bSystemProblemDialog::checkSystem( m_mainWindow );
+ }
+
+ if( processCmdLineArgs() )
+ KTipDialog::showTip( m_mainWindow );
+ }
+
+ // write the current version to make sure checks such as K3bSystemProblemDialog::readCheckSystemConfig
+ // use a proper value
+ generalOptions.writeEntry( "config version", m_core->version() );
+}
+
+
+int K3bApplication::newInstance()
+{
+ if( m_needToInit ) {
+ // init();
+ m_needToInit = false;
+ }
+ else
+ processCmdLineArgs();
+
+ return KUniqueApplication::newInstance();
+}
+
+
+bool K3bApplication::processCmdLineArgs()
+{
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ bool showTips = true;
+ bool dialogOpen = false;
+
+ if( k3bcore->jobsRunning() > 0 ) {
+ K3bPassivePopup::showPopup( i18n("K3b is currently busy and cannot start any other operations."),
+ i18n("K3b is busy"),
+ K3bPassivePopup::Information );
+ return true;
+ }
+
+ K3bDoc* doc = 0;
+ if( args->isSet( "datacd" ) ) {
+ doc = m_mainWindow->slotNewDataDoc();
+ }
+ else if( args->isSet( "audiocd" ) ) {
+ doc = m_mainWindow->slotNewAudioDoc();
+ }
+ else if( args->isSet( "mixedcd" ) ) {
+ doc = m_mainWindow->slotNewMixedDoc();
+ }
+ else if( args->isSet( "videocd" ) ) {
+ doc = m_mainWindow->slotNewVcdDoc();
+ }
+ else if( args->isSet( "emovixcd" ) ) {
+ doc = m_mainWindow->slotNewMovixDoc();
+ }
+ else if( args->isSet( "datadvd" ) ) {
+ doc = m_mainWindow->slotNewDvdDoc();
+ }
+ else if( args->isSet( "emovixdvd" ) ) {
+ doc = m_mainWindow->slotNewMovixDvdDoc();
+ }
+ else if( args->isSet( "videodvd" ) ) {
+ doc = m_mainWindow->slotNewVideoDvdDoc();
+ }
+
+ // if we created a doc the urls are used to populate it
+ if( doc ) {
+ KURL::List urls;
+ for( int i = 0; i < args->count(); i++ )
+ urls.append( args->url(i) );
+ dynamic_cast<K3bView*>( doc->view() )->addUrls( urls );
+ }
+ // otherwise we open them as documents
+ else {
+ for( int i = 0; i < args->count(); i++ ) {
+ m_mainWindow->openDocument( args->url(i) );
+ }
+ }
+
+ // we only allow one dialog to be opened
+ if( args->isSet( "cdimage" ) ) {
+ showTips = false;
+ dialogOpen = true;
+ if( k3bcore->jobsRunning() == 0 ) {
+ m_mainWindow->slotWriteCdImage( KURL::fromPathOrURL( QFile::decodeName( args->getOption( "cdimage" ) ) ) );
+ }
+ }
+ else if( args->isSet( "dvdimage" ) ) {
+ showTips = false;
+ dialogOpen = true;
+ if( k3bcore->jobsRunning() == 0 ) {
+ m_mainWindow->slotWriteDvdIsoImage( KURL::fromPathOrURL( QFile::decodeName( args->getOption( "dvdimage" ) ) ) );
+ }
+ }
+ else if( args->isSet( "image" ) ) {
+ showTips = false;
+ dialogOpen = true;
+ KURL url = KURL::fromPathOrURL( QFile::decodeName( args->getOption( "image" ) ) );
+ if( k3bcore->jobsRunning() == 0 ) {
+ if( K3b::filesize( url ) > 1000*1024*1024 )
+ m_mainWindow->slotWriteDvdIsoImage( url );
+ else
+ m_mainWindow->slotWriteCdImage( url );
+ }
+ }
+ else if( args->isSet("copycd") ) {
+ showTips = false;
+ dialogOpen = true;
+ qApp->processEvents();
+ m_mainWindow->cdCopy( K3b::urlToDevice( KURL::fromPathOrURL( QFile::decodeName( args->getOption( "copycd" ) ) ) ) );
+ }
+ else if( args->isSet("copydvd") ) {
+ showTips = false;
+ dialogOpen = true;
+ m_mainWindow->dvdCopy( K3b::urlToDevice( KURL::fromPathOrURL( QFile::decodeName( args->getOption( "copydvd" ) ) ) ) );
+ }
+ else if( args->isSet("erasecd") ) {
+ showTips = false;
+ dialogOpen = true;
+ m_mainWindow->blankCdrw( K3b::urlToDevice( KURL::fromPathOrURL( QFile::decodeName( args->getOption( "erasecd" ) ) ) ) );
+ }
+ else if( args->isSet("formatdvd") ) {
+ showTips = false;
+ dialogOpen = true;
+ m_mainWindow->formatDvd( K3b::urlToDevice( KURL::fromPathOrURL( QFile::decodeName( args->getOption( "formatdvd" ) ) ) ) );
+ }
+
+ // no dialog used here
+ if( args->isSet( "cddarip" ) ) {
+ m_mainWindow->cddaRip( K3b::urlToDevice( KURL::fromPathOrURL( QFile::decodeName( args->getOption( "cddarip" ) ) ) ) );
+ }
+ else if( args->isSet( "videodvdrip" ) ) {
+ m_mainWindow->videoDvdRip( K3b::urlToDevice( KURL::fromPathOrURL( QFile::decodeName( args->getOption( "videodvdrip" ) ) ) ) );
+ }
+ else if( args->isSet( "videocdrip" ) ) {
+ m_mainWindow->videoCdRip( K3b::urlToDevice( KURL::fromPathOrURL( QFile::decodeName( args->getOption( "videocdrip" ) ) ) ) );
+ }
+
+ if( !dialogOpen && args->isSet( "burn" ) ) {
+ if( m_core->projectManager()->activeDoc() ) {
+ showTips = false;
+ dialogOpen = true;
+ static_cast<K3bView*>( m_core->projectManager()->activeDoc()->view() )->slotBurn();
+ }
+ }
+
+ // FIXME: seems not like the right place...
+ if( args->isSet( "ao" ) )
+ if( !m_audioServer->setOutputMethod( args->getOption( "ao" ) ) )
+ K3bPassivePopup::showPopup( i18n("Could not find Audio Output plugin '%1'").arg( args->getOption("ao") ),
+ i18n("Initialization Problem"),
+ K3bPassivePopup::Warning );
+
+ args->clear();
+
+ return showTips;
+}
+
+
+void K3bApplication::slotShutDown()
+{
+ k3bappcore->mediaCache()->clearDeviceList();
+ K3bThread::waitUntilFinished();
+}
+
+
+
+K3bApplication::Core::Core( QObject* parent )
+ : K3bCore( parent ),
+ m_appDeviceManager(0),
+ m_mediaCache(0)
+{
+ s_k3bAppCore = this;
+ m_themeManager = new K3bThemeManager( this );
+ m_projectManager = new K3bProjectManager( this );
+ // we need the themes on startup (loading them is fast anyway :)
+ m_themeManager->loadThemes();
+
+ m_jobInterface = new K3bJobInterface( this );
+ m_interface = new K3bInterface();
+ dcopClient()->setDefaultObject( m_interface->objId() );
+}
+
+
+K3bApplication::Core::~Core()
+{
+}
+
+
+void K3bApplication::Core::initDeviceManager()
+{
+ if( !m_appDeviceManager ) {
+ // our very own special device manager
+ m_appDeviceManager = new K3bAppDeviceManager( this );
+ }
+ if( !m_mediaCache ) {
+ // create the media cache but do not connect it to the device manager
+ // yet to speed up application start. We connect it in init()
+ // once the devicemanager has scanned for devices.
+ m_mediaCache = new K3bMediaCache( this );
+ }
+
+ m_appDeviceManager->setMediaCache( m_mediaCache );
+}
+
+
+K3bDevice::DeviceManager* K3bApplication::Core::deviceManager() const
+{
+ return appDeviceManager();
+}
+
+
+KConfig* K3bApplication::Core::config() const
+{
+ return kapp->config();
+}
+
+
+void K3bApplication::Core::init()
+{
+ //
+ // The eMovix program is a special case which is not part of
+ // the default programs handled by K3bCore
+ //
+ initExternalBinManager();
+ externalBinManager()->addProgram( new K3bMovixProgram() );
+ externalBinManager()->addProgram( new K3bNormalizeProgram() );
+ K3b::addTranscodePrograms( externalBinManager() );
+ K3b::addVcdimagerPrograms( externalBinManager() );
+
+ K3bCore::init();
+
+ mediaCache()->buildDeviceList( deviceManager() );
+
+ connect( deviceManager(), SIGNAL(changed(K3bDevice::DeviceManager*)),
+ mediaCache(), SLOT(buildDeviceList(K3bDevice::DeviceManager*)) );
+}
+
+
+void K3bApplication::Core::readSettings( KConfig* cnf )
+{
+ K3bCore::readSettings( cnf );
+
+ KConfig* c = cnf;
+ if( !c )
+ c = config();
+
+ m_themeManager->readConfig( config() );
+}
+
+
+void K3bApplication::Core::saveSettings( KConfig* cnf )
+{
+ if( !cnf )
+ cnf = config();
+
+ K3bCore::saveSettings( cnf );
+ m_themeManager->saveConfig( cnf );
+}
+
+
+bool K3bApplication::Core::internalBlockDevice( K3bDevice::Device* dev )
+{
+ if( K3bCore::internalBlockDevice( dev ) ) {
+ if( mediaCache() ) {
+ m_deviceBlockMap[dev] = mediaCache()->blockDevice( dev );
+ }
+
+#ifdef HAVE_HAL
+ if( K3bDevice::HalConnection::instance()->lock( dev ) != K3bDevice::HalConnection::org_freedesktop_Hal_Success )
+ kdDebug() << "(K3bInterferingSystemsHandler) HAL lock failed." << endl;
+#endif
+
+ //
+ // Check if the device is in use
+ //
+ // FIXME: Use the top level widget as parent
+ K3bLsofWrapperDialog::checkDevice( dev );
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
+void K3bApplication::Core::internalUnblockDevice( K3bDevice::Device* dev )
+{
+ if( mediaCache() ) {
+ mediaCache()->unblockDevice( dev, m_deviceBlockMap[dev] );
+ m_deviceBlockMap.erase( dev );
+ }
+
+#ifdef HAVE_HAL
+ K3bDevice::HalConnection::instance()->unlock( dev );
+#endif
+
+ K3bCore::internalUnblockDevice( dev );
+}
+
+#include "k3bapplication.moc"
diff --git a/src/k3bapplication.h b/src/k3bapplication.h
new file mode 100644
index 0000000..8dafac1
--- /dev/null
+++ b/src/k3bapplication.h
@@ -0,0 +1,156 @@
+/*
+ *
+ * $Id: k3bapplication.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef _K3B_APPLICATION_H_
+#define _K3B_APPLICATION_H_
+
+#include <kuniqueapplication.h>
+#include <k3bcore.h>
+
+#include <qmap.h>
+
+#define k3bappcore K3bApplication::Core::k3bAppCore()
+
+
+class K3bMainWindow;
+class K3bInterface;
+class K3bJobInterface;
+class K3bAudioServer;
+class K3bThemeManager;
+class K3bProjectManager;
+class K3bAppDeviceManager;
+class K3bMediaCache;
+
+
+class K3bApplication : public KUniqueApplication
+{
+ Q_OBJECT
+
+ public:
+ K3bApplication();
+ ~K3bApplication();
+
+ int newInstance();
+
+ class Core;
+
+ public slots:
+ void init();
+
+ signals:
+ void initializationInfo( const QString& );
+ void initializationDone();
+
+ private slots:
+ void slotShutDown();
+
+ private:
+ bool processCmdLineArgs();
+
+ Core* m_core;
+ K3bAudioServer* m_audioServer;
+ K3bMainWindow* m_mainWindow;
+
+ bool m_needToInit;
+};
+
+
+/**
+ * The application's core which extends K3bCore with some additional features
+ * like the thememanager or an enhanced device manager.
+ */
+class K3bApplication::Core : public K3bCore
+{
+ Q_OBJECT
+
+ public:
+ Core( QObject* parent );
+ ~Core();
+
+ void init();
+
+ // make sure the libk3b uses the same configuration
+ // needed since the lib still depends on K3bCore::config
+ // the goal is to make the lib independent from the config
+ KConfig* config() const;
+
+ void readSettings( KConfig* c = 0 );
+ void saveSettings( KConfig* c = 0 );
+
+ /**
+ * \reimplemented from K3bCore. We use our own devicemanager here.
+ */
+ K3bDevice::DeviceManager* deviceManager() const;
+
+ K3bAppDeviceManager* appDeviceManager() const { return m_appDeviceManager; }
+
+ K3bThemeManager* themeManager() const { return m_themeManager; }
+
+ K3bProjectManager* projectManager() const { return m_projectManager; }
+
+ K3bMediaCache* mediaCache() const { return m_mediaCache; }
+
+ K3bMainWindow* k3bMainWindow() const { return m_mainWindow; }
+
+ K3bInterface* interface() const { return m_interface; }
+
+ K3bJobInterface* jobInterface() const { return m_jobInterface; }
+
+ static Core* k3bAppCore() { return s_k3bAppCore; }
+
+ signals:
+ /**
+ * This is used for showing info in the K3b splashscreen
+ */
+ void initializationInfo( const QString& );
+
+ /**
+ * Any component may request busy info
+ * In the K3b main app this will be displayed
+ * as a moving square in the taskbar
+ *
+ * FIXME: this is bad design
+ */
+ void busyInfoRequested( const QString& );
+
+ /**
+ * FIXME: this is bad design
+ */
+ void busyFinishRequested();
+
+ private:
+ void initDeviceManager();
+
+ bool internalBlockDevice( K3bDevice::Device* );
+ void internalUnblockDevice( K3bDevice::Device* );
+
+ K3bInterface* m_interface;
+ K3bJobInterface* m_jobInterface;
+
+ K3bThemeManager* m_themeManager;
+ K3bMainWindow* m_mainWindow;
+ K3bProjectManager* m_projectManager;
+ K3bAppDeviceManager* m_appDeviceManager;
+ K3bMediaCache* m_mediaCache;
+
+ QMap<K3bDevice::Device*, int> m_deviceBlockMap;
+
+ static Core* s_k3bAppCore;
+
+ friend class K3bApplication;
+};
+
+#endif
diff --git a/src/k3baudioplayer.cpp b/src/k3baudioplayer.cpp
new file mode 100644
index 0000000..645b3cf
--- /dev/null
+++ b/src/k3baudioplayer.cpp
@@ -0,0 +1,663 @@
+/*
+ *
+ * $Id: k3baudioplayer.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3baudioplayer.h"
+#include <k3bmsf.h>
+#include "kcutlabel.h"
+
+#include <qlabel.h>
+#include <qtoolbutton.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qdatetime.h>
+#include <qfont.h>
+#include <qslider.h>
+#include <qlistview.h>
+#include <qfile.h>
+#include <qpalette.h>
+#include <qheader.h>
+#include <qevent.h>
+#include <qdragobject.h>
+#include <qptrlist.h>
+#include <kurldrag.h>
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <kaction.h>
+
+#include <string.h>
+
+#ifdef WITH_ARTS
+#include <arts/artsflow.h>
+#endif
+
+#include <kdebug.h>
+
+using namespace std;
+
+K3bPlayListViewItem::K3bPlayListViewItem( const QString& filename, QListView* parent )
+ : KListViewItem( parent ), m_filename( filename )
+{
+ m_length = 0;
+ m_bActive = false;
+}
+
+
+K3bPlayListViewItem::K3bPlayListViewItem( const QString& filename, QListView* parent, QListViewItem* after )
+ : KListViewItem( parent, after ), m_filename( filename )
+{
+ m_length = 0;
+ m_bActive = false;
+}
+
+
+K3bPlayListViewItem::~K3bPlayListViewItem()
+{
+}
+
+
+QString K3bPlayListViewItem::text( int c ) const
+{
+ switch( c ) {
+ case 0:
+ {
+ int pos = m_filename.findRev("/");
+ if( pos >= 0 )
+ return m_filename.mid(pos+1);
+ return m_filename;
+ }
+
+ case 1:
+ if( m_length > 0 )
+ return K3b::Msf(m_length).toString(false);
+
+ default:
+ return "";
+ }
+}
+
+
+void K3bPlayListViewItem::paintCell( QPainter* p, const QColorGroup& cg, int c, int w, int a )
+{
+ if( m_bActive ) {
+ // change the color of the text:
+ // change roles: Text, HighlightedText, HighLight
+ QColorGroup newCg( cg );
+
+ // we assume the user has not configured a very dark color as base color
+ newCg.setColor( QColorGroup::Text, red );
+ newCg.setColor( QColorGroup::Highlight, red );
+ newCg.setColor( QColorGroup::HighlightedText, white );
+
+ KListViewItem::paintCell( p, newCg, c, w, a );
+ }
+ else
+ KListViewItem::paintCell( p, cg, c, w, a );
+}
+
+
+K3bPlayListView::K3bPlayListView( QWidget* parent, const char* name )
+ : KListView( parent, name )
+{
+ addColumn( i18n("Filename") );
+ addColumn( i18n("Length") );
+ setAllColumnsShowFocus( true );
+ setAcceptDrops( true );
+ setDropVisualizer( true );
+ setDragEnabled(true);
+ setItemsMovable( true );
+ header()->setClickEnabled( false );
+ setSorting( -1 );
+}
+
+
+K3bPlayListView::~K3bPlayListView()
+{
+}
+
+
+bool K3bPlayListView::acceptDrag( QDropEvent* e ) const
+{
+ // we accept textdrag (urls) and moved items (supported by KListView)
+ return KURLDrag::canDecode(e) || KListView::acceptDrag(e);
+}
+
+
+QDragObject* K3bPlayListView::dragObject()
+{
+ QPtrList<QListViewItem> list = selectedItems();
+
+ if( list.isEmpty() )
+ return 0;
+
+ QPtrListIterator<QListViewItem> it(list);
+ KURL::List urls;
+
+ for( ; it.current(); ++it )
+ urls.append( KURL( ((K3bPlayListViewItem*)it.current())->filename() ) );
+
+ return KURLDrag::newDrag( urls, viewport() );
+}
+
+
+K3bAudioPlayer::K3bAudioPlayer( QWidget* parent, const char* name )
+ : QWidget( parent, name )
+#ifdef WITH_ARTS
+, m_playObject( Arts::PlayObject::null() )
+#endif
+{
+ m_currentItem = 0L;
+ // initialize
+ // ------------------------------------------------------------------------
+ m_labelFilename = new KCutLabel( i18n("no file"), this );
+ m_labelOverallTime = new QLabel( "00:00", this );
+ m_labelCurrentTime = new QLabel( "00:00", this );
+
+ m_viewPlayList = new K3bPlayListView( this );
+
+ m_labelOverallTime->setAlignment( AlignHCenter | AlignVCenter );
+ m_labelCurrentTime->setAlignment( AlignHCenter | AlignVCenter );
+ m_labelOverallTime->setFrameStyle( QFrame::StyledPanel | QFrame::Plain );
+ m_labelCurrentTime->setFrameStyle( QFrame::StyledPanel | QFrame::Plain );
+ m_labelFilename->setFrameStyle( QFrame::StyledPanel | QFrame::Plain );
+ m_labelOverallTime->setPalette( QPalette( QColor(238, 238, 205) ) );
+ m_labelCurrentTime->setPalette( QPalette( QColor(238, 238, 205) ) );
+ m_labelFilename->setPalette( QPalette( QColor(238, 238, 205) ) );
+
+ m_buttonPlay = new QToolButton( this );
+ m_buttonPause = new QToolButton( this );
+ m_buttonStop = new QToolButton( this );
+ m_buttonPlay->setIconSet( SmallIconSet("player_play") );
+ m_buttonPause->setIconSet( SmallIconSet("player_pause") );
+ m_buttonStop->setIconSet( SmallIconSet("player_stop") );
+ m_buttonForward = new QToolButton( this );
+ m_buttonBack = new QToolButton( this );
+ m_buttonForward->setIconSet( SmallIconSet("player_end") );
+ m_buttonBack->setIconSet( SmallIconSet("player_start") );
+
+ m_seekSlider = new QSlider( QSlider::Horizontal, this );
+
+ m_updateTimer = new QTimer( this );
+ // ------------------------------------------------------------------------
+
+ // layout
+ // ------------------------------------------------------------------------
+ QGridLayout* grid = new QGridLayout( this );
+ grid->setSpacing( 2 );
+ grid->setMargin( 0 );
+
+ grid->addWidget( m_buttonPlay, 1, 0 );
+ grid->addWidget( m_buttonPause, 1, 1 );
+ grid->addWidget( m_buttonStop, 1, 2 );
+ grid->addColSpacing( 3, 5 );
+ grid->addWidget( m_buttonBack, 1, 4 );
+ grid->addWidget( m_buttonForward, 1, 5 );
+
+ grid->addMultiCellWidget( m_labelFilename, 0, 0, 0, 6 );
+
+ grid->addMultiCellWidget( m_seekSlider, 1, 1, 6, 8 );
+
+ grid->addWidget( m_labelCurrentTime, 0, 7 );
+ grid->addWidget( m_labelOverallTime, 0, 8 );
+
+ grid->addMultiCellWidget( m_viewPlayList, 2, 2, 0, 8 );
+ grid->setRowStretch( 2, 1 );
+ grid->setColStretch( 6, 1 );
+ // ------------------------------------------------------------------------
+
+
+ // actions
+ // ------------------------------------------------------------------------
+ m_actionRemove = new KAction( i18n( "Remove" ), "editdelete",
+ Key_Delete, this, SLOT(slotRemoveSelected()),
+ this, "audioplayer_remove" );
+ m_actionClear = new KAction( i18n( "Clear List" ), "editclear",
+ 0, this, SLOT(clear()),
+ this, "audioplayer_clear" );
+
+ m_contextMenu = new KActionMenu( this, "audio_player_menu" );
+ m_contextMenu->insert(m_actionRemove);
+ m_contextMenu->insert(m_actionClear);
+ // ------------------------------------------------------------------------
+
+
+ // connections
+ // ------------------------------------------------------------------------
+ connect( m_viewPlayList, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)),
+ this, SLOT(slotShowContextMenu(KListView*, QListViewItem*, const QPoint&)) );
+
+ connect( m_buttonPlay, SIGNAL(clicked()), this, SLOT(play()) );
+ connect( m_buttonStop, SIGNAL(clicked()), this, SLOT(stop()) );
+ connect( m_buttonPause, SIGNAL(clicked()), this, SLOT(pause()) );
+
+ connect( m_buttonForward, SIGNAL(clicked()), this, SLOT(forward()) );
+ connect( m_buttonBack, SIGNAL(clicked()), this, SLOT(back()) );
+
+ connect( m_seekSlider, SIGNAL(sliderMoved(int)), this, SLOT(seek(int)) );
+ connect( m_seekSlider, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateCurrentTime(int)) );
+
+ connect( m_updateTimer, SIGNAL(timeout()), this, SLOT(slotUpdateDisplay()) );
+ connect( m_updateTimer, SIGNAL(timeout()), this, SLOT(slotCheckEnd()) );
+
+ connect( m_viewPlayList, SIGNAL(doubleClicked(QListViewItem*)),
+ this, SLOT(slotPlayItem(QListViewItem*)) );
+ connect( m_viewPlayList, SIGNAL(dropped(QDropEvent*,QListViewItem*)),
+ this, SLOT(slotDropped(QDropEvent*,QListViewItem*)) );
+ // ------------------------------------------------------------------------
+
+
+ m_bLengthReady = false;
+}
+
+
+K3bAudioPlayer::~K3bAudioPlayer()
+{
+ // we remove the reference to the play object
+ // if we don't do this it won't be removed and K3b will crash (not sure why)
+#ifdef WITH_ARTS
+ m_playObject = Arts::PlayObject::null();
+#endif
+}
+
+
+int K3bAudioPlayer::state()
+{
+#ifdef WITH_ARTS
+ if( !m_playObject.isNull() ) {
+ switch( m_playObject.state() ) {
+ case Arts::posIdle:
+ return STOPPED;
+ case Arts::posPlaying:
+ return PLAYING;
+ case Arts::posPaused:
+ return PAUSED;
+ }
+ }
+ else if( m_currentItem )
+ return STOPPED;
+#endif
+
+ return EMPTY;
+}
+
+
+void K3bAudioPlayer::playFile( const QString& filename )
+{
+ clear();
+ if( QFile::exists( filename ) ) {
+ K3bPlayListViewItem* item = new K3bPlayListViewItem( filename, m_viewPlayList );
+ setCurrentItem( item );
+ play();
+ emit started( filename );
+ }
+}
+
+
+void K3bAudioPlayer::playFiles( const QStringList& files )
+{
+ clear();
+ QStringList::ConstIterator it = files.begin();
+ playFile( *it );
+ ++it;
+
+ for( ; it != files.end(); ++it )
+ enqueueFile( *it );
+}
+
+
+void K3bAudioPlayer::enqueueFile( const QString& filename )
+{
+ if( QFile::exists( filename ) )
+ (void)new K3bPlayListViewItem( filename, m_viewPlayList, m_viewPlayList->lastChild() );
+}
+
+
+void K3bAudioPlayer::enqueueFiles( const QStringList& files )
+{
+ for( QStringList::ConstIterator it = files.begin(); it != files.end(); ++it )
+ enqueueFile( *it );
+}
+
+
+void K3bAudioPlayer::play()
+{
+#ifdef WITH_ARTS
+ if( !m_currentItem ) {
+ setCurrentItem( m_viewPlayList->firstChild() );
+ }
+
+ if( m_currentItem ) {
+ if( m_playObject.isNull() ) {
+ Arts::PlayObjectFactory factory = Arts::Reference("global:Arts_PlayObjectFactory");
+ if( factory.isNull() ) {
+ kdDebug() << "(K3bAudioPlayer) could not create PlayObjectFactory. Possibly no artsd running." << endl;
+ m_labelFilename->setText( i18n("No running aRtsd found") );
+ return;
+ }
+
+ m_playObject = factory.createPlayObject( string(QFile::encodeName(m_currentItem->filename()) ) );
+ if( m_playObject.isNull() ) {
+ kdDebug() << "(K3bAudioPlayer) no aRts module available for: " << m_currentItem->filename() << endl;
+ m_labelFilename->setText( i18n("Unknown file format") );
+
+ // play the next if there is any
+ if( m_currentItem->itemBelow() ) {
+ setCurrentItem( m_currentItem->itemBelow() );
+ play();
+ }
+ return;
+ }
+ }
+ if( m_playObject.state() != Arts::posPlaying ) {
+ m_playObject.play();
+ emit started();
+ m_updateTimer->start( 1000 );
+ }
+
+ slotUpdateFilename();
+ }
+#endif
+}
+
+
+void K3bAudioPlayer::slotPlayItem( QListViewItem* item )
+{
+ setCurrentItem( item );
+ play();
+}
+
+
+void K3bAudioPlayer::stop()
+{
+#ifdef WITH_ARTS
+ if( !m_playObject.isNull() ) {
+ m_updateTimer->stop();
+ m_playObject.halt();
+ m_playObject = Arts::PlayObject::null();
+ m_bLengthReady = false;
+
+ emit stopped();
+ }
+#endif
+
+ m_seekSlider->setValue(0);
+ slotUpdateFilename();
+ slotUpdateCurrentTime(0);
+}
+
+
+void K3bAudioPlayer::pause()
+{
+#ifdef WITH_ARTS
+ if( !m_playObject.isNull() ) {
+ if( m_playObject.state() == Arts::posPlaying ) {
+ m_updateTimer->stop();
+ m_playObject.pause();
+ emit paused();
+ }
+
+ slotUpdateFilename();
+ }
+#endif
+}
+
+
+void K3bAudioPlayer::seek( long pos )
+{
+#ifdef WITH_ARTS
+ if( !m_playObject.isNull() ) {
+ if( m_playObject.state() != Arts::posIdle ) {
+ if( pos < 0 ) {
+ m_playObject.seek( Arts::poTime() );
+ }
+ else if( m_playObject.overallTime().seconds < pos ) {
+ m_playObject.seek( m_playObject.overallTime() );
+ }
+ else if( pos != m_playObject.currentTime().seconds ) {
+ m_playObject.seek( Arts::poTime( pos, 0, -1, "" ) );
+ }
+ }
+ }
+ else {
+ m_seekSlider->setValue(0);
+ slotUpdateCurrentTime(0);
+ }
+#endif
+}
+
+
+
+void K3bAudioPlayer::seek( int pos )
+{
+ seek( (long)pos );
+}
+
+
+void K3bAudioPlayer::forward()
+{
+ if( m_currentItem ) {
+ if( m_currentItem->itemBelow() ) {
+ bool bPlay = false;
+ if( state() == PLAYING )
+ bPlay = true;
+
+ setCurrentItem( m_currentItem->itemBelow() );
+
+ if( bPlay )
+ play();
+ }
+ }
+}
+
+
+void K3bAudioPlayer::back()
+{
+ if( m_currentItem ) {
+ if( m_currentItem->itemAbove() ) {
+ bool bPlay = false;
+ if( state() == PLAYING )
+ bPlay = true;
+
+ setCurrentItem( m_currentItem->itemAbove() );
+
+ if( bPlay )
+ play();
+ }
+ }
+}
+
+
+void K3bAudioPlayer::clear()
+{
+ setCurrentItem( 0 );
+ m_viewPlayList->clear();
+}
+
+
+long K3bAudioPlayer::length()
+{
+#ifdef WITH_ARTS
+ if( !m_playObject.isNull() ) {
+ return m_playObject.overallTime().seconds;
+ }
+#endif
+ return 0;
+}
+
+
+long K3bAudioPlayer::position()
+{
+#ifdef WITH_ARTS
+ if( !m_playObject.isNull() ) {
+ return m_playObject.currentTime().seconds;
+ }
+#endif
+ return 0;
+}
+
+
+// FIXME: let my do some useful stuff!
+bool K3bAudioPlayer::supportsMimetype( const QString& mimetype )
+{
+ if( mimetype.contains("audio") || mimetype.contains("ogg") )
+ return true;
+ else
+ return false;
+}
+
+
+void K3bAudioPlayer::slotCheckEnd()
+{
+#ifdef WITH_ARTS
+ if( !m_playObject.isNull() ) {
+ if( m_playObject.state() == Arts::posIdle ) {
+ if( m_currentItem->nextSibling() ) {
+ setCurrentItem( m_currentItem->nextSibling() );
+ play();
+ }
+ else {
+ stop();
+ }
+ emit ended();
+ }
+ }
+#endif
+}
+
+
+void K3bAudioPlayer::setCurrentItem( QListViewItem* item )
+{
+ if( item == 0 ) {
+ stop();
+ m_labelOverallTime->setText("00:00");
+ m_labelFilename->setText( i18n("no file") );
+ m_currentItem = 0;
+ }
+ else if( K3bPlayListViewItem* playItem = dynamic_cast<K3bPlayListViewItem*>(item) ) {
+ if( m_currentItem ) {
+ // reset m_currentItem
+ m_currentItem->setActive( false );
+ stop();
+ }
+ m_currentItem = playItem;
+ m_currentItem->setActive( true );
+
+ // paint the activity changes
+ m_viewPlayList->viewport()->update();
+
+ slotUpdateFilename();
+ }
+}
+
+
+void K3bAudioPlayer::slotUpdateCurrentTime( int time )
+{
+ m_labelCurrentTime->setText( K3b::Msf( time*75 ).toString(false) );
+}
+
+
+void K3bAudioPlayer::slotUpdateLength( long time )
+{
+ m_labelOverallTime->setText( K3b::Msf( time*75 ).toString(false) );
+}
+
+
+void K3bAudioPlayer::slotUpdateFilename()
+{
+ if( m_currentItem ) {
+ QString display = m_currentItem->filename();
+ int pos = display.findRev("/");
+ if( pos >= 0 )
+ display = display.mid(pos+1);
+
+ switch( state() ) {
+ case PLAYING:
+ display.prepend( QString("(%1) ").arg(i18n("playing")) );
+ break;
+ case PAUSED:
+ display.prepend( QString("(%1) ").arg(i18n("paused")) );
+ break;
+ case STOPPED:
+ display.prepend( QString("(%1) ").arg(i18n("stopped")) );
+ break;
+ default:
+ break;
+ }
+
+ m_labelFilename->setText( display );
+ }
+}
+
+
+void K3bAudioPlayer::slotUpdateDisplay()
+{
+ if( m_currentItem ) {
+ // we need to set the length here because sometimes it is not ready in the beginning (?)
+ if( !m_bLengthReady && length() > 0 ) {
+ slotUpdateLength( length() );
+ m_seekSlider->setMaxValue( length() );
+ m_currentItem->setLength( 75 * length() );
+ m_bLengthReady = true;
+
+ m_viewPlayList->viewport()->update();
+ }
+
+ m_seekSlider->setValue( position() );
+ }
+}
+
+
+void K3bAudioPlayer::slotDropped( QDropEvent* e, QListViewItem* after )
+{
+ if( !after )
+ after = m_viewPlayList->lastChild();
+
+ KURL::List urls;
+ KURLDrag::decode( e, urls );
+
+ for( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it ) {
+ if( QFile::exists( (*it).path() ) ) {
+ QListViewItem* newItem = new K3bPlayListViewItem( (*it).path(), m_viewPlayList, after );
+ after = newItem;
+ }
+ }
+}
+
+
+void K3bAudioPlayer::slotRemoveSelected()
+{
+ QPtrList<QListViewItem> selected = m_viewPlayList->selectedItems();
+ for( QListViewItem* item = selected.first(); item; item = selected.next() ) {
+ if( item == m_currentItem )
+ setCurrentItem(0);
+ delete item;
+ }
+}
+
+
+void K3bAudioPlayer::slotShowContextMenu( KListView*, QListViewItem* item, const QPoint& p )
+{
+ if( item )
+ m_actionRemove->setEnabled( true );
+ else
+ m_actionRemove->setEnabled( false );
+
+ m_contextMenu->popup(p);
+}
+
+
+#include "k3baudioplayer.moc"
diff --git a/src/k3baudioplayer.h b/src/k3baudioplayer.h
new file mode 100644
index 0000000..1bc28a9
--- /dev/null
+++ b/src/k3baudioplayer.h
@@ -0,0 +1,208 @@
+/*
+ *
+ * $Id: k3baudioplayer.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BAUDIOPLAYER_H
+#define K3BAUDIOPLAYER_H
+
+#include <klistview.h>
+
+#include <config.h>
+
+#ifdef WITH_ARTS
+#include <arts/kmedia2.h>
+#include <arts/kartsdispatcher.h>
+#endif
+
+class QTimer;
+class QLabel;
+class QToolButton;
+class QSlider;
+class QPainter;
+class QColorGroup;
+class QDropEvent;
+class QDragObject;
+class KAction;
+class KActionMenu;
+
+
+/**
+ * Special ListViewItem for the K3bAudioPlayer playlist
+ * @author Sebastian Trueg
+ */
+class K3bPlayListViewItem : public KListViewItem
+{
+ public:
+ K3bPlayListViewItem( const QString&, QListView* parent );
+ K3bPlayListViewItem( const QString&, QListView* parent, QListViewItem* after );
+ ~K3bPlayListViewItem();
+
+ /** @returns the filename for the first column and the
+ * length in format 00:00.00 for the second column
+ */
+ virtual QString text( int c ) const;
+
+ void setLength( unsigned long l ) { m_length = l; }
+ unsigned long length() const { return m_length; }
+ const QString& filename() const { return m_filename; }
+
+ /**
+ * reimplemented from QListViewItem
+ * takes the m_bActive flag into account.
+ */
+ virtual void paintCell( QPainter*, const QColorGroup&, int, int, int );
+
+ void setActive( bool a ) { m_bActive = a; }
+
+ protected:
+ /** path to the associated file */
+ QString m_filename;
+
+ /** length in frames (1/75 second) */
+ unsigned long m_length;
+
+ bool m_bActive;
+};
+
+
+
+/**
+ * Playlistview just needed to accept
+ * url drags
+ */
+class K3bPlayListView : public KListView
+{
+Q_OBJECT
+
+ public:
+ K3bPlayListView( QWidget* parent = 0, const char* name = 0 );
+ ~K3bPlayListView();
+
+ protected:
+ bool acceptDrag( QDropEvent* e ) const;
+ QDragObject* dragObject();
+};
+
+
+
+
+/**
+ * @author Sebastian Trueg
+ */
+class K3bAudioPlayer : public QWidget
+{
+Q_OBJECT
+
+ public:
+ K3bAudioPlayer( QWidget* parent = 0, const char* name = 0 );
+ ~K3bAudioPlayer();
+
+ bool supportsMimetype( const QString& mimetype );
+
+ /**
+ * length of current playing in seconds
+ */
+ long length();
+
+ /**
+ * current position in seconds
+ */
+ long position();
+
+ /**
+ * EMPTY - no file loaded
+ */
+ enum player_state { PLAYING, PAUSED, STOPPED, EMPTY };
+
+ int state();
+
+ signals:
+ void started( const QString& filename );
+ void started();
+ void stopped();
+ void paused();
+ void ended();
+
+ public slots:
+ void playFile( const QString& filename );
+ void playFiles( const QStringList& files );
+ void enqueueFile( const QString& filename );
+ void enqueueFiles( const QStringList& files );
+
+ /** clears the playlist */
+ void clear();
+ void play();
+ void forward();
+ void back();
+ void stop();
+ void pause();
+ void seek( long pos );
+ void seek( int pos );
+
+/* protected: */
+/* void dragEnterEvent( QDragEnterEvent* e ); */
+/* void dropEvent( QDropEvent* e ); */
+
+ private slots:
+ void slotCheckEnd();
+ void slotUpdateDisplay();
+ void slotUpdateCurrentTime( int time );
+ void slotUpdateLength( long time );
+ void slotUpdateFilename();
+ void slotPlayItem( QListViewItem* item );
+ void slotDropped( QDropEvent* e, QListViewItem* after );
+
+ /**
+ * set the actual item. Will set m_currentItem and
+ * handle highlighting of the current item
+ */
+ void setCurrentItem( QListViewItem* item );
+ void slotRemoveSelected();
+ void slotShowContextMenu( KListView*, QListViewItem* item, const QPoint& p );
+
+ private:
+#ifdef WITH_ARTS
+ Arts::PlayObject m_playObject;
+ KArtsDispatcher m_dispatcher;
+#endif
+ QString m_filename;
+
+ QLabel* m_labelFilename;
+ QLabel* m_labelCurrentTime;
+ QLabel* m_labelOverallTime;
+
+ QToolButton* m_buttonPlay;
+ QToolButton* m_buttonPause;
+ QToolButton* m_buttonStop;
+ QToolButton* m_buttonForward;
+ QToolButton* m_buttonBack;
+
+ K3bPlayListView* m_viewPlayList;
+
+ QSlider* m_seekSlider;
+
+ QTimer* m_updateTimer;
+
+ K3bPlayListViewItem* m_currentItem;
+
+ bool m_bLengthReady;
+
+ KAction* m_actionRemove;
+ KAction* m_actionClear;
+ KActionMenu* m_contextMenu;
+};
+
+
+#endif
diff --git a/src/k3baudioprojectinterface.cpp b/src/k3baudioprojectinterface.cpp
new file mode 100644
index 0000000..1d06d5a
--- /dev/null
+++ b/src/k3baudioprojectinterface.cpp
@@ -0,0 +1,92 @@
+/*
+ *
+ * $Id: k3baudioprojectinterface.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include "k3baudioprojectinterface.h"
+
+#include <k3baudiodoc.h>
+#include <k3baudiotrack.h>
+
+
+K3bAudioProjectInterface::K3bAudioProjectInterface( K3bAudioDoc* doc, const char* name )
+ : K3bProjectInterface( doc, name ),
+ m_audioDoc(doc)
+{
+}
+
+
+int K3bAudioProjectInterface::trackCount() const
+{
+ return m_audioDoc->numOfTracks();
+}
+
+
+QString K3bAudioProjectInterface::title() const
+{
+ return m_audioDoc->title();
+}
+
+
+QString K3bAudioProjectInterface::artist() const
+{
+ return m_audioDoc->artist();
+}
+
+
+QString K3bAudioProjectInterface::trackTitle( int trackNum ) const
+{
+ K3bAudioTrack* track = m_audioDoc->getTrack( trackNum );
+ if( track )
+ return track->title();
+ else
+ return QString::null;
+}
+
+
+QString K3bAudioProjectInterface::trackArtist( int trackNum ) const
+{
+ K3bAudioTrack* track = m_audioDoc->getTrack( trackNum );
+ if( track )
+ return track->artist();
+ else
+ return QString::null;
+}
+
+
+void K3bAudioProjectInterface::setTitle( const QString& title )
+{
+ m_audioDoc->setTitle( title );
+}
+
+
+void K3bAudioProjectInterface::setArtist( const QString& artist )
+{
+ m_audioDoc->setArtist( artist );
+}
+
+
+void K3bAudioProjectInterface::setTrackTitle( int trackNum, const QString& title )
+{
+ K3bAudioTrack* track = m_audioDoc->getTrack( trackNum );
+ if( track )
+ track->setTitle( title );
+}
+
+
+void K3bAudioProjectInterface::setTrackArtist( int trackNum, const QString& artist )
+{
+ K3bAudioTrack* track = m_audioDoc->getTrack( trackNum );
+ if( track )
+ track->setArtist( artist );
+}
diff --git a/src/k3baudioprojectinterface.h b/src/k3baudioprojectinterface.h
new file mode 100644
index 0000000..e7d649e
--- /dev/null
+++ b/src/k3baudioprojectinterface.h
@@ -0,0 +1,63 @@
+/*
+ *
+ * $Id: k3baudioprojectinterface.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef _K3B_AUDIO_PROJECT_INTERFACE_H_
+#define _K3B_AUDIO_PROJECT_INTERFACE_H_
+
+#include "k3bprojectinterface.h"
+
+class K3bAudioDoc;
+
+
+class K3bAudioProjectInterface : public K3bProjectInterface
+{
+ K_DCOP
+
+ public:
+ K3bAudioProjectInterface( K3bAudioDoc*, const char* name = 0 );
+
+ k_dcop:
+ int trackCount() const;
+ QString title() const;
+ QString artist() const;
+ QString trackTitle( int trackNum ) const;
+ QString trackArtist( int trackNum ) const;
+
+ /**
+ * Set the global CD-Text title field.
+ */
+ void setTitle( const QString& title );
+
+ /**
+ * Set the global CD-Text artist field.
+ */
+ void setArtist( const QString& artist );
+
+ /**
+ * Set the track CD-Text title field.
+ */
+ void setTrackTitle( int trackNum, const QString& title );
+
+ /**
+ * Set the track CD-Text artist field.
+ */
+ void setTrackArtist( int trackNum, const QString& artist );
+
+ private:
+ K3bAudioDoc* m_audioDoc;
+};
+
+#endif
diff --git a/src/k3bburnprogressdialog.cpp b/src/k3bburnprogressdialog.cpp
new file mode 100644
index 0000000..a5ad3a4
--- /dev/null
+++ b/src/k3bburnprogressdialog.cpp
@@ -0,0 +1,134 @@
+/*
+ *
+ * $Id$
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bburnprogressdialog.h"
+
+#include "k3bapplication.h"
+#include "k3bjob.h"
+#include <k3bdevice.h>
+#include "k3bstdguiitems.h"
+#include "k3bthemedlabel.h"
+#include <k3bthememanager.h>
+
+#include <kglobal.h>
+#include <kprogress.h>
+#include <klocale.h>
+
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qframe.h>
+
+
+K3bBurnProgressDialog::K3bBurnProgressDialog( QWidget *parent, const char *name, bool showSubProgress,
+ bool modal, WFlags wf )
+ : K3bJobProgressDialog(parent,name, showSubProgress, modal, wf)
+{
+ m_labelWritingSpeed = new QLabel( m_frameExtraInfo, "m_labelWritingSpeed" );
+ // m_labelWritingSpeed->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) );
+
+ m_frameExtraInfoLayout->addWidget( m_labelWritingSpeed, 2, 0 );
+ m_frameExtraInfoLayout->addWidget( new QLabel( i18n("Estimated writing speed:"), m_frameExtraInfo ), 1, 0 );
+
+ m_labelWriter = new K3bThemedLabel( m_frameExtraInfo );
+ m_labelWriter->setFrameShape( QFrame::StyledPanel );
+ m_labelWriter->setFrameShadow( QFrame::Sunken );
+ m_labelWriter->setLineWidth( 1 );
+ m_labelWriter->setMargin( 5 );
+ QFont textLabel14_font( m_labelWriter->font() );
+ textLabel14_font.setBold( true );
+ m_labelWriter->setFont( textLabel14_font );
+
+ m_frameExtraInfoLayout->addMultiCellWidget( m_labelWriter, 0, 0, 0, 3 );
+ m_frameExtraInfoLayout->addWidget( new QLabel( i18n("Software buffer:"), m_frameExtraInfo ), 1, 2 );
+ m_frameExtraInfoLayout->addWidget( new QLabel( i18n("Device buffer:"), m_frameExtraInfo ), 2, 2 );
+
+ m_progressWritingBuffer = new KProgress( m_frameExtraInfo, "m_progressWritingBuffer" );
+ m_frameExtraInfoLayout->addWidget( m_progressWritingBuffer, 1, 3 );
+
+ m_progressDeviceBuffer = new KProgress( m_frameExtraInfo );
+ m_frameExtraInfoLayout->addWidget( m_progressDeviceBuffer, 2, 3 );
+ m_frameExtraInfoLayout->addMultiCellWidget( K3bStdGuiItems::verticalLine( m_frameExtraInfo ), 1, 2, 1, 1 );
+}
+
+K3bBurnProgressDialog::~K3bBurnProgressDialog()
+{
+}
+
+
+void K3bBurnProgressDialog::setJob( K3bJob* job )
+{
+ if( K3bBurnJob* burnJob = dynamic_cast<K3bBurnJob*>(job) )
+ setBurnJob(burnJob);
+ else
+ K3bJobProgressDialog::setJob(job);
+}
+
+
+void K3bBurnProgressDialog::setBurnJob( K3bBurnJob* burnJob )
+{
+ K3bJobProgressDialog::setJob(burnJob);
+
+ if( burnJob ) {
+ connect( burnJob, SIGNAL(bufferStatus(int)), this, SLOT(slotBufferStatus(int)) );
+ connect( burnJob, SIGNAL(deviceBuffer(int)), this, SLOT(slotDeviceBuffer(int)) );
+ connect( burnJob, SIGNAL(writeSpeed(int, int)), this, SLOT(slotWriteSpeed(int, int)) );
+ connect( burnJob, SIGNAL(burning(bool)), m_progressWritingBuffer, SLOT(setEnabled(bool)) );
+ connect( burnJob, SIGNAL(burning(bool)), m_progressDeviceBuffer, SLOT(setEnabled(bool)) );
+ connect( burnJob, SIGNAL(burning(bool)), m_labelWritingSpeed, SLOT(setEnabled(bool)) );
+
+ if( burnJob->writer() )
+ m_labelWriter->setText( i18n("Writer: %1 %2").arg(burnJob->writer()->vendor()).
+ arg(burnJob->writer()->description()) );
+
+ m_labelWritingSpeed->setText( i18n("no info") );
+ m_progressWritingBuffer->setFormat( i18n("no info") );
+ m_progressDeviceBuffer->setFormat( i18n("no info") );
+ }
+}
+
+
+void K3bBurnProgressDialog::slotFinished( bool success )
+{
+ K3bJobProgressDialog::slotFinished( success );
+ if( success ) {
+ m_labelWritingSpeed->setEnabled( false );
+ m_progressWritingBuffer->setEnabled( false );
+ m_progressDeviceBuffer->setEnabled( false );
+ }
+}
+
+
+void K3bBurnProgressDialog::slotBufferStatus( int b )
+{
+ m_progressWritingBuffer->setFormat( "%p%" );
+ m_progressWritingBuffer->setValue( b );
+}
+
+
+void K3bBurnProgressDialog::slotDeviceBuffer( int b )
+{
+ m_progressDeviceBuffer->setFormat( "%p%" );
+ m_progressDeviceBuffer->setValue( b );
+}
+
+
+void K3bBurnProgressDialog::slotWriteSpeed( int s, int multiplicator )
+{
+ m_labelWritingSpeed->setText( QString("%1 KB/s (%2x)").arg(s).arg(KGlobal::locale()->formatNumber((double)s/(double)multiplicator,2)) );
+}
+
+#include "k3bburnprogressdialog.moc"
diff --git a/src/k3bburnprogressdialog.h b/src/k3bburnprogressdialog.h
new file mode 100644
index 0000000..db27ddb
--- /dev/null
+++ b/src/k3bburnprogressdialog.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * $Id: k3bburnprogressdialog.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BBURNPROGRESSDIALOG_H
+#define K3BBURNPROGRESSDIALOG_H
+
+#include <k3bjobprogressdialog.h>
+
+class K3bBurnJob;
+class KProgress;
+class QLabel;
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bBurnProgressDialog : public K3bJobProgressDialog {
+
+ Q_OBJECT
+
+ public:
+ K3bBurnProgressDialog( QWidget* parent = 0, const char* name = 0, bool showSubProgress = true,
+ bool modal = true, WFlags = 0 );
+ ~K3bBurnProgressDialog();
+
+ void setJob( K3bJob* );
+ void setBurnJob( K3bBurnJob* );
+
+ protected slots:
+ void slotWriteSpeed( int, int );
+ void slotBufferStatus( int );
+ void slotDeviceBuffer( int );
+ void slotFinished(bool);
+
+ protected:
+ QLabel* m_labelWriter;
+ KProgress* m_progressWritingBuffer;
+ KProgress* m_progressDeviceBuffer;
+ QLabel* m_labelWritingSpeed;
+};
+
+#endif
diff --git a/src/k3bcontentsview.cpp b/src/k3bcontentsview.cpp
new file mode 100644
index 0000000..304ae0d
--- /dev/null
+++ b/src/k3bcontentsview.cpp
@@ -0,0 +1,86 @@
+/*
+ *
+ * $Id: k3bcdcontentsview.cpp 582796 2006-09-10 15:31:38Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include "k3bcontentsview.h"
+
+#include <k3bthemedheader.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+
+
+K3bContentsView::K3bContentsView( bool withHeader,
+ QWidget* parent,
+ const char* name )
+ : QWidget( parent, name ),
+ m_header(0),
+ m_centerWidget(0)
+{
+ if( withHeader ) {
+ QVBoxLayout* lay = new QVBoxLayout( this );
+ lay->setMargin( 2 );
+ lay->setSpacing( 0 );
+
+ m_header = new K3bThemedHeader( this );
+ lay->addWidget( m_header );
+
+ m_header->setLeftPixmap( K3bTheme::MEDIA_LEFT );
+ m_header->setRightPixmap( K3bTheme::MEDIA_NONE );
+ }
+}
+
+
+K3bContentsView::~K3bContentsView()
+{
+}
+
+
+void K3bContentsView::setMainWidget( QWidget* w )
+{
+ m_centerWidget = w;
+ ((QVBoxLayout*)layout())->addWidget( w );
+}
+
+
+QWidget* K3bContentsView::mainWidget()
+{
+ if( !m_centerWidget )
+ setMainWidget( new QWidget( this ) );
+ return m_centerWidget;
+}
+
+
+void K3bContentsView::setTitle( const QString& s )
+{
+ if( m_header )
+ m_header->setTitle( s );
+}
+
+
+void K3bContentsView::setLeftPixmap( K3bTheme::PixmapType s )
+{
+ if( m_header )
+ m_header->setLeftPixmap( s );
+}
+
+
+void K3bContentsView::setRightPixmap( K3bTheme::PixmapType s )
+{
+ if( m_header )
+ m_header->setRightPixmap( s );
+}
+
+#include "k3bcontentsview.moc"
diff --git a/src/k3bcontentsview.h b/src/k3bcontentsview.h
new file mode 100644
index 0000000..a3b6f45
--- /dev/null
+++ b/src/k3bcontentsview.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * $Id: k3bcdcontentsview.h 576315 2006-08-23 19:32:42Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef _K3B_CONTENTS_VIEW_H_
+#define _K3B_CONTENTS_VIEW_H_
+
+#include <qwidget.h>
+#include <k3bthememanager.h>
+
+class K3bThemedHeader;
+
+
+class K3bContentsView : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ virtual ~K3bContentsView();
+
+ protected:
+ K3bContentsView( bool withHeader,
+ QWidget* parent = 0,
+ const char* name = 0 );
+
+ QWidget* mainWidget();
+ void setMainWidget( QWidget* );
+ void setTitle( const QString& );
+ void setLeftPixmap( K3bTheme::PixmapType );
+ void setRightPixmap( K3bTheme::PixmapType );
+
+ private:
+ K3bThemedHeader* m_header;
+ QWidget* m_centerWidget;
+};
+
+#endif
diff --git a/src/k3bdatamodewidget.cpp b/src/k3bdatamodewidget.cpp
new file mode 100644
index 0000000..669da59
--- /dev/null
+++ b/src/k3bdatamodewidget.cpp
@@ -0,0 +1,106 @@
+/*
+ *
+ * $Id: k3bdatamodewidget.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bdatamodewidget.h"
+#include <k3bglobals.h>
+
+#include <klocale.h>
+#include <kconfig.h>
+
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+
+static const int s_autoIndex = 0;
+static const int s_mode1Index = 1;
+static const int s_mode2Index = 2;
+
+
+K3bDataModeWidget::K3bDataModeWidget( QWidget* parent, const char* name )
+ : QComboBox( false, parent, name )
+{
+ insertItem( i18n("Auto"), s_autoIndex );
+ insertItem( i18n("Mode1"), s_mode1Index );
+ insertItem( i18n("Mode2"), s_mode2Index );
+
+ QToolTip::add( this,i18n("Select the mode for the data-track") );
+ QWhatsThis::add( this, i18n("<p><b>Data Mode</b>"
+ "<p>Data tracks may be written in two different modes:</p>"
+ "<p><b>Auto</b><br>"
+ "Let K3b select the best suited data mode.</p>"
+ "<p><b>Mode 1</b><br>"
+ "This is the <em>original</em> writing mode as introduced in the "
+ "<em>Yellow Book</em> standard. It is the preferred mode when writing "
+ "pure data CDs.</p>"
+ "<p><b>Mode 2</b><br>"
+ "To be exact <em>XA Mode 2 Form 1</em>, but since the "
+ "other modes are rarely used it is common to refer to it as <em>Mode 2</em>.</p>"
+ "<p><b>Be aware:</b> Do not mix different modes on one CD. "
+ "Some older drives may have problems reading mode 1 multisession CDs.") );
+}
+
+
+K3bDataModeWidget::~K3bDataModeWidget()
+{
+}
+
+
+int K3bDataModeWidget::dataMode() const
+{
+ if( currentItem() == s_autoIndex )
+ return K3b::DATA_MODE_AUTO;
+ else if( currentItem() == s_mode1Index )
+ return K3b::MODE1;
+ else
+ return K3b::MODE2;
+}
+
+
+void K3bDataModeWidget::setDataMode( int mode )
+{
+ if( mode == K3b::MODE1 )
+ setCurrentItem( s_mode1Index );
+ else if( mode == K3b::MODE2 )
+ setCurrentItem( s_mode2Index );
+ else
+ setCurrentItem( s_autoIndex );
+}
+
+
+void K3bDataModeWidget::saveConfig( KConfigBase* c )
+{
+ QString datamode;
+ if( dataMode() == K3b::MODE1 )
+ datamode = "mode1";
+ else if( dataMode() == K3b::MODE2 )
+ datamode = "mode2";
+ else
+ datamode = "auto";
+ c->writeEntry( "data_track_mode", datamode );
+}
+
+
+void K3bDataModeWidget::loadConfig( KConfigBase* c )
+{
+ QString datamode = c->readEntry( "data_track_mode" );
+ if( datamode == "mode1" )
+ setDataMode( K3b::MODE1 );
+ else if( datamode == "mode2" )
+ setDataMode( K3b::MODE2 );
+ else
+ setDataMode( K3b::DATA_MODE_AUTO );
+}
+
+#include "k3bdatamodewidget.moc"
diff --git a/src/k3bdatamodewidget.h b/src/k3bdatamodewidget.h
new file mode 100644
index 0000000..647225f
--- /dev/null
+++ b/src/k3bdatamodewidget.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * $Id: k3bdatamodewidget.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef _K3B_DATAMODE_WIDGET_H_
+#define _K3B_DATAMODE_WIDGET_H_
+
+#include <qcombobox.h>
+
+
+class KConfigBase;
+
+
+class K3bDataModeWidget : public QComboBox
+{
+ Q_OBJECT
+
+ public:
+ K3bDataModeWidget( QWidget* parent = 0, const char* name = 0 );
+ ~K3bDataModeWidget();
+
+ /**
+ * returnes K3b::DataMode
+ */
+ int dataMode() const;
+
+ void saveConfig( KConfigBase* );
+ void loadConfig( KConfigBase* );
+
+ public slots:
+ void setDataMode( int );
+};
+
+#endif
diff --git a/src/k3bdataprojectinterface.cpp b/src/k3bdataprojectinterface.cpp
new file mode 100644
index 0000000..6adf07d
--- /dev/null
+++ b/src/k3bdataprojectinterface.cpp
@@ -0,0 +1,128 @@
+/*
+ *
+ * $Id: k3bdataprojectinterface.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include "k3bdataprojectinterface.h"
+
+#include <k3bdatadoc.h>
+#include <k3bdiritem.h>
+#include <k3bisooptions.h>
+
+
+K3bDataProjectInterface::K3bDataProjectInterface( K3bDataDoc* doc, const char* name )
+ : K3bProjectInterface( doc, name ),
+ m_dataDoc(doc)
+{
+}
+
+
+K3bDataProjectInterface::~K3bDataProjectInterface()
+{
+}
+
+
+bool K3bDataProjectInterface::createFolder( const QString& name )
+{
+ return createFolder( name, "/" );
+}
+
+
+bool K3bDataProjectInterface::createFolder( const QString& name, const QString& parent )
+{
+ K3bDataItem* p = m_dataDoc->root()->findByPath( parent );
+ if( p && p->isDir() && !static_cast<K3bDirItem*>(p)->find( name ) ) {
+ m_dataDoc->addEmptyDir( name, static_cast<K3bDirItem*>(p) );
+ return true;
+ }
+ return false;
+}
+
+
+void K3bDataProjectInterface::addUrl( const QString& url, const QString& parent )
+{
+ addUrls( QStringList(url), parent );
+}
+
+
+void K3bDataProjectInterface::addUrls( const QStringList& urls, const QString& parent )
+{
+ K3bDataItem* p = m_dataDoc->root()->findByPath( parent );
+ if( p && p->isDir() )
+ m_dataDoc->addUrls( KURL::List(urls), static_cast<K3bDirItem*>(p) );
+}
+
+
+bool K3bDataProjectInterface::removeItem( const QString& path )
+{
+ K3bDataItem* p = m_dataDoc->root()->findByPath( path );
+ if( p && p->isRemoveable() ) {
+ m_dataDoc->removeItem( p );
+ return true;
+ }
+ else
+ return false;
+}
+
+
+bool K3bDataProjectInterface::renameItem( const QString& path, const QString& newName )
+{
+ K3bDataItem* p = m_dataDoc->root()->findByPath( path );
+ if( p && p->isRenameable() && !newName.isEmpty() ) {
+ p->setK3bName( newName );
+ return true;
+ }
+ else
+ return false;
+}
+
+
+void K3bDataProjectInterface::setVolumeID( const QString& id )
+{
+ m_dataDoc->setVolumeID( id );
+}
+
+bool K3bDataProjectInterface::isFolder( const QString& path ) const
+{
+ K3bDataItem* p = m_dataDoc->root()->findByPath( path );
+ if( p )
+ return p->isDir();
+ else
+ return false;
+}
+
+
+QStringList K3bDataProjectInterface::children( const QString& path ) const
+{
+ QStringList l;
+ K3bDataItem* item = m_dataDoc->root()->findByPath( path );
+ if( item && item->isDir() ) {
+ const QPtrList<K3bDataItem>& cl = static_cast<K3bDirItem*>(item)->children();
+ for( QPtrListIterator<K3bDataItem> it( cl ); *it; ++it )
+ l.append( it.current()->k3bName() );
+ }
+
+ return l;
+}
+
+
+bool K3bDataProjectInterface::setSortWeight( const QString& path, long weight ) const
+{
+ K3bDataItem* item = m_dataDoc->root()->findByPath( path );
+ if( item ) {
+ item->setSortWeight( weight );
+ return true;
+ }
+ else
+ return false;
+}
diff --git a/src/k3bdataprojectinterface.h b/src/k3bdataprojectinterface.h
new file mode 100644
index 0000000..689455b
--- /dev/null
+++ b/src/k3bdataprojectinterface.h
@@ -0,0 +1,105 @@
+/*
+ *
+ * $Id: k3bdataprojectinterface.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef _K3B_DATA_PROJECT_INTERFACE_H_
+#define _K3B_DATA_PROJECT_INTERFACE_H_
+
+#include "k3bprojectinterface.h"
+
+#include <qstringlist.h>
+
+class K3bDataDoc;
+
+
+class K3bDataProjectInterface : public K3bProjectInterface
+{
+ K_DCOP
+
+ public:
+ K3bDataProjectInterface( K3bDataDoc*, const char* name = 0 );
+ ~K3bDataProjectInterface();
+
+ k_dcop:
+ /**
+ * Create a new folder in the root of the doc.
+ * This is the same as calling createFolder( name, "/" )
+ */
+ bool createFolder( const QString& name );
+
+ /**
+ * Create a new folder with name @p name in the folder with the
+ * absolute path @p parent.
+ *
+ * \return true if the folder was created successfully, false if
+ * an item with the same name already exists or the parent
+ * directory could not be found.
+ *
+ * Example: createFolder( "test", "/foo/bar" ) will create the
+ * folder /foo/bar/test.
+ */
+ bool createFolder( const QString& name, const QString& parent );
+
+ /**
+ * Add urls to a specific folder in the project.
+ *
+ * Example: addUrl( "test.txt", "/foo/bar" ) will add the file test.txt
+ * to folder /foo/bar.
+ */
+ void addUrl( const QString& url, const QString& parent );
+
+ void addUrls( const QStringList& urls, const QString& parent );
+
+ /**
+ * Remove an item
+ * \return true if the item was successfully removed.
+ */
+ bool removeItem( const QString& path );
+
+ /**
+ * Rename an item
+ * \return true if the item was successfully renamed, false if
+ * no item could be found at \p path, \p newName is empty,
+ * or the item cannot be renamed for some reason.
+ */
+ bool renameItem( const QString& path, const QString& newName );
+
+ /**
+ * Set the volume ID of the data project. This is the name shown by Windows
+ * when the CD is inserted.
+ */
+ void setVolumeID( const QString& id );
+
+ /**
+ * \return true if the specified path exists in the project and it is a folder.
+ */
+ bool isFolder( const QString& path ) const;
+
+ /**
+ * \return the names of the child elements of the item determined by path.
+ */
+ QStringList children( const QString& path ) const;
+
+ /**
+ * Set the sort weight of an item
+ * \return false if the item at \p could not be found.
+ */
+ bool setSortWeight( const QString& path, long weight ) const;
+
+ private:
+ K3bDataDoc* m_dataDoc;
+};
+
+#endif
diff --git a/src/k3bdebuggingoutputdialog.cpp b/src/k3bdebuggingoutputdialog.cpp
new file mode 100644
index 0000000..7ffe84c
--- /dev/null
+++ b/src/k3bdebuggingoutputdialog.cpp
@@ -0,0 +1,162 @@
+/*
+ *
+ * $Id: k3bdebuggingoutputdialog.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include "k3bdebuggingoutputdialog.h"
+
+#include <k3bdevicemanager.h>
+#include <k3bdevice.h>
+#include <k3bdeviceglobals.h>
+#include <k3bcore.h>
+#include <k3bversion.h>
+#include <k3bglobals.h>
+
+#include <qtextedit.h>
+#include <qcursor.h>
+#include <qfile.h>
+#include <qclipboard.h>
+
+#include <klocale.h>
+#include <kstdguiitem.h>
+#include <kglobalsettings.h>
+#include <kapplication.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+
+
+K3bDebuggingOutputDialog::K3bDebuggingOutputDialog( QWidget* parent )
+ : KDialogBase( parent, "debugViewDialog", true, i18n("Debugging Output"), Close|User1|User2, Close,
+ false,
+ KStdGuiItem::saveAs(),
+ KGuiItem( i18n("Copy"), "editcopy" ) )
+{
+ setButtonTip( User1, i18n("Save to file") );
+ setButtonTip( User2, i18n("Copy to clipboard") );
+
+ debugView = new QTextEdit( this );
+ debugView->setReadOnly(true);
+ debugView->setTextFormat( QTextEdit::PlainText );
+ debugView->setCurrentFont( KGlobalSettings::fixedFont() );
+ debugView->setWordWrap( QTextEdit::NoWrap );
+
+ setMainWidget( debugView );
+
+ resize( 600, 300 );
+}
+
+
+void K3bDebuggingOutputDialog::setOutput( const QMap<QString, QStringList>& map )
+{
+ // the following may take some time
+ QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
+
+ clear();
+
+ // add the debugging output
+ for( QMap<QString, QStringList>::ConstIterator itMap = map.begin(); itMap != map.end(); ++itMap ) {
+ const QStringList& list = itMap.data();
+ debugView->append( itMap.key() + "\n" );
+ debugView->append( "-----------------------\n" );
+ for( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) {
+ QStringList lines = QStringList::split( "\n", *it );
+ // do every line
+ QStringList::ConstIterator end( lines.end() );
+ for( QStringList::ConstIterator str = lines.begin(); str != end; ++str )
+ debugView->append( *str + "\n" );
+ }
+ m_paragraphMap[itMap.key()] = debugView->paragraphs();
+ debugView->append( "\n" );
+ }
+
+ QApplication::restoreOverrideCursor();
+}
+
+
+void K3bDebuggingOutputDialog::addOutput( const QString& app, const QString& msg )
+{
+ QMap<QString, int>::Iterator it = m_paragraphMap.find( app );
+
+ if( it == m_paragraphMap.end() ) {
+ // create new section
+ debugView->append( app + "\n" );
+ debugView->append( "-----------------------\n" );
+ debugView->append( msg + "\n" );
+ m_paragraphMap[app] = debugView->paragraphs();
+ debugView->append( "\n" );
+ }
+ else {
+ debugView->insertParagraph( msg, *it );
+ // update the paragraphs map
+ // FIXME: we cannot count on the map to be sorted properly!
+ while( it != m_paragraphMap.end() ) {
+ it.data() += 1;
+ ++it;
+ }
+ }
+}
+
+
+void K3bDebuggingOutputDialog::clear()
+{
+ debugView->clear();
+ m_paragraphMap.clear();
+
+ addOutput( "System", "K3b Version: " + k3bcore->version() );
+ addOutput( "System", "KDE Version: " + QString(KDE::versionString()) );
+ addOutput( "System", "QT Version: " + QString(qVersion()) );
+ addOutput( "System", "Kernel: " + K3b::kernelVersion() );
+
+ // devices in the logfile
+ for( QPtrListIterator<K3bDevice::Device> it( k3bcore->deviceManager()->allDevices() ); *it; ++it ) {
+ K3bDevice::Device* dev = *it;
+ addOutput( "Devices",
+ QString( "%1 (%2, %3) [%5] [%6] [%7]" )
+ .arg( dev->vendor() + " " + dev->description() + " " + dev->version() )
+ .arg( dev->blockDeviceName() )
+ .arg( dev->genericDevice() )
+ .arg( K3bDevice::deviceTypeString( dev->type() ) )
+ .arg( K3bDevice::mediaTypeString( dev->supportedProfiles() ) )
+ .arg( K3bDevice::writingModeString( dev->writingModes() ) ) );
+ }
+}
+
+
+void K3bDebuggingOutputDialog::slotUser1()
+{
+ QString filename = KFileDialog::getSaveFileName();
+ if( !filename.isEmpty() ) {
+ QFile f( filename );
+ if( !f.exists() || KMessageBox::warningContinueCancel( this,
+ i18n("Do you want to overwrite %1?").arg(filename),
+ i18n("File Exists"), i18n("Overwrite") )
+ == KMessageBox::Continue ) {
+
+ if( f.open( IO_WriteOnly ) ) {
+ QTextStream t( &f );
+ t << debugView->text();
+ }
+ else {
+ KMessageBox::error( this, i18n("Could not open file %1").arg(filename) );
+ }
+ }
+ }
+}
+
+
+void K3bDebuggingOutputDialog::slotUser2()
+{
+ QApplication::clipboard()->setText( debugView->text(), QClipboard::Clipboard );
+}
+
+#include "k3bdebuggingoutputdialog.moc"
diff --git a/src/k3bdebuggingoutputdialog.h b/src/k3bdebuggingoutputdialog.h
new file mode 100644
index 0000000..0e74b71
--- /dev/null
+++ b/src/k3bdebuggingoutputdialog.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * $Id: k3bdebuggingoutputdialog.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#ifndef _K3B_DEBUGGING_OUTPUT_DIALOG_H_
+#define _K3B_DEBUGGING_OUTPUT_DIALOG_H_
+
+#include <kdialogbase.h>
+#include <qmap.h>
+
+class QTextEdit;
+
+class K3bDebuggingOutputDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ K3bDebuggingOutputDialog( QWidget* parent );
+
+ public slots:
+ void setOutput( const QMap<QString, QStringList>& );
+ void addOutput( const QString&, const QString& );
+ void clear();
+
+ private:
+ void slotUser1();
+ void slotUser2();
+
+ QTextEdit* debugView;
+ QMap<QString, int> m_paragraphMap;
+};
+
+
+
+#endif
diff --git a/src/k3bdebuggingoutputfile.cpp b/src/k3bdebuggingoutputfile.cpp
new file mode 100644
index 0000000..2f99e96
--- /dev/null
+++ b/src/k3bdebuggingoutputfile.cpp
@@ -0,0 +1,75 @@
+/*
+ *
+ * $Id: k3bdebuggingoutputfile.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include "k3bdebuggingoutputfile.h"
+
+#include <k3bdevicemanager.h>
+#include <k3bdevice.h>
+#include <k3bcore.h>
+#include <k3bversion.h>
+#include <k3bdeviceglobals.h>
+#include <k3bglobals.h>
+
+#include <kstandarddirs.h>
+#include <kglobalsettings.h>
+#include <kapplication.h>
+
+#include <qtextstream.h>
+
+
+K3bDebuggingOutputFile::K3bDebuggingOutputFile()
+ : QFile( locateLocal( "appdata", "lastlog.log", true ) )
+{
+}
+
+
+bool K3bDebuggingOutputFile::open()
+{
+ if( !QFile::open( IO_WriteOnly ) )
+ return false;
+
+ addOutput( "System", "K3b Version: " + k3bcore->version() );
+ addOutput( "System", "KDE Version: " + QString(KDE::versionString()) );
+ addOutput( "System", "QT Version: " + QString(qVersion()) );
+ addOutput( "System", "Kernel: " + K3b::kernelVersion() );
+
+ // devices in the logfile
+ for( QPtrListIterator<K3bDevice::Device> it( k3bcore->deviceManager()->allDevices() ); *it; ++it ) {
+ K3bDevice::Device* dev = *it;
+ addOutput( "Devices",
+ QString( "%1 (%2, %3) [%5] [%6] [%7]" )
+ .arg( dev->vendor() + " " + dev->description() + " " + dev->version() )
+ .arg( dev->blockDeviceName() )
+ .arg( dev->genericDevice() )
+ .arg( K3bDevice::deviceTypeString( dev->type() ) )
+ .arg( K3bDevice::mediaTypeString( dev->supportedProfiles() ) )
+ .arg( K3bDevice::writingModeString( dev->writingModes() ) ) );
+ }
+
+ return true;
+}
+
+
+void K3bDebuggingOutputFile::addOutput( const QString& app, const QString& msg )
+{
+ if( !isOpen() )
+ open();
+
+ QTextStream s( this );
+ s << "[" << app << "] " << msg << endl;
+ flush();
+}
+
+#include "k3bdebuggingoutputfile.moc"
diff --git a/src/k3bdebuggingoutputfile.h b/src/k3bdebuggingoutputfile.h
new file mode 100644
index 0000000..c0af0e5
--- /dev/null
+++ b/src/k3bdebuggingoutputfile.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * $Id: k3bdebuggingoutputfile.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#ifndef _K3B_DEBUGGING_OUTPUT_FILE_H_
+#define _K3B_DEBUGGING_OUTPUT_FILE_H_
+
+#include <qfile.h>
+#include <qobject.h>
+
+class K3bDebuggingOutputFile : public QObject, public QFile
+{
+ Q_OBJECT
+
+ public:
+ K3bDebuggingOutputFile();
+
+ /**
+ * Open the default output file and write some system information.
+ */
+ bool open();
+
+ public slots:
+ void addOutput( const QString&, const QString& );
+};
+
+
+#endif
diff --git a/src/k3bdiroperator.cpp b/src/k3bdiroperator.cpp
new file mode 100644
index 0000000..12c6ba4
--- /dev/null
+++ b/src/k3bdiroperator.cpp
@@ -0,0 +1,159 @@
+
+/*
+ *
+ * $Id: k3bdiroperator.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bdiroperator.h"
+
+#include <k3bapplication.h>
+#include <k3b.h>
+#include <k3bcore.h>
+
+#include <kcombiview.h>
+#include <kfilepreview.h>
+#include <kaction.h>
+#include <kbookmarkmenu.h>
+#include <kstandarddirs.h>
+#include <kpopupmenu.h>
+
+#include <qdir.h>
+
+
+K3bDirOperator::K3bDirOperator(const KURL& url, QWidget* parent, const char* name )
+ : KDirOperator( url, parent, name )
+{
+ setViewConfig( k3bcore->config(), "file view" );
+ setMode( KFile::Files );
+
+ // disable the del-key since we still have a focus problem and users keep
+ // deleting files when they want to remove project entries
+ KAction* aDelete = actionCollection()->action("delete");
+ if( aDelete )
+ aDelete->setShortcut( 0 );
+
+ // add the bookmark stuff
+ KBookmarkManager* bmMan = KBookmarkManager::managerForFile( locateLocal( "data", "k3b/bookmarks.xml" ), false );
+ bmMan->setEditorOptions( i18n("K3b Bookmarks"), false );
+ bmMan->setUpdate( true );
+ bmMan->setShowNSBookmarks( false );
+
+ m_bmPopup = new KActionMenu( i18n("Bookmarks"), "bookmark", this, "bookmarks" );
+ m_bmMenu = new KBookmarkMenu( bmMan, this, m_bmPopup->popupMenu(), actionCollection(), true );
+
+ (void)new KAction( i18n("&Add to Project"), SHIFT+Key_Return,
+ this, SLOT(slotAddFilesToProject()),
+ actionCollection(), "add_file_to_project");
+}
+
+
+K3bDirOperator::~K3bDirOperator()
+{
+ delete m_bmMenu;
+}
+
+
+void K3bDirOperator::readConfig( KConfig* cfg, const QString& group )
+{
+ QString oldGroup = cfg->group();
+ cfg->setGroup( group );
+
+ KDirOperator::readConfig( cfg, group );
+ setView( KFile::Default );
+
+ //
+ // There seems to be a bug in the KDELibs which makes setURL crash on
+ // some systems when used with a non-existing url
+ //
+ QString lastUrl = cfg->readPathEntry( "last url", QDir::home().absPath() );
+ while( !QFile::exists(lastUrl) ) {
+ QString urlUp = lastUrl.section( '/', 0, -2 );
+ if( urlUp == lastUrl )
+ lastUrl = QDir::home().absPath();
+ else
+ lastUrl = urlUp;
+ }
+
+ setURL( KURL::fromPathOrURL(lastUrl), true );
+
+ cfg->setGroup( oldGroup );
+
+ emit urlEntered( url() );
+}
+
+
+void K3bDirOperator::writeConfig( KConfig* cfg, const QString& group )
+{
+ QString oldGroup = cfg->group();
+ cfg->setGroup( group );
+
+ KDirOperator::writeConfig( cfg, group );
+ cfg->writePathEntry( "last url", url().path() );
+
+ cfg->setGroup( oldGroup );
+}
+
+
+void K3bDirOperator::openBookmarkURL( const QString& url )
+{
+ setURL( KURL::fromPathOrURL( url ), true );
+}
+
+
+QString K3bDirOperator::currentTitle() const
+{
+ return url().path(-1);
+}
+
+
+QString K3bDirOperator::currentURL() const
+{
+ return url().path(-1);
+}
+
+
+void K3bDirOperator::activatedMenu( const KFileItem*, const QPoint& pos )
+{
+ // both from KDirOperator
+ setupMenu();
+ updateSelectionDependentActions();
+
+ // insert our own actions
+ KActionMenu* dirOpMenu = (KActionMenu*)actionCollection()->action("popupMenu");
+ dirOpMenu->insert( new KActionSeparator( actionCollection() ) );
+ dirOpMenu->insert( m_bmPopup );
+
+ dirOpMenu->insert( actionCollection()->action("add_file_to_project"), 0 );
+ dirOpMenu->insert( new KActionSeparator( actionCollection() ), 1 );
+
+ bool hasSelection = view() && view()->selectedItems() &&
+ !view()->selectedItems()->isEmpty();
+ actionCollection()->action("add_file_to_project")->setEnabled( hasSelection && k3bappcore->k3bMainWindow()->activeView() != 0 );
+
+ dirOpMenu->popup( pos );
+}
+
+
+void K3bDirOperator::slotAddFilesToProject()
+{
+ KURL::List files;
+ for( QPtrListIterator<KFileItem> it( *(selectedItems()) ); it.current(); ++it ) {
+ files.append( it.current()->url() );
+ }
+ if( !files.isEmpty() )
+ k3bappcore->k3bMainWindow()->addUrls( files );
+}
+
+#include "k3bdiroperator.moc"
+
diff --git a/src/k3bdiroperator.h b/src/k3bdiroperator.h
new file mode 100644
index 0000000..b231a8d
--- /dev/null
+++ b/src/k3bdiroperator.h
@@ -0,0 +1,82 @@
+/*
+ *
+ * $Id: k3bdiroperator.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BDIROPERATOR_H
+#define K3BDIROPERATOR_H
+
+#include <kdiroperator.h>
+#include <kbookmarkmanager.h>
+
+class QIconViewItem;
+class QListViewItem;
+class KBookmarkMenu;
+class KActionMenu;
+
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bDirOperator : public KDirOperator, public KBookmarkOwner
+{
+ Q_OBJECT
+
+ public:
+ K3bDirOperator( const KURL& urlName = KURL(), QWidget* parent = 0, const char* name = 0 );
+ ~K3bDirOperator();
+
+ /**
+ * reimplemented from KDirOperator
+ */
+ void readConfig( KConfig* cfg, const QString& group );
+
+ /**
+ * reimplemented from KDirOperator
+ */
+ void writeConfig( KConfig* cfg, const QString& group );
+
+ /**
+ * reimplemented from KBookmarkOwner
+ */
+ void openBookmarkURL( const QString& url );
+
+ /**
+ * reimplemented from KBookmarkOwner
+ */
+ QString currentTitle() const;
+
+ /**
+ * reimplemented from KBookmarkOwner
+ */
+ QString currentURL() const;
+
+ KActionMenu* bookmarkMenu() const { return m_bmPopup; }
+
+ public slots:
+ void slotAddFilesToProject();
+
+ protected slots:
+ /**
+ * reimplemented from KDirOperator
+ */
+ void activatedMenu( const KFileItem*, const QPoint& );
+
+ private:
+ KBookmarkMenu* m_bmMenu;
+ KActionMenu* m_bmPopup;
+};
+
+#endif
diff --git a/src/k3bdirview.cpp b/src/k3bdirview.cpp
new file mode 100644
index 0000000..d711300
--- /dev/null
+++ b/src/k3bdirview.cpp
@@ -0,0 +1,367 @@
+/*
+ *
+ * $Id: k3bdirview.cpp 627621 2007-01-27 12:31:44Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include <config.h>
+
+#include "k3bdirview.h"
+#include "k3bapplication.h"
+#include "k3b.h"
+
+#include "rip/k3baudiocdview.h"
+#include "rip/k3bvideocdview.h"
+#ifdef HAVE_LIBDVDREAD
+#include "rip/videodvd/k3bvideodvdrippingview.h"
+#endif
+#include "k3bfileview.h"
+#include "k3bfiletreeview.h"
+#include "k3bappdevicemanager.h"
+#include "k3bdiskinfoview.h"
+#include <k3bdevicehandler.h>
+#include <k3bdevice.h>
+#include <k3bthememanager.h>
+#include <k3bmediacache.h>
+#include <k3bexternalbinmanager.h>
+#include <k3bpassivepopup.h>
+
+#include <unistd.h>
+// QT-includes
+#include <qdir.h>
+#include <qlistview.h>
+#include <qstring.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qpixmap.h>
+#include <qstringlist.h>
+#include <qstrlist.h>
+#include <qheader.h>
+#include <qsplitter.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qiconset.h>
+#include <qvaluelist.h>
+#include <qlabel.h>
+#include <qwidgetstack.h>
+#include <qscrollview.h>
+#include <qpainter.h>
+#include <qsimplerichtext.h>
+
+// KDE-includes
+#include <kmimetype.h>
+#include <kcursor.h>
+#include <kfiledetailview.h>
+#include <ktoolbar.h>
+#include <kiconloader.h>
+#include <kurl.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kio/file.h>
+#include <kio/global.h>
+#include <krun.h>
+#include <kprocess.h>
+#include <kio/job.h>
+#include <kcombobox.h>
+#include <kfiletreeview.h>
+#include <kdialog.h>
+#include <kmessagebox.h>
+#include <kstdaction.h>
+#include <kconfig.h>
+#include <kaction.h>
+#include <kinputdialog.h>
+
+
+
+class K3bDirView::Private
+{
+public:
+ bool contextMediaInfoRequested;
+};
+
+
+
+K3bDirView::K3bDirView(K3bFileTreeView* treeView, QWidget *parent, const char *name )
+ : QVBox(parent, name),
+ m_fileTreeView(treeView),
+ m_bViewDiskInfo(false)
+{
+ d = new Private;
+ d->contextMediaInfoRequested = false;
+
+ if( !m_fileTreeView ) {
+ m_mainSplitter = new QSplitter( this );
+ m_fileTreeView = new K3bFileTreeView( m_mainSplitter );
+ m_viewStack = new QWidgetStack( m_mainSplitter );
+ }
+ else {
+ m_viewStack = new QWidgetStack( this );
+ m_mainSplitter = 0;
+ }
+
+ m_fileTreeView->header()->hide();
+
+ m_fileView = new K3bFileView(m_viewStack, "fileView");
+ m_cdView = new K3bAudioCdView(m_viewStack, "cdview");
+ m_videoView = new K3bVideoCdView(m_viewStack, "videoview");
+ m_infoView = new K3bDiskInfoView(m_viewStack, "infoView");
+#ifdef HAVE_LIBDVDREAD
+ m_movieView = new K3bVideoDVDRippingView(m_viewStack, "movieview");
+#endif
+
+ m_viewStack->raiseWidget( m_fileView );
+
+ m_fileTreeView->addDefaultBranches();
+ m_fileTreeView->addCdDeviceBranches( k3bcore->deviceManager() );
+ m_fileTreeView->setCurrentDevice( k3bappcore->appDeviceManager()->currentDevice() );
+
+ m_fileView->setAutoUpdate( true ); // in case we look at the mounted path
+
+ if( m_mainSplitter ) {
+ // split
+ QValueList<int> sizes = m_mainSplitter->sizes();
+ int all = sizes[0] + sizes[1];
+ sizes[1] = all*2/3;
+ sizes[0] = all - sizes[1];
+ m_mainSplitter->setSizes( sizes );
+ }
+
+ connect( m_fileTreeView, SIGNAL(urlExecuted(const KURL&)),
+ this, SLOT(slotDirActivated(const KURL&)) );
+ connect( m_fileTreeView, SIGNAL(deviceExecuted(K3bDevice::Device*)),
+ this, SLOT(showDevice(K3bDevice::Device*)) );
+ connect( m_fileTreeView, SIGNAL(deviceExecuted(K3bDevice::Device*)),
+ this, SIGNAL(deviceSelected(K3bDevice::Device*)) );
+ connect( m_fileTreeView, SIGNAL(contextMenu(K3bDevice::Device*, const QPoint&)),
+ this, SLOT(slotFileTreeContextMenu(K3bDevice::Device*, const QPoint&)) );
+
+ connect( m_fileView, SIGNAL(urlEntered(const KURL&)), m_fileTreeView, SLOT(followUrl(const KURL&)) );
+ connect( m_fileView, SIGNAL(urlEntered(const KURL&)), this, SIGNAL(urlEntered(const KURL&)) );
+
+ connect( k3bappcore->appDeviceManager(), SIGNAL(mountFinished(const QString&)),
+ this, SLOT(slotMountFinished(const QString&)) );
+ connect( k3bappcore->appDeviceManager(), SIGNAL(unmountFinished(bool)),
+ this, SLOT(slotUnmountFinished(bool)) );
+ connect( k3bappcore->appDeviceManager(), SIGNAL(detectingDiskInfo(K3bDevice::Device*)),
+ this, SLOT(slotDetectingDiskInfo(K3bDevice::Device*)) );
+}
+
+K3bDirView::~K3bDirView()
+{
+ delete d;
+}
+
+
+void K3bDirView::showUrl( const KURL& url )
+{
+ slotDirActivated( url );
+}
+
+
+void K3bDirView::showDevice( K3bDevice::Device* dev )
+{
+ d->contextMediaInfoRequested = true;
+ m_fileTreeView->setSelectedDevice( dev );
+ showMediumInfo( k3bappcore->mediaCache()->medium( dev ) );
+}
+
+
+void K3bDirView::slotDetectingDiskInfo( K3bDevice::Device* dev )
+{
+ d->contextMediaInfoRequested = false;
+ m_fileTreeView->setSelectedDevice( dev );
+ showMediumInfo( k3bappcore->mediaCache()->medium( dev ) );
+}
+
+
+void K3bDirView::showMediumInfo( const K3bMedium& medium )
+{
+ if( !d->contextMediaInfoRequested ||
+ medium.diskInfo().diskState() == K3bDevice::STATE_EMPTY ||
+ medium.diskInfo().diskState() == K3bDevice::STATE_NO_MEDIA ) {
+
+ // show cd info
+ m_viewStack->raiseWidget( m_infoView );
+ m_infoView->reload( medium );
+ return;
+ }
+
+#ifdef HAVE_LIBDVDREAD
+ else if( medium.content() & K3bMedium::CONTENT_VIDEO_DVD ) {
+ KMessageBox::ButtonCode r = KMessageBox::Yes;
+ if( KMessageBox::shouldBeShownYesNo( "videodvdripping", r ) ) {
+ r = (KMessageBox::ButtonCode)
+ KMessageBox::questionYesNoCancel( this,
+ i18n("<p>You have selected the K3b Video DVD ripping tool."
+ "<p>It is intended to <em>rip single titles</em> from a video DVD "
+ "into a compressed format such as XviD. Menu structures are completely ignored."
+ "<p>If you intend to copy the plain Video DVD vob files from the DVD "
+ "(including decryption) for further processing with another application, "
+ "please use the following link to access the Video DVD file structure: "
+ "<a href=\"videodvd:/\">videodvd:/</a>"
+ "<p>If you intend to make a copy of the entire Video DVD including all menus "
+ "and extras it is recommended to use the K3b DVD Copy tool."),
+ i18n("Video DVD ripping"),
+ i18n("Continue"),
+ i18n("Open DVD Copy Dialog"),
+ "videodvdripping",
+ KMessageBox::AllowLink );
+ }
+ else { // if we do not show the dialog we always continue with the ripping. Everything else would be confusing
+ r = KMessageBox::Yes;
+ }
+
+ if( r == KMessageBox::Cancel ) {
+ // m_viewStack->raiseWidget( m_fileView );
+ }
+ else if( r == KMessageBox::No ) {
+ m_viewStack->raiseWidget( m_fileView );
+ static_cast<K3bMainWindow*>( kapp->mainWidget() )->slotDvdCopy();
+ }
+ else {
+ m_movieView->reload( medium );
+ m_viewStack->raiseWidget( m_movieView );
+ }
+
+ return;
+ }
+#endif
+
+ else if( medium.content() & K3bMedium::CONTENT_DATA ) {
+ bool mount = true;
+ if( medium.content() & K3bMedium::CONTENT_VIDEO_CD ) {
+ if( !k3bcore ->externalBinManager() ->foundBin( "vcdxrip" ) ) {
+ KMessageBox::sorry( this,
+ i18n("K3b uses vcdxrip from the vcdimager package to rip Video CDs. "
+ "Please make sure it is installed.") );
+ }
+ else {
+ if( KMessageBox::questionYesNo( this,
+ i18n("Found %1. Do you want K3b to mount the data part "
+ "or show all the tracks?").arg( i18n("Video CD") ),
+ i18n("Video CD"),
+ i18n("Mount CD"),
+ i18n("Show Video Tracks") ) == KMessageBox::No ) {
+ mount = false;
+ m_viewStack->raiseWidget( m_videoView );
+ m_videoView->reload( medium );
+ }
+ }
+ }
+ else if( medium.content() & K3bMedium::CONTENT_AUDIO ) {
+ if( KMessageBox::questionYesNo( this,
+ i18n("Found %1. Do you want K3b to mount the data part "
+ "or show all the tracks?").arg( i18n("Audio CD") ),
+ i18n("Audio CD"),
+ i18n("Mount CD"),
+ i18n("Show Audio Tracks") ) == KMessageBox::No ) {
+ mount = false;
+ m_viewStack->raiseWidget( m_cdView );
+ m_cdView->reload( medium );
+ }
+ }
+
+ if( mount )
+ k3bappcore->appDeviceManager()->mountDisk( medium.device() );
+ }
+
+ else if( medium.content() & K3bMedium::CONTENT_AUDIO ) {
+ m_viewStack->raiseWidget( m_cdView );
+ m_cdView->reload( medium );
+ }
+
+ else {
+ // show cd info
+ m_viewStack->raiseWidget( m_infoView );
+ m_infoView->reload( medium );
+ }
+
+ d->contextMediaInfoRequested = false;
+}
+
+
+void K3bDirView::slotMountFinished( const QString& mp )
+{
+ if( !mp.isEmpty() ) {
+ slotDirActivated( mp );
+ m_fileView->reload(); // HACK to get the contents shown... FIXME
+ }
+ else {
+ m_viewStack->raiseWidget( m_fileView );
+ K3bPassivePopup::showPopup( i18n("<p>K3b was unable to mount medium <b>%1</b> in device <em>%2 - %3</em>")
+ .arg( k3bappcore->mediaCache()->medium( k3bappcore->appDeviceManager()->currentDevice() ).shortString() )
+ .arg( k3bappcore->appDeviceManager()->currentDevice()->vendor() )
+ .arg( k3bappcore->appDeviceManager()->currentDevice()->description() ),
+ i18n("Mount Failed"),
+ K3bPassivePopup::Warning );
+ }
+}
+
+
+void K3bDirView::slotUnmountFinished( bool success )
+{
+ if( success ) {
+ // TODO: check if the fileview is still displaying a folder from the medium
+ }
+ else {
+ K3bPassivePopup::showPopup( i18n("<p>K3b was unable to unmount medium <b>%1</b> in device <em>%2 - %3</em>")
+ .arg( k3bappcore->mediaCache()->medium( k3bappcore->appDeviceManager()->currentDevice() ).shortString() )
+ .arg( k3bappcore->appDeviceManager()->currentDevice()->vendor() )
+ .arg( k3bappcore->appDeviceManager()->currentDevice()->description() ),
+ i18n("Unmount Failed"),
+ K3bPassivePopup::Warning );
+ }
+}
+
+
+void K3bDirView::slotFileTreeContextMenu( K3bDevice::Device* /*dev*/, const QPoint& p )
+{
+ KAction* a = k3bappcore->appDeviceManager()->actionCollection()->action( "device_popup" );
+ if( KActionMenu* m = dynamic_cast<KActionMenu*>(a) )
+ m->popup( p );
+}
+
+
+void K3bDirView::slotDirActivated( const QString& url )
+{
+// m_urlCombo->insertItem( url, 0 );
+ slotDirActivated( KURL::fromPathOrURL(url) );
+}
+
+
+void K3bDirView::slotDirActivated( const KURL& url )
+{
+ m_fileView->setUrl(url, true);
+// m_urlCombo->setEditText( url.path() );
+
+ m_viewStack->raiseWidget( m_fileView );
+}
+
+
+void K3bDirView::home()
+{
+ slotDirActivated( QDir::homeDirPath() );
+}
+
+
+void K3bDirView::saveConfig( KConfig* c )
+{
+ m_fileView->saveConfig(c);
+}
+
+
+void K3bDirView::readConfig( KConfig* c )
+{
+ m_fileView->readConfig(c);
+}
+
+#include "k3bdirview.moc"
diff --git a/src/k3bdirview.h b/src/k3bdirview.h
new file mode 100644
index 0000000..7d4cdf0
--- /dev/null
+++ b/src/k3bdirview.h
@@ -0,0 +1,100 @@
+/*
+ *
+ * $Id: k3bdirview.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BDIRVIEW_H
+#define K3BDIRVIEW_H
+
+#include <qvbox.h>
+
+#include <k3bmedium.h>
+
+class QSplitter;
+class KURL;
+class K3bAudioCdView;
+class K3bVideoCdView;
+class K3bFileView;
+class K3bVideoDVDRippingView;
+class KComboBox;
+class K3bFileTreeView;
+class QWidgetStack;
+class K3bDiskInfoView;
+class QScrollView;
+class QLabel;
+class KConfig;
+class K3bDeviceBranch;
+
+namespace K3bDevice {
+ class Device;
+ class DiskInfo;
+}
+
+namespace KIO {
+ class Job;
+}
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bDirView : public QVBox
+{
+ Q_OBJECT
+
+ public:
+ K3bDirView(K3bFileTreeView* tree, QWidget *parent=0, const char *name=0);
+ ~K3bDirView();
+
+ public slots:
+ void saveConfig( KConfig* c );
+ void readConfig( KConfig* c );
+ void showUrl( const KURL& );
+ void showDevice( K3bDevice::Device* );
+
+ protected slots:
+ void slotDirActivated( const KURL& );
+ void slotDirActivated( const QString& );
+ void slotMountFinished( const QString& );
+ void slotUnmountFinished( bool );
+ void showMediumInfo( const K3bMedium& );
+ void slotDetectingDiskInfo( K3bDevice::Device* dev );
+ void home();
+ void slotFileTreeContextMenu( K3bDevice::Device* dev, const QPoint& p );
+
+ signals:
+ void urlEntered( const KURL& );
+ void deviceSelected( K3bDevice::Device* );
+
+ private:
+ QWidgetStack* m_viewStack;
+ QScrollView* m_scroll;
+
+ K3bAudioCdView* m_cdView;
+ K3bVideoCdView* m_videoView;
+ K3bVideoDVDRippingView* m_movieView;
+ K3bFileView* m_fileView;
+ K3bDiskInfoView* m_infoView;
+
+ KComboBox* m_urlCombo;
+ QSplitter* m_mainSplitter;
+ K3bFileTreeView* m_fileTreeView;
+
+ bool m_bViewDiskInfo;
+
+ class Private;
+ Private* d;
+};
+
+#endif
diff --git a/src/k3bdiskinfoview.cpp b/src/k3bdiskinfoview.cpp
new file mode 100644
index 0000000..4a1208f
--- /dev/null
+++ b/src/k3bdiskinfoview.cpp
@@ -0,0 +1,500 @@
+/*
+ *
+ * $Id: k3bdiskinfoview.cpp 643214 2007-03-16 15:25:24Z trueg $
+ * Copyright (C) 2003-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include <config.h>
+
+
+#include "k3bdiskinfoview.h"
+
+#include <k3bdiskinfo.h>
+#include <k3bcdtext.h>
+#include <k3bdeviceglobals.h>
+#include <k3bglobals.h>
+#include <k3bstdguiitems.h>
+#include <k3blistview.h>
+#include <k3biso9660.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qfont.h>
+#include <qcolor.h>
+#include <qheader.h>
+#include <qstring.h>
+#include <qpainter.h>
+#include <qpalette.h>
+#include <qpixmap.h>
+#include <qregion.h>
+#include <qframe.h>
+
+#include <kdialog.h>
+#include <klocale.h>
+#include <klistview.h>
+#include <kiconloader.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kio/global.h>
+
+
+// FIXME: use K3bListViewItem instead
+class K3bDiskInfoView::HeaderViewItem : public KListViewItem
+{
+public:
+ HeaderViewItem( QListView* parent )
+ : KListViewItem( parent ) {}
+ HeaderViewItem( QListViewItem* parent )
+ : KListViewItem( parent ) {}
+ HeaderViewItem( QListView* parent, QListViewItem* after )
+ : KListViewItem( parent, after ) {}
+ HeaderViewItem( QListViewItem* parent, QListViewItem* after )
+ : KListViewItem( parent, after ) {}
+ HeaderViewItem( QListView* parent, const QString& t1 )
+ : KListViewItem( parent, t1 ) {}
+ HeaderViewItem( QListViewItem* parent, const QString& t1 )
+ : KListViewItem( parent, t1 ) {}
+ HeaderViewItem( QListView* parent, QListViewItem* after, const QString& t1 )
+ : KListViewItem( parent, after, t1 ) {}
+ HeaderViewItem( QListViewItem* parent, QListViewItem* after, const QString& t1 )
+ : KListViewItem( parent, after, t1 ) {}
+
+ void paintCell( QPainter* p, const QColorGroup & cg, int column, int width, int align )
+ {
+ QFont f ( p->font() );
+ f.setBold( true );
+ p->setFont( f );
+ KListViewItem::paintCell( p, cg, column, width, align );
+ }
+};
+
+
+class K3bDiskInfoView::TwoColumnViewItem : public KListViewItem
+{
+public:
+ TwoColumnViewItem( QListView* parent )
+ : KListViewItem( parent ) {}
+ TwoColumnViewItem( QListViewItem* parent )
+ : KListViewItem( parent ) {}
+ TwoColumnViewItem( QListView* parent, QListViewItem* after )
+ : KListViewItem( parent, after ) {}
+ TwoColumnViewItem( QListViewItem* parent, QListViewItem* after )
+ : KListViewItem( parent, after ) {}
+ TwoColumnViewItem( QListView* parent, const QString& t1 )
+ : KListViewItem( parent, t1 ) {}
+ TwoColumnViewItem( QListViewItem* parent, const QString& t1 )
+ : KListViewItem( parent, t1 ) {}
+ TwoColumnViewItem( QListView* parent, QListViewItem* after, const QString& t1 )
+ : KListViewItem( parent, after, t1 ) {}
+ TwoColumnViewItem( QListViewItem* parent, QListViewItem* after, const QString& t1 )
+ : KListViewItem( parent, after, t1 ) {}
+
+ void paintCell( QPainter* p, const QColorGroup & cg, int column, int width, int align )
+ {
+
+ if( column == 1 ) {
+ int newWidth = width;
+
+ int i = 2;
+ for( ; i < listView()->columns(); ++i ) {
+ newWidth += listView()->columnWidth( i );
+ }
+
+ // TODO: find a way to get the TRUE new width after resizing
+
+ // QRect r = p->clipRegion().boundingRect();
+ // r.setWidth( newWidth );
+ // p->setClipRect( r );
+ p->setClipping( false );
+
+ KListViewItem::paintCell( p, cg, column, newWidth, align );
+ } else if( column == 0 )
+ KListViewItem::paintCell( p, cg, column, width, align );
+ }
+};
+
+
+
+K3bDiskInfoView::K3bDiskInfoView( QWidget* parent, const char* name )
+ : K3bMediaContentsView( true,
+ K3bMedium::CONTENT_ALL,
+ K3bDevice::MEDIA_ALL|K3bDevice::MEDIA_UNKNOWN,
+ K3bDevice::STATE_EMPTY|K3bDevice::STATE_INCOMPLETE|K3bDevice::STATE_COMPLETE|K3bDevice::STATE_UNKNOWN,
+ parent, name )
+{
+ m_infoView = new KListView( this );
+ setMainWidget( m_infoView );
+
+ m_infoView->setSorting( -1 );
+ m_infoView->setAllColumnsShowFocus( true );
+ m_infoView->setSelectionMode( QListView::NoSelection );
+ m_infoView->setResizeMode( KListView::AllColumns );
+ m_infoView->setAlternateBackground( QColor() );
+
+ m_infoView->addColumn( "1" );
+ m_infoView->addColumn( "2" );
+ m_infoView->addColumn( "3" );
+ m_infoView->addColumn( "4" );
+#ifdef K3B_DEBUG
+ m_infoView->addColumn( "index0" );
+#endif
+
+ m_infoView->header()->hide();
+
+ // do not automatically reload the disk info
+ // setAutoReload( false );
+}
+
+
+K3bDiskInfoView::~K3bDiskInfoView()
+{}
+
+
+void K3bDiskInfoView::reloadMedium()
+{
+ m_infoView->clear();
+
+ setTitle( medium().shortString( true ) );
+
+ if( medium().diskInfo().diskState() == K3bDevice::STATE_NO_MEDIA ) {
+ (void)new QListViewItem( m_infoView, i18n("No medium present") );
+ setRightPixmap( K3bTheme::MEDIA_NONE );
+ }
+ else {
+ if( medium().diskInfo().empty() ) {
+ setRightPixmap( K3bTheme::MEDIA_EMPTY );
+ }
+ else {
+ switch( medium().toc().contentType() ) {
+ case K3bDevice::AUDIO:
+ setRightPixmap( K3bTheme::MEDIA_AUDIO );
+ break;
+ case K3bDevice::DATA: {
+ if( medium().content() & K3bMedium::CONTENT_VIDEO_DVD ) {
+ setRightPixmap( K3bTheme::MEDIA_VIDEO );
+ }
+ else {
+ setRightPixmap( K3bTheme::MEDIA_DATA );
+ }
+ break;
+ }
+ case K3bDevice::MIXED:
+ setRightPixmap( K3bTheme::MEDIA_MIXED );
+ break;
+ default:
+ setTitle( i18n("Unknown Disk Type") );
+ setRightPixmap( K3bTheme::MEDIA_NONE );
+ }
+ }
+
+ createMediaInfoItems( medium() );
+
+
+ // iso9660 info
+ // /////////////////////////////////////////////////////////////////////////////////////
+ if( medium().content() & K3bMedium::CONTENT_DATA ) {
+ (void)new KListViewItem( m_infoView, m_infoView->lastChild() ); // empty spacer item
+ createIso9660InfoItems( medium().iso9660Descriptor() );
+ }
+
+ // tracks
+ // /////////////////////////////////////////////////////////////////////////////////////
+ if( !medium().toc().isEmpty() ) {
+
+ if( m_infoView->childCount() )
+ (void)new KListViewItem( m_infoView, m_infoView->lastChild() ); // empty spacer item
+
+ KListViewItem* trackHeaderItem = new HeaderViewItem( m_infoView, m_infoView->lastChild(), i18n("Tracks") );
+
+ // create header item
+ KListViewItem* item = new KListViewItem( trackHeaderItem,
+ i18n("Type"),
+ i18n("Attributes"),
+ i18n("First-Last Sector"),
+ i18n("Length") );
+
+#ifdef K3B_DEBUG
+ item->setText( 4, "Index0" );
+#endif
+
+ int lastSession = 0;
+
+ // if we have multiple sessions we create a header item for every session
+ KListViewItem* trackItem = 0;
+ if( medium().diskInfo().numSessions() > 1 && medium().toc()[0].session() > 0 ) {
+ trackItem = new HeaderViewItem( trackHeaderItem, item, i18n("Session %1").arg(1) );
+ lastSession = 1;
+ }
+ else
+ trackItem = trackHeaderItem;
+
+ // create items for the tracks
+ K3bDevice::Toc::const_iterator it;
+ int index = 1;
+ for( it = medium().toc().begin(); it != medium().toc().end(); ++it ) {
+ const K3bTrack& track = *it;
+
+ if( medium().diskInfo().numSessions() > 1 && track.session() != lastSession ) {
+ lastSession = track.session();
+ trackItem->setOpen(true);
+ trackItem = new HeaderViewItem( trackHeaderItem,
+ m_infoView->lastItem()->parent(),
+ i18n("Session %1").arg(lastSession) );
+ }
+
+ item = new KListViewItem( trackItem, item );
+ QString text;
+ if( track.type() == K3bTrack::AUDIO ) {
+ item->setPixmap( 0, SmallIcon( "sound" ) );
+ text = i18n("Audio");
+ } else {
+ item->setPixmap( 0, SmallIcon( "tar" ) );
+ if( track.mode() == K3bTrack::MODE1 )
+ text = i18n("Data/Mode1");
+ else if( track.mode() == K3bTrack::MODE2 )
+ text = i18n("Data/Mode2");
+ else if( track.mode() == K3bTrack::XA_FORM1 )
+ text = i18n("Data/Mode2 XA Form1");
+ else if( track.mode() == K3bTrack::XA_FORM2 )
+ text = i18n("Data/Mode2 XA Form2");
+ else
+ text = i18n("Data");
+ }
+ item->setText( 0, i18n("%1 (%2)").arg( QString::number(index).rightJustify( 2, ' ' )).arg(text) );
+ item->setText( 1, QString( "%1/%2" )
+ .arg( track.copyPermitted() ? i18n("copy") : i18n("no copy") )
+ .arg( track.type() == K3bTrack::AUDIO
+ ? ( track.preEmphasis() ? i18n("preemp") : i18n("no preemp") )
+ : ( track.recordedIncremental() ? i18n("incremental") : i18n("uninterrupted") ) ) );
+ item->setText( 2,
+ QString("%1 - %2")
+ .arg(track.firstSector().lba())
+ .arg(track.lastSector().lba()) );
+ item->setText( 3, QString::number( track.length().lba() ) + " (" + track.length().toString() + ")" );
+
+#ifdef K3B_DEBUG
+ if( track.type() == K3bTrack::AUDIO )
+ item->setText( 4, QString( "%1 (%2)" ).arg(track.index0().toString()).arg(track.index0().lba()) );
+#endif
+ ++index;
+ }
+
+ trackItem->setOpen(true);
+ trackHeaderItem->setOpen( true );
+ }
+
+
+ // CD-TEXT
+ // /////////////////////////////////////////////////////////////////////////////////////
+ if( !medium().cdText().isEmpty() ) {
+ medium().cdText().debug();
+ if( m_infoView->childCount() )
+ (void)new KListViewItem( m_infoView, m_infoView->lastChild() ); // empty spacer item
+
+ KListViewItem* cdTextHeaderItem = new HeaderViewItem( m_infoView,
+ m_infoView->lastChild(),
+ i18n("CD-TEXT (excerpt)") );
+
+ // create header item
+ KListViewItem* item = new KListViewItem( cdTextHeaderItem,
+ i18n("Performer"),
+ i18n("Title"),
+ i18n("Songwriter"),
+ i18n("Composer") );
+ item = new KListViewItem( cdTextHeaderItem, item );
+ item->setText( 0, i18n("CD:") + " " +
+ medium().cdText().performer() );
+ item->setText( 1, medium().cdText().title() );
+ item->setText( 2, medium().cdText().songwriter() );
+ item->setText( 3, medium().cdText().composer() );
+
+ int index = 1;
+ for( unsigned int i = 0; i < medium().cdText().count(); ++i ) {
+ item = new KListViewItem( cdTextHeaderItem, item );
+ item->setText( 0, QString::number(index).rightJustify( 2, ' ' ) + " " +
+ medium().cdText().at(i).performer() );
+ item->setText( 1, medium().cdText().at(i).title() );
+ item->setText( 2, medium().cdText().at(i).songwriter() );
+ item->setText( 3, medium().cdText().at(i).composer() );
+ ++index;
+ }
+
+ cdTextHeaderItem->setOpen( true );
+ }
+ }
+}
+
+
+void K3bDiskInfoView::createMediaInfoItems( const K3bMedium& medium )
+{
+ const K3bDevice::DiskInfo& info = medium.diskInfo();
+
+ KListViewItem* atipItem = new HeaderViewItem( m_infoView, m_infoView->lastItem(), i18n("Medium") );
+ QString typeStr;
+ if( info.mediaType() != K3bDevice::MEDIA_UNKNOWN )
+ typeStr = K3bDevice::mediaTypeString( info.mediaType() );
+ else
+ typeStr = i18n("Unknown (probably CD-ROM)");
+
+ KListViewItem* atipChild = new KListViewItem( atipItem, i18n("Type:"), typeStr );
+
+ if( info.isDvdMedia() )
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Media ID:"),
+ !info.mediaId().isEmpty() ? QString::fromLatin1( info.mediaId() ) : i18n("unknown") );
+
+
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Capacity:"),
+ i18n("%1 min").arg(info.capacity().toString()),
+ KIO::convertSize(info.capacity().mode1Bytes()) );
+
+ if( !info.empty() )
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Used Capacity:"),
+ i18n("%1 min").arg(info.size().toString()),
+ KIO::convertSize(info.size().mode1Bytes()) );
+
+ if( info.appendable() )
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Remaining:"),
+ i18n("%1 min").arg( info.remainingSize().toString() ),
+ KIO::convertSize(info.remainingSize().mode1Bytes()) );
+
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Rewritable:"),
+ info.rewritable() ? i18n("yes") : i18n("no") );
+
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Appendable:"),
+ info.appendable() ? i18n("yes") : i18n("no") );
+
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Empty:"),
+ info.empty() ? i18n("yes") : i18n("no") );
+
+ if( info.isDvdMedia() )
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Layers:"),
+ QString::number( info.numLayers() ) );
+
+ if( info.mediaType() == K3bDevice::MEDIA_DVD_PLUS_RW ) {
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Background Format:") );
+ switch( info.bgFormatState() ) {
+ case K3bDevice::BG_FORMAT_NONE:
+ atipChild->setText( 1, i18n("not formatted") );
+ break;
+ case K3bDevice::BG_FORMAT_INCOMPLETE:
+ atipChild->setText( 1, i18n("incomplete") );
+ break;
+ case K3bDevice::BG_FORMAT_IN_PROGRESS:
+ atipChild->setText( 1, i18n("in progress") );
+ break;
+ case K3bDevice::BG_FORMAT_COMPLETE:
+ atipChild->setText( 1, i18n("complete") );
+ break;
+ }
+ }
+
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Sessions:"),
+ QString::number( info.numSessions() ) );
+
+ if( info.mediaType() & K3bDevice::MEDIA_WRITABLE ) {
+ atipChild = new KListViewItem( atipItem, atipChild,
+ i18n("Supported writing speeds:") );
+ QString s;
+ if( medium.writingSpeeds().isEmpty() )
+ s = "-";
+ else
+ for( QValueList<int>::const_iterator it = medium.writingSpeeds().begin();
+ it != medium.writingSpeeds().end(); ++it ) {
+ if( !s.isEmpty() ) {
+ s.append( "\n" );
+ atipChild->setMultiLinesEnabled( true );
+ }
+
+ if( info.isDvdMedia() )
+ s.append( QString().sprintf( "%.1fx (%d KB/s)", (double)*it / 1385.0, *it ) );
+ else
+ s.append( QString( "%1x (%2 KB/s)" ).arg( *it/175 ).arg( *it ) );
+ }
+
+ atipChild->setText( 1, s );
+ }
+
+ atipItem->setOpen( true );
+}
+
+
+void K3bDiskInfoView::createIso9660InfoItems( const K3bIso9660SimplePrimaryDescriptor& iso )
+{
+ KListViewItem* iso9660Item = new HeaderViewItem( m_infoView, m_infoView->lastChild(),
+ i18n("ISO9660 Filesystem Info") );
+ KListViewItem* iso9660Child = 0;
+
+ iso9660Child = new KListViewItem( iso9660Item, iso9660Child,
+ i18n("System Id:"),
+ iso.systemId.isEmpty()
+ ? QString("-")
+ : iso.systemId );
+ iso9660Child = new KListViewItem( iso9660Item, iso9660Child,
+ i18n("Volume Id:"),
+ iso.volumeId.isEmpty()
+ ? QString("-")
+ : iso.volumeId );
+ iso9660Child = new KListViewItem( iso9660Item, iso9660Child,
+ i18n("Volume Set Id:"),
+ iso.volumeSetId.isEmpty()
+ ? QString("-")
+ : iso.volumeSetId );
+ iso9660Child = new KListViewItem( iso9660Item, iso9660Child,
+ i18n("Publisher Id:"),
+ iso.publisherId.isEmpty()
+ ? QString("-")
+ : iso.publisherId );
+ iso9660Child = new KListViewItem( iso9660Item, iso9660Child,
+ i18n("Preparer Id:"),
+ iso.preparerId.isEmpty()
+ ? QString("-")
+ : iso.preparerId );
+ iso9660Child = new KListViewItem( iso9660Item, iso9660Child,
+ i18n("Application Id:"),
+ iso.applicationId.isEmpty()
+ ? QString("-")
+ : iso.applicationId );
+// iso9660Child = new KListViewItem( iso9660Item, iso9660Child,
+// i18n("Volume Size:"),
+// QString( "%1 (%2*%3)" )
+// .arg(iso.logicalBlockSize
+// *iso.volumeSpaceSize)
+// .arg(iso.logicalBlockSize)
+// .arg(iso.volumeSpaceSize),
+// KIO::convertSize(iso.logicalBlockSize
+// *iso.volumeSpaceSize) );
+
+ iso9660Item->setOpen( true );
+}
+
+
+void K3bDiskInfoView::enableInteraction( bool enable )
+{
+ QListViewItemIterator it( m_infoView );
+ while( it.current() ) {
+ it.current()->setEnabled( enable );
+ ++it;
+ }
+}
+
+#include "k3bdiskinfoview.moc"
+
diff --git a/src/k3bdiskinfoview.h b/src/k3bdiskinfoview.h
new file mode 100644
index 0000000..7c817a7
--- /dev/null
+++ b/src/k3bdiskinfoview.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * $Id: k3bdiskinfoview.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+
+#ifndef K3BDISKINFOVIEW_H
+#define K3BDISKINFOVIEW_H
+
+#include "k3bmediacontentsview.h"
+#include "k3bmedium.h"
+
+class QLabel;
+class KListView;
+class K3bIso9660;
+
+namespace K3bDevice {
+ class DiskInfoDetector;
+ class DiskInfo;
+}
+
+class K3bDiskInfoView : public K3bMediaContentsView
+{
+ Q_OBJECT
+
+ public:
+ K3bDiskInfoView( QWidget* parent = 0, const char* name = 0 );
+ ~K3bDiskInfoView();
+
+ void enableInteraction( bool enable );
+
+ private:
+ void reloadMedium();
+
+ void createMediaInfoItems( const K3bMedium& );
+ void createIso9660InfoItems( const K3bIso9660SimplePrimaryDescriptor& );
+
+ KListView* m_infoView;
+
+ class HeaderViewItem;
+ class TwoColumnViewItem;
+};
+
+
+#endif
diff --git a/src/k3bemptydiscwaiter.cpp b/src/k3bemptydiscwaiter.cpp
new file mode 100644
index 0000000..7e11198
--- /dev/null
+++ b/src/k3bemptydiscwaiter.cpp
@@ -0,0 +1,761 @@
+/*
+ *
+ * $Id: k3bemptydiscwaiter.cpp 642801 2007-03-15 12:39:04Z trueg $
+ * Copyright (C) 2003-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bemptydiscwaiter.h"
+#include "k3bmediacache.h"
+#include "k3bapplication.h"
+#include <k3bdevice.h>
+#include <k3bdeviceglobals.h>
+#include <k3bdevicehandler.h>
+#include <k3bglobals.h>
+#include <k3bcore.h>
+#include <k3biso9660.h>
+#include "k3bblankingjob.h"
+#include <k3bbusywidget.h>
+#include <k3bprogressdialog.h>
+#include <k3bdvdformattingjob.h>
+
+#include <qtimer.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qpushbutton.h>
+#include <qapplication.h>
+#include <qeventloop.h>
+#include <qfont.h>
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kactivelabel.h>
+#include <knotifyclient.h>
+
+
+class K3bEmptyDiscWaiter::Private
+{
+public:
+ Private()
+ : erasingInfoDialog(0) {
+ dialogVisible = false;
+ inLoop = false;
+ mediumChanged = 0;
+ blockMediaChange = false;
+ }
+
+ K3bDevice::Device* device;
+
+ int wantedMediaType;
+ int wantedMediaState;
+
+ QString wantedMediaTypeString;
+
+ int result;
+ int dialogVisible;
+ bool inLoop;
+
+ bool blockMediaChange;
+ int mediumChanged;
+
+ bool forced;
+ bool canceled;
+
+ bool waitingDone;
+
+ QLabel* labelRequest;
+ QLabel* labelFoundMedia;
+ QLabel* pixLabel;
+
+ K3bProgressDialog* erasingInfoDialog;
+};
+
+
+
+K3bEmptyDiscWaiter::K3bEmptyDiscWaiter( K3bDevice::Device* device, QWidget* parent, const char* name )
+ : KDialogBase( KDialogBase::Plain, i18n("Waiting for Disk"),
+ KDialogBase::Cancel|KDialogBase::User1|KDialogBase::User2|KDialogBase::User3,
+ KDialogBase::User3, parent, name, true, true, i18n("Force"), i18n("Eject"), i18n("Load") )
+{
+ d = new Private();
+ d->device = device;
+
+ // setup the gui
+ // -----------------------------
+ d->labelRequest = new QLabel( plainPage() );
+ d->labelRequest->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
+ d->labelFoundMedia = new QLabel( plainPage() );
+ d->pixLabel = new QLabel( plainPage() );
+ d->pixLabel->setAlignment( Qt::AlignHCenter | Qt::AlignTop );
+
+ QFont f( d->labelFoundMedia->font() );
+ f.setBold(true);
+ d->labelFoundMedia->setFont( f );
+
+ QGridLayout* grid = new QGridLayout( plainPage() );
+ grid->setMargin( marginHint() );
+ grid->setSpacing( spacingHint() );
+
+ grid->addMultiCellWidget( d->pixLabel, 0, 2, 0, 0 );
+ grid->addColSpacing( 1, 20 );
+ grid->addWidget( new QLabel( i18n("Found media:"), plainPage() ), 0, 2 );
+ grid->addWidget( d->labelFoundMedia, 0, 3 );
+ grid->addMultiCellWidget( d->labelRequest, 1, 1, 2, 3 );
+ grid->setRowStretch( 2, 1 );
+ grid->setColStretch( 3, 1 );
+ // -----------------------------
+
+ connect( k3bappcore->mediaCache(), SIGNAL(mediumChanged(K3bDevice::Device*)),
+ this, SLOT(slotMediumChanged(K3bDevice::Device*)) );
+
+ QToolTip::add( actionButton(KDialogBase::User1),
+ i18n("Force K3b to continue if it seems not to detect your empty CD/DVD.") );
+}
+
+
+K3bEmptyDiscWaiter::~K3bEmptyDiscWaiter()
+{
+ delete d;
+}
+
+
+int K3bEmptyDiscWaiter::waitForDisc( int mediaState, int mediaType, const QString& message )
+{
+ if ( d->inLoop ) {
+ kdError() << "(K3bEmptyDiscWaiter) Recursive call detected." << endl;
+ return -1;
+ }
+
+ d->wantedMediaState = mediaState;
+ d->wantedMediaType = mediaType;
+ d->dialogVisible = false;
+ d->forced = false;
+ d->canceled = false;
+ d->waitingDone = false;
+ d->blockMediaChange = false;
+ d->mediumChanged = 0;
+
+ //
+ // We do not cover every case here but just the ones that really make sense
+ //
+ if( (d->wantedMediaType & K3bDevice::MEDIA_WRITABLE_DVD) &&
+ (d->wantedMediaType & K3bDevice::MEDIA_WRITABLE_CD) )
+ d->wantedMediaTypeString = i18n("CD-R(W) or DVD%1R(W)").arg("");
+ else if( d->wantedMediaType & K3bDevice::MEDIA_WRITABLE_DVD_SL )
+ d->wantedMediaTypeString = i18n("DVD%1R(W)").arg("");
+ else if( d->wantedMediaType & K3bDevice::MEDIA_WRITABLE_DVD_DL )
+ d->wantedMediaTypeString = i18n("Double Layer DVD%1R").arg("");
+ else
+ d->wantedMediaTypeString = i18n("CD-R(W)");
+
+ if( message.isEmpty() ) {
+ if( (d->wantedMediaState & K3bDevice::STATE_COMPLETE) && (d->wantedMediaState & K3bDevice::STATE_INCOMPLETE) )
+ d->labelRequest->setText( i18n("Please insert a complete or appendable %4 medium "
+ "into drive<p><b>%1 %2 (%3)</b>.")
+ .arg(d->device->vendor())
+ .arg(d->device->description())
+ .arg(d->device->devicename())
+ .arg( d->wantedMediaTypeString ) );
+ else if( d->wantedMediaState & K3bDevice::STATE_COMPLETE )
+ d->labelRequest->setText( i18n("Please insert a complete %4 medium "
+ "into drive<p><b>%1 %2 (%3)</b>.")
+ .arg(d->device->vendor())
+ .arg(d->device->description())
+ .arg(d->device->devicename())
+ .arg( d->wantedMediaTypeString ) );
+ else if( (d->wantedMediaState & K3bDevice::STATE_INCOMPLETE) && (d->wantedMediaState & K3bDevice::STATE_EMPTY) )
+ d->labelRequest->setText( i18n("Please insert an empty or appendable %4 medium "
+ "into drive<p><b>%1 %2 (%3)</b>.")
+ .arg(d->device->vendor())
+ .arg(d->device->description())
+ .arg(d->device->devicename())
+ .arg( d->wantedMediaTypeString ) );
+ else if( d->wantedMediaState & K3bDevice::STATE_INCOMPLETE )
+ d->labelRequest->setText( i18n("Please insert an appendable %4 medium "
+ "into drive<p><b>%1 %2 (%3)</b>.")
+ .arg(d->device->vendor())
+ .arg(d->device->description())
+ .arg(d->device->devicename())
+ .arg( d->wantedMediaTypeString ) );
+ else if( d->wantedMediaState & K3bDevice::STATE_EMPTY )
+ d->labelRequest->setText( i18n("Please insert an empty %4 medium "
+ "into drive<p><b>%1 %2 (%3)</b>.")
+ .arg(d->device->vendor())
+ .arg(d->device->description())
+ .arg(d->device->devicename())
+ .arg( d->wantedMediaTypeString ) );
+ else // fallback case (this should not happen in K3b)
+ d->labelRequest->setText( i18n("Please insert a suitable medium "
+ "into drive<p><b>%1 %2 (%3)</b>.")
+ .arg(d->device->vendor())
+ .arg(d->device->description())
+ .arg(d->device->devicename()) );
+
+ }
+ else
+ d->labelRequest->setText( message );
+
+ if( d->wantedMediaType & K3bDevice::MEDIA_WRITABLE_DVD )
+ d->pixLabel->setPixmap( KGlobal::instance()->iconLoader()->loadIcon( "dvd_unmount",
+ KIcon::NoGroup, KIcon::SizeMedium ) );
+ else
+ d->pixLabel->setPixmap( KGlobal::instance()->iconLoader()->loadIcon( "cdwriter_unmount",
+ KIcon::NoGroup, KIcon::SizeMedium ) );
+
+ adjustSize();
+
+ slotMediumChanged( d->device );
+
+ //
+ // in case we already found a medium and thus the dialog is not shown entering
+ // the loop only causes problems (since there is no dialog yet the user could
+ // not have forced or canceled yet
+ //
+ if( !d->waitingDone ) {
+ d->inLoop = true;
+ QApplication::eventLoop()->enterLoop();
+ }
+
+ return d->result;
+}
+
+
+int K3bEmptyDiscWaiter::exec()
+{
+ return waitForDisc();
+}
+
+
+void K3bEmptyDiscWaiter::slotMediumChanged( K3bDevice::Device* dev )
+{
+ kdDebug() << "(K3bEmptyDiscWaiter) slotMediumChanged() " << endl;
+ if( d->forced || d->canceled || d->device != dev )
+ return;
+
+ //
+ // This slot may open dialogs which enter a new event loop and that
+ // may result in another call to this slot if a medium changes while
+ // a dialog is open
+ //
+ if( d->blockMediaChange ) {
+ d->mediumChanged++;
+ return;
+ }
+
+ d->blockMediaChange = true;
+
+ KConfig* c = k3bcore->config();
+ bool formatWithoutAsking = KConfigGroup( k3bcore->config(), "General Options" ).readBoolEntry( "auto rewritable erasing", false );
+
+ K3bMedium medium = k3bappcore->mediaCache()->medium( dev );
+
+ d->labelFoundMedia->setText( medium.shortString( false ) );
+
+ if( medium.diskInfo().diskState() == K3bDevice::STATE_NO_MEDIA ) {
+ continueWaiting();
+ d->blockMediaChange = false;
+ return;
+ }
+
+// QString mediaState;
+// if( medium.diskInfo().diskState() == K3bDevice::STATE_COMPLETE )
+// mediaState = i18n("complete");
+// else if( medium.diskInfo().diskState() == K3bDevice::STATE_INCOMPLETE )
+// mediaState = i18n("appendable");
+// else if( medium.diskInfo().diskState() == K3bDevice::STATE_EMPTY )
+// mediaState = i18n("empty");
+
+// if( !mediaState.isEmpty() )
+// mediaState = " (" + mediaState +")";
+
+
+ // /////////////////////////////////////////////////////////////
+ //
+ // DVD+RW handling
+ //
+ // /////////////////////////////////////////////////////////////
+
+ // DVD+RW: if empty we need to preformat. Although growisofs does it before writing doing it here
+ // allows better control and a progress bar. If it's not empty we should check if there is
+ // already a filesystem on the media.
+ if( (d->wantedMediaType & K3bDevice::MEDIA_DVD_PLUS_RW) &&
+ (medium.diskInfo().mediaType() & K3bDevice::MEDIA_DVD_PLUS_RW) ) {
+
+ kdDebug() << "(K3bEmptyDiscWaiter) ------ found DVD+RW as wanted." << endl;
+
+ if( medium.diskInfo().diskState() == K3bDevice::STATE_EMPTY ) {
+ if( d->wantedMediaState & K3bDevice::STATE_EMPTY ) {
+ // special case for the formatting job which wants to preformat on it's own!
+ if( d->wantedMediaState & K3bDevice::STATE_COMPLETE &&
+ d->wantedMediaState & K3bDevice::STATE_EMPTY ) {
+ kdDebug() << "(K3bEmptyDiscWaiter) special case: DVD+RW for the formatting job." << endl;
+ finishWaiting( K3bDevice::MEDIA_DVD_PLUS_RW );
+ }
+ else {
+ // empty - preformat without asking
+ prepareErasingDialog();
+
+ K3bDvdFormattingJob job( this );
+ job.setDevice( d->device );
+ job.setQuickFormat( true );
+ job.setForce( false );
+ job.setForceNoEject( true );
+
+ d->erasingInfoDialog->setText( i18n("Preformatting DVD+RW") );
+ connect( &job, SIGNAL(finished(bool)), this, SLOT(slotErasingFinished(bool)) );
+ connect( &job, SIGNAL(percent(int)), d->erasingInfoDialog, SLOT(setProgress(int)) );
+ connect( d->erasingInfoDialog, SIGNAL(cancelClicked()), &job, SLOT(cancel()) );
+ job.start( medium.diskInfo() );
+ d->erasingInfoDialog->exec( true );
+ }
+ }
+ else {
+ kdDebug() << "(K3bEmptyDiscWaiter) starting devicehandler: empty DVD+RW where a non-empty was requested." << endl;
+ continueWaiting();
+ }
+ }
+ else {
+ //
+ // We have a DVD+RW medium which is already preformatted
+ //
+ if( d->wantedMediaState == K3bDevice::STATE_EMPTY ) {
+ // check if the media contains a filesystem
+ K3bIso9660 isoF( d->device );
+ bool hasIso = isoF.open();
+
+ if( formatWithoutAsking ||
+ !hasIso ||
+ KMessageBox::warningContinueCancel( parentWidgetToUse(),
+ i18n("Found %1 media in %2 - %3. "
+ "Should it be overwritten?")
+ .arg("DVD+RW")
+ .arg(d->device->vendor())
+ .arg(d->device->description()),
+ i18n("Found %1").arg("DVD+RW"),i18n("Overwrite") ) == KMessageBox::Continue ) {
+ finishWaiting( K3bDevice::MEDIA_DVD_PLUS_RW );
+ }
+ else {
+ kdDebug() << "(K3bEmptyDiscWaiter) starting devicehandler: no DVD+RW overwrite" << endl;
+ K3b::unmount( d->device );
+ K3bDevice::eject( d->device );
+ continueWaiting();
+ }
+ }
+
+ //
+ // We want a DVD+RW not nessessarily empty. No problem, just use this one. Becasue incomplete and complete
+ // are handled the same everywhere (isofs is grown).
+ //
+ else {
+ finishWaiting( K3bDevice::MEDIA_DVD_PLUS_RW );
+ }
+ }
+ } // --- DVD+RW --------
+
+
+ // /////////////////////////////////////////////////////////////
+ //
+ // DVD-RW handling
+ //
+ // /////////////////////////////////////////////////////////////
+
+ //
+ // DVD-RW in sequential mode can be empty. DVD-RW in restricted overwrite mode is always complete.
+ //
+ else if( (d->wantedMediaType & (K3bDevice::MEDIA_DVD_RW|
+ K3bDevice::MEDIA_DVD_RW_SEQ|
+ K3bDevice::MEDIA_DVD_RW_OVWR) ) &&
+ (medium.diskInfo().mediaType() & (K3bDevice::MEDIA_DVD_RW|
+ K3bDevice::MEDIA_DVD_RW_SEQ|
+ K3bDevice::MEDIA_DVD_RW_OVWR) ) ) {
+
+ kdDebug() << "(K3bEmptyDiscWaiter) ------ found DVD-R(W) as wanted." << endl;
+
+ // we format in the following cases:
+ // seq. incr. and not empty and empty requested
+ // seq. incr. and restr. overwri. reqested
+ // restr. ovw. and seq. incr. requested
+
+ // we have exactly what was requested
+ if( (d->wantedMediaType & medium.diskInfo().mediaType()) &&
+ (d->wantedMediaState & medium.diskInfo().diskState()) ) {
+ finishWaiting( medium.diskInfo().mediaType() );
+ }
+
+ // DVD-RW in restr. overwrite may just be overwritten
+ else if( (medium.diskInfo().mediaType() & K3bDevice::MEDIA_DVD_RW_OVWR) &&
+ (d->wantedMediaType & K3bDevice::MEDIA_DVD_RW_OVWR) ) {
+ if( d->wantedMediaState == K3bDevice::STATE_EMPTY ) {
+
+ kdDebug() << "(K3bEmptyDiscWaiter) ------ DVD-RW restricted overwrite." << endl;
+
+ // check if the media contains a filesystem
+ K3bIso9660 isoF( d->device );
+ bool hasIso = isoF.open();
+
+ if( formatWithoutAsking ||
+ !hasIso ||
+ KMessageBox::warningContinueCancel( parentWidgetToUse(),
+ i18n("Found %1 media in %2 - %3. "
+ "Should it be overwritten?")
+ .arg(K3bDevice::mediaTypeString(medium.diskInfo().mediaType()))
+ .arg(d->device->vendor())
+ .arg(d->device->description()),
+ i18n("Found %1").arg("DVD-RW"),i18n("Overwrite") ) == KMessageBox::Continue ) {
+ finishWaiting( K3bDevice::MEDIA_DVD_RW_OVWR );
+ }
+ else {
+ kdDebug() << "(K3bEmptyDiscWaiter) starting devicehandler: no DVD-RW overwrite." << endl;
+ K3b::unmount( d->device );
+ K3bDevice::eject( d->device );
+ continueWaiting();
+ }
+ }
+
+ else if( !(d->wantedMediaState & K3bDevice::STATE_EMPTY ) ) {
+ // check if the media contains a filesystem
+ K3bIso9660 isoF( d->device );
+ bool hasIso = isoF.open();
+
+ if( hasIso ) {
+ finishWaiting( K3bDevice::MEDIA_DVD_RW_OVWR );
+ }
+ else {
+ kdDebug() << "(K3bEmptyDiscWaiter) starting devicehandler: empty DVD-RW where a non-empty was requested." << endl;
+ continueWaiting();
+ }
+ }
+
+ //
+ // We want a DVD-RW overwrite not nessessarily empty. No problem, just use this one. Becasue incomplete and complete
+ // are handled the same everywhere (isofs is grown).
+ //
+ else {
+ finishWaiting( K3bDevice::MEDIA_DVD_RW_OVWR );
+ }
+ }
+
+ // formatting
+ else if( ( (d->wantedMediaType & K3bDevice::MEDIA_DVD_RW_OVWR) &&
+ (medium.diskInfo().mediaType() & K3bDevice::MEDIA_DVD_RW_SEQ) &&
+ !(d->wantedMediaType & K3bDevice::MEDIA_DVD_RW_SEQ) ) ||
+
+ ( (d->wantedMediaType & K3bDevice::MEDIA_DVD_RW_SEQ) &&
+ (medium.diskInfo().mediaType() & K3bDevice::MEDIA_DVD_RW_OVWR) &&
+ !(d->wantedMediaType & K3bDevice::MEDIA_DVD_RW_OVWR) ) ||
+
+ ( (d->wantedMediaType & K3bDevice::MEDIA_DVD_RW_SEQ) &&
+ (medium.diskInfo().mediaType() & K3bDevice::MEDIA_DVD_RW_SEQ) &&
+ (d->wantedMediaState & K3bDevice::STATE_EMPTY) &&
+ (medium.diskInfo().diskState() != K3bDevice::STATE_EMPTY) ) ) {
+
+ kdDebug() << "(K3bEmptyDiscWaiter) ------ DVD-RW needs to be formated." << endl;
+
+ if( formatWithoutAsking ||
+ KMessageBox::warningContinueCancel( parentWidgetToUse(),
+ i18n("Found %1 media in %2 - %3. "
+ "Should it be formatted?")
+ .arg( K3bDevice::mediaTypeString(medium.diskInfo().mediaType()) )
+ .arg(d->device->vendor())
+ .arg(d->device->description()),
+ i18n("Found %1").arg("DVD-RW"), i18n("Format") ) == KMessageBox::Continue ) {
+
+ kdDebug() << "(K3bEmptyDiscWaiter) ------ formatting DVD-RW." << endl;
+
+ prepareErasingDialog();
+
+ K3bDvdFormattingJob job( this );
+ job.setDevice( d->device );
+ // we prefere the current mode of the media if no special mode has been requested
+ job.setMode( ( (d->wantedMediaType & K3bDevice::MEDIA_DVD_RW_SEQ) &&
+ (d->wantedMediaType & K3bDevice::MEDIA_DVD_RW_OVWR) )
+ ? ( medium.diskInfo().mediaType() == K3bDevice::MEDIA_DVD_RW_OVWR
+ ? K3b::WRITING_MODE_RES_OVWR
+ : K3b::WRITING_MODE_INCR_SEQ )
+ : ( (d->wantedMediaType & K3bDevice::MEDIA_DVD_RW_SEQ)
+ ? K3b::WRITING_MODE_INCR_SEQ
+ : K3b::WRITING_MODE_RES_OVWR ) );
+ job.setQuickFormat( true );
+ job.setForce( false );
+ job.setForceNoEject(true);
+
+ d->erasingInfoDialog->setText( i18n("Formatting DVD-RW") );
+ connect( &job, SIGNAL(finished(bool)), this, SLOT(slotErasingFinished(bool)) );
+ connect( &job, SIGNAL(percent(int)), d->erasingInfoDialog, SLOT(setProgress(int)) );
+ connect( d->erasingInfoDialog, SIGNAL(cancelClicked()), &job, SLOT(cancel()) );
+ job.start( medium.diskInfo() );
+ d->erasingInfoDialog->exec( true );
+ }
+ else {
+ kdDebug() << "(K3bEmptyDiscWaiter) starting devicehandler: no DVD-RW formatting." << endl;
+ K3b::unmount( d->device );
+ K3bDevice::eject( d->device );
+ continueWaiting();
+ }
+ }
+ else {
+ kdDebug() << "(K3bEmptyDiscWaiter) ------ nothing useful found." << endl;
+ continueWaiting();
+ }
+ } // --- DVD-RW ------
+
+
+ // /////////////////////////////////////////////////////////////
+ //
+ // CD handling (and DVD-R and DVD+R)
+ //
+ // /////////////////////////////////////////////////////////////
+
+ // we have exactly what was requested
+ else if( (d->wantedMediaType & medium.diskInfo().mediaType()) &&
+ (d->wantedMediaState & medium.diskInfo().diskState()) )
+ finishWaiting( medium.diskInfo().mediaType() );
+
+ else if( (medium.diskInfo().mediaType() != K3bDevice::MEDIA_UNKNOWN) &&
+ (d->wantedMediaType & medium.diskInfo().mediaType()) &&
+ (d->wantedMediaState & medium.diskInfo().diskState()) )
+ finishWaiting( medium.diskInfo().mediaType() );
+
+ // this is for CD drives that are not able to determine the state of a disk
+ else if( medium.diskInfo().diskState() == K3bDevice::STATE_UNKNOWN &&
+ medium.diskInfo().mediaType() == K3bDevice::MEDIA_CD_ROM &&
+ d->wantedMediaType & K3bDevice::MEDIA_CD_ROM )
+ finishWaiting( medium.diskInfo().mediaType() );
+
+ // format CD-RW
+ else if( (d->wantedMediaType & medium.diskInfo().mediaType()) &&
+ (d->wantedMediaState & K3bDevice::STATE_EMPTY) &&
+ medium.diskInfo().rewritable() ) {
+
+ if( formatWithoutAsking ||
+ KMessageBox::questionYesNo( parentWidgetToUse(),
+ i18n("Found rewritable media in %1 - %2. "
+ "Should it be erased?").arg(d->device->vendor()).arg(d->device->description()),
+ i18n("Found Rewritable Disk"),
+ KGuiItem(i18n("&Erase"), "cdrwblank"),
+ KGuiItem(i18n("E&ject")) ) == KMessageBox::Yes ) {
+
+
+ prepareErasingDialog();
+
+ // start a k3bblankingjob
+ d->erasingInfoDialog->setText( i18n("Erasing CD-RW") );
+
+ // the user may be using cdrdao for erasing as cdrecord does not work
+ int erasingApp = K3b::DEFAULT;
+ if( KConfigGroup( c, "General Options" ).readBoolEntry( "Manual writing app selection", false ) ) {
+ erasingApp = K3b::writingAppFromString( KConfigGroup( c, "CDRW Erasing" ).readEntry( "writing_app" ) );
+ }
+
+ K3bBlankingJob job( this );
+ job.setDevice( d->device );
+ job.setMode( K3bBlankingJob::Fast );
+ job.setForce(true);
+ job.setForceNoEject(true);
+ job.setSpeed( 0 ); // Auto
+ job.setWritingApp( erasingApp );
+ connect( &job, SIGNAL(finished(bool)), this, SLOT(slotErasingFinished(bool)) );
+ connect( d->erasingInfoDialog, SIGNAL(cancelClicked()), &job, SLOT(cancel()) );
+ job.start();
+ d->erasingInfoDialog->exec( false );
+ }
+ else {
+ kdDebug() << "(K3bEmptyDiscWaiter) starting devicehandler: no CD-RW overwrite." << endl;
+ K3b::unmount( d->device );
+ K3bDevice::eject( d->device );
+ continueWaiting();
+ }
+ }
+ else {
+ kdDebug() << "(K3bEmptyDiscWaiter) ------ nothing useful found." << endl;
+ continueWaiting();
+ }
+
+ // handle queued medium changes
+ d->blockMediaChange = false;
+ if( d->mediumChanged > 0 ) {
+ d->mediumChanged--;
+ slotMediumChanged( dev );
+ }
+}
+
+
+void K3bEmptyDiscWaiter::showDialog()
+{
+ // we need to show the dialog if not done already
+ if( !d->dialogVisible ) {
+
+ KNotifyClient::event( 0, "WaitingForMedium", i18n("Waiting for Medium") );
+
+ d->dialogVisible = true;
+ clearWFlags( WDestructiveClose );
+ setWFlags( WShowModal );
+ setResult( 0 );
+ show();
+ }
+}
+
+
+void K3bEmptyDiscWaiter::continueWaiting()
+{
+ showDialog();
+}
+
+
+void K3bEmptyDiscWaiter::slotCancel()
+{
+ kdDebug() << "(K3bEmptyDiscWaiter) slotCancel() " << endl;
+ d->canceled = true;
+ finishWaiting( CANCELED );
+}
+
+
+void K3bEmptyDiscWaiter::slotUser1()
+{
+ d->forced = true;
+ finishWaiting( DISK_READY );
+}
+
+
+void K3bEmptyDiscWaiter::slotUser2()
+{
+ K3b::unmount( d->device );
+ K3bDevice::eject( d->device );
+}
+
+
+void K3bEmptyDiscWaiter::slotUser3()
+{
+ K3bDevice::load( d->device );
+}
+
+
+void K3bEmptyDiscWaiter::finishWaiting( int code )
+{
+ kdDebug() << "(K3bEmptyDiscWaiter) finishWaiting() " << endl;
+
+ d->waitingDone = true;
+ d->result = code;
+
+ if( d->dialogVisible )
+ hide();
+
+ if( d->inLoop ) {
+ d->inLoop = false;
+ kdDebug() << "(K3bEmptyDiscWaiter) exitLoop " << endl;
+ QApplication::eventLoop()->exitLoop();
+ }
+}
+
+
+void K3bEmptyDiscWaiter::slotErasingFinished( bool success )
+{
+ if( success ) {
+ connect( K3bDevice::reload( d->device ),
+ SIGNAL(finished(K3bDevice::DeviceHandler*)),
+ this,
+ SLOT(slotReloadingAfterErasingFinished(K3bDevice::DeviceHandler*)) );
+ }
+ else {
+ K3bDevice::eject( d->device );
+ KMessageBox::error( d->erasingInfoDialog, i18n("Erasing failed.") );
+ d->erasingInfoDialog->hide(); // close the dialog thus ending it's event loop -> back to slotMediumChanged
+ }
+}
+
+
+void K3bEmptyDiscWaiter::slotReloadingAfterErasingFinished( K3bDevice::DeviceHandler* )
+{
+ // close the dialog thus ending it's event loop -> back to slotMediumChanged
+ d->erasingInfoDialog->hide();
+}
+
+
+int K3bEmptyDiscWaiter::wait( K3bDevice::Device* device, bool appendable, int mediaType, QWidget* parent )
+{
+ K3bEmptyDiscWaiter d( device, parent ? parent : qApp->activeWindow() );
+ int mediaState = K3bDevice::STATE_EMPTY;
+ if( appendable ) mediaState |= K3bDevice::STATE_INCOMPLETE;
+ return d.waitForDisc( mediaState, mediaType );
+}
+
+
+int K3bEmptyDiscWaiter::wait( K3bDevice::Device* device,
+ int mediaState,
+ int mediaType,
+ const QString& message,
+ QWidget* parent )
+{
+ K3bEmptyDiscWaiter d( device, parent ? parent : qApp->activeWindow() );
+ return d.waitForDisc( mediaState, mediaType, message );
+}
+
+
+void K3bEmptyDiscWaiter::prepareErasingDialog()
+{
+ // we hide the emptydiskwaiter so the info dialog needs to have the same parent
+ if( !d->erasingInfoDialog )
+ d->erasingInfoDialog = new K3bProgressDialog( QString::null, parentWidget() );
+
+ //
+ // hide the dialog
+ //
+ if( d->dialogVisible ) {
+ hide();
+ d->dialogVisible = false;
+ }
+}
+
+
+QWidget* K3bEmptyDiscWaiter::parentWidgetToUse()
+{
+ // we might also show dialogs if the discwaiter widget is not visible yet
+ if( d->dialogVisible )
+ return this;
+ else
+ return parentWidget();
+}
+
+
+int K3bEmptyDiscWaiter::waitForMedia( K3bDevice::Device* device,
+ int mediaState,
+ int mediaType,
+ const QString& message )
+{
+ // this is only needed for the formatting
+ return wait( device, mediaState, mediaType, message, d->erasingInfoDialog );
+}
+
+
+bool K3bEmptyDiscWaiter::questionYesNo( const QString& text,
+ const QString& caption,
+ const QString& yesText,
+ const QString& noText )
+{
+ return ( KMessageBox::questionYesNo( parentWidgetToUse(),
+ text,
+ caption,
+ yesText.isEmpty() ? KStdGuiItem::yes() : KGuiItem(yesText),
+ noText.isEmpty() ? KStdGuiItem::no() : KGuiItem(noText) ) == KMessageBox::Yes );
+}
+
+
+void K3bEmptyDiscWaiter::blockingInformation( const QString& text,
+ const QString& caption )
+{
+ KMessageBox::information( this, text, caption );
+}
+
+#include "k3bemptydiscwaiter.moc"
diff --git a/src/k3bemptydiscwaiter.h b/src/k3bemptydiscwaiter.h
new file mode 100644
index 0000000..ce3bced
--- /dev/null
+++ b/src/k3bemptydiscwaiter.h
@@ -0,0 +1,139 @@
+/*
+ *
+ * $Id: k3bemptydiscwaiter.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BEMPTYDISCWAITER_H
+#define K3BEMPTYDISCWAITER_H
+
+#include <kdialogbase.h>
+#include <k3bjobhandler.h>
+
+#include <k3bdiskinfo.h>
+
+namespace K3bDevice {
+ class Device;
+ class DeviceHandler;
+}
+
+
+/**
+ * Tests for an empty cd in a given device.
+ *
+ * Use the static wait methods.
+ *
+ * @author Sebastian Trueg
+ */
+class K3bEmptyDiscWaiter : public KDialogBase, public K3bJobHandler
+{
+ Q_OBJECT
+
+ public:
+ ~K3bEmptyDiscWaiter();
+
+ /**
+ * This should be replaced by the mediaType that was found or -1 for forced.
+ * MEDIA_NONE if canceled.
+ */
+ enum returnValue { DISK_READY = 0,
+ CANCELED = -1 };
+
+ /**
+ * the same as waitForEmptyDisc( false );
+ */
+ int exec();
+
+ /**
+ * @reimplemented from K3bJobHandler
+ * \internal do not use!
+ */
+ int waitForMedia( K3bDevice::Device*,
+ int mediaState = K3bDevice::STATE_EMPTY,
+ int mediaType = K3bDevice::MEDIA_WRITABLE_CD,
+ const QString& message = QString::null );
+
+ /**
+ * @reimplemented from K3bJobHandler
+ */
+ bool questionYesNo( const QString& text,
+ const QString& caption = QString::null,
+ const QString& yesText = QString::null,
+ const QString& noText = QString::null );
+
+ /**
+ * reimplemented from K3bJobHandler
+ */
+ void blockingInformation( const QString& text,
+ const QString& caption = QString::null );
+
+ /**
+ * This only openes a dialog if the first check failed.
+ */
+ static int wait( K3bDevice::Device* device,
+ bool appendable = false,
+ int mediaType = K3bDevice::MEDIA_WRITABLE_CD,
+ QWidget* parent = 0 );
+
+ /**
+ * Starts the emptydiskwaiter.
+ *
+ * \param mediaState a bitwise combination of the K3bDevice::State enum
+ * \param mediaType a bitwise combination of the K3bDevice::MediaType enum
+ * \return the found MediaType on success, 0 if forced and -1 if canceled
+ */
+ static int wait( K3bDevice::Device*,
+ int mediaState,
+ int mediaType = K3bDevice::MEDIA_WRITABLE_CD,
+ const QString& message = QString::null,
+ QWidget* parent = 0 );
+
+ protected slots:
+ void slotCancel();
+ void slotUser1();
+ void slotUser2();
+ void slotUser3();
+ void slotMediumChanged( K3bDevice::Device* );
+ void showDialog();
+ void continueWaiting();
+ void slotErasingFinished( bool );
+ void slotReloadingAfterErasingFinished( K3bDevice::DeviceHandler* );
+
+ protected:
+ /**
+ * Use the static wait methods.
+ */
+ explicit K3bEmptyDiscWaiter( K3bDevice::Device* device, QWidget* parent = 0, const char* name = 0 );
+
+ int waitForDisc( int mediaState = K3bDevice::STATE_EMPTY,
+ int mediaType = K3bDevice::MEDIA_WRITABLE_CD,
+ const QString& message = QString::null );
+
+
+ /**
+ * Nobody closes this dialog but itself!
+ */
+ void closeEvent( QCloseEvent* ) {}
+
+ private:
+ void finishWaiting( int );
+ void prepareErasingDialog();
+
+ QWidget* parentWidgetToUse();
+
+ class Private;
+ Private* d;
+};
+
+
+#endif
diff --git a/src/k3bfiletreecombobox.cpp b/src/k3bfiletreecombobox.cpp
new file mode 100644
index 0000000..ce9b6b7
--- /dev/null
+++ b/src/k3bfiletreecombobox.cpp
@@ -0,0 +1,393 @@
+/*
+ *
+ * $Id: k3bfiletreecombobox.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bfiletreecombobox.h"
+#include "k3bfiletreeview.h"
+
+#include <k3bdevicemanager.h>
+#include <k3bdevice.h>
+#include <k3bcore.h>
+#include <k3bglobals.h>
+
+#include <qrect.h>
+#include <qapplication.h>
+#include <qstyle.h>
+#include <qlistbox.h>
+#include <qheader.h>
+#include <qevent.h>
+#include <qpainter.h>
+#include <qpalette.h>
+#include <qdrawutil.h>
+#include <qdir.h>
+
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <kurlcompletion.h>
+#include <kuser.h>
+
+
+class K3bFileTreeComboBox::Private
+{
+public:
+ Private() {
+ poppedUp = false;
+ ignoreNextMouseClick = false;
+ }
+ bool poppedUp;
+ bool ignoreNextMouseClick; // used when the view was hidden with the arrow button
+
+ KURLCompletion* urlCompletion;
+};
+
+
+K3bFileTreeComboBox::K3bFileTreeComboBox( QWidget* parent, const char* name )
+ : KComboBox( true, parent, name )
+{
+ d = new Private;
+
+ d->urlCompletion = new KURLCompletion();
+ setCompletionObject( d->urlCompletion );
+
+ m_fileTreeView = new K3bFileTreeView( this );
+ m_fileTreeView->hide();
+ m_fileTreeView->reparent( this, WType_Popup, QPoint(0,0), false );
+ m_fileTreeView->header()->hide();
+ m_fileTreeView->installEventFilter(this);
+
+ m_fileTreeView->addDefaultBranches();
+ m_fileTreeView->addCdDeviceBranches( k3bcore->deviceManager() );
+
+ // HACK! Why the hell is QComboBox that closed???
+ listBox()->insertItem( "HACK" );
+
+ connect( m_fileTreeView, SIGNAL(deviceExecuted(K3bDevice::Device*)),
+ this, SLOT(slotDeviceExecuted(K3bDevice::Device*)) );
+ connect( m_fileTreeView, SIGNAL(urlExecuted(const KURL&)),
+ this, SLOT(slotUrlExecuted(const KURL&)) );
+
+ connect( lineEdit(), SIGNAL(returnPressed()),
+ this, SLOT(slotGoUrl()) );
+
+ // TODO: subclass KURLCompletition to support the dev:/ stuff and block any non-local urls
+}
+
+
+K3bFileTreeComboBox::~K3bFileTreeComboBox()
+{
+ delete d->urlCompletion;
+ delete d;
+}
+
+
+void K3bFileTreeComboBox::slotDeviceExecuted( K3bDevice::Device* dev )
+{
+ setDevice( dev );
+ popdown();
+ emit deviceExecuted( dev );
+}
+
+
+void K3bFileTreeComboBox::slotUrlExecuted( const KURL& url )
+{
+ setUrl( url );
+ emit urlExecuted( url );
+}
+
+
+void K3bFileTreeComboBox::setUrl( const KURL& url )
+{
+ setEditText( SmallIcon("folder"), K3b::convertToLocalUrl(url).path() );
+ popdown();
+}
+
+
+void K3bFileTreeComboBox::setDevice( K3bDevice::Device* dev )
+{
+ setEditText( SmallIcon("cdrom_unmount"), dev->vendor() + " " + dev->description() + " (" + dev->blockDeviceName() + ")" );
+}
+
+
+void K3bFileTreeComboBox::setEditText( const QPixmap& pix, const QString& t )
+{
+ // QComboBox::changeItem() doesn't honor the pixmap when
+ // using an editable combobox, so we just remove and insert
+
+ setUpdatesEnabled( false );
+ lineEdit()->setUpdatesEnabled( false );
+
+ removeItem(0);
+ insertItem( pix, t, 0 );
+ lineEdit()->setText( t );
+
+ setUpdatesEnabled( true );
+ lineEdit()->setUpdatesEnabled( true );
+ update();
+}
+
+
+void K3bFileTreeComboBox::setCurrentItem( int )
+{
+ // the current item is always 0 due to the ugly but quite smart HACK ;)
+}
+
+
+void K3bFileTreeComboBox::setCurrentText( const QString& )
+{
+}
+
+
+void K3bFileTreeComboBox::popup()
+{
+ // code mainly from qcombobox.cpp
+
+ m_fileTreeView->triggerUpdate();
+ int w = QMAX( m_fileTreeView->sizeHint().width(), width() );
+ int h = m_fileTreeView->sizeHint().height();
+ QRect screen = QApplication::desktop()->availableGeometry( this );
+ int sx = screen.x(); // screen pos
+ int sy = screen.y();
+ int sw = screen.width(); // screen width
+ int sh = screen.height(); // screen height
+ QPoint pos = mapToGlobal( QPoint(0,height()) );
+ // ## Similar code is in QPopupMenu
+ int x = pos.x();
+ int y = pos.y();
+
+ // the complete widget must be visible
+ if ( x + w > sx + sw )
+ x = sx+sw - w;
+ if ( x < sx )
+ x = sx;
+ if (y + h > sy+sh && y - h - height() >= 0 )
+ y = y - h - height();
+
+ QRect rect =
+ style().querySubControlMetrics( QStyle::CC_ComboBox, this,
+ QStyle::SC_ComboBoxListBoxPopup,
+ QStyleOption( x, y, w, h ) );
+ // work around older styles that don't implement the combobox
+ // listbox popup subcontrol
+ if ( rect.isNull() )
+ rect.setRect( x, y, w, h );
+
+ m_fileTreeView->setGeometry( rect );
+ m_fileTreeView->raise();
+
+ // TODO: somehow set the current item
+
+ m_fileTreeView->show();
+ d->poppedUp = true;
+ d->ignoreNextMouseClick = false;
+}
+
+
+void K3bFileTreeComboBox::popdown()
+{
+ m_fileTreeView->hide();
+ d->poppedUp = false;
+ repaint(); // repaint the arrow
+}
+
+
+void K3bFileTreeComboBox::slotGoUrl()
+{
+ QString p = currentText();
+
+ // check for a media url or a device string
+ if( K3bDevice::Device* dev = K3b::urlToDevice( p ) ) {
+ emit deviceExecuted( dev );
+ return;
+ }
+
+ // check for our own internal format
+ else if( p.contains("/dev/") ) {
+ int pos1 = p.findRev('(');
+ int pos2 = p.findRev(')');
+ QString devStr = p.mid( pos1+1, pos2-pos1-1 );
+ if( K3bDevice::Device* dev = k3bcore->deviceManager()->findDevice( devStr ) ) {
+ emit deviceExecuted( dev );
+ return;
+ }
+ }
+
+ // no device -> select url
+
+ //
+ // Properly replace home dirs.
+ // a single ~ will be replaced with the current user's home dir
+ // while for example "~ftp" will be replaced by the home dir of user
+ // ftp
+ //
+ // TODO: move this to k3bglobals
+
+ // to expand another user's home dir we need a tilde followed by a user name
+ static QRegExp someUsersHomeDir( "\\~([^/]+)" );
+ int pos = 0;
+ while( ( pos = someUsersHomeDir.search( p, pos ) ) != -1 ) {
+ KUser user( someUsersHomeDir.cap(1) );
+ if( user.isValid() )
+ p.replace( pos, someUsersHomeDir.cap(1).length() + 1, user.homeDir() );
+ else
+ ++pos; // skip this ~
+ }
+
+ // now replace the unmatched tildes with our home dir
+ p.replace( "~", K3b::prepareDir( QDir::homeDirPath() ) );
+
+
+ lineEdit()->setText( p );
+ KURL url;
+ url.setPath( p );
+ emit urlExecuted( url );
+}
+
+
+bool K3bFileTreeComboBox::eventFilter( QObject* o, QEvent* e )
+{
+ if( dynamic_cast<K3bFileTreeView*>(o) == m_fileTreeView ) {
+ if( e->type() == QEvent::DragLeave ) {
+ // the user dragged a dir from the filetree
+ // now
+ popdown();
+ return true;
+ }
+ else if( e->type() == QEvent::KeyPress ) {
+ QKeyEvent *k = (QKeyEvent *)e;
+ if( k->key() == Qt::Key_Escape ) {
+ popdown();
+ return true;
+ }
+ }
+ else if( e->type() == QEvent::MouseButtonPress ) {
+ QMouseEvent* me = (QMouseEvent*)e;
+ if ( !m_fileTreeView->rect().contains( me->pos() ) ) {
+ QRect arrowRect = style().querySubControlMetrics( QStyle::CC_ComboBox, this,
+ QStyle::SC_ComboBoxArrow);
+ arrowRect = QStyle::visualRect(arrowRect, this);
+
+ // Correction for motif style, where arrow is smaller
+ // and thus has a rect that doesn't fit the button.
+ arrowRect.setHeight( QMAX( height() - (2 * arrowRect.y()), arrowRect.height() ) );
+
+ if ( arrowRect.contains( mapFromGlobal(me->globalPos()) ) ) {
+ d->ignoreNextMouseClick = true; // in the case we hit the arrow button
+ }
+ popdown();
+ }
+ return false; // we need this in the listview
+ }
+
+ return false;
+ }
+ else
+ return KComboBox::eventFilter(o, e);
+}
+
+
+void K3bFileTreeComboBox::mousePressEvent( QMouseEvent* e )
+{
+ // mainly from qcombobox.cpp
+
+ if ( e->button() != LeftButton )
+ return;
+ if ( d->ignoreNextMouseClick ) {
+ d->ignoreNextMouseClick = FALSE;
+ return;
+ }
+
+ QRect arrowRect = style().querySubControlMetrics( QStyle::CC_ComboBox, this,
+ QStyle::SC_ComboBoxArrow);
+ arrowRect = QStyle::visualRect(arrowRect, this);
+
+ // Correction for motif style, where arrow is smaller
+ // and thus has a rect that doesn't fit the button.
+ arrowRect.setHeight( QMAX( height() - (2 * arrowRect.y()), arrowRect.height() ) );
+
+ if ( arrowRect.contains( e->pos() ) ) {
+ popup();
+ repaint( FALSE );
+ }
+}
+
+
+void K3bFileTreeComboBox::keyPressEvent( QKeyEvent* e )
+{
+ if( e->key() == Qt::Key_Escape ) {
+ popdown();
+ }
+ KComboBox::keyPressEvent(e);
+}
+
+
+void K3bFileTreeComboBox::paintEvent( QPaintEvent* )
+{
+ // a lot of code from qcombobox.cpp
+
+ // we only need this since there is no way to change the status of the arrow-button
+
+ QPainter p( this );
+ const QColorGroup & g = colorGroup();
+ p.setPen(g.text());
+
+ QStyle::SFlags flags = QStyle::Style_Default;
+ if (isEnabled())
+ flags |= QStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= QStyle::Style_HasFocus;
+
+ if ( width() < 5 || height() < 5 ) {
+ qDrawShadePanel( &p, rect(), g, FALSE, 2,
+ &g.brush( QColorGroup::Button ) );
+ return;
+ }
+
+ // bool reverse = QApplication::reverseLayout();
+
+ style().drawComplexControl( QStyle::CC_ComboBox, &p, this, rect(), g,
+ flags, QStyle::SC_All,
+ (d->poppedUp ?
+ QStyle::SC_ComboBoxArrow :
+ QStyle::SC_None ));
+
+ QRect re = style().querySubControlMetrics( QStyle::CC_ComboBox, this,
+ QStyle::SC_ComboBoxEditField );
+ re = QStyle::visualRect(re, this);
+ p.setClipRect( re );
+
+// QListBoxItem * item = listBox()->item( 0 );
+// if ( item ) {
+// // we calculate the QListBoxTexts height (ignoring strut)
+// int itemh = d->listBox()->fontMetrics().lineSpacing() + 2;
+// p.translate( re.x(), re.y() + (re.height() - itemh)/2 );
+// item->paint( &p );
+// }
+// } else if ( d->listBox() && d->listBox()->item( 0 ) ) {
+ p.setClipping( FALSE );
+ QListBoxItem * item = listBox()->item( 0 );
+ const QPixmap *pix = item->pixmap();
+ if ( pix ) {
+ p.fillRect( re.x(), re.y(), pix->width() + 4, re.height(),
+ colorGroup().brush( QColorGroup::Base ) );
+ p.drawPixmap( re.x() + 2, re.y() +
+ ( re.height() - pix->height() ) / 2, *pix );
+ }
+// }
+ p.setClipping( FALSE );
+}
+
+
+#include "k3bfiletreecombobox.moc"
+
diff --git a/src/k3bfiletreecombobox.h b/src/k3bfiletreecombobox.h
new file mode 100644
index 0000000..50bc683
--- /dev/null
+++ b/src/k3bfiletreecombobox.h
@@ -0,0 +1,72 @@
+/*
+ *
+ * $Id: k3bfiletreecombobox.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#ifndef _K3B_FILETREE_COMBOBOX_H_
+#define _K3B_FILETREE_COMBOBOX_H_
+
+#include <kcombobox.h>
+
+class K3bFileTreeView;
+class QEvent;
+class QKeyEvent;
+class QMouseEvent;
+class QPaintEvent;
+
+namespace K3bDevice {
+ class Device;
+}
+
+class K3bFileTreeComboBox : public KComboBox
+{
+ Q_OBJECT
+
+ public:
+ K3bFileTreeComboBox( QWidget* parent = 0, const char* name = 0 );
+ ~K3bFileTreeComboBox();
+
+ void popup();
+ void popdown();
+
+ void setCurrentItem( int );
+ void setCurrentText( const QString& );
+
+ public slots:
+ void setDevice( K3bDevice::Device* );
+ void setUrl( const KURL& url );
+ void slotGoUrl();
+
+ signals:
+ void urlExecuted( const KURL& url );
+ void deviceExecuted( K3bDevice::Device* dev );
+
+ private slots:
+ void slotDeviceExecuted( K3bDevice::Device* );
+ void slotUrlExecuted( const KURL& url );
+
+ protected:
+ bool eventFilter( QObject*, QEvent* );
+ void keyPressEvent( QKeyEvent* );
+ void mousePressEvent( QMouseEvent* );
+ void paintEvent( QPaintEvent* );
+
+ private:
+ void setEditText( const QPixmap& pix, const QString& t );
+
+ class Private;
+ Private* d;
+ K3bFileTreeView* m_fileTreeView;
+};
+
+#endif
diff --git a/src/k3bfiletreeview.cpp b/src/k3bfiletreeview.cpp
new file mode 100644
index 0000000..36c86c3
--- /dev/null
+++ b/src/k3bfiletreeview.cpp
@@ -0,0 +1,728 @@
+/*
+ *
+ * $Id: k3bfiletreeview.cpp 657858 2007-04-25 08:25:11Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bfiletreeview.h"
+#include "k3bappdevicemanager.h"
+#include "k3bapplication.h"
+#include "k3bmediacache.h"
+#include "k3btooltip.h"
+#include "k3bthememanager.h"
+
+#include <k3bdevice.h>
+#include <k3bdiskinfo.h>
+#include <k3bglobals.h>
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <kstandarddirs.h>
+#include <kaction.h>
+#include <kio/global.h>
+#include <kfileitem.h>
+#include <kapplication.h>
+#include <kglobalsettings.h>
+
+#include <qdir.h>
+#include <qevent.h>
+#include <qdragobject.h>
+#include <qcursor.h>
+#include <qnamespace.h>
+#include <qmap.h>
+#include <qptrdict.h>
+#include <qpainter.h>
+#include <qfont.h>
+#include <qstyle.h>
+#include <qlabel.h>
+#include <qlayout.h>
+
+
+K3bDeviceBranch::K3bDeviceBranch( KFileTreeView* view, K3bDevice::Device* dev, KFileTreeViewItem* item )
+ : KFileTreeBranch( view,
+ KURL( "media:/" + dev->blockDeviceName() ),
+ QString("%1 - %2").arg(dev->vendor()).arg(dev->description()),
+ ( dev->burner()
+ ? SmallIcon("cdwriter_unmount")
+ : SmallIcon("cdrom_unmount") ),
+ false,
+ item == 0
+ ? new K3bDeviceBranchViewItem( view, dev, this )
+ : item ),
+ m_device( dev ),
+ m_showBlockDeviceName( false )
+{
+ setAutoUpdate(true);
+ root()->setExpandable(false);
+ updateLabel();
+
+ connect( k3bappcore->mediaCache(), SIGNAL(mediumChanged(K3bDevice::Device*)),
+ this, SLOT(slotMediumChanged(K3bDevice::Device*)) );
+}
+
+
+bool K3bDeviceBranch::populate( const KURL& url, KFileTreeViewItem *currItem )
+{
+ // FIXME: we somehow need to "unpopulate" once the medium is unmounted
+
+ // make sure we do not try to populate in case we are not mounted
+ if( K3b::isMounted( m_device ) ) {
+ bool b = KFileTreeBranch::populate( url, currItem );
+ populateFinished( currItem );
+ return b;
+ }
+ else
+ populateFinished( currItem );
+
+ return true;
+}
+
+
+void K3bDeviceBranch::setCurrent( bool c )
+{
+ static_cast<K3bDeviceBranchViewItem*>( root() )->setCurrent( c );
+}
+
+
+void K3bDeviceBranch::updateLabel()
+{
+ if( m_showBlockDeviceName )
+ setName( QString("%1 %2 (%3)")
+ .arg(m_device->vendor())
+ .arg(m_device->description())
+ .arg(m_device->blockDeviceName()) );
+ else
+ setName( QString("%1 %2")
+ .arg(m_device->vendor())
+ .arg(m_device->description()) );
+
+ if( k3bappcore->mediaCache() ) {
+ root()->setMultiLinesEnabled( true );
+ root()->setText( 0, name() + "\n" + k3bappcore->mediaCache()->mediumString( m_device ) );
+ static_cast<K3bFileTreeView*>( root()->listView() )->updateMinimumWidth();
+ }
+ else {
+ root()->setMultiLinesEnabled( false );
+ root()->setText( 0, name() );
+ }
+}
+
+
+void K3bDeviceBranch::slotMediumChanged( K3bDevice::Device* dev )
+{
+ if( dev == m_device )
+ updateLabel();
+}
+
+
+void K3bDeviceBranch::showBlockDeviceName( bool b )
+{
+ m_showBlockDeviceName = b;
+ updateLabel();
+}
+
+
+K3bFileTreeBranch::K3bFileTreeBranch( KFileTreeView* view,
+ const KURL& url,
+ const QString& name,
+ const QPixmap& pix,
+ bool showHidden,
+ KFileTreeViewItem* item )
+ : KFileTreeBranch( view, url, name, pix, showHidden,
+ item == 0
+ ? new K3bFileTreeViewItem( view,
+ new KFileItem( url, "inode/directory",
+ S_IFDIR ),
+ this )
+ : item )
+{
+}
+
+
+
+K3bDeviceBranchViewItem::K3bDeviceBranchViewItem( KFileTreeViewItem* parent,
+ K3bDevice::Device* dev,
+ K3bDeviceBranch* branch )
+ : KFileTreeViewItem( parent,
+ new KFileItem( KURL( "media:/" + dev->blockDeviceName() ),
+ "inode/directory",
+ S_IFDIR ),
+ branch ),
+ m_bCurrent( false ),
+ m_device( dev )
+{
+}
+
+
+K3bDeviceBranchViewItem::K3bDeviceBranchViewItem( KFileTreeView* parent,
+ K3bDevice::Device* dev,
+ K3bDeviceBranch* branch )
+ : KFileTreeViewItem( parent,
+ new KFileItem( KURL( "media:/" + dev->blockDeviceName() ),
+ "inode/directory",
+ S_IFDIR ),
+ branch ),
+ m_bCurrent( false ),
+ m_device( dev )
+{
+}
+
+
+void K3bDeviceBranchViewItem::setCurrent( bool c )
+{
+ m_bCurrent = c;
+ repaint();
+}
+
+
+void K3bDeviceBranchViewItem::paintCell( QPainter* p, const QColorGroup& cg, int /* col */, int width, int align )
+{
+ p->save();
+
+ int xpos = 1;
+ int ypos = 1;
+ QFontMetrics fm( p->fontMetrics() );
+
+ if( isSelected() ) {
+ p->fillRect( 0, 0, width, height(),
+ cg.brush( QColorGroup::Highlight ) );
+ p->setPen( cg.highlightedText() );
+ }
+ else {
+ p->fillRect( 0, 0, width, height(), cg.base() );
+ p->setPen( cg.text() );
+ }
+
+ if( pixmap(0) ) {
+ p->drawPixmap( xpos, ypos, *pixmap(0) );
+ xpos += pixmap(0)->width() + 5;
+ }
+
+ if( m_bCurrent ) {
+ QFont f( listView()->font() );
+ f.setBold( true );
+ p->setFont( f );
+ }
+
+ ypos += fm.ascent();
+ QString line1 = text(0).left( text(0).find('\n') );
+ p->drawText( xpos, ypos, line1 );
+
+ QFont f( listView()->font() );
+ f.setItalic( true );
+ f.setBold( false );
+ f.setPointSize( f.pointSize() - 2 );
+ p->setFont( f );
+
+ ypos += p->fontMetrics().height() + 1;
+ QString line2 = text(0).mid( text(0).find('\n')+1 );
+ p->drawText( xpos - p->fontMetrics().leftBearing( line2[0] ), ypos, line2 );
+
+
+ // from QListViewItem
+ if( isOpen() && childCount() ) {
+ int textheight = fm.size( align, text(0) ).height() + 2 * listView()->itemMargin();
+ textheight = QMAX( textheight, QApplication::globalStrut().height() );
+ if ( textheight % 2 > 0 )
+ textheight++;
+ if ( textheight < height() ) {
+ int w = listView()->treeStepSize() / 2;
+ listView()->style().drawComplexControl( QStyle::CC_ListView, p, listView(),
+ QRect( 0, textheight, w + 1, height() - textheight + 1 ), cg,
+ QStyle::Style_Enabled,
+ QStyle::SC_ListViewExpand,
+ (uint)QStyle::SC_All, QStyleOption( this ) );
+ }
+ }
+
+ p->restore();
+}
+
+
+int K3bDeviceBranchViewItem::widthHint() const
+{
+ QFont f( listView()->font() );
+ if ( m_bCurrent ) {
+ f.setBold( true );
+ }
+ int w = QFontMetrics(f).width( text(0).left( text(0).find('\n') ) );
+
+ f.setItalic( true );
+ f.setBold( false );
+ f.setPointSize( f.pointSize() - 2 );
+ w = QMAX( w, QFontMetrics(f).width( text(0).mid( text(0).find('\n')+1 ) ) );
+
+ w++; // see paintCell
+
+ if( pixmap(0) )
+ w += pixmap(0)->width() + 5;
+
+ return w;
+}
+
+
+QString K3bDeviceBranchViewItem::key( int column, bool ascending ) const
+{
+ return "0" + KFileTreeViewItem::key( column, ascending );
+}
+
+
+
+K3bFileTreeViewItem::K3bFileTreeViewItem( KFileTreeViewItem* parent, KFileItem* item, KFileTreeBranch* branch )
+ : KFileTreeViewItem( parent, item, branch )
+{
+}
+
+
+K3bFileTreeViewItem::K3bFileTreeViewItem( KFileTreeView* parent, KFileItem* item, KFileTreeBranch* branch )
+ : KFileTreeViewItem( parent, item, branch )
+{
+}
+
+
+QString K3bFileTreeViewItem::key( int column, bool ascending ) const
+{
+ return "1" + KFileTreeViewItem::key( column, ascending );
+}
+
+
+class K3bDeviceTreeToolTip : public K3bToolTip
+{
+public:
+ K3bDeviceTreeToolTip( QWidget* parent, K3bFileTreeView* lv );
+
+ void maybeTip( const QPoint &pos );
+
+private:
+ K3bFileTreeView* m_view;
+};
+
+
+K3bDeviceTreeToolTip::K3bDeviceTreeToolTip( QWidget* parent, K3bFileTreeView* lv )
+ : K3bToolTip( parent ),
+ m_view( lv )
+{
+ setTipTimeout( 500 );
+}
+
+
+void K3bDeviceTreeToolTip::maybeTip( const QPoint& pos )
+{
+ if( !parentWidget() || !m_view )
+ return;
+
+ K3bDeviceBranchViewItem* item = dynamic_cast<K3bDeviceBranchViewItem*>( m_view->itemAt( pos ) );
+ if( !item )
+ return;
+
+ K3bDevice::Device* dev = static_cast<K3bDeviceBranch*>( item->branch() )->device();
+
+ QFrame* tooltip = new QFrame( parentWidget() );
+ tooltip->setFrameStyle( QFrame::Panel | QFrame::Raised );
+ tooltip->setFrameShape( QFrame::StyledPanel );
+ QGridLayout* lay = new QGridLayout( tooltip, 2, 2, tooltip->frameWidth()*2 /*margin*/, 6 /*spacing*/ );
+
+ QString text = k3bappcore->mediaCache()->medium( dev ).longString();
+ int detailsStart = text.find( "<p>", 3 );
+ QString details = text.mid( detailsStart );
+ text.truncate( detailsStart );
+
+ QLabel* label = new QLabel( text, tooltip );
+ label->setMargin( 9 );
+ lay->addMultiCellWidget( label, 0, 0, 0, 1 );
+ label = new QLabel( details, tooltip );
+ label->setMargin( 9 );
+ label->setAlignment( Qt::Vertical );
+ lay->addMultiCellWidget( label, 1, 2, 0, 0 );
+ label = new QLabel( tooltip );
+ lay->addWidget( label, 2, 1 );
+ lay->setColStretch( 0, 1 );
+
+ if( K3bTheme* theme = k3bappcore->themeManager()->currentTheme() ) {
+ tooltip->setPaletteBackgroundColor( theme->backgroundColor() );
+ tooltip->setPaletteForegroundColor( theme->foregroundColor() );
+ K3bTheme::PixmapType pm;
+ int c = k3bappcore->mediaCache()->medium( dev ).content();
+ if( c & (K3bMedium::CONTENT_VIDEO_CD|K3bMedium::CONTENT_VIDEO_DVD) )
+ pm = K3bTheme::MEDIA_VIDEO;
+ else if( c & K3bMedium::CONTENT_AUDIO &&
+ c & K3bMedium::CONTENT_DATA )
+ pm = K3bTheme::MEDIA_MIXED;
+ else if( c & K3bMedium::CONTENT_AUDIO )
+ pm = K3bTheme::MEDIA_AUDIO;
+ else if( c & K3bMedium::CONTENT_DATA )
+ pm = K3bTheme::MEDIA_DATA;
+ else {
+ K3bDevice::DiskInfo di = k3bappcore->mediaCache()->diskInfo( dev );
+ if( di.diskState() == K3bDevice::STATE_EMPTY )
+ pm = K3bTheme::MEDIA_EMPTY;
+ else
+ pm = K3bTheme::MEDIA_NONE;
+ }
+ label->setPixmap( theme->pixmap( pm ) );
+ }
+
+ // the tooltip will take care of deleting the widget
+ tip( m_view->itemRect( item ), tooltip );
+}
+
+
+
+class K3bFileTreeView::Private
+{
+public:
+ Private()
+ : deviceManager(0),
+ currentDeviceBranch(0) {
+ }
+
+ QPtrDict<K3bDeviceBranch> deviceBranchDict;
+ QMap<KFileTreeBranch*, K3bDevice::Device*> branchDeviceMap;
+
+ K3bDevice::DeviceManager* deviceManager;
+ K3bDeviceBranch* currentDeviceBranch;
+
+ K3bDeviceTreeToolTip* toolTip;
+};
+
+K3bFileTreeView::K3bFileTreeView( QWidget *parent, const char *name )
+ : KFileTreeView( parent, name )
+{
+ d = new Private();
+
+ d->toolTip = new K3bDeviceTreeToolTip( viewport(), this );
+
+ addColumn( i18n("Directories") );
+ setDragEnabled( true );
+ setAlternateBackground( QColor() );
+ setFullWidth(true);
+ // setRootIsDecorated(true);
+ setSorting(0);
+
+ m_dirOnlyMode = true;
+ m_menuEnabled = false;
+
+ connect( this, SIGNAL(executed(QListViewItem*)), this, SLOT(slotItemExecuted(QListViewItem*)) );
+ connect( this, SIGNAL(returnPressed(QListViewItem*)), this, SLOT(slotItemExecuted(QListViewItem*)) );
+ connect( this, SIGNAL(contextMenu(KListView*, QListViewItem* , const QPoint& )),
+ this, SLOT(slotContextMenu(KListView*, QListViewItem* , const QPoint& )) );
+
+ // we always simulate the single click
+ slotSettingsChangedK3b(KApplication::SETTINGS_MOUSE);
+ if( kapp )
+ connect( kapp, SIGNAL(settingsChanged(int)), SLOT(slotSettingsChangedK3b(int)) );
+
+ initActions();
+}
+
+
+K3bFileTreeView::~K3bFileTreeView()
+{
+ delete d;
+}
+
+
+void K3bFileTreeView::clear()
+{
+ KFileTreeView::clear();
+ if( d->deviceManager )
+ d->deviceManager->disconnect( this );
+ d->deviceManager = 0;
+}
+
+
+void K3bFileTreeView::initActions()
+{
+// m_actionCollection = new KActionCollection( this );
+
+// m_devicePopupMenu = new KActionMenu( m_actionCollection, "device_popup_menu" );
+// m_urlPopupMenu = new KActionMenu( m_actionCollection, "url_popup_menu" );
+
+// KAction* actionDiskInfo = new KAction( i18n("&Disk Info"), "info", 0, this, SLOT(slotShowDiskInfo()),
+// m_actionCollection, "disk_info");
+// KAction* actionUnmount = new KAction( i18n("&Unmount"), "cdrom_unmount", 0, this, SLOT(slotUnmountDisk()),
+// m_actionCollection, "disk_unmount");
+// KAction* actionEject = new KAction( i18n("&Eject"), "", 0, this, SLOT(slotEjectDisk()),
+// m_actionCollection, "disk_eject");
+
+// m_devicePopupMenu->insert( actionDiskInfo );
+// m_devicePopupMenu->insert( new KActionSeparator( this ) );
+// m_devicePopupMenu->insert( actionUnmount );
+// m_devicePopupMenu->insert( actionEject );
+
+}
+
+
+void K3bFileTreeView::addDefaultBranches()
+{
+ KURL home = KURL::fromPathOrURL( QDir::homeDirPath() );
+ KURL root = KURL( "file:/" );
+
+ KFileTreeBranch* treeBranch = addBranch( new K3bFileTreeBranch( this, root, i18n("Root"), SmallIcon("folder_red") ) );
+ treeBranch = addBranch( new K3bFileTreeBranch( this, home, i18n("Home"), SmallIcon("folder_home") ) );
+ treeBranch->setOpen( true );
+}
+
+
+void K3bFileTreeView::addCdDeviceBranches( K3bDevice::DeviceManager* dm )
+{
+ kdDebug() << "(K3bFileTreeView::addCdDeviceBranches)" << endl;
+
+ // remove all previous added device branches
+ for( QMap<KFileTreeBranch*, K3bDevice::Device*>::Iterator it = d->branchDeviceMap.begin();
+ it != d->branchDeviceMap.end(); ++it ) {
+ removeBranch( it.key() );
+ }
+
+ // clear the maps
+ d->branchDeviceMap.clear();
+ d->deviceBranchDict.clear();
+
+ for( QPtrListIterator<K3bDevice::Device> it( dm->allDevices() ); *it; ++it )
+ addDeviceBranch( *it );
+
+ if( dm != d->deviceManager ) {
+ if( d->deviceManager )
+ d->deviceManager->disconnect( this );
+ d->deviceManager = dm;
+
+ // make sure we get changes to the config
+ connect( dm, SIGNAL(changed(K3bDevice::DeviceManager*)),
+ this, SLOT(addCdDeviceBranches(K3bDevice::DeviceManager*)) );
+
+ if( K3bAppDeviceManager* appDevM = dynamic_cast<K3bAppDeviceManager*>( dm ) )
+ connect( appDevM, SIGNAL(currentDeviceChanged(K3bDevice::Device*)),
+ this, SLOT(setCurrentDevice(K3bDevice::Device*)) );
+ }
+
+ K3bDevice::Device* currentDevice = k3bappcore->appDeviceManager()->currentDevice();
+ if ( !currentDevice && !k3bappcore->appDeviceManager()->allDevices().isEmpty() ) {
+ k3bappcore->appDeviceManager()->setCurrentDevice( k3bappcore->appDeviceManager()->allDevices().getFirst() );
+ }
+
+ d->currentDeviceBranch = d->deviceBranchDict[currentDevice];
+ if( d->currentDeviceBranch ) {
+ d->currentDeviceBranch->setCurrent( true );
+ }
+
+ kdDebug() << "(K3bFileTreeView::addCdDeviceBranches) done" << endl;
+}
+
+
+void K3bFileTreeView::addDeviceBranch( K3bDevice::Device* dev )
+{
+ K3bDeviceBranch* newBranch = new K3bDeviceBranch( this, dev );
+ addBranch( newBranch );
+
+ // search for an equal device
+ int equalCnt = 0;
+ K3bDeviceBranch* equalBranch = 0;
+ for( QMap<KFileTreeBranch*, K3bDevice::Device*>::Iterator it = d->branchDeviceMap.begin();
+ it != d->branchDeviceMap.end(); ++it ) {
+ K3bDevice::Device* itDev = it.data();
+ K3bDeviceBranch* itBranch = (K3bDeviceBranch*)it.key();
+ if( itDev->vendor() == dev->vendor() &&
+ itDev->description() == dev->description() ) {
+ ++equalCnt;
+ equalBranch = itBranch;
+ }
+ }
+
+ // if there is at least one equal device add the block device name
+ // if there is more than one equal device they have been updated after
+ // adding the last one so there is no need to update more than two
+ if( equalCnt > 0 ) {
+ kdDebug() << "(K3bFileTreeView) equal branch" << endl;
+ newBranch->showBlockDeviceName(true);
+ equalBranch->showBlockDeviceName(true);
+ }
+
+ // add to maps
+ d->branchDeviceMap.insert( newBranch, dev );
+ d->deviceBranchDict.insert( (void*)dev, newBranch );
+
+ updateMinimumWidth();
+}
+
+
+KFileTreeBranch* K3bFileTreeView::addBranch( KFileTreeBranch* branch )
+{
+ KFileTreeBranch* newBranch = KFileTreeView::addBranch( branch );
+ newBranch->setChildRecurse( false );
+ setDirOnlyMode( newBranch, m_dirOnlyMode );
+
+ return newBranch;
+}
+
+
+KFileTreeBranch* K3bFileTreeView::addBranch( const KURL& url, const QString& name, const QPixmap& pix, bool showHidden )
+{
+ KFileTreeBranch* newBranch = KFileTreeView::addBranch( url, name, pix, showHidden );
+ newBranch->setChildRecurse( false );
+ setDirOnlyMode( newBranch, m_dirOnlyMode );
+
+ return newBranch;
+}
+
+
+void K3bFileTreeView::slotItemExecuted( QListViewItem* item )
+{
+ KFileTreeViewItem* treeItem = static_cast<KFileTreeViewItem*>(item);
+ if( d->branchDeviceMap.contains( treeItem->branch() ) &&
+ treeItem == treeItem->branch()->root() ) {
+ K3bDevice::Device* dev = d->branchDeviceMap[treeItem->branch()];
+ k3bappcore->appDeviceManager()->setCurrentDevice( dev );
+ emit deviceExecuted( dev );
+ }
+ else
+ emit urlExecuted( treeItem->url() );
+}
+
+
+void K3bFileTreeView::setTreeDirOnlyMode( bool b )
+{
+ m_dirOnlyMode = b;
+}
+
+
+void K3bFileTreeView::followUrl( const KURL& url )
+{
+ // TODO: first try the current branch
+ KFileTreeBranchIterator it( branches() );
+ for( ; *it; ++it ) {
+ if( !d->branchDeviceMap.contains( *it ) )
+ if( KFileTreeViewItem* item = (*it)->findTVIByURL( url ) ) {
+ setCurrentItem( item );
+ setSelected(item, true);
+ ensureItemVisible( item );
+ return;
+ }
+ }
+}
+
+
+void K3bFileTreeView::slotContextMenu( KListView*, QListViewItem* item, const QPoint& p )
+{
+ KFileTreeViewItem* treeItem = dynamic_cast<KFileTreeViewItem*>(item);
+ if( treeItem ) {
+ K3bDevice::Device* device = 0;
+ QMap<KFileTreeBranch*, K3bDevice::Device*>::iterator devIt =
+ d->branchDeviceMap.find( treeItem->branch() );
+ if( devIt != d->branchDeviceMap.end() )
+ device = devIt.data();
+
+ setCurrentItem( treeItem );
+ setSelected( treeItem, true);
+
+ if( device ) {
+ k3bappcore->appDeviceManager()->setCurrentDevice( device );
+ emit contextMenu( device, p );
+ }
+ else
+ emit contextMenu( treeItem->url(), p );
+ }
+ else
+ kdWarning() << "(K3bFileTreeView) found viewItem that is no KFileTreeViewItem!" << endl;
+}
+
+
+K3bDevice::Device* K3bFileTreeView::selectedDevice() const
+{
+ KFileTreeViewItem* treeItem = dynamic_cast<KFileTreeViewItem*>(selectedItem());
+ if( treeItem ) {
+ if( d->branchDeviceMap.contains( treeItem->branch() ) )
+ return d->branchDeviceMap[treeItem->branch()];
+ }
+ return 0;
+}
+
+
+KURL K3bFileTreeView::selectedUrl() const
+{
+ KFileTreeViewItem* treeItem = dynamic_cast<KFileTreeViewItem*>(selectedItem());
+ if( treeItem ) {
+ if( !d->branchDeviceMap.contains( treeItem->branch() ) )
+ return treeItem->url();
+ }
+ return KURL();
+}
+
+
+void K3bFileTreeView::setCurrentDevice( K3bDevice::Device* dev )
+{
+ if( d->currentDeviceBranch )
+ d->currentDeviceBranch->setCurrent( false );
+
+ if( dev ) {
+ if ( ( d->currentDeviceBranch = branch( dev ) ) )
+ d->currentDeviceBranch->setCurrent( true );
+ }
+
+ updateMinimumWidth();
+}
+
+
+void K3bFileTreeView::setSelectedDevice( K3bDevice::Device* dev )
+{
+ setCurrentDevice( dev );
+ K3bDeviceBranch* b = branch( dev );
+ setCurrentItem( b->root() );
+ setSelected( b->root(), true );
+}
+
+
+K3bDeviceBranch* K3bFileTreeView::branch( K3bDevice::Device* dev )
+{
+ return d->deviceBranchDict.find( (void*)dev );
+}
+
+
+void K3bFileTreeView::slotSettingsChangedK3b(int category)
+{
+ // we force single click like konqueror does. This really should be done in KFileTreeView
+
+ if( category == KApplication::SETTINGS_MOUSE ) {
+ disconnect(this, SIGNAL(mouseButtonClicked(int, QListViewItem*, const QPoint &, int)),
+ this, SLOT(slotMouseButtonClickedK3b(int, QListViewItem*, const QPoint &, int)));
+
+ if( !KGlobalSettings::singleClick() )
+ connect(this, SIGNAL(mouseButtonClicked(int, QListViewItem*, const QPoint &, int)),
+ this, SLOT(slotMouseButtonClickedK3b(int, QListViewItem*, const QPoint &, int)));
+ }
+}
+
+
+void K3bFileTreeView::slotMouseButtonClickedK3b( int btn, QListViewItem *item, const QPoint &pos, int c )
+{
+ if( (btn == LeftButton) && item )
+ emitExecute(item, pos, c);
+}
+
+
+void K3bFileTreeView::updateMinimumWidth()
+{
+ //
+ // only handle the device branches, we don't care about the folders.
+ //
+ int w = 0;
+ for( QMap<KFileTreeBranch*, K3bDevice::Device*>::Iterator it = d->branchDeviceMap.begin();
+ it != d->branchDeviceMap.end(); ++it ) {
+ w = QMAX( w, static_cast<K3bDeviceBranchViewItem*>( it.key()->root() )->widthHint() );
+ }
+
+ // width of the items + scrollbar width + the frame + a little eyecandy spacing
+ setMinimumWidth( w + verticalScrollBar()->sizeHint().width() + 2*frameWidth() + 2 );
+}
+
+#include "k3bfiletreeview.moc"
diff --git a/src/k3bfiletreeview.h b/src/k3bfiletreeview.h
new file mode 100644
index 0000000..31a25c4
--- /dev/null
+++ b/src/k3bfiletreeview.h
@@ -0,0 +1,199 @@
+/*
+ *
+ * $Id: k3bfiletreeview.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BFILETREEVIEW_H
+#define K3BFILETREEVIEW_H
+
+
+#include <kfiletreeview.h>
+
+class KFileTreeBranch;
+class KActionCollection;
+class KActionMenu;
+class QPoint;
+class QDropEvent;
+class QDragEnterEvent;
+
+namespace K3bDevice {
+ class Device;
+ class DeviceManager;
+}
+
+namespace KIO {
+ class Job;
+}
+
+
+class K3bDeviceBranch : public KFileTreeBranch
+{
+ Q_OBJECT
+
+ public:
+ K3bDeviceBranch( KFileTreeView*, K3bDevice::Device* dev, KFileTreeViewItem* item = 0 );
+
+ K3bDevice::Device* device() const { return m_device; }
+
+ /**
+ * Adds or removes the blockdevicename from the branch name
+ */
+ void showBlockDeviceName( bool b );
+
+ public slots:
+ void setCurrent( bool );
+
+ bool populate( const KURL& url, KFileTreeViewItem *currItem );
+
+ private slots:
+ void slotMediumChanged( K3bDevice::Device* );
+
+ private:
+ void updateLabel();
+
+ K3bDevice::Device* m_device;
+ bool m_showBlockDeviceName;
+};
+
+
+class K3bFileTreeBranch : public KFileTreeBranch
+{
+ public:
+ K3bFileTreeBranch( KFileTreeView*,
+ const KURL& url,
+ const QString& name,
+ const QPixmap& pix,
+ bool showHidden = false,
+ KFileTreeViewItem* item = 0 );
+};
+
+
+class K3bDeviceBranchViewItem : public KFileTreeViewItem
+{
+ public:
+ K3bDeviceBranchViewItem( KFileTreeViewItem*, K3bDevice::Device*, K3bDeviceBranch* );
+ K3bDeviceBranchViewItem( KFileTreeView*, K3bDevice::Device*, K3bDeviceBranch* );
+
+ QString key( int column, bool ascending ) const;
+
+ void setCurrent( bool );
+
+ void paintCell( QPainter* p, const QColorGroup& cg, int col, int width, int align );
+
+ int widthHint() const;
+
+ private:
+ bool m_bCurrent;
+
+ K3bDevice::Device* m_device;
+};
+
+
+class K3bFileTreeViewItem : public KFileTreeViewItem
+{
+ public:
+ K3bFileTreeViewItem( KFileTreeViewItem*, KFileItem*, KFileTreeBranch* );
+ K3bFileTreeViewItem( KFileTreeView *, KFileItem*, KFileTreeBranch* );
+
+ QString key( int column, bool ascending ) const;
+};
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bFileTreeView : public KFileTreeView
+{
+ Q_OBJECT
+
+ public:
+ K3bFileTreeView( QWidget *parent = 0, const char *name = 0 );
+ ~K3bFileTreeView();
+
+
+ virtual KFileTreeBranch* addBranch( KFileTreeBranch* );
+ virtual KFileTreeBranch* addBranch( const KURL& url, const QString& name, const QPixmap& , bool showHidden = false );
+
+ K3bDeviceBranch* branch( K3bDevice::Device* dev );
+
+ /**
+ * returns 0 if no device is selected
+ */
+ K3bDevice::Device* selectedDevice() const;
+
+ /**
+ * returnes an empty url if no url is selected
+ */
+ KURL selectedUrl() const;
+
+ public slots:
+ /**
+ * adds home and root dir branch
+ */
+ void addDefaultBranches();
+ void addCdDeviceBranches( K3bDevice::DeviceManager* );
+ void addDeviceBranch( K3bDevice::Device* dev );
+
+ /**
+ * Make dev the current device. This does not mean that the device entry
+ * will be highlighted but marked otherwise since this means that it is the
+ * current device in the application and not the treeview.
+ */
+ void setCurrentDevice( K3bDevice::Device* dev );
+
+ /**
+ * his will highlight the device and also make it the current device.
+ */
+ void setSelectedDevice( K3bDevice::Device* dev );
+
+ void followUrl( const KURL& url );
+ void setTreeDirOnlyMode( bool b );
+ void enablePopupMenu( bool b ) { m_menuEnabled = b; }
+
+ /**
+ * @reimplemented
+ */
+ virtual void clear();
+
+ void updateMinimumWidth();
+
+ signals:
+ void urlExecuted( const KURL& url );
+ void deviceExecuted( K3bDevice::Device* dev );
+
+ /** only gets emitted if the menu is disabled */
+ void contextMenu( K3bDevice::Device*, const QPoint& );
+ /** only gets emitted if the menu is disabled */
+ void contextMenu( const KURL& url, const QPoint& );
+
+ private slots:
+ void slotItemExecuted( QListViewItem* item );
+ void slotContextMenu( KListView*, QListViewItem*, const QPoint& );
+ void slotSettingsChangedK3b(int category);
+ void slotMouseButtonClickedK3b( int btn, QListViewItem *item, const QPoint &pos, int c );
+
+ private:
+ void initActions();
+
+ class Private;
+ Private* d;
+
+ bool m_dirOnlyMode;
+ KActionCollection* m_actionCollection;
+ KActionMenu* m_devicePopupMenu;
+ KActionMenu* m_urlPopupMenu;
+ bool m_menuEnabled;
+};
+
+#endif
diff --git a/src/k3bfileview.cpp b/src/k3bfileview.cpp
new file mode 100644
index 0000000..04ce435
--- /dev/null
+++ b/src/k3bfileview.cpp
@@ -0,0 +1,183 @@
+/*
+ *
+ * $Id: k3bfileview.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bfileview.h"
+#include "k3b.h"
+#include "k3bdiroperator.h"
+#include "k3btoolbox.h"
+#include "k3bapplication.h"
+
+#include <qwidget.h>
+#include <qdragobject.h>
+#include <qlayout.h>
+#include <qdir.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qtoolbutton.h>
+
+#include <kfiledetailview.h>
+#include <klistview.h>
+#include <kaction.h>
+#include <ktoolbar.h>
+#include <ktoolbarbutton.h>
+#include <kurl.h>
+#include <kurldrag.h>
+#include <kfilefiltercombo.h>
+#include <klocale.h>
+#include <kfileitem.h>
+#include <kmessagebox.h>
+#include <kdirlister.h>
+#include <kprogress.h>
+
+
+K3bFileView::K3bFileView(QWidget *parent, const char *name )
+ : K3bContentsView( false, parent, name)
+{
+ setupGUI();
+}
+
+
+K3bFileView::~K3bFileView()
+{
+}
+
+
+KActionCollection* K3bFileView::actionCollection() const
+{
+ return m_dirOp->actionCollection();
+}
+
+
+void K3bFileView::setupGUI()
+{
+ QVBoxLayout* layout = new QVBoxLayout( this );
+ // layout->setAutoAdd( true );
+
+ m_dirOp = new K3bDirOperator( KURL::fromPathOrURL(QDir::home().absPath()), this );
+ m_toolBox = new K3bToolBox( this );
+
+ layout->addWidget( m_toolBox );
+ layout->addWidget( m_dirOp );
+ layout->setStretchFactor( m_dirOp, 1 );
+
+ // setup actions
+ KAction* actionHome = m_dirOp->actionCollection()->action("home");
+ KAction* actionBack = m_dirOp->actionCollection()->action("back");
+ KAction* actionUp = m_dirOp->actionCollection()->action("up");
+ KAction* actionReload = m_dirOp->actionCollection()->action("reload");
+
+ m_toolBox->addButton( actionUp );
+ m_toolBox->addButton( actionBack );
+ m_toolBox->addButton( actionHome );
+ m_toolBox->addButton( actionReload );
+ m_toolBox->addSpacing();
+ m_toolBox->addButton( m_dirOp->actionCollection()->action("short view") );
+ m_toolBox->addButton( m_dirOp->actionCollection()->action("detailed view") );
+ m_toolBox->addSpacing();
+ m_toolBox->addButton( m_dirOp->bookmarkMenu() );
+ m_toolBox->addSpacing();
+
+ // create filter selection combobox
+ m_toolBox->addSpacing();
+ m_toolBox->addLabel( i18n("Filter:") );
+ m_toolBox->addSpacing();
+ m_filterWidget = new KFileFilterCombo( m_toolBox, "filterwidget" );
+ m_toolBox->addWidget( m_filterWidget );
+ m_toolBox->addStretch();
+ m_toolBox->addWidget( m_dirOp->progressBar() );
+
+ m_filterWidget->setEditable( true );
+ QString filter = i18n("*|All Files");
+ filter += "\n" + i18n("audio/x-mp3 audio/x-wav application/x-ogg |Sound Files");
+ filter += "\n" + i18n("audio/x-wav |Wave Sound Files");
+ filter += "\n" + i18n("audio/x-mp3 |MP3 Sound Files");
+ filter += "\n" + i18n("application/x-ogg |Ogg Vorbis Sound Files");
+ filter += "\n" + i18n("video/mpeg |MPEG Video Files");
+ m_filterWidget->setFilter(filter);
+
+ connect( m_filterWidget, SIGNAL(filterChanged()), SLOT(slotFilterChanged()) );
+
+ connect( m_dirOp, SIGNAL(fileHighlighted(const KFileItem*)), this, SLOT(slotFileHighlighted(const KFileItem*)) );
+ connect( m_dirOp, SIGNAL(urlEntered(const KURL&)), this, SIGNAL(urlEntered(const KURL&)) );
+ connect( m_dirOp, SIGNAL(fileSelected(const KFileItem*)), m_dirOp, SLOT(slotAddFilesToProject()) );
+
+ slotFileHighlighted(0);
+}
+
+void K3bFileView::setDir( const QString& dir )
+{
+ KURL url;
+ url.setPath(dir);
+ setUrl( url );
+}
+
+
+void K3bFileView::setUrl(const KURL& url, bool forward)
+{
+ m_dirOp->setURL( url, forward );
+}
+
+KURL K3bFileView::url()
+{
+ return m_dirOp->url();
+}
+
+void K3bFileView::setAutoUpdate( bool b )
+{
+ m_dirOp->dirLister()->setAutoUpdate( b );
+}
+
+void K3bFileView::slotFileHighlighted( const KFileItem* )
+{
+}
+
+
+void K3bFileView::slotFilterChanged()
+{
+ QString filter = m_filterWidget->currentFilter();
+ m_dirOp->clearFilter();
+
+ if( filter.find( '/' ) > -1 ) {
+ QStringList types = QStringList::split( " ", filter );
+ types.prepend( "inode/directory" );
+ m_dirOp->setMimeFilter( types );
+ }
+ else
+ m_dirOp->setNameFilter( filter );
+
+ m_dirOp->rereadDir();
+ // emit filterChanged( filter );
+}
+
+
+void K3bFileView::reload()
+{
+ m_dirOp->actionCollection()->action("reload")->activate();
+}
+
+
+void K3bFileView::saveConfig( KConfig* c )
+{
+ m_dirOp->writeConfig( c, "file view" );
+}
+
+
+void K3bFileView::readConfig( KConfig* c )
+{
+ m_dirOp->readConfig( c, "file view" );
+}
+
+#include "k3bfileview.moc"
diff --git a/src/k3bfileview.h b/src/k3bfileview.h
new file mode 100644
index 0000000..f89d3b8
--- /dev/null
+++ b/src/k3bfileview.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * $Id: k3bfileview.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BFILEVIEW_H
+#define K3BFILEVIEW_H
+
+
+#include "k3bcontentsview.h"
+
+
+class K3bDirOperator;
+class QDragObject;
+class KURL;
+class KFileFilterCombo;
+class KFileItem;
+class KActionCollection;
+class KConfig;
+class K3bToolBox;
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bFileView : public K3bContentsView
+{
+ Q_OBJECT
+
+ public:
+ K3bFileView(QWidget *parent=0, const char *name=0);
+ ~K3bFileView();
+
+ void setUrl( const KURL &url, bool forward = true );
+ KURL url();
+
+ KActionCollection* actionCollection() const;
+
+ void reload();
+
+ signals:
+ void urlEntered( const KURL& url );
+
+ public slots:
+ void setDir( const QString& );
+ void saveConfig( KConfig* c );
+ void readConfig( KConfig* c );
+ void setAutoUpdate( bool );
+
+ private:
+ K3bToolBox* m_toolBox;
+ K3bDirOperator* m_dirOp;
+ KFileFilterCombo* m_filterWidget;
+
+ void setupGUI();
+
+ private slots:
+ void slotFilterChanged();
+ void slotFileHighlighted( const KFileItem* item );
+};
+
+
+#endif
diff --git a/src/k3bfirstrun.cpp b/src/k3bfirstrun.cpp
new file mode 100644
index 0000000..23a285a
--- /dev/null
+++ b/src/k3bfirstrun.cpp
@@ -0,0 +1,84 @@
+/*
+ *
+ * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $
+ * Copyright (C) 2006 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include "k3bfirstrun.h"
+#include "k3b.h"
+#include "k3bservicemenuinstaller.h"
+#include <k3bcore.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kconfig.h>
+
+#include <qlayout.h>
+#include <qlabel.h>
+
+
+void K3bFirstRun::run( QWidget* parent )
+{
+ if( !k3bcore->config()->readBoolEntry( "First run", true ) )
+ return;
+
+ k3bcore->config()->writeEntry( "First run", false );
+
+ // for now the first run dialog only asks for
+ // the konqui integration. So in case it is
+ // already installed there is no need to show the
+ // dialog.
+ K3bServiceInstaller si;
+ if( si.allInstalled() )
+ return;
+
+ K3bFirstRun dlg( parent );
+ if( dlg.exec() == QDialog::Accepted )
+ si.install( parent );
+}
+
+
+K3bFirstRun::K3bFirstRun( QWidget* parent )
+ : KDialogBase( Plain,
+ i18n("First Run"),
+ Ok|Cancel,
+ Ok,
+ parent,
+ 0,
+ true,
+ true )
+{
+ setButtonOK( i18n("Enable Konqueror integration") );
+ setButtonCancel( i18n("No Konqueror integration") );
+
+ QFrame* plain = plainPage();
+ QLabel* label = new QLabel( i18n("<p>K3b can integrate itself into Konqueror. This integration "
+ "allows to start K3b from the context menu in the file manager."
+ "<p><em>The Konqueror integration can always be disabled and "
+ "enabled again from the K3b settings.</em>"), plain );
+ QLabel* pixLabel = new QLabel( plain );
+ pixLabel->setPixmap( DesktopIcon( "konqueror" ) );
+
+ QHBoxLayout* lay = new QHBoxLayout( plain );
+ lay->setMargin( 0 );
+ lay->setSpacing( spacingHint() );
+ lay->addWidget( pixLabel );
+ lay->addWidget( label );
+ lay->setStretchFactor( label, 1 );
+}
+
+
+K3bFirstRun::~K3bFirstRun()
+{
+}
+
+#include "k3bfirstrun.moc"
diff --git a/src/k3bfirstrun.h b/src/k3bfirstrun.h
new file mode 100644
index 0000000..d59c931
--- /dev/null
+++ b/src/k3bfirstrun.h
@@ -0,0 +1,34 @@
+/*
+ *
+ * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $
+ * Copyright (C) 2006 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#ifndef _K3B_FIRST_RUN_H_
+#define _K3B_FIRST_RUN_H_
+
+#include <kdialogbase.h>
+
+
+class K3bFirstRun : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ static void run( QWidget* parent = 0 );
+
+ private:
+ K3bFirstRun( QWidget* parent );
+ ~K3bFirstRun();
+};
+
+#endif
diff --git a/src/k3bflatbutton.cpp b/src/k3bflatbutton.cpp
new file mode 100644
index 0000000..808de32
--- /dev/null
+++ b/src/k3bflatbutton.cpp
@@ -0,0 +1,203 @@
+/*
+ *
+ * $Id: k3bflatbutton.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include "k3bflatbutton.h"
+#include "k3bthememanager.h"
+#include "k3bapplication.h"
+
+#include <kaction.h>
+#include <kiconloader.h>
+#include <kglobal.h>
+
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qfontmetrics.h>
+#include <qpixmap.h>
+
+
+K3bFlatButton::K3bFlatButton( QWidget *parent, const char *name )
+ : QFrame( parent, name/*, WNoAutoErase*/ ),
+ m_pressed(false)
+{
+ init();
+}
+
+
+K3bFlatButton::K3bFlatButton( const QString& text, QWidget *parent, const char *name )
+ : QFrame( parent, name/*, WNoAutoErase*/ ),
+ m_pressed(false)
+{
+ init();
+ setText( text );
+}
+
+
+K3bFlatButton::K3bFlatButton( KAction* a, QWidget *parent, const char *name )
+ : QFrame( parent, name/*, WNoAutoErase*/ ),
+ m_pressed(false)
+{
+ init();
+
+ setText( a->text() );
+ QToolTip::add( this, a->toolTip() );
+ setPixmap( KGlobal::iconLoader()->loadIcon( a->icon(), KIcon::NoGroup, 32 ) );
+ connect( this, SIGNAL(clicked()), a, SLOT(activate()) );
+}
+
+
+K3bFlatButton::~K3bFlatButton() {}
+
+
+void K3bFlatButton::init()
+{
+ setHover(false);
+ setMargin(5);
+ setFrameStyle( QFrame::Box|QFrame::Plain );
+
+ connect( k3bappcore->themeManager(), SIGNAL(themeChanged()), this, SLOT(slotThemeChanged()) );
+ connect( kapp, SIGNAL(appearanceChanged()), this, SLOT(slotThemeChanged()) );
+ slotThemeChanged();
+}
+
+
+void K3bFlatButton::setText( const QString& s )
+{
+ m_text = s;
+ m_text.remove( '&' );
+
+ update();
+}
+
+
+void K3bFlatButton::setPixmap( const QPixmap& p )
+{
+ m_pixmap = p;
+ update();
+}
+
+
+void K3bFlatButton::enterEvent( QEvent* )
+{
+ setHover(true);
+}
+
+
+void K3bFlatButton::leaveEvent( QEvent* )
+{
+ setHover(false);
+}
+
+
+void K3bFlatButton::mousePressEvent( QMouseEvent* e )
+{
+ if( e->button() == QMouseEvent::LeftButton ) {
+ emit pressed();
+ m_pressed = true;
+ }
+ else
+ e->ignore();
+}
+
+
+void K3bFlatButton::mouseReleaseEvent( QMouseEvent* e )
+{
+ if( e->button() == QMouseEvent::LeftButton ) {
+ if( m_pressed )
+ emit clicked();
+ m_pressed = false;
+ }
+ else
+ e->ignore();
+}
+
+
+void K3bFlatButton::setHover( bool b )
+{
+ if( b ) {
+ setPaletteBackgroundColor( m_foreColor );
+ setPaletteForegroundColor( m_backColor );
+ } else {
+ setPaletteBackgroundColor( m_backColor );
+ setPaletteForegroundColor( m_foreColor );
+ }
+
+ m_hover = b;
+
+ update();
+}
+
+
+QSize K3bFlatButton::sizeHint() const
+{
+ // height: pixmap + 5 spacing + font height + frame width
+ // width: max( pixmap, text) + frame width
+ return QSize( QMAX( m_pixmap.width(), fontMetrics().width( m_text ) ) + frameWidth()*2,
+ m_pixmap.height() + fontMetrics().height() + 5 + frameWidth()*2 );
+}
+
+
+void K3bFlatButton::drawContents( QPainter* p )
+{
+ QRect rect = contentsRect();
+
+// if( m_hover )
+// p->fillRect( rect, m_foreColor );
+// else if( parentWidget() ) {
+// QRect r( mapToParent( QPoint(lineWidth(), lineWidth()) ),
+// mapToParent( QPoint(width()-2*lineWidth(), height()-2*lineWidth() )) );
+
+// parentWidget()->repaint( r );
+// }
+
+ p->save();
+
+ QRect textRect = fontMetrics().boundingRect( m_text );
+ int textX = QMAX( 0, ( rect.width() - textRect.width() ) / 2 );
+ int textY = textRect.height();
+
+ if( !m_pixmap.isNull() ) {
+ p->translate( rect.left(), rect.top() );
+ textX = QMAX( textX, (m_pixmap.width() - textRect.width()) / 2 );
+ textY += 5 + m_pixmap.height();
+
+ int pixX = QMAX( QMAX( 0, (textRect.width() - m_pixmap.width()) / 2 ),
+ ( rect.width() - m_pixmap.width() ) / 2 );
+ p->drawPixmap( pixX, 0, m_pixmap );
+ p->drawText( textX, textY, m_text );
+ }
+ else
+ p->drawText( rect, Qt::AlignCenter, m_text );
+
+ p->restore();
+}
+
+
+void K3bFlatButton::setColors( const QColor& fore, const QColor& back )
+{
+ m_foreColor = fore;
+ m_backColor = back;
+
+ setHover( m_hover );
+}
+
+
+void K3bFlatButton::slotThemeChanged()
+{
+ if( K3bTheme* theme = k3bappcore->themeManager()->currentTheme() ) {
+ setColors( theme->foregroundColor(), theme->backgroundColor() );
+ }
+}
+
+#include "k3bflatbutton.moc"
diff --git a/src/k3bflatbutton.h b/src/k3bflatbutton.h
new file mode 100644
index 0000000..a3dc97e
--- /dev/null
+++ b/src/k3bflatbutton.h
@@ -0,0 +1,77 @@
+/*
+ *
+ * $Id: k3bflatbutton.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#ifndef FLATBUTTON_H
+#define FLATBUTTON_H
+
+#include <qframe.h>
+#include <qcolor.h>
+#include <qpixmap.h>
+
+class QEvent;
+class QMouseEvent;
+class QPainter;
+class KAction;
+
+
+/**
+@author Sebastian Trueg
+*/
+class K3bFlatButton : public QFrame
+{
+ Q_OBJECT
+
+ public:
+ K3bFlatButton( QWidget *parent = 0, const char *name = 0 );
+ K3bFlatButton( const QString& text, QWidget *parent = 0, const char *name = 0 );
+ K3bFlatButton( KAction*, QWidget *parent = 0, const char *name = 0 );
+
+ ~K3bFlatButton();
+
+ QSize sizeHint() const;
+
+ public slots:
+ void setColors( const QColor& fore, const QColor& back );
+ void setText( const QString& );
+ void setPixmap( const QPixmap& );
+
+ signals:
+ void pressed();
+ void clicked();
+
+ private slots:
+ void slotThemeChanged();
+
+ private:
+ void init();
+
+ void mousePressEvent(QMouseEvent* e);
+ void mouseReleaseEvent(QMouseEvent* e);
+ void enterEvent( QEvent* );
+ void leaveEvent( QEvent* );
+ void drawContents( QPainter* );
+
+ void setHover( bool );
+
+ bool m_pressed;
+ QColor m_backColor;
+ QColor m_foreColor;
+ QString m_text;
+ QPixmap m_pixmap;
+
+ bool m_hover;
+};
+
+#endif
diff --git a/src/k3binteractiondialog.cpp b/src/k3binteractiondialog.cpp
new file mode 100644
index 0000000..4784c7f
--- /dev/null
+++ b/src/k3binteractiondialog.cpp
@@ -0,0 +1,662 @@
+/*
+ *
+ * $Id$
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3binteractiondialog.h"
+#include "k3btitlelabel.h"
+#include "kcutlabel.h"
+#include "k3bstdguiitems.h"
+#include "k3bpushbutton.h"
+#include "k3bthemedheader.h"
+#include "k3bthememanager.h"
+#include <k3bapplication.h>
+#include <k3btoolbutton.h>
+#include <k3bmultichoicedialog.h>
+
+#include <qlabel.h>
+#include <qtoolbutton.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qstring.h>
+#include <qpoint.h>
+#include <qfont.h>
+#include <qpopupmenu.h>
+#include <qeventloop.h>
+#include <qapplication.h>
+#include <qtimer.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <kstdguiitem.h>
+#include <kpushbutton.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <kglobalsettings.h>
+#include <kdeversion.h>
+
+
+K3bInteractionDialog::K3bInteractionDialog( QWidget* parent,
+ const char* name,
+ const QString& title,
+ const QString& subTitle,
+ int buttonMask,
+ int defaultButton,
+ const QString& configGroup,
+ bool modal,
+ WFlags fl )
+ : KDialog( parent, name, modal, fl ),
+ m_mainWidget(0),
+ m_defaultButton(defaultButton),
+ m_configGroup(configGroup),
+ m_exitLoopOnHide(true),
+ m_inLoop(false),
+ m_inToggleMode(false),
+ m_delayedInit(false)
+{
+ installEventFilter( this );
+
+ mainGrid = new QGridLayout( this );
+ mainGrid->setSpacing( spacingHint() );
+ mainGrid->setMargin( marginHint() );
+
+ // header
+ // ---------------------------------------------------------------------------------------------------
+ m_dialogHeader = new K3bThemedHeader( this );
+ mainGrid->addMultiCellWidget( m_dialogHeader, 0, 0, 0, 2 );
+
+
+ // settings buttons
+ // ---------------------------------------------------------------------------------------------------
+ if( !m_configGroup.isEmpty() ) {
+ QHBoxLayout* layout2 = new QHBoxLayout( 0, 0, spacingHint(), "layout2");
+ m_buttonLoadSettings = new K3bToolButton( /*i18n("User Defaults"), */this );
+ ((K3bToolButton*)m_buttonLoadSettings)->setIconSet( SmallIconSet( "revert" ) );
+ QPopupMenu* userDefaultsPopup = new QPopupMenu( m_buttonLoadSettings );
+ userDefaultsPopup->insertItem( i18n("Load default settings"), this, SLOT(slotLoadK3bDefaults()) );
+ userDefaultsPopup->insertItem( i18n("Load saved settings"), this, SLOT(slotLoadUserDefaults()) );
+ userDefaultsPopup->insertItem( i18n("Load last used settings"), this, SLOT(slotLoadLastSettings()) );
+ ((QToolButton*)m_buttonLoadSettings)->setPopup( userDefaultsPopup );
+ ((K3bToolButton*)m_buttonLoadSettings)->setInstantMenu( true );
+ layout2->addWidget( m_buttonLoadSettings );
+
+ m_buttonSaveSettings = new QToolButton( /*i18n("Save User Defaults"), */this, "m_buttonSaveSettings" );
+ ((QToolButton*)m_buttonSaveSettings)->setIconSet( SmallIconSet( "filesave" ) );
+ layout2->addWidget( m_buttonSaveSettings );
+
+ mainGrid->addLayout( layout2, 2, 0 );
+ }
+
+ QSpacerItem* spacer = new QSpacerItem( 10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ mainGrid->addItem( spacer, 2, 1 );
+
+
+ // action buttons
+ // ---------------------------------------------------------------------------------------------------
+ QHBoxLayout* layout5 = new QHBoxLayout( 0, 0, spacingHint(), "layout5");
+
+ if( buttonMask & START_BUTTON ) {
+ KGuiItem startItem = KStdGuiItem::ok();
+ m_buttonStart = new KPushButton( startItem, this, "m_buttonStart" );
+ // refine the button text
+ setButtonText( START_BUTTON,
+ i18n("Start"),
+ i18n("Start the task") );
+ QFont fnt( m_buttonStart->font() );
+ fnt.setBold(true);
+ m_buttonStart->setFont( fnt );
+ }
+ else
+ m_buttonStart = 0;
+
+ if( buttonMask & SAVE_BUTTON ) {
+ m_buttonSave = new KPushButton( KStdGuiItem::save(), this, "m_buttonSave" );
+ }
+ else
+ m_buttonSave = 0;
+
+ if( buttonMask & CANCEL_BUTTON ) {
+ m_buttonCancel = new KPushButton( KConfigGroup( k3bcore->config(), "General Options" )
+ .readBoolEntry( "keep action dialogs open", false )
+ ? KStdGuiItem::close()
+ : KStdGuiItem::cancel(),
+ this,
+ "m_buttonCancel" );
+ }
+ else
+ m_buttonCancel = 0;
+
+ // we only handle some of the possible settings since
+ // our buttons are always to the right of the dialog
+ int btl = 0;
+#if KDE_IS_VERSION(3,3,0)
+ btl = KGlobalSettings::buttonLayout();
+#endif
+ switch( btl ) {
+ case 0: // KDE default
+ default:
+ if ( m_buttonStart )
+ layout5->addWidget( m_buttonStart );
+ if ( m_buttonSave )
+ layout5->addWidget( m_buttonSave );
+ if ( m_buttonCancel )
+ layout5->addWidget( m_buttonCancel );
+ break;
+
+ case 1: // something different
+ if ( m_buttonCancel )
+ layout5->addWidget( m_buttonCancel );
+ if ( m_buttonSave )
+ layout5->addWidget( m_buttonSave );
+ if ( m_buttonStart )
+ layout5->addWidget( m_buttonStart );
+ break;
+
+ case 2: // GTK-Style
+ if ( m_buttonSave )
+ layout5->addWidget( m_buttonSave );
+ if ( m_buttonCancel )
+ layout5->addWidget( m_buttonCancel );
+ if ( m_buttonStart )
+ layout5->addWidget( m_buttonStart );
+ break;
+ }
+
+ mainGrid->addLayout( layout5, 2, 2 );
+
+ mainGrid->setRowStretch( 1, 1 );
+
+ setTitle( title, subTitle );
+
+ initConnections();
+ initToolTipsAndWhatsThis();
+
+ setDefaultButton( START_BUTTON );
+}
+
+K3bInteractionDialog::~K3bInteractionDialog()
+{
+}
+
+
+void K3bInteractionDialog::show()
+{
+ KDialog::show();
+ if( KPushButton* b = getButton( m_defaultButton ) )
+ b->setFocus();
+}
+
+
+QSize K3bInteractionDialog::sizeHint() const
+{
+ QSize s = KDialog::sizeHint();
+ // I want the dialogs to look good.
+ // That means their height should never outgrow their width
+ if( s.height() > s.width() )
+ s.setWidth( s.height() );
+
+ return s;
+}
+
+
+void K3bInteractionDialog::initConnections()
+{
+ if( m_buttonStart ) {
+ connect( m_buttonStart, SIGNAL(clicked()),
+ this, SLOT(slotStartClickedInternal()) );
+ }
+ if( m_buttonSave ) {
+// connect( m_buttonSave, SIGNAL(clicked()),
+// this, SLOT(slotSaveLastSettings()) );
+ connect( m_buttonSave, SIGNAL(clicked()),
+ this, SLOT(slotSaveClicked()) );
+ }
+ if( m_buttonCancel )
+ connect( m_buttonCancel, SIGNAL(clicked()),
+ this, SLOT(slotCancelClicked()) );
+
+ if( !m_configGroup.isEmpty() ) {
+ connect( m_buttonSaveSettings, SIGNAL(clicked()),
+ this, SLOT(slotSaveUserDefaults()) );
+ }
+}
+
+
+void K3bInteractionDialog::initToolTipsAndWhatsThis()
+{
+ if( !m_configGroup.isEmpty() ) {
+ // ToolTips
+ // -------------------------------------------------------------------------
+ QToolTip::add( m_buttonLoadSettings, i18n("Load default or saved settings") );
+ QToolTip::add( m_buttonSaveSettings, i18n("Save current settings to reuse them later") );
+
+ // What's This info
+ // -------------------------------------------------------------------------
+ QWhatsThis::add( m_buttonLoadSettings, i18n("<p>Load a set of settings either from the default K3b settings, "
+ "settings saved before, or the last used ones.") );
+ QWhatsThis::add( m_buttonSaveSettings, i18n("<p>Saves the current settings of the action dialog."
+ "<p>These settings can be loaded with the <em>Load saved settings</em> "
+ "button."
+ "<p><b>The K3b defaults are not overwritten by this.</b>") );
+ }
+}
+
+
+void K3bInteractionDialog::setTitle( const QString& title, const QString& subTitle )
+{
+ m_dialogHeader->setTitle( title, subTitle );
+
+ setCaption( title );
+}
+
+
+void K3bInteractionDialog::setMainWidget( QWidget* w )
+{
+ w->reparent( this, QPoint(0,0) );
+ mainGrid->addMultiCellWidget( w, 1, 1, 0, 2 );
+ m_mainWidget = w;
+}
+
+QWidget* K3bInteractionDialog::mainWidget()
+{
+ if( !m_mainWidget ) {
+ setMainWidget( new QWidget( this ) );
+ }
+ return m_mainWidget;
+}
+
+void K3bInteractionDialog::slotLoadK3bDefaults()
+{
+ loadK3bDefaults();
+}
+
+void K3bInteractionDialog::slotLoadUserDefaults()
+{
+ KConfigGroup c( k3bcore->config(), m_configGroup );
+ loadUserDefaults( &c );
+}
+
+void K3bInteractionDialog::slotSaveUserDefaults()
+{
+ KConfigGroup c( k3bcore->config(), m_configGroup );
+ saveUserDefaults( &c );
+}
+
+
+void K3bInteractionDialog::slotLoadLastSettings()
+{
+ KConfigGroup c( k3bcore->config(), "last used " + m_configGroup );
+ loadUserDefaults( &c );
+}
+
+
+void K3bInteractionDialog::saveLastSettings()
+{
+ KConfigGroup c( k3bcore->config(), "last used " + m_configGroup );
+ saveUserDefaults( &c );
+}
+
+
+void K3bInteractionDialog::slotStartClickedInternal()
+{
+ saveLastSettings();
+
+ KConfigGroup c( k3bcore->config(), "General Options" );
+ if( !c.readNumEntry( "action dialog startup settings", 0 ) ) {
+ // first time saving last used settings
+ switch( K3bMultiChoiceDialog::choose( i18n("Action Dialog Settings"),
+ i18n("<p>K3b handles three sets of settings in action dialogs: "
+ "the defaults, the saved settings, and the last used settings. "
+ "Please choose which of these sets should be loaded if an action "
+ "dialog is opened again."
+ "<p><em>Be aware that this choice can always be changed from the K3b "
+ "configuration dialog.</em>"),
+ QMessageBox::Question,
+ this,
+ 0,
+ 3,
+ i18n("Default Settings"),
+ i18n("Saved Settings"),
+ i18n("Last Used Settings") ) ) {
+ case 1:
+ c.writeEntry( "action dialog startup settings", LOAD_K3B_DEFAULTS );
+ break;
+ case 2:
+ c.writeEntry( "action dialog startup settings", LOAD_SAVED_SETTINGS );
+ break;
+ case 3:
+ c.writeEntry( "action dialog startup settings", LOAD_LAST_SETTINGS );
+ break;
+ }
+ }
+
+ slotStartClicked();
+}
+
+
+void K3bInteractionDialog::slotStartClicked()
+{
+ emit started();
+}
+
+void K3bInteractionDialog::slotCancelClicked()
+{
+ emit canceled();
+ close( false );
+}
+
+void K3bInteractionDialog::slotSaveClicked()
+{
+ emit saved();
+}
+
+
+void K3bInteractionDialog::setDefaultButton( int button )
+{
+ m_defaultButton = button;
+
+ // reset all other default buttons
+ if( KPushButton* b = getButton( START_BUTTON ) )
+ b->setDefault( true );
+ if( KPushButton* b = getButton( SAVE_BUTTON ) )
+ b->setDefault( true );
+ if( KPushButton* b = getButton( CANCEL_BUTTON ) )
+ b->setDefault( true );
+
+ // set the selected default
+ if( KPushButton* b = getButton( button ) )
+ b->setDefault( true );
+}
+
+
+bool K3bInteractionDialog::eventFilter( QObject* o, QEvent* ev )
+{
+ if( dynamic_cast<K3bInteractionDialog*>(o) == this &&
+ ev->type() == QEvent::KeyPress ) {
+
+ QKeyEvent* kev = dynamic_cast<QKeyEvent*>(ev);
+
+ switch ( kev->key() ) {
+ case Key_Enter:
+ case Key_Return:
+ // if the process finished this closes the dialog
+ if( m_defaultButton == START_BUTTON ) {
+ if( m_buttonStart->isEnabled() )
+ slotStartClickedInternal();
+ }
+ else if( m_defaultButton == CANCEL_BUTTON ) {
+ if( m_buttonCancel->isEnabled() )
+ slotCancelClicked();
+ }
+ else if( m_defaultButton == SAVE_BUTTON ) {
+ if( m_buttonSave->isEnabled() )
+ slotSaveClicked();
+ }
+ return true;
+
+ case Key_Escape:
+ // simulate button clicks
+ if( m_buttonCancel ) {
+ if( m_buttonCancel->isEnabled() )
+ slotCancelClicked();
+ }
+ return true;
+ }
+ }
+
+ return KDialog::eventFilter( o, ev );
+}
+
+
+KPushButton* K3bInteractionDialog::getButton( int button )
+{
+ switch( button ) {
+ case START_BUTTON:
+ return m_buttonStart;
+ case SAVE_BUTTON:
+ return m_buttonSave;
+ case CANCEL_BUTTON:
+ return m_buttonCancel;
+ default:
+ return 0;
+ }
+}
+
+
+void K3bInteractionDialog::setButtonGui( int button,
+ const KGuiItem& item )
+{
+ if( KPushButton* b = getButton( button ) )
+ b->setGuiItem( item );
+}
+
+
+void K3bInteractionDialog::setButtonText( int button,
+ const QString& text,
+ const QString& tooltip,
+ const QString& whatsthis )
+{
+ if( KPushButton* b = getButton( button ) ) {
+ b->setText( text );
+ QToolTip::remove( b );
+ QWhatsThis::remove( b );
+ QToolTip::add( b, tooltip );
+ QWhatsThis::add( b, whatsthis );
+ }
+}
+
+
+void K3bInteractionDialog::setButtonEnabled( int button, bool enabled )
+{
+ if( KPushButton* b = getButton( button ) ) {
+ b->setEnabled( enabled );
+ // make sure the correct button is selected as default again
+ setDefaultButton( m_defaultButton );
+ }
+}
+
+
+void K3bInteractionDialog::setButtonShown( int button, bool shown )
+{
+ if( KPushButton* b = getButton( button ) ) {
+ b->setShown( shown );
+ // make sure the correct button is selected as default again
+ setDefaultButton( m_defaultButton );
+ }
+}
+
+
+void K3bInteractionDialog::setStartButtonText( const QString& text,
+ const QString& tooltip,
+ const QString& whatsthis )
+{
+ if( m_buttonStart ) {
+ m_buttonStart->setText( text );
+ QToolTip::remove( m_buttonStart );
+ QWhatsThis::remove( m_buttonStart );
+ QToolTip::add( m_buttonStart, tooltip );
+ QWhatsThis::add( m_buttonStart, whatsthis );
+ }
+}
+
+
+void K3bInteractionDialog::setCancelButtonText( const QString& text,
+ const QString& tooltip,
+ const QString& whatsthis )
+{
+ if( m_buttonCancel ) {
+ m_buttonCancel->setText( text );
+ QToolTip::remove( m_buttonCancel );
+ QWhatsThis::remove( m_buttonCancel );
+ QToolTip::add( m_buttonCancel, tooltip );
+ QWhatsThis::add( m_buttonCancel, whatsthis );
+ }
+}
+
+
+void K3bInteractionDialog::setSaveButtonText( const QString& text,
+ const QString& tooltip,
+ const QString& whatsthis )
+{
+ if( m_buttonSave ) {
+ m_buttonSave->setText( text );
+ QToolTip::remove( m_buttonSave );
+ QWhatsThis::remove( m_buttonSave );
+ QToolTip::add( m_buttonSave, tooltip );
+ QWhatsThis::add( m_buttonSave, whatsthis );
+ }
+}
+
+
+void K3bInteractionDialog::saveUserDefaults( KConfigBase* )
+{
+}
+
+
+void K3bInteractionDialog::loadUserDefaults( KConfigBase* )
+{
+}
+
+
+void K3bInteractionDialog::loadK3bDefaults()
+{
+}
+
+
+void K3bInteractionDialog::loadStartupSettings()
+{
+ KConfigGroup c( k3bcore->config(), "General Options" );
+
+ // earlier K3b versions loaded the saved settings
+ // so that is what we do as a default
+ int i = c.readNumEntry( "action dialog startup settings", LOAD_SAVED_SETTINGS );
+ switch( i ) {
+ case LOAD_K3B_DEFAULTS:
+ slotLoadK3bDefaults();
+ break;
+ case LOAD_SAVED_SETTINGS:
+ slotLoadUserDefaults();
+ break;
+ case LOAD_LAST_SETTINGS:
+ slotLoadLastSettings();
+ break;
+ }
+}
+
+
+int K3bInteractionDialog::exec()
+{
+ return exec( true );
+}
+
+
+int K3bInteractionDialog::exec( bool returnOnHide )
+{
+ m_exitLoopOnHide = returnOnHide;
+
+ // the following code is mainly taken from QDialog::exec
+
+ if( m_inLoop ) {
+ kdError() << "(K3bInteractionDialog::exec) Recursive call detected." << endl;
+ return -1;
+ }
+
+ bool destructiveClose = testWFlags( WDestructiveClose );
+ clearWFlags( WDestructiveClose );
+
+ bool wasShowModal = testWFlags( WShowModal );
+ setWFlags( WShowModal );
+ setResult( 0 );
+
+ loadStartupSettings();
+ show();
+ if( m_delayedInit )
+ QTimer::singleShot( 0, this, SLOT(slotDelayedInit()) );
+ else
+ init();
+
+ m_inLoop = true;
+ QApplication::eventLoop()->enterLoop();
+
+ if( !wasShowModal )
+ clearWFlags( WShowModal );
+
+ int res = result();
+
+ if( destructiveClose )
+ delete this;
+
+ return res;
+}
+
+
+void K3bInteractionDialog::hide()
+{
+ if( isHidden() )
+ return;
+
+ KDialog::hide();
+
+ if( m_inLoop && m_exitLoopOnHide ) {
+ m_inLoop = false;
+ QApplication::eventLoop()->exitLoop();
+ }
+}
+
+
+bool K3bInteractionDialog::close( bool alsoDelete )
+{
+ if( m_inLoop && !m_exitLoopOnHide ) {
+ m_inLoop = false;
+ QApplication::eventLoop()->exitLoop();
+ }
+
+ return KDialog::close( alsoDelete );
+}
+
+
+void K3bInteractionDialog::done( int r )
+{
+ if( m_inLoop && !m_exitLoopOnHide ) {
+ m_inLoop = false;
+ QApplication::eventLoop()->exitLoop();
+ }
+
+ return KDialog::done( r );
+}
+
+
+void K3bInteractionDialog::slotToggleAll()
+{
+ if( !m_inToggleMode ) {
+ m_inToggleMode = true;
+ toggleAll();
+ m_inToggleMode = false;
+ }
+}
+
+
+void K3bInteractionDialog::toggleAll()
+{
+}
+
+
+void K3bInteractionDialog::slotDelayedInit()
+{
+ init();
+}
+
+#include "k3binteractiondialog.moc"
diff --git a/src/k3binteractiondialog.h b/src/k3binteractiondialog.h
new file mode 100644
index 0000000..2bdb426
--- /dev/null
+++ b/src/k3binteractiondialog.h
@@ -0,0 +1,279 @@
+/*
+ *
+ * $Id: k3binteractiondialog.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#ifndef _K3B_INTERACTION_DIALOG_H_
+#define _K3B_INTERACTION_DIALOG_H_
+
+#include <kdialog.h>
+
+
+class QGridLayout;
+class QLabel;
+class KPushButton;
+class QButton;
+class K3bThemedHeader;
+class KConfigBase;
+class KGuiItem;
+
+
+/**
+ * This is the base dialog for all the dialogs in K3b that start
+ * some job. Use setMainWidget to set the contents or let mainWidget()
+ * create an empty plain page.
+ * The default implementations of the slots just emit the
+ * corresponding signals.
+ */
+class K3bInteractionDialog : public KDialog
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * The constructor.
+ * loadUserDefaults will be called automatically when the dialog is showing.
+ *
+ * @param title the text to be displayed in the K3b header (not the widget frame)
+ * @param subTitle additional text that will be displayed after the title in smaller size
+ * @param buttonMask combination of Buttons
+ * @param defaultButton may also be null to deactivate the feature
+ * @param configgroup The config group used for the loadUserDefaults and saveUserDefaults methods
+ */
+ K3bInteractionDialog( QWidget* parent = 0,
+ const char* name = 0,
+ const QString& title = QString::null,
+ const QString& subTitle = QString::null,
+ int buttonMask = START_BUTTON|CANCEL_BUTTON,
+ int defaultButton = START_BUTTON,
+ const QString& configgroup = QString::null,
+ bool modal = true,
+ WFlags fl = 0 );
+ virtual ~K3bInteractionDialog();
+
+ void setMainWidget( QWidget* w );
+ void setTitle( const QString& title, const QString& subTitle = QString::null );
+ void setDefaultButton( int b );
+
+ /**
+ * Reimplemented for internal reasons. The API does not change.
+ */
+ int exec();
+
+ /**
+ * @param returnOnHide if false the dialog can be hidden and shown without being closed.
+ * one needs to call close() to actually close the dialog.
+ */
+ int exec( bool returnOnHide );
+
+ /**
+ * reimplemented to allow initialization after the dialog has been opened.
+ */
+ void show();
+
+ /**
+ * Reimplemented for internal reasons. The API does not change.
+ */
+ void hide();
+
+ /**
+ * Reimplemented for internal reasons. The API does not change.
+ */
+ bool close( bool alsoDelete );
+
+ inline bool close() { return close( false ); }
+
+ /**
+ * If no mainWidget has been set a plain page will be created.
+ */
+ QWidget* mainWidget();
+
+ enum Buttons {
+ START_BUTTON = 1,
+ SAVE_BUTTON = 2,
+ CANCEL_BUTTON = 4
+ };
+
+ QSize sizeHint() const;
+
+ const QString& configGroup() const { return m_configGroup; }
+
+ /**
+ * K3b's dialogs use this method to determine if it is safe to hide when starting
+ * some action. Take for example the copy dialog which starts a copy job with a progress
+ * dialog. Both the job and the progress dialog are deleted by the copy dialog after the
+ * progress dialog has been closed. If the copy dialog would hide itself before starting
+ * the job and exitLoopOnHide() would return true the hiding would result in the exec call
+ * of the copy dialog to return. And what would that mean for the code after the hide()
+ * statement (deleting of the job and so on).
+ *
+ * \return true in case this dialog will not exit it's private event loop
+ * in case it is hidden.
+ *
+ * \see exec(bool)
+ */
+ bool exitLoopOnHide() const { return m_exitLoopOnHide; }
+
+ enum StartUpSettings {
+ LOAD_K3B_DEFAULTS = 1,
+ LOAD_SAVED_SETTINGS = 2,
+ LOAD_LAST_SETTINGS = 3
+ };
+
+ signals:
+ void started();
+ void canceled();
+ void saved();
+
+ public slots:
+ /**
+ * \deprecated use setButtonText
+ */
+ void setStartButtonText( const QString& text,
+ const QString& tooltip = QString::null,
+ const QString& whatsthis = QString::null );
+ /**
+ * \deprecated use setButtonText
+ */
+ void setCancelButtonText( const QString& text,
+ const QString& tooltip = QString::null,
+ const QString& whatsthis = QString::null );
+ /**
+ * \deprecated use setButtonText
+ */
+ void setSaveButtonText( const QString& text,
+ const QString& tooltip = QString::null,
+ const QString& whatsthis = QString::null );
+
+ void setButtonGui( int button,
+ const KGuiItem& );
+
+ void setButtonText( int button,
+ const QString& text,
+ const QString& tooltip = QString::null,
+ const QString& whatsthis = QString::null );
+
+ void setButtonEnabled( int button, bool enabled );
+ void setButtonShown( int button, bool enabled );
+
+ /**
+ * If set true the init() method will be called via a QTimer to ensure event
+ * handling be done before (default: false).
+ */
+ void setDelayedInitialization( bool b ) { m_delayedInit = b; }
+
+ protected slots:
+ // FIXME: replace these with protected methods which are called from private slots.
+ virtual void slotStartClicked();
+
+ /**
+ * The default implementation emits the canceled() signal
+ * and calls close()
+ */
+ virtual void slotCancelClicked();
+ virtual void slotSaveClicked();
+
+ /**
+ * This slot will call the toggleAll() method protecting from infinite loops
+ * caused by one element influencing another element which in turn influences
+ * the first.
+ *
+ * Connect this slot to GUI elements (like Checkboxes) that change
+ * the state of the whole dialog.
+ */
+ void slotToggleAll();
+
+ protected:
+ /**
+ * Reimplement this method in case you are using slotToggleAll()
+ */
+ virtual void toggleAll();
+
+ /**
+ * Reimplement this to support the save/load user default buttons.
+ * @p config is already set to the correct group.
+ *
+ * The save/load buttons are only activated if the config group is
+ * set in the constructor.
+ */
+ virtual void saveUserDefaults( KConfigBase* config );
+
+ /**
+ * Reimplement this to support the save/load user default buttons.
+ * @p config is already set to the correct group.
+ *
+ * The save/load buttons are only activated if the config group is
+ * set in the constructor.
+ */
+ virtual void loadUserDefaults( KConfigBase* config );
+
+ /**
+ * Reimplement this to support the "k3b defaults" button.
+ * set all GUI options to reasonable defaults.
+ */
+ virtual void loadK3bDefaults();
+
+ /**
+ * This is called after the dialog has been shown.
+ * Use this for initialization that should happen
+ * when the user already sees the dialog.
+ */
+ virtual void init() {}
+
+ /**
+ * reimplemented from QDialog
+ */
+ virtual bool eventFilter( QObject*, QEvent* );
+
+ protected slots:
+ /**
+ * Reimplemented for internal reasons. The API does not change.
+ */
+ virtual void done( int );
+
+ private slots:
+ void slotLoadK3bDefaults();
+ void slotLoadUserDefaults();
+ void slotSaveUserDefaults();
+ void slotLoadLastSettings();
+ void slotStartClickedInternal();
+ void slotDelayedInit();
+
+ private:
+ void initConnections();
+ void initToolTipsAndWhatsThis();
+ void saveLastSettings();
+ void loadStartupSettings();
+
+ KPushButton* getButton( int );
+
+ K3bThemedHeader* m_dialogHeader;
+ KPushButton* m_buttonStart;
+ KPushButton* m_buttonSave;
+ KPushButton* m_buttonCancel;
+ QWidget* m_mainWidget;
+
+ QButton* m_buttonLoadSettings;
+ QButton* m_buttonSaveSettings;
+
+ QGridLayout* mainGrid;
+ int m_defaultButton;
+ QString m_configGroup;
+
+ bool m_exitLoopOnHide;
+ bool m_inLoop;
+ bool m_inToggleMode;
+ bool m_delayedInit;
+};
+
+#endif
diff --git a/src/k3binterface.cpp b/src/k3binterface.cpp
new file mode 100644
index 0000000..c95e598
--- /dev/null
+++ b/src/k3binterface.cpp
@@ -0,0 +1,192 @@
+/*
+ *
+ * $Id: k3binterface.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3binterface.h"
+#include "k3bprojectinterface.h"
+#include "k3bprojectmanager.h"
+#include "k3bapplication.h"
+#include "k3bdoc.h"
+#include "k3bview.h"
+#include "k3bcore.h"
+#include "k3b.h"
+
+#include <k3bglobals.h>
+
+#include <dcopclient.h>
+#include <qptrlist.h>
+#include <qtimer.h>
+
+
+
+K3bInterface::K3bInterface()
+ : DCOPObject( "K3bInterface" ),
+ m_main( 0 )
+{
+}
+
+DCOPRef K3bInterface::createDataCDProject()
+{
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( k3bappcore->projectManager()->createProject( K3bDoc::DATA ) )->objId() );
+}
+
+DCOPRef K3bInterface::createAudioCDProject()
+{
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( k3bappcore->projectManager()->createProject( K3bDoc::AUDIO ) )->objId() );
+}
+
+DCOPRef K3bInterface::createMixedCDProject()
+{
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( k3bappcore->projectManager()->createProject( K3bDoc::MIXED ) )->objId() );
+}
+
+DCOPRef K3bInterface::createVideoCDProject()
+{
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( k3bappcore->projectManager()->createProject( K3bDoc::VCD ) )->objId() );
+}
+
+DCOPRef K3bInterface::createMovixCDProject()
+{
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( k3bappcore->projectManager()->createProject( K3bDoc::MOVIX ) )->objId() );
+}
+
+DCOPRef K3bInterface::createDataDVDProject()
+{
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( k3bappcore->projectManager()->createProject( K3bDoc::DVD ) )->objId() );
+}
+
+DCOPRef K3bInterface::createVideoDVDProject()
+{
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( k3bappcore->projectManager()->createProject( K3bDoc::VIDEODVD ) )->objId() );
+}
+
+DCOPRef K3bInterface::createMovixDVDProject()
+{
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( k3bappcore->projectManager()->createProject( K3bDoc::MOVIX_DVD ) )->objId() );
+}
+
+DCOPRef K3bInterface::currentProject()
+{
+ K3bView* view = m_main->activeView();
+ if( view )
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( view->doc() )->objId() );
+ else
+ return DCOPRef();
+}
+
+DCOPRef K3bInterface::openProject( const KURL& url )
+{
+ K3bDoc* doc = k3bappcore->projectManager()->openProject( url );
+ if( doc )
+ return DCOPRef( kapp->dcopClient()->appId(),
+ k3bappcore->projectManager()->dcopInterface( doc )->objId() );
+ else
+ return DCOPRef();
+}
+
+QValueList<DCOPRef> K3bInterface::projects()
+{
+ QValueList<DCOPRef> lst;
+ const QPtrList<K3bDoc>& docs = k3bappcore->projectManager()->projects();
+ for( QPtrListIterator<K3bDoc> it( docs ); it.current(); ++it )
+ lst.append( DCOPRef( kapp->dcopClient()->appId(), k3bappcore->projectManager()->dcopInterface( it.current() )->objId() ) );
+
+ return lst;
+}
+
+void K3bInterface::addUrls( const KURL::List& urls )
+{
+ m_main->addUrls( urls );
+}
+
+void K3bInterface::addUrl( const KURL& url )
+{
+ KURL::List l;
+ l.append(url);
+ addUrls( l );
+}
+
+
+void K3bInterface::copyCd( const KURL& dev )
+{
+ m_main->cdCopy( K3b::urlToDevice( dev ) );
+}
+
+
+void K3bInterface::copyDvd( const KURL& dev )
+{
+ m_main->dvdCopy( K3b::urlToDevice( dev ) );
+}
+
+
+void K3bInterface::copyCd()
+{
+ // HACK since we want this method to return immediately
+ QTimer::singleShot( 0, m_main, SLOT(slotCdCopy()) );
+}
+
+
+void K3bInterface::copyDvd()
+{
+ // HACK since we want this method to return immediately
+ QTimer::singleShot( 0, m_main, SLOT(slotDvdCopy()) );
+}
+
+
+void K3bInterface::eraseCdrw()
+{
+ // HACK since we want this method to return immediately
+ QTimer::singleShot( 0, m_main, SLOT(slotBlankCdrw()) );
+}
+
+
+void K3bInterface::formatDvd()
+{
+ // HACK since we want this method to return immediately
+ QTimer::singleShot( 0, m_main, SLOT(slotFormatDvd()) );
+}
+
+
+void K3bInterface::burnCdImage( const KURL& url )
+{
+ m_main->slotWriteCdImage( url );
+}
+
+
+void K3bInterface::burnDvdImage( const KURL& url )
+{
+ m_main->slotWriteDvdIsoImage( url );
+}
+
+
+bool K3bInterface::blocked() const
+{
+ return k3bcore->jobsRunning();
+}
+
+
+void K3bInterface::cddaRip( const KURL& dev )
+{
+ m_main->cddaRip( K3b::urlToDevice( dev ) );
+}
diff --git a/src/k3binterface.h b/src/k3binterface.h
new file mode 100644
index 0000000..b54e2ef
--- /dev/null
+++ b/src/k3binterface.h
@@ -0,0 +1,102 @@
+/*
+ *
+ * $Id: k3binterface.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef _K3B_INTERFACE_H_
+#define _K3B_INTERFACE_H_
+
+#include <dcopobject.h>
+#include <dcopref.h>
+#include <qvaluelist.h>
+
+#include <kurl.h>
+
+class K3bMainWindow;
+namespace K3bDevice {
+ class Device;
+}
+
+
+class K3bInterface : public DCOPObject
+{
+ K_DCOP
+
+ public:
+ K3bInterface();
+
+ void setMainWindow( K3bMainWindow* mw ) { m_main = mw; }
+
+ k_dcop:
+ /**
+ * returns a DCOPRef to a K3bProjectInterface
+ */
+ DCOPRef createDataCDProject();
+ DCOPRef createAudioCDProject();
+ DCOPRef createMixedCDProject();
+ DCOPRef createVideoCDProject();
+ DCOPRef createMovixCDProject();
+ DCOPRef createDataDVDProject();
+ DCOPRef createVideoDVDProject();
+ DCOPRef createMovixDVDProject();
+
+ /**
+ * Returns a reference to the currently active project.
+ * This is useful to do things like:
+ *
+ * <pre>k3b --audiocd</pre>
+ * and then use dcop on the newly created project via:
+ * <pre>dcop $(dcop k3b K3bInterface currentProject) something</pre>
+ */
+ DCOPRef currentProject();
+
+ DCOPRef openProject( const KURL& url );
+
+ QValueList<DCOPRef> projects();
+
+ void copyCd();
+ void copyDvd();
+ void copyCd( const KURL& dev );
+ void copyDvd( const KURL& dev );
+ void eraseCdrw();
+ void formatDvd();
+ void burnCdImage( const KURL& url );
+ void burnDvdImage( const KURL& url );
+
+ /**
+ * Open the audio ripping window for the specified device.
+ */
+ void cddaRip( const KURL& dev );
+
+ /**
+ * Add URLs to the current active project.
+ * If no project is open a new Audio or Data CD
+ * project will be created depending on the type
+ * of the first file.
+ */
+ void addUrls( const KURL::List& urls );
+ void addUrl( const KURL& url );
+
+ /**
+ * @return true if currently some job is running.
+ */
+ bool blocked() const;
+
+ private:
+ K3bMainWindow* m_main;
+
+ K3bDevice::Device* m_lastDevice;
+};
+
+#endif
diff --git a/src/k3bjobinterface.cpp b/src/k3bjobinterface.cpp
new file mode 100644
index 0000000..60e4436
--- /dev/null
+++ b/src/k3bjobinterface.cpp
@@ -0,0 +1,190 @@
+/*
+ *
+ * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $
+ * Copyright (C) 2006 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#include "k3bjobinterface.h"
+
+#include <k3bjob.h>
+
+#include <qcstring.h>
+#include <qdatastream.h>
+
+
+K3bJobInterface::K3bJobInterface( QObject* parent )
+ : QObject( parent ),
+ DCOPObject( "K3bJobInterface" ),
+ m_job( 0 )
+{
+}
+
+
+void K3bJobInterface::setJob( K3bJob* job )
+{
+ if( m_job )
+ m_job->disconnect( this );
+
+ m_job = job;
+ m_lastProgress = m_lastSubProgress = 0;
+
+ if( m_job ) {
+ connect( m_job, SIGNAL(newTask(const QString&)), this, SLOT(slotNewTask(const QString&)) );
+ connect( m_job, SIGNAL(newSubTask(const QString&)), this, SLOT(slotNewSubTask(const QString&)) );
+ connect( m_job, SIGNAL(infoMessage(const QString&, int)), this, SLOT(slotInfoMessage(const QString&, int)) );
+ connect( m_job, SIGNAL(finished(bool)), this, SLOT(slotFinished(bool)) );
+ connect( m_job, SIGNAL(started()), this, SLOT(slotStarted()) );
+ connect( m_job, SIGNAL(canceled()), this, SLOT(slotCanceled()) );
+ connect( m_job, SIGNAL(percent(int)), this, SLOT(slotProgress(int)) );
+ connect( m_job, SIGNAL(subPercent(int)), this, SLOT(slotSubProgress(int)) );
+ connect( m_job, SIGNAL(nextTrack(int, int)), this, SLOT(slotNextTrack(int, int)) );
+
+ if( m_job->inherits( "K3bBurnJob" ) ) {
+ connect( m_job, SIGNAL(bufferStatus(int)), this, SLOT(slotBuffer(int)) );
+ connect( m_job, SIGNAL(deviceBuffer(int)), this, SLOT(slotDeviceBuffer(int)) );
+ }
+
+ connect( m_job, SIGNAL(destroyed()), this, SLOT(slotDestroyed()) );
+ }
+}
+
+
+bool K3bJobInterface::jobRunning() const
+{
+ return ( m_job && m_job->active() );
+}
+
+
+QString K3bJobInterface::jobDescription() const
+{
+ if( m_job )
+ return m_job->jobDescription();
+ else
+ return QString::null;
+}
+
+
+QString K3bJobInterface::jobDetails() const
+{
+ if( m_job )
+ return m_job->jobDetails();
+ else
+ return QString::null;
+}
+
+
+void K3bJobInterface::slotStarted()
+{
+ m_lastProgress = m_lastSubProgress = 0;
+ emitDCOPSignal( "started()", QByteArray() );
+}
+
+
+void K3bJobInterface::slotCanceled()
+{
+ emitDCOPSignal( "canceled()", QByteArray() );
+}
+
+
+void K3bJobInterface::slotFinished( bool success )
+{
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << success;
+ emitDCOPSignal( "finished(bool)", params );
+}
+
+
+void K3bJobInterface::slotInfoMessage( const QString& message, int type )
+{
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << message << type;
+ emitDCOPSignal( "infoMessage(QString)", params );
+}
+
+
+void K3bJobInterface::slotProgress( int val )
+{
+ if( m_lastProgress != val ) {
+ m_lastProgress = val;
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << val;
+ emitDCOPSignal( "progress(int)", params );
+ }
+}
+
+
+void K3bJobInterface::slotSubProgress( int val )
+{
+ if( m_lastSubProgress != val ) {
+ m_lastSubProgress = val;
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << val;
+ emitDCOPSignal( "subProgress(int)", params );
+ }
+}
+
+
+void K3bJobInterface::slotNewTask( const QString& task )
+{
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << task;
+ emitDCOPSignal( "newTask(QString)", params );
+}
+
+
+void K3bJobInterface::slotNewSubTask( const QString& task )
+{
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << task;
+ emitDCOPSignal( "newSubTask(QString)", params );
+}
+
+
+void K3bJobInterface::slotBuffer( int val )
+{
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << val;
+ emitDCOPSignal( "buffer(int)", params );
+}
+
+
+void K3bJobInterface::slotDeviceBuffer( int val )
+{
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << val;
+ emitDCOPSignal( "deviceBuffer(int)", params );
+}
+
+
+void K3bJobInterface::slotNextTrack( int track, int numTracks )
+{
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << track << numTracks;
+ emitDCOPSignal( "nextTrack(int,int)", params );
+}
+
+
+void K3bJobInterface::slotDestroyed()
+{
+ m_job = 0;
+}
+
+#include "k3bjobinterface.moc"
diff --git a/src/k3bjobinterface.h b/src/k3bjobinterface.h
new file mode 100644
index 0000000..0d27ac2
--- /dev/null
+++ b/src/k3bjobinterface.h
@@ -0,0 +1,82 @@
+/*
+ *
+ * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $
+ * Copyright (C) 2006 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#ifndef _K3B_JOB_INTERFACE_H_
+#define _K3B_JOB_INTERFACE_H_
+
+#include <qobject.h>
+#include <dcopobject.h>
+
+class K3bJob;
+
+
+/**
+ * A DCOP interface for K3b's currently running job.
+ *
+ * This may be used for example in a karamba theme with a non-volitile
+ * DCOP connection.
+ */
+class K3bJobInterface : public QObject, public DCOPObject
+{
+ Q_OBJECT
+ K_DCOP
+
+ public:
+ K3bJobInterface( QObject* parent );
+
+ void setJob( K3bJob* );
+
+ k_dcop:
+ bool jobRunning() const;
+
+ QString jobDescription() const;
+ QString jobDetails() const;
+
+ k_dcop_signals:
+ void started();
+ void canceled();
+ void finished( bool );
+ void infoMessage( const QString&, int );
+ void progress( int );
+ void subProgress( int );
+ void newTask( const QString& );
+ void newSubTask( const QString& );
+ void buffer( int );
+ void deviceBuffer( int );
+ void nextTrack( int track, int numTracks );
+
+ private slots:
+ void slotStarted();
+ void slotCanceled();
+ void slotFinished( bool );
+ void slotInfoMessage( const QString&, int );
+ void slotProgress( int );
+ void slotSubProgress( int );
+ void slotNewTask( const QString& );
+ void slotNewSubTask( const QString& );
+ void slotBuffer( int );
+ void slotDeviceBuffer( int );
+ void slotNextTrack( int track, int numTracks );
+
+ void slotDestroyed();
+
+ private:
+ K3bJob* m_job;
+
+ int m_lastProgress;
+ int m_lastSubProgress;
+};
+
+#endif
diff --git a/src/k3bjobprogressdialog.cpp b/src/k3bjobprogressdialog.cpp
new file mode 100644
index 0000000..351f1d9
--- /dev/null
+++ b/src/k3bjobprogressdialog.cpp
@@ -0,0 +1,696 @@
+/*
+ *
+ * $Id$
+ * Copyright (C) 2003-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bjobprogressdialog.h"
+#include "k3bapplication.h"
+#include "k3bemptydiscwaiter.h"
+#include "k3bjobprogressosd.h"
+#include "k3bdebuggingoutputdialog.h"
+#include "k3bapplication.h"
+#include "k3bjobinterface.h"
+#include "k3bthemedlabel.h"
+#include <k3bjob.h>
+#include <kcutlabel.h>
+#include <k3bdevice.h>
+#include <k3bdevicemanager.h>
+#include <k3bdeviceglobals.h>
+#include <k3bglobals.h>
+#include <k3bstdguiitems.h>
+#include <k3bversion.h>
+#include <k3bthememanager.h>
+
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qvariant.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qdatetime.h>
+#include <qstring.h>
+#include <qhbox.h>
+#include <qheader.h>
+#include <qscrollbar.h>
+#include <qpoint.h>
+#include <qfontmetrics.h>
+#include <qtimer.h>
+#include <qfont.h>
+#include <qeventloop.h>
+#include <qfile.h>
+#include <qapplication.h>
+
+#include <kprogress.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <klistview.h>
+#include <kiconloader.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <knotifyclient.h>
+#include <kstandarddirs.h>
+#include <kapplication.h>
+#include <kmainwindow.h>
+#include <kstdguiitem.h>
+#include <kpushbutton.h>
+
+
+
+
+class K3bJobProgressDialog::Private
+{
+public:
+ int lastProgress;
+};
+
+
+
+K3bJobProgressDialog::K3bJobProgressDialog( QWidget* parent,
+ const char* name,
+ bool showSubProgress,
+ bool modal, WFlags fl )
+ : KDialog( parent, name, modal, fl ),
+ in_loop(false),
+ m_osd(0)
+{
+ d = new Private;
+
+ setupGUI();
+ setupConnections();
+
+ if( !showSubProgress ) {
+ m_progressSubPercent->hide();
+ }
+
+ m_job = 0;
+ m_timer = new QTimer( this );
+
+ connect( m_timer, SIGNAL(timeout()), this, SLOT(slotUpdateTime()) );
+}
+
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+K3bJobProgressDialog::~K3bJobProgressDialog()
+{
+ delete d;
+ delete m_osd;
+}
+
+
+void K3bJobProgressDialog::setupGUI()
+{
+ QVBoxLayout* mainLayout = new QVBoxLayout( this, 11, 6, "mainLayout");
+
+
+ // header
+ // ------------------------------------------------------------------------------------------
+ QFrame* headerFrame = new QFrame( this, "headerFrame" );
+ headerFrame->setFrameShape( QFrame::StyledPanel );
+ headerFrame->setFrameShadow( QFrame::Sunken );
+ headerFrame->setLineWidth( 1 );
+ headerFrame->setMargin( 1 );
+ QHBoxLayout* headerLayout = new QHBoxLayout( headerFrame );
+ headerLayout->setMargin( 2 ); // to make sure the frame gets displayed
+ headerLayout->setSpacing( 0 );
+ m_pixLabel = new K3bThemedLabel( headerFrame );
+ headerLayout->addWidget( m_pixLabel );
+
+ QFrame* frame4 = new QFrame( headerFrame, "frame4" );
+ frame4->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)5, 1, 0, frame4->sizePolicy().hasHeightForWidth() ) );
+ frame4->setFrameShape( QFrame::NoFrame );
+ frame4->setFrameShadow( QFrame::Raised );
+ QVBoxLayout* frame4Layout = new QVBoxLayout( frame4, 6, 3, "frame4Layout");
+
+ m_labelJob = new K3bThemedLabel( frame4 );
+ m_labelJob->setMinimumVisibleText( 40 );
+ QFont m_labelJob_font( m_labelJob->font() );
+ m_labelJob_font.setPointSize( m_labelJob_font.pointSize() + 2 );
+ m_labelJob_font.setBold( true );
+ m_labelJob->setFont( m_labelJob_font );
+ m_labelJob->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) );
+ frame4Layout->addWidget( m_labelJob );
+
+ m_labelJobDetails = new K3bThemedLabel( frame4 );
+ m_labelJobDetails->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)5, 0, 1, m_labelJobDetails->sizePolicy().hasHeightForWidth() ) );
+ m_labelJobDetails->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) );
+ frame4Layout->addWidget( m_labelJobDetails );
+ headerLayout->addWidget( frame4 );
+
+ mainLayout->addWidget( headerFrame );
+ // ------------------------------------------------------------------------------------------
+
+
+ m_viewInfo = new KListView( this, "m_viewInfo" );
+ m_viewInfo->addColumn( "" );
+ m_viewInfo->addColumn( i18n( "Message" ) );
+ m_viewInfo->setFullWidth( true );
+ m_viewInfo->header()->hide();
+ m_viewInfo->setSorting(-1);
+ mainLayout->addWidget( m_viewInfo );
+
+
+ // progress header
+ // ------------------------------------------------------------------------------------------
+ QFrame* progressHeaderFrame = new QFrame( this, "progressHeaderFrame" );
+ progressHeaderFrame->setFrameShape( QFrame::StyledPanel );
+ progressHeaderFrame->setFrameShadow( QFrame::Sunken );
+ progressHeaderFrame->setLineWidth( 1 );
+ progressHeaderFrame->setMargin( 1 );
+
+ QHBoxLayout* progressHeaderLayout = new QHBoxLayout( progressHeaderFrame );
+ progressHeaderLayout->setMargin( 2 );
+ progressHeaderLayout->setSpacing( 0 );
+
+ QFrame* frame5 = new QFrame( progressHeaderFrame, "frame5" );
+ frame5->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)5, 1, 0, frame5->sizePolicy().hasHeightForWidth() ) );
+ frame5->setFrameShape( QFrame::NoFrame );
+ frame5->setFrameShadow( QFrame::Raised );
+ QVBoxLayout* frame5Layout = new QVBoxLayout( frame5, 6, 3, "frame5Layout");
+
+ m_labelTask = new K3bThemedLabel( frame5 );
+ QFont m_labelTask_font( m_labelTask->font() );
+ m_labelTask_font.setPointSize( m_labelTask_font.pointSize() + 2 );
+ m_labelTask_font.setBold( true );
+ m_labelTask->setFont( m_labelTask_font );
+ frame5Layout->addWidget( m_labelTask );
+
+ m_labelElapsedTime = new K3bThemedLabel( frame5 );
+ m_labelElapsedTime->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)5, 0, 1, m_labelElapsedTime->sizePolicy().hasHeightForWidth() ) );
+ frame5Layout->addWidget( m_labelElapsedTime );
+ progressHeaderLayout->addWidget( frame5 );
+
+ progressHeaderLayout->addWidget( new K3bThemedLabel( K3bTheme::PROGRESS_RIGHT, progressHeaderFrame ) );
+ mainLayout->addWidget( progressHeaderFrame );
+ // ------------------------------------------------------------------------------------------
+
+ QHBoxLayout* layout3 = new QHBoxLayout( 0, 0, 6, "layout3");
+
+ m_labelSubTask = new KCutLabel( this, "m_labelSubTask" );
+ layout3->addWidget( m_labelSubTask );
+
+ m_labelSubProcessedSize = new QLabel( this, "m_labelSubProcessedSize" );
+ m_labelSubProcessedSize->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) );
+ layout3->addWidget( m_labelSubProcessedSize );
+ mainLayout->addLayout( layout3 );
+
+ m_progressSubPercent = new KProgress( this, "m_progressSubPercent" );
+ mainLayout->addWidget( m_progressSubPercent );
+
+ QHBoxLayout* layout4 = new QHBoxLayout( 0, 0, 6, "layout4");
+
+ QLabel* textLabel5 = new QLabel( i18n("Overall progress:"), this, "textLabel5" );
+ layout4->addWidget( textLabel5 );
+
+ m_labelProcessedSize = new QLabel( this, "m_labelProcessedSize" );
+ m_labelProcessedSize->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) );
+ layout4->addWidget( m_labelProcessedSize );
+ mainLayout->addLayout( layout4 );
+
+ m_progressPercent = new KProgress( this, "m_progressPercent" );
+ mainLayout->addWidget( m_progressPercent );
+
+ m_frameExtraInfo = new QFrame( this, "m_frameExtraInfo" );
+ m_frameExtraInfo->setFrameShape( QFrame::NoFrame );
+ m_frameExtraInfo->setFrameShadow( QFrame::Raised );
+ m_frameExtraInfoLayout = new QGridLayout( m_frameExtraInfo );
+ m_frameExtraInfoLayout->setMargin(0);
+ m_frameExtraInfoLayout->setSpacing( spacingHint() );
+ mainLayout->addWidget( m_frameExtraInfo );
+
+ QFrame* line2 = new QFrame( this, "line2" );
+ line2->setFrameShape( QFrame::HLine );
+ line2->setFrameShadow( QFrame::Sunken );
+ mainLayout->addWidget( line2 );
+
+ QHBoxLayout* layout5 = new QHBoxLayout( 0, 0, 6, "layout5");
+ QSpacerItem* spacer = new QSpacerItem( 10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ layout5->addItem( spacer );
+
+ m_buttonCancel = new KPushButton( KStdGuiItem::cancel(), this, "m_buttonCancel" );
+ layout5->addWidget( m_buttonCancel );
+ m_buttonClose = new KPushButton( KStdGuiItem::close(), this );
+ layout5->addWidget( m_buttonClose );
+ m_buttonShowDebug = new QPushButton( i18n("Show Debugging Output"), this );
+ layout5->addWidget( m_buttonShowDebug );
+
+ mainLayout->addLayout( layout5 );
+
+ m_pixLabel->setThemePixmap( K3bTheme::PROGRESS_WORKING );
+
+ slotThemeChanged();
+
+ connect( k3bappcore->themeManager(), SIGNAL(themeChanged()),
+ this, SLOT(slotThemeChanged()) );
+ connect( kapp, SIGNAL(appearanceChanged()),
+ this, SLOT(slotThemeChanged()) );
+}
+
+
+void K3bJobProgressDialog::show()
+{
+ if( KConfigGroup( k3bcore->config(), "General Options" ).readBoolEntry( "hide main window while writing", false ) )
+ if( QWidget* w = kapp->mainWidget() )
+ w->hide();
+
+ if( m_osd ) {
+ m_osd->readSettings( k3bcore->config() );
+ m_osd->show();
+ }
+
+ KDialog::show();
+}
+
+
+void K3bJobProgressDialog::setExtraInfo( QWidget *extra )
+{
+ extra->reparent( m_frameExtraInfo, QPoint(0,0) );
+ m_frameExtraInfoLayout->addWidget( extra, 0, 0 );
+}
+
+
+void K3bJobProgressDialog::closeEvent( QCloseEvent* e )
+{
+ if( m_buttonClose->isVisible() ) {
+ KDialog::closeEvent( e );
+ if( QWidget* w = kapp->mainWidget() )
+ w->show();
+
+ if( !m_plainCaption.isEmpty() )
+ if( KMainWindow* w = dynamic_cast<KMainWindow*>(kapp->mainWidget()) )
+ w->setPlainCaption( m_plainCaption );
+
+ if( m_osd ) {
+ m_osd->hide();
+ m_osd->saveSettings( kapp->config() );
+ }
+ }
+ else
+ e->ignore();
+}
+
+
+void K3bJobProgressDialog::setupConnections()
+{
+ connect( m_buttonCancel, SIGNAL(clicked()), this, SLOT(slotCancelButtonPressed()) );
+ connect( m_buttonClose, SIGNAL(clicked()), this, SLOT(close()) );
+ connect( m_buttonShowDebug, SIGNAL(clicked()), this, SLOT(slotShowDebuggingOutput()) );
+}
+
+
+void K3bJobProgressDialog::slotProcessedSize( int processed, int size )
+{
+ m_labelProcessedSize->setText( i18n("%1 of %2 MB").arg( processed ).arg( size ) );
+}
+
+
+void K3bJobProgressDialog::slotProcessedSubSize( int processedTrackSize, int trackSize )
+{
+ m_labelSubProcessedSize->setText( i18n("%1 of %2 MB").arg(processedTrackSize).arg(trackSize) );
+}
+
+
+void K3bJobProgressDialog::slotInfoMessage( const QString& infoString, int type )
+{
+ QListViewItem* currentInfoItem = new QListViewItem( m_viewInfo, m_viewInfo->lastItem(), QString::null, infoString );
+ currentInfoItem->setSelectable( false );
+
+ // set the icon
+ switch( type ) {
+ case K3bJob::ERROR:
+ currentInfoItem->setPixmap( 0, SmallIcon( "stop" ) );
+ break;
+ case K3bJob::WARNING:
+ currentInfoItem->setPixmap( 0, SmallIcon( "yellowinfo" ) );
+ break;
+ case K3bJob::SUCCESS:
+ currentInfoItem->setPixmap( 0, SmallIcon( "ok" ) );
+ break;
+ case K3bJob::INFO:
+ default:
+ currentInfoItem->setPixmap( 0, SmallIcon( "info" ) );
+ }
+
+ // This should scroll down (hopefully!)
+ m_viewInfo->ensureItemVisible( currentInfoItem );
+}
+
+
+void K3bJobProgressDialog::slotFinished( bool success )
+{
+ kdDebug() << "(K3bJobProgressDialog) received finished signal!" << endl;
+
+ m_logFile.close();
+
+ if( success ) {
+ m_pixLabel->setThemePixmap( K3bTheme::PROGRESS_SUCCESS );
+
+ m_labelTask->setText( i18n("Success.") );
+ m_labelTask->setPaletteForegroundColor( Qt::darkGreen );
+ m_labelSubTask->setText( QString::null );
+
+ m_progressPercent->setValue(100);
+ m_progressSubPercent->setValue(100);
+ slotProgress(100);
+
+ // one last time update to be sure no remaining time is displayed anymore
+ slotUpdateTime();
+
+ if( m_osd )
+ m_osd->setText( i18n("Success.") );
+
+ KNotifyClient::event( 0, "SuccessfullyFinished", i18n("Successfully finished.") );
+ }
+ else {
+ m_pixLabel->setThemePixmap( K3bTheme::PROGRESS_FAIL );
+
+ m_labelTask->setPaletteForegroundColor( Qt::red );
+
+ if( m_bCanceled ) {
+ m_labelTask->setText( i18n("Canceled.") );
+ if( m_osd )
+ m_osd->setText( i18n("Canceled.") );
+ }
+ else {
+ m_labelTask->setText( i18n("Error.") );
+ if( m_osd )
+ m_osd->setText( i18n("Error.") );
+ }
+
+ KNotifyClient::event( 0, "FinishedWithError", i18n("Finished with errors") );
+ }
+
+ m_buttonCancel->hide();
+ m_buttonShowDebug->show();
+ m_buttonClose->show();
+ m_timer->stop();
+}
+
+
+void K3bJobProgressDialog::slotCanceled()
+{
+ m_bCanceled = true;
+}
+
+
+void K3bJobProgressDialog::setJob( K3bJob* job )
+{
+ m_bCanceled = false;
+
+ // clear everything
+ m_buttonClose->hide();
+ m_buttonShowDebug->hide();
+ m_buttonCancel->show();
+ m_buttonCancel->setEnabled(true);
+ m_viewInfo->clear();
+ m_progressPercent->setValue(0);
+ m_progressSubPercent->setValue(0);
+ m_labelTask->setText("");
+ m_labelSubTask->setText("");
+ m_labelProcessedSize->setText("");
+ m_labelSubProcessedSize->setText("");
+ m_labelTask->setPaletteForegroundColor( k3bappcore->themeManager()->currentTheme()->foregroundColor() );
+ m_debugOutputMap.clear();
+
+ // disconnect from the former job
+ if( m_job )
+ disconnect( m_job );
+ m_job = job;
+
+ if( job ) {
+
+ // connect to all the shit
+ connect( job, SIGNAL(infoMessage(const QString&,int)), this, SLOT(slotInfoMessage(const QString&,int)) );
+
+ connect( job, SIGNAL(percent(int)), m_progressPercent, SLOT(setValue(int)) );
+ connect( job, SIGNAL(percent(int)), this, SLOT(slotProgress(int)) );
+ connect( job, SIGNAL(subPercent(int)), m_progressSubPercent, SLOT(setValue(int)) );
+
+ connect( job, SIGNAL(processedSubSize(int, int)), this, SLOT(slotProcessedSubSize(int, int)) );
+ connect( job, SIGNAL(processedSize(int, int)), this, SLOT(slotProcessedSize(int, int)) );
+
+ connect( job, SIGNAL(newTask(const QString&)), this, SLOT(slotNewTask(const QString&)) );
+ connect( job, SIGNAL(newSubTask(const QString&)), this, SLOT(slotNewSubTask(const QString&)) );
+ connect( job, SIGNAL(started()), this, SLOT(slotStarted()) );
+ connect( job, SIGNAL(finished(bool)), this, SLOT(slotFinished(bool)) );
+ connect( job, SIGNAL(canceled()), this, SLOT(slotCanceled()) );
+
+ connect( job, SIGNAL(debuggingOutput(const QString&, const QString&)),
+ this, SLOT(slotDebuggingOutput(const QString&, const QString&)) );
+
+ m_labelJob->setText( m_job->jobDescription() );
+ m_labelJobDetails->setText( m_job->jobDetails() );
+
+ setCaption( m_job->jobDescription() );
+
+ if( KConfigGroup( k3bcore->config(), "General Options" ).readBoolEntry( "Show progress OSD", true ) ) {
+ if( !m_osd )
+ m_osd = new K3bJobProgressOSD( this, "progressosd" );
+ }
+ else
+ delete m_osd;
+
+ if( m_osd ) {
+ m_osd->setText( job->jobDescription() );
+ // FIXME: use a setJob method and let the osd also change the text color to red/green
+ // connect( job, SIGNAL(newTask(const QString&)), m_osd, SLOT(setText(const QString&)) );
+ connect( job, SIGNAL(percent(int)), m_osd, SLOT(setProgress(int)) );
+ }
+ }
+}
+
+
+void K3bJobProgressDialog::slotCancelButtonPressed()
+{
+ if( m_job )
+ if( KMessageBox::questionYesNo( this, i18n("Do you really want to cancel?"), i18n("Cancel Confirmation") ) == KMessageBox::Yes ) {
+ if( m_job ) {
+ m_job->cancel();
+ m_buttonCancel->setDisabled(true); // do not cancel twice
+ }
+ }
+}
+
+
+void K3bJobProgressDialog::slotNewSubTask(const QString& name)
+{
+ m_labelSubTask->setText(name);
+ m_labelSubProcessedSize->setText("");
+ m_progressSubPercent->setValue(0);
+}
+
+void K3bJobProgressDialog::slotNewTask(const QString& name)
+{
+ m_labelTask->setText( name );
+}
+
+
+void K3bJobProgressDialog::slotStarted()
+{
+ d->lastProgress = 0;
+ m_timer->start( 1000 );
+ m_startTime = QTime::currentTime();
+ if( KMainWindow* w = dynamic_cast<KMainWindow*>(kapp->mainWidget()) )
+ m_plainCaption = w->caption();
+
+ m_logFile.open();
+}
+
+
+void K3bJobProgressDialog::slotUpdateTime()
+{
+ int elapsed = m_startTime.secsTo( QTime::currentTime() );
+
+ QString s = i18n("Elapsed time: %1 h").arg( QTime().addSecs(elapsed).toString() );
+ if( d->lastProgress > 0 && d->lastProgress < 100 ) {
+ int rem = m_startTime.secsTo( m_lastProgressUpdateTime ) * (100-d->lastProgress) / d->lastProgress;
+ s += " / " + i18n("Remaining: %1 h").arg( QTime().addSecs(rem).toString() );
+ }
+
+ m_labelElapsedTime->setText( s );
+}
+
+
+void K3bJobProgressDialog::slotDebuggingOutput( const QString& type, const QString& output )
+{
+ m_debugOutputMap[type].append(output);
+ m_logFile.addOutput( type, output );
+}
+
+
+void K3bJobProgressDialog::slotShowDebuggingOutput()
+{
+ K3bDebuggingOutputDialog debugWidget( this );
+ debugWidget.setOutput( m_debugOutputMap );
+ debugWidget.exec();
+}
+
+
+void K3bJobProgressDialog::slotProgress( int percent )
+{
+ if( percent > d->lastProgress ) {
+ d->lastProgress = percent;
+ m_lastProgressUpdateTime = QTime::currentTime();
+ if( KMainWindow* w = dynamic_cast<KMainWindow*>(kapp->mainWidget()) ) {
+ w->setPlainCaption( QString( "(%1%) %2" ).arg(percent).arg(m_plainCaption) );
+ }
+
+ setCaption( QString( "(%1%) %2" ).arg(percent).arg(m_job->jobDescription()) );
+ }
+}
+
+
+void K3bJobProgressDialog::keyPressEvent( QKeyEvent *e )
+{
+ e->accept();
+
+ switch ( e->key() ) {
+ case Key_Enter:
+ case Key_Return:
+ // if the process finished this closes the dialog
+ if( m_buttonClose->isVisible() )
+ close();
+ break;
+ case Key_Escape:
+ // simulate button clicks
+ if( m_buttonCancel->isVisible() && m_buttonCancel->isEnabled() )
+ slotCancelButtonPressed();
+ else if( !m_buttonCancel->isVisible() )
+ close();
+ break;
+ default:
+ // nothing
+ break;
+ }
+}
+
+
+QSize K3bJobProgressDialog::sizeHint() const
+{
+ QSize s = layout()->totalSizeHint();
+ if( s.width() < s.height() )
+ s.setWidth( s.height() );
+ return s;
+}
+
+
+int K3bJobProgressDialog::startJob( K3bJob* job )
+{
+ if( job ) {
+ setJob( job );
+ k3bappcore->jobInterface()->setJob( job );
+ }
+ else if( !m_job ) {
+ kdError() << "(K3bJobProgressDialog) null job!" << endl;
+ return -1;
+ }
+
+ // the following code is mainly taken from QDialog::exec
+
+ if ( in_loop ) {
+ kdError() << "(K3bJobProgressDialog::startJob) Recursive call detected." << endl;
+ return -1;
+ }
+
+ bool destructiveClose = testWFlags( WDestructiveClose );
+ clearWFlags( WDestructiveClose );
+
+ bool wasShowModal = testWFlags( WShowModal );
+ setWFlags( WShowModal );
+ setResult( 0 );
+
+ show();
+
+ // start the job after showing the dialog
+ m_job->start();
+
+ in_loop = true;
+ QApplication::eventLoop()->enterLoop();
+
+ if ( !wasShowModal )
+ clearWFlags( WShowModal );
+
+ int res = result();
+
+ if ( destructiveClose )
+ delete this;
+
+ return res;
+}
+
+
+void K3bJobProgressDialog::hide()
+{
+ // we need to reimplement this since
+ // QDialog does not know if we are in a loop from startJob
+
+ if ( isHidden() )
+ return;
+
+ KDialog::hide();
+
+ if ( in_loop ) {
+ in_loop = FALSE;
+ QApplication::eventLoop()->exitLoop();
+ }
+}
+
+
+int K3bJobProgressDialog::waitForMedia( K3bDevice::Device* device,
+ int mediaState,
+ int mediaType,
+ const QString& message )
+{
+ return K3bEmptyDiscWaiter::wait( device, mediaState, mediaType, message, this );
+}
+
+
+bool K3bJobProgressDialog::questionYesNo( const QString& text,
+ const QString& caption,
+ const QString& yesText,
+ const QString& noText )
+{
+ return ( KMessageBox::questionYesNo( this,
+ text,
+ caption,
+ yesText.isEmpty() ? KStdGuiItem::yes() : KGuiItem(yesText),
+ noText.isEmpty() ? KStdGuiItem::no() : KGuiItem(noText) ) == KMessageBox::Yes );
+}
+
+
+void K3bJobProgressDialog::blockingInformation( const QString& text,
+ const QString& caption )
+{
+ KMessageBox::information( this, text, caption );
+}
+
+
+void K3bJobProgressDialog::slotThemeChanged()
+{
+ if( K3bTheme* theme = k3bappcore->themeManager()->currentTheme() ) {
+ static_cast<QWidget*>(child( "frame4" ))->setPaletteBackgroundColor( theme->backgroundColor() );
+ static_cast<QWidget*>(child( "frame4" ))->setPaletteForegroundColor( theme->backgroundColor() );
+ static_cast<QWidget*>(child( "frame5" ))->setPaletteBackgroundColor( theme->backgroundColor() );
+ static_cast<QWidget*>(child( "frame5" ))->setPaletteForegroundColor( theme->backgroundColor() );
+ static_cast<QWidget*>(child( "progressHeaderFrame" ))->setPaletteBackgroundColor( theme->backgroundColor() );
+ static_cast<QWidget*>(child( "progressHeaderFrame" ))->setPaletteForegroundColor( theme->backgroundColor() );
+ static_cast<QWidget*>(child( "headerFrame" ))->setPaletteBackgroundColor( theme->backgroundColor() );
+ static_cast<QWidget*>(child( "headerFrame" ))->setPaletteForegroundColor( theme->backgroundColor() );
+ }
+}
+
+#include "k3bjobprogressdialog.moc"
diff --git a/src/k3bjobprogressdialog.h b/src/k3bjobprogressdialog.h
new file mode 100644
index 0000000..5bc1af2
--- /dev/null
+++ b/src/k3bjobprogressdialog.h
@@ -0,0 +1,173 @@
+/*
+ *
+ * $Id: k3bjobprogressdialog.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.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 option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef _K3B_JOB_PROGRESSDIALOG_H_
+#define _K3B_JOB_PROGRESSDIALOG_H_
+
+#include <kdialog.h>
+
+#include "k3bdebuggingoutputfile.h"
+
+#include <k3bjobhandler.h>
+
+#include <qdatetime.h>
+#include <qfile.h>
+
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class KListView;
+class QFrame;
+class QGroupBox;
+class QLabel;
+class QListViewItem;
+class KProgress;
+class QPushButton;
+class QTimer;
+class K3bJob;
+class KCutLabel;
+class QCloseEvent;
+class QGridLayout;
+class QKeyEvent;
+class K3bJobProgressOSD;
+class K3bThemedLabel;
+
+
+class K3bJobProgressDialog : public KDialog, public K3bJobHandler
+{
+ Q_OBJECT
+
+ public:
+ K3bJobProgressDialog( QWidget* parent = 0,
+ const char* name = 0,
+ bool showSubProgress = true,
+ bool modal = FALSE,
+ WFlags fl = 0 );
+ virtual ~K3bJobProgressDialog();
+
+ virtual void setJob( K3bJob* job );
+ void setExtraInfo( QWidget *extra );
+
+ /**
+ * reimplemented for internal reasons
+ */
+ void show();
+
+ /**
+ * reimplemented for internal reasons
+ */
+ void hide();
+
+ /**
+ * This will show the dialog and then start the given job or
+ * if job == 0 the job set with setJob
+ * Use instead of exec()
+ */
+ int startJob( K3bJob* job = 0 );
+
+ QSize sizeHint() const;
+
+ /**
+ * @reimplemented from K3bJobHandler
+ */
+ int waitForMedia( K3bDevice::Device*,
+ int mediaState = K3bDevice::STATE_EMPTY,
+ int mediaType = K3bDevice::MEDIA_WRITABLE_CD,
+ const QString& message = QString::null );
+
+ /**
+ * @reimplemented from K3bJobHandler
+ */
+ bool questionYesNo( const QString& text,
+ const QString& caption = QString::null,
+ const QString& yesText = QString::null,
+ const QString& noText = QString::null );
+
+ /**
+ * reimplemented from K3bJobHandler
+ */
+ void blockingInformation( const QString& text,
+ const QString& caption = QString::null );
+
+ protected slots:
+ virtual void slotProcessedSize( int processed, int size );
+ virtual void slotProcessedSubSize( int processed, int size );
+ virtual void slotInfoMessage( const QString& infoString, int type );