summaryrefslogtreecommitdiffstats
path: root/src/projects
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/projects
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/projects')
-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
123 files changed, 23707 insertions, 0 deletions
diff --git a/src/projects/Makefile.am b/src/projects/Makefile.am
new file mode 100644
index 0000000..751eb71
--- /dev/null
+++ b/src/projects/Makefile.am
@@ -0,0 +1,86 @@
+AM_CPPFLAGS= -I$(srcdir)/../../libk3b/core \
+ -I$(srcdir)/../../libk3bdevice \
+ -I$(srcdir)/../../libk3b/projects \
+ -I$(srcdir)/../../libk3b/projects/audiocd \
+ -I$(srcdir)/../../libk3b/projects/datacd \
+ -I$(srcdir)/../../libk3b/projects/mixedcd \
+ -I$(srcdir)/../../libk3b/projects/movixcd \
+ -I$(srcdir)/../../libk3b/projects/datadvd \
+ -I$(srcdir)/../../libk3b/projects/videocd \
+ -I$(srcdir)/../../libk3b/projects/videodvd \
+ -I$(srcdir)/../../libk3b/projects/movixdvd \
+ -I$(srcdir)/../../libk3b/cddb \
+ -I$(srcdir)/../../libk3b/tools \
+ -I$(srcdir)/../../libk3b/plugin \
+ -I$(srcdir)/../rip \
+ -I$(srcdir)/.. \
+ $(all_includes)
+
+METASOURCES = AUTO
+
+SUBDIRS = kostore
+
+noinst_LTLIBRARIES = libprojects.la
+
+libprojects_la_LIBADD = ../rip/librip.la ./kostore/libkostore.la
+
+libprojects_la_SOURCES = k3baudioburndialog.cpp \
+ k3baudiocdtextwidget.cpp \
+ k3baudiodatasourceviewitem.cpp \
+ k3baudioeditorwidget.cpp \
+ k3baudiotrackdialog.cpp \
+ k3baudiotrackwidget.cpp \
+ k3baudiotrackplayer.cpp \
+ k3baudiotracksplitdialog.cpp \
+ k3baudiotrackview.cpp \
+ k3baudiotrackviewitem.cpp \
+ k3baudioview.cpp \
+ base_k3baudiocdtextwidget.ui \
+ base_k3baudiocdtextallfieldswidget.ui \
+ base_k3baudiotrackwidget.ui \
+ k3bmixedburndialog.cpp \
+ k3bmixeddirtreeview.cpp \
+ k3bmixedview.cpp \
+ base_k3badvanceddataimagesettings.ui \
+ base_k3bbootimageview.ui \
+ base_k3bdataimagesettings.ui \
+ base_k3bdatavolumedescwidget.ui \
+ k3bdataadvancedimagesettingswidget.cpp \
+ k3bdatadirtreeview.cpp \
+ k3bdatafileview.cpp \
+ k3bdataimagesettingswidget.cpp \
+ k3bdatapropertiesdialog.cpp \
+ k3bdataview.cpp \
+ k3bdataviewitem.cpp \
+ k3bdatavolumedescwidget.cpp \
+ k3bdataburndialog.cpp \
+ k3bbootimagedialog.cpp \
+ k3bbootimageview.cpp \
+ k3bdvdburndialog.cpp \
+ k3bdvdview.cpp \
+ base_k3bmovixoptionswidget.ui \
+ k3bmovixburndialog.cpp \
+ k3bmovixlistview.cpp \
+ k3bmovixoptionswidget.cpp \
+ k3bmovixview.cpp \
+ k3bmovixdvdburndialog.cpp \
+ k3bmovixdvdview.cpp \
+ k3bvideodvdburndialog.cpp \
+ k3bvideodvdview.cpp \
+ k3bvcdburndialog.cpp \
+ k3bvcdlistview.cpp \
+ k3bvcdlistviewitem.cpp \
+ k3bvcdtrackdialog.cpp \
+ k3bvcdview.cpp \
+ k3bfillstatusdisplay.cpp \
+ k3bview.cpp \
+ k3bprojectburndialog.cpp \
+ k3bprojectplugindialog.cpp \
+ k3baudiotracktrmlookupdialog.cpp \
+ k3bdatamultisessioncombobox.cpp \
+ k3bmusicbrainzjob.cpp \
+ k3bdataurladdingdialog.cpp \
+ k3bdatasessionimportdialog.cpp \
+ k3baudiodatasourceeditwidget.cpp \
+ k3baudiotrackaddingdialog.cpp \
+ k3bencodingconverter.cpp \ No newline at end of file
diff --git a/src/projects/base_k3badvanceddataimagesettings.ui b/src/projects/base_k3badvanceddataimagesettings.ui
new file mode 100644
index 0000000..593b404
--- /dev/null
+++ b/src/projects/base_k3badvanceddataimagesettings.ui
@@ -0,0 +1,193 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>base_K3bAdvancedDataImageSettings</class>
+<author>Sebastian Trueg</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>base_K3bDataCustomFilesystemsWidget</cstring>
+ </property>
+ <property name="caption">
+ <string>Custom Data Filesystems</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>groupIsoSettings</cstring>
+ </property>
+ <property name="title">
+ <string>File System Settings</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KListView">
+ <column>
+ <property name="text">
+ <string>ISO9660 Filesystem</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>m_viewIsoSettings</cstring>
+ </property>
+ <property name="fullWidth">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>File Systems</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkRockRidge</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Generate Rock Ridge extensions</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Add Rock Ridge extensions to the file system</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;If this option is checked, K3b will generate the System Use Sharing Protocol records (SUSP) specified by the Rock Ridge Interchange Protocol (IEEE-P1282).
+&lt;p&gt;Rock Ridge extends the ISO-9660 filesystem by features equal to the UNIX filesystems (permissions, symbolic links, very long filenames, ...). It uses ISO-8859 or UTF-16 based characters and allows 255 octets.
+&lt;p&gt;Rock Ridge extensions are located at the end of each ISO-9660 directory record. This makes the Rock Ridge tree closely coupled to the ISO-9660 tree.
+&lt;p&gt;&lt;b&gt;It is highly recommended to use Rock Ridge extensions on every data CD or DVD.&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkJoliet</cstring>
+ </property>
+ <property name="text">
+ <string>Generate &amp;Joliet extensions</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Add Joliet extensions to the file system</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;If this option is checked, K3b will add additional Joliet extensions to the ISO-9660 file system.
+&lt;p&gt;Joliet is not an accepted independent international standard like ISO-9660 or Rock Ridge. It is mainly used on Windows systems.
+&lt;p&gt;Joliet does not allow all characters, so the Joliet filenames are not identical to the filenames on disk (as compared to Rock Ridge). Joliet has a filename length limitation of 64 chars (independent from the character coding and type e.g. European vs. Japanese). This is annoying, as modern file systems all allow 255 characters per path name component.
+&lt;p&gt;Joliet uses UTF-16 coding.
+&lt;p&gt;&lt;b&gt;Caution:&lt;/b&gt; With the exception of Linux and FreeBSD, there is no POSIX-like OS that supports Joliet. So &lt;b&gt;never create Joliet-only CDs or DVDs&lt;/b&gt; for that reason.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkUdf</cstring>
+ </property>
+ <property name="text">
+ <string>Generate &amp;UDF structures</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Add UDF structures to the file system</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;If this option is checked K3b will create UDF filesystem structures in addition to the ISO9660 filesystem.
+&lt;p&gt;The UDF (&lt;em&gt;&lt;b&gt;U&lt;/b&gt;niversal &lt;b&gt;D&lt;/b&gt;isk &lt;b&gt;F&lt;/b&gt;ormat&lt;/em&gt;) is mainly used for DVDs.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox" row="0" column="1">
+ <property name="name">
+ <cstring>groupBox5</cstring>
+ </property>
+ <property name="title">
+ <string>Other Settings</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkForceInputCharset</cstring>
+ </property>
+ <property name="text">
+ <string>F&amp;orce input charset:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <property name="name">
+ <cstring>m_comboInputCharset</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkPreservePermissions</cstring>
+ </property>
+ <property name="text">
+ <string>Preserve file permissions (bac&amp;kup)</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;If this option is checked, all files in the resulting file system will have exactly the same permissions as the source files. (Otherwise, all files will have equal permissions and be owned by root).
+&lt;p&gt;This is mainly useful for backups.&lt;p&gt;&lt;b&gt;Caution:&lt;/b&gt; The permissions may not make much sense on other file systems; for example, if a user that owns a file on the CD or DVD does not exist.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>m_checkForceInputCharset</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_comboInputCharset</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>m_checkRockRidge</tabstop>
+ <tabstop>m_checkJoliet</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klistview.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/src/projects/base_k3baudiocdtextallfieldswidget.ui b/src/projects/base_k3baudiocdtextallfieldswidget.ui
new file mode 100644
index 0000000..e178d1f
--- /dev/null
+++ b/src/projects/base_k3baudiocdtextallfieldswidget.ui
@@ -0,0 +1,275 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>base_K3bAudioCdTextAllFieldsWidget</class>
+<author>Sebastian Trueg</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>base_K3bAudioCdTextAllFieldsWidget</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="8" column="0">
+ <property name="name">
+ <cstring>textLabel8</cstring>
+ </property>
+ <property name="text">
+ <string>Messa&amp;ge:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editMessage</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="4" column="1">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_editSongwriter</cstring>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonCopySongwriter</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Copy to all tracks</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="6" column="0">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;UPC EAN:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editUpc_ean</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="5" column="1">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_editComposer</cstring>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonCopyComposer</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Copy to all tracks</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>So&amp;ngwriter:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editSongwriter</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Composer:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editComposer</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="7" column="0">
+ <property name="name">
+ <cstring>textLabel7</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Disk id:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editDisc_id</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="3" column="1">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_editArranger</cstring>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonCopyArranger</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Copy to all tracks</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Arranger:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editArranger</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="6" column="1">
+ <property name="name">
+ <cstring>m_editUpc_ean</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="7" column="1">
+ <property name="name">
+ <cstring>m_editDisc_id</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="8" column="1">
+ <property name="name">
+ <cstring>m_editMessage</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Performer:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editPerformer</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_editTitle</cstring>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonCopyTitle</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Copy to all tracks</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Title:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editTitle</cstring>
+ </property>
+ </widget>
+ <widget class="Line" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line4</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="1">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_editPerformer</cstring>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonCopyPerformer</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Copy to all tracks</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/src/projects/base_k3baudiocdtextwidget.ui b/src/projects/base_k3baudiocdtextwidget.ui
new file mode 100644
index 0000000..50daff2
--- /dev/null
+++ b/src/projects/base_k3baudiocdtextwidget.ui
@@ -0,0 +1,222 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>base_K3bAudioCdTextWidget</class>
+<comment>Widget to edit the global CD-Text in a K3b audio project.</comment>
+<author>Sebastian Trueg</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>K3bAudioCDTextWidget</cstring>
+ </property>
+ <property name="caption">
+ <string>K3bAudioCDTextWidget</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>m_groupCdText</cstring>
+ </property>
+ <property name="title">
+ <string>Write CD-Text</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string></string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;&lt;b&gt;CD-Text&lt;/b&gt;
+&lt;p&gt;If this option is checked K3b uses some otherwise unused space on the Audio CD to store additional information, like the artist or the CD title.
+&lt;p&gt;CD-Text is an extension to the audio CD standard introduced by Sony.
+&lt;p&gt;CD-Text will only be usable on CD players that support this extension (mostly car CD players) and software like K3b, of course.
+&lt;p&gt;Since a CD-Text-enhanced Audio CD will work in any Hifi CD or DVD player even if the player does not support CD-Text explicitly, enabling it is never a bad idea (just remember to fill in the CD-Text information).</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame3</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Perf&amp;ormer:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editPerformer</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="1">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_editPerformer</cstring>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonCopyPerformer</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Copy to all tracks</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="1">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_editTitle</cstring>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonCopyTitle</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Copy to all tracks</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Title:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editTitle</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout15</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>m_buttonMoreFields</cstring>
+ </property>
+ <property name="text">
+ <string>More Fiel&amp;ds...</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>m_buttonCopyTitle</sender>
+ <signal>clicked()</signal>
+ <receiver>K3bAudioCDTextWidget</receiver>
+ <slot>slotCopyTitle()</slot>
+ </connection>
+ <connection>
+ <sender>m_buttonCopyPerformer</sender>
+ <signal>clicked()</signal>
+ <receiver>K3bAudioCDTextWidget</receiver>
+ <slot>slotCopyPerformer()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>m_editTitle</tabstop>
+ <tabstop>m_editPerformer</tabstop>
+</tabstops>
+<slots>
+ <slot access="protected" specifier="pure virtual">slotCopyTitle()</slot>
+ <slot access="protected" specifier="pure virtual">slotCopyPerformer()</slot>
+ <slot access="protected" specifier="pure virtual">slotCopyArranger()</slot>
+ <slot access="protected" specifier="pure virtual">slotCopyComposer()</slot>
+ <slot access="protected" specifier="pure virtual">slotCopySongwriter()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/src/projects/base_k3baudiotrackwidget.ui b/src/projects/base_k3baudiotrackwidget.ui
new file mode 100644
index 0000000..813b042
--- /dev/null
+++ b/src/projects/base_k3baudiotrackwidget.ui
@@ -0,0 +1,336 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>base_K3bAudioTrackWidget</class>
+<author>Sebastian Trueg</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>K3bAudioTrackWidget</cstring>
+ </property>
+ <property name="caption">
+ <string>K3bAudioTrackWidget</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QTabWidget">
+ <property name="name">
+ <cstring>m_mainTab</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>C&amp;D-Text</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit" row="4" column="1">
+ <property name="name">
+ <cstring>m_editSongwriter</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>So&amp;ngwriter:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editSongwriter</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="3" column="1">
+ <property name="name">
+ <cstring>m_editArranger</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="3" column="3">
+ <property name="name">
+ <cstring>m_editComposer</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="5" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>m_editMessage</cstring>
+ </property>
+ </widget>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>line2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Arranger:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editArranger</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="2" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Composer:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editComposer</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>textLabel8</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Message:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editMessage</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>m_editTitle</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Performer:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editPerformer</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="2">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;ISRC:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editIsrc</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Title:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editTitle</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="4" column="3">
+ <property name="name">
+ <cstring>m_editIsrc</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="0" column="3">
+ <property name="name">
+ <cstring>m_editPerformer</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>350</width>
+ <height>50</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Options</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkPreemphasis</cstring>
+ </property>
+ <property name="text">
+ <string>Preemph&amp;asis</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;Preemphasis is mainly used in audio processing. Higher frequencies in audio signals usually have lower amplitudes. This can lead to bad signal quality on noisy transmission because the high frequencies might become too weak. To avoid this effect, high frequencies are amplified before transmission (preemphasis); the receiver will then weaken them accordingly for playback.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkCopyPermitted</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Copy permitted</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_labelPostGap</cstring>
+ </property>
+ <property name="text">
+ <string>Post-Gap:</string>
+ </property>
+ </widget>
+ <widget class="K3bMsfEdit">
+ <property name="name">
+ <cstring>m_editPostGap</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Set the length of the track's post-gap</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;On an audio CD each track (except for the last) can have a post-gap.
+This does not mean that K3b adds an additional gap of silence to the track. This setting simply influences the display on a Hifi audio CD player. The part of an audio track that is marked as post-gap is counted backwards.
+&lt;p&gt;This setting is irrelevant for most users as todays CD burners can put arbitrary audio data in the post-gap when burning in DAO mode.
+&lt;p&gt;&lt;i&gt;In other CD-burning applications the post-gap might be called the pre-gap. The pre-gap of track 2 is the same as the post-gap of track 1.
+&lt;p&gt;&lt;b&gt;Changing the post-gap does not change the length of the track!&lt;/b&gt;
+&lt;p&gt;&lt;b&gt;When writing in TAO writing mode (not recommended for Audio CDs) the post-gap will most likely be muted and on some burners forced to 2 seconds.&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>161</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>41</width>
+ <height>80</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </widget>
+ </hbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>K3bMsfEdit</class>
+ <header location="global">k3bmsfedit.h</header>
+ <sizehint>
+ <width>100</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="XBM.GZ" length="79">789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f</data>
+ </image>
+</images>
+<tabstops>
+ <tabstop>m_editTitle</tabstop>
+ <tabstop>m_editPerformer</tabstop>
+ <tabstop>m_editArranger</tabstop>
+ <tabstop>m_editComposer</tabstop>
+ <tabstop>m_editSongwriter</tabstop>
+ <tabstop>m_editIsrc</tabstop>
+ <tabstop>m_editMessage</tabstop>
+ <tabstop>m_checkPreemphasis</tabstop>
+ <tabstop>m_checkCopyPermitted</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>k3bmsfedit.h</includehint>
+</includehints>
+</UI>
diff --git a/src/projects/base_k3bbootimageview.ui b/src/projects/base_k3bbootimageview.ui
new file mode 100644
index 0000000..6ba21f6
--- /dev/null
+++ b/src/projects/base_k3bbootimageview.ui
@@ -0,0 +1,394 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>base_K3bBootImageView</class>
+<author>Sebastian Trueg</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>base_K3bBootImageView</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout17</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>label</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Boot images:</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>m_buttonNew</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;New...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Add new boot image</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>m_buttonDelete</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Remove selected boot image</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="KListView">
+ <column>
+ <property name="text">
+ <string>Emulation Type</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Size</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Local Path</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>m_viewImages</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="fullWidth">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>m_groupImageType</cstring>
+ </property>
+ <property name="title">
+ <string>Emulation Type</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>m_radioFloppy</cstring>
+ </property>
+ <property name="text">
+ <string>Flopp&amp;y</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Emulate a 1440/2880 kb floppy</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>m_radioHarddisk</cstring>
+ </property>
+ <property name="text">
+ <string>Harddisk</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Emulate a harddisk</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>m_radioNoEmulation</cstring>
+ </property>
+ <property name="text">
+ <string>None</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>No emulation at all</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>m_groupOptions</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Settings</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkNoBoot</cstring>
+ </property>
+ <property name="text">
+ <string>No boot image</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Do not boot from the emulated floppy/harddisk</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkInfoTable</cstring>
+ </property>
+ <property name="text">
+ <string>Boot-info-table</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout10</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>m_editLoadSegment</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>m_editLoadSize</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Boot load segment:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Boot load size:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout16</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>m_buttonToggleOptions</cstring>
+ </property>
+ <property name="text">
+ <string>Show Advanced Op&amp;tions</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer16</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>261</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout18</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Boot catalog:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>m_editBootCataloge</cstring>
+ </property>
+ <property name="text">
+ <string>boot/boot.catalog</string>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>m_radioFloppy</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>base_K3bBootImageView</receiver>
+ <slot>slotOptionsChanged()</slot>
+ </connection>
+ <connection>
+ <sender>m_radioHarddisk</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>base_K3bBootImageView</receiver>
+ <slot>slotOptionsChanged()</slot>
+ </connection>
+ <connection>
+ <sender>m_checkNoBoot</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>base_K3bBootImageView</receiver>
+ <slot>slotOptionsChanged()</slot>
+ </connection>
+ <connection>
+ <sender>m_checkInfoTable</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>base_K3bBootImageView</receiver>
+ <slot>slotOptionsChanged()</slot>
+ </connection>
+ <connection>
+ <sender>m_editLoadSegment</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>base_K3bBootImageView</receiver>
+ <slot>slotOptionsChanged()</slot>
+ </connection>
+ <connection>
+ <sender>m_editLoadSize</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>base_K3bBootImageView</receiver>
+ <slot>slotOptionsChanged()</slot>
+ </connection>
+ <connection>
+ <sender>m_radioNoEmulation</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>textLabel2_2</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_radioNoEmulation</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>textLabel3</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_radioNoEmulation</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_editLoadSegment</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_radioNoEmulation</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_editLoadSize</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_radioNoEmulation</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_checkNoBoot</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_radioNoEmulation</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>base_K3bBootImageView</receiver>
+ <slot>slotOptionsChanged()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot access="protected">slotOptionsChanged()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klistview.h</includehint>
+</includehints>
+</UI>
diff --git a/src/projects/base_k3bdataimagesettings.ui b/src/projects/base_k3bdataimagesettings.ui
new file mode 100644
index 0000000..3427ab7
--- /dev/null
+++ b/src/projects/base_k3bdataimagesettings.ui
@@ -0,0 +1,274 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>base_K3bDataImageSettings</class>
+<author>Sebastian Trueg</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>base_K3bDataImageSetings</cstring>
+ </property>
+ <property name="caption">
+ <string>Data Image Settings</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>m_groupVolumeName</cstring>
+ </property>
+ <property name="title">
+ <string>Volume Name</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>m_editVolumeName</cstring>
+ </property>
+ <property name="maxLength">
+ <number>32</number>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>m_buttonMoreVolDescFields</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;More fields...</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>m_groupFileSystem</cstring>
+ </property>
+ <property name="title">
+ <string>File System</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>m_comboFilesystems</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>File system presets</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>m_buttonCustomFilesystems</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Custom...</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>m_groupSymlinks</cstring>
+ </property>
+ <property name="title">
+ <string>Symbolic Links</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>No Change</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Discard broken symlinks</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Discard all symlinks</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Follow symlinks</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_comboSymlinkHandling</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Symbolic link handling in the project</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;K3b can create ISO9660 filesystems that contain symlinks if the Rock Ridge extensions are enabled (they are by default). You can change the way symlinks are handled in a K3b project.
+
+&lt;p&gt;&lt;b&gt;No Change&lt;/b&gt;&lt;br&gt;
+Symlinks are used as they have been added to the project.
+
+&lt;p&gt;&lt;b&gt;Discard broken symlinks&lt;/b&gt;&lt;br&gt;
+K3b will discard all symbolic links that do not point to a file inside the project. That includes all links to absolute paths like '/home/myhome/testfile'.
+
+&lt;p&gt;&lt;b&gt;Discard all symlinks&lt;/b&gt;&lt;br&gt;
+K3b will discard all symbolic links that have been added to the project; meaning that the resulting file system will have no links at all.
+
+&lt;p&gt;&lt;b&gt;Follow symlinks&lt;/b&gt;&lt;br&gt;
+Each symbolic link in the project will be replaced with the contents of the file it is pointing to. Thus, the resulting filesystem will not contain any symbolic links.&lt;br&gt;
+Be aware that in case Rock Ridge extensions are disabled (which is not recommended) symbolic links are always followed because ISO9660 does not support symbolic links.
+
+&lt;p&gt;&lt;b&gt;Caution:&lt;/b&gt; Symbolic links require Rock Ridge extensions.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>m_groupWhitespace</cstring>
+ </property>
+ <property name="title">
+ <string>White space handling</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>No Change</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Strip</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Extended Strip</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Replace</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_comboSpaceHandling</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Handling of spaces in filenames</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;&lt;b&gt;No Change&lt;/b&gt;&lt;br&gt;
+If this option is checked, K3b will leave all spaces in filenames as they are.
+&lt;p&gt;&lt;b&gt;Strip&lt;/b&gt;&lt;br&gt;
+If this option is checked, K3b will remove all spaces from all filenames.&lt;br&gt;
+Example: 'my good file.ext' becomes 'mygoodfile.ext'
+&lt;p&gt;&lt;b&gt;Extended Strip&lt;/b&gt;&lt;br&gt;
+If this option is checked K3b will remove all spaces in all filenames and capitalize all letters following a space.&lt;br&gt;
+Example: 'my good file.ext' becomes 'myGoodFile.ext'
+&lt;p&gt;&lt;b&gt;Replace&lt;/b&gt;&lt;br&gt;
+If this option is checked, K3b will replace all spaces in all filenames with the specified characters.&lt;br&gt;
+Example: 'my good file.ext' becomes 'my_good_file.ext'</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>m_editReplace</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>_</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>The string to replace spaces with</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<tabstops>
+ <tabstop>m_editReplace</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/projects/base_k3bdatavolumedescwidget.ui b/src/projects/base_k3bdatavolumedescwidget.ui
new file mode 100644
index 0000000..ce31be9
--- /dev/null
+++ b/src/projects/base_k3bdatavolumedescwidget.ui
@@ -0,0 +1,370 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>base_K3bDataVolumeDescWidget</class>
+<author>Sebastian Trueg</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>base_K3bDataVolumeDescWidget</cstring>
+ </property>
+ <property name="caption">
+ <string>Volume Descriptor</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>m_editVolumeName</cstring>
+ </property>
+ <property name="maxLength">
+ <number>32</number>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>m_editVolumeSetName</cstring>
+ </property>
+ <property name="maxLength">
+ <number>128</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>V&amp;olume set name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editVolumeSetName</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Volume name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editVolumeName</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="3" column="1">
+ <property name="name">
+ <cstring>m_editPublisher</cstring>
+ </property>
+ <property name="maxLength">
+ <number>128</number>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="4" column="1">
+ <property name="name">
+ <cstring>m_editPreparer</cstring>
+ </property>
+ <property name="maxLength">
+ <number>128</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>P&amp;reparer:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editPreparer</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>P&amp;ublisher:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editPublisher</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Volu&amp;me set size:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_spinVolumeSetSize</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="1">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>m_spinVolumeSetSize</cstring>
+ </property>
+ <property name="specialValueText">
+ <string></string>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Volume set &amp;number:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_spinVolumeSetNumber</cstring>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>m_spinVolumeSetNumber</cstring>
+ </property>
+ <property name="specialValueText">
+ <string></string>
+ </property>
+ <property name="maxValue">
+ <number>2</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="6" column="0">
+ <property name="name">
+ <cstring>TextLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>S&amp;ystem:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editSystem</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="6" column="1">
+ <property name="name">
+ <cstring>m_editSystem</cstring>
+ </property>
+ <property name="maxLength">
+ <number>32</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="7" column="0">
+ <property name="name">
+ <cstring>TextLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Application:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_editApplication</cstring>
+ </property>
+ </widget>
+ <spacer row="12" column="1">
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="Line" row="5" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="7" column="1">
+ <property name="name">
+ <cstring>m_editApplication</cstring>
+ </property>
+ <property name="maxLength">
+ <number>128</number>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="11" column="1">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>m_editBiblio</cstring>
+ </property>
+ <property name="maxLength">
+ <number>37</number>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonFindBiblio</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select a bibliographic file from the project</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="9" column="1">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>m_editAbstract</cstring>
+ </property>
+ <property name="maxLength">
+ <number>37</number>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonFindAbstract</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select an abstract file from the project</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="10" column="1">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>m_editCopyright</cstring>
+ </property>
+ <property name="maxLength">
+ <number>37</number>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>m_buttonFindCopyright</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select a copyright file from the project</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="9" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Abstract file:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="10" column="0">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Copyright file:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="11" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Bibliographic file:</string>
+ </property>
+ </widget>
+ <widget class="Line" row="8" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<tabstops>
+ <tabstop>m_editVolumeName</tabstop>
+ <tabstop>m_editVolumeSetName</tabstop>
+ <tabstop>m_spinVolumeSetSize</tabstop>
+ <tabstop>m_spinVolumeSetNumber</tabstop>
+ <tabstop>m_editPublisher</tabstop>
+ <tabstop>m_editPreparer</tabstop>
+ <tabstop>m_editSystem</tabstop>
+ <tabstop>m_editApplication</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/projects/base_k3bmovixoptionswidget.ui b/src/projects/base_k3bmovixoptionswidget.ui
new file mode 100644
index 0000000..973dd11
--- /dev/null
+++ b/src/projects/base_k3bmovixoptionswidget.ui
@@ -0,0 +1,337 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>base_K3bMovixOptionsWidget</class>
+<author>Sebastian trueg</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>GroupBoxPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="title">
+ <string>Playback Settings</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>MPlayer subtitle fontset:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="0" column="1">
+ <property name="name">
+ <cstring>m_comboSubtitleFontset</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select the font to be used to render subtitles</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>textLabel7</cstring>
+ </property>
+ <property name="text">
+ <string>Unwanted MPlayer options:</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkRandomPlay</cstring>
+ </property>
+ <property name="text">
+ <string>Pla&amp;y files randomly</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>The files are played in random order</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;If this option is checked the order in which the files are played is determined randomly every time it is played.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkNoDma</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Do not use DMA</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Do not use DMA for media access</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;If this option is checked the resulting eMovix CD/DVD will not use DMA for accessing the drive. This will slow down reading from the CD/DVD but may be necessary on some systems that do not support DMA.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLineEdit" row="5" column="1">
+ <property name="name">
+ <cstring>m_editUnwantedMplayerOptions</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>MPlayer options you want to be sure MPlayer will not use</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;Here one can specify MPlayer options that should never be used.
+&lt;p&gt;They have to be separated by spaces:
+&lt;pre&gt;opt1 opt2 opt3&lt;/pre&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="4" column="1">
+ <property name="name">
+ <cstring>m_editAdditionalMplayerOptions</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Additional MPlayer options</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;MPlayer options that should be used in any case.
+&lt;p&gt;They have to be separated by spaces:
+&lt;pre&gt;opt1 opt2 opt3&lt;/pre&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>Additional MPlayer options:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Loop playlist:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>m_spinLoop</cstring>
+ </property>
+ <property name="suffix">
+ <string> time(s)</string>
+ </property>
+ <property name="specialValueText">
+ <string>infinity</string>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>How many times should the playlist be looped</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>m_labelAudioBackground</cstring>
+ </property>
+ <property name="text">
+ <string>Audio Player Background:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>m_comboAudioBackground</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Background video to show during audio playback</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;&lt;b&gt;Audio Player Background&lt;/b&gt;
+&lt;p&gt;During audio playback normally the screen would be black. However, if a background movie has been selected, eMovix will display it during playback.
+&lt;p&gt;Additional background movies can be installed. However, this is not as simple as a few mouse clicks. The background movies are stored in the emovix shared data folder (mostly &lt;i&gt;/usr/share/emovix&lt;/i&gt; or &lt;i&gt;/usr/local/share/emovix&lt;/i&gt;) under &lt;em&gt;backgrounds&lt;/em&gt;. So to add a background one has to copy the file to that folder.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Startup Behavior</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>m_labelKeyboardLayout</cstring>
+ </property>
+ <property name="text">
+ <string>Keyboard Layout:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>eMovix boot messages language:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="0" column="1">
+ <property name="name">
+ <cstring>m_comboBootMessageLanguage</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select the language of the eMovix help screens</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Default boot label:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="2" column="1">
+ <property name="name">
+ <cstring>m_comboDefaultBootLabel</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select the default Linux kernel configuration</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;&lt;b&gt;eMovix Boot Labels&lt;/b&gt;
+&lt;p&gt;eMovix provides are variety or different boot configurations which can be selected at boot time via a boot label (compare Lilo or Grub). The many different boot configurations mainly influence the Video output.
+&lt;p&gt;The &lt;b&gt;default&lt;/b&gt;, &lt;b&gt;movix&lt;/b&gt;, or &lt;b&gt;MoviX&lt;/b&gt; labels start a general Vesa video driver.
+&lt;p&gt;The &lt;b&gt;TV&lt;/b&gt; labels can be used to direct video to the TV output of the graphic board. eMovix provides TVout drivers for different brands of graphic boards.
+&lt;p&gt;The &lt;b&gt;FB&lt;/b&gt; labels refer to configurations that start a Frame Buffer driver in different screen resolutions.
+&lt;p&gt;The &lt;b&gt;AA&lt;/b&gt; labels make eMovix output the video through the Ascii-Art library which displays the picture in text mode through the usage of simple Acsii characters.
+&lt;p&gt;The &lt;b&gt;hd&lt;/b&gt; label makes eMovix boot from the local harddisk instead of the medium. This can be used to prevent accidental starting of an eMovix medium.
+&lt;p&gt;The &lt;b&gt;floppy&lt;/b&gt; label makes eMovix boot from the local floppy drive instead of the medium.</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>m_comboKeyboardLayout</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select the layout of the keyboard</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;The keyboard layout selected here will be used for the eMovix commands like controlling the media player.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Behavior After Playing</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkEject</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;ject disk</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Eject the disk after playing has finished</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;If this option is checked the disk will be ejected after MPlayer has finished.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkShutdown</cstring>
+ </property>
+ <property name="text">
+ <string>Sh&amp;utdown</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Shutdown after playing has finished</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;If this option is checked the PC will be shut down after MPlayer has finished playing.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_checkReboot</cstring>
+ </property>
+ <property name="text">
+ <string>Re&amp;boot</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Reboot after playing has finished</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;p&gt;If this option is checked the PC will be rebooted after MPlayer has finished playing.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>m_checkShutdown</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_checkReboot</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_checkReboot</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_checkShutdown</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kcombobox.h</includehint>
+</includehints>
+</UI>
diff --git a/src/projects/k3baudioburndialog.cpp b/src/projects/k3baudioburndialog.cpp
new file mode 100644
index 0000000..97bf318
--- /dev/null
+++ b/src/projects/k3baudioburndialog.cpp
@@ -0,0 +1,341 @@
+/*
+ *
+ * $Id: k3baudioburndialog.cpp 623768 2007-01-15 13:33:55Z 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 "k3baudioburndialog.h"
+#include "k3baudioview.h"
+#include "k3baudiotrackplayer.h"
+#include "k3baudiotrack.h"
+#include "k3baudiocdtracksource.h"
+#include <k3bcore.h>
+#include "k3baudiodoc.h"
+#include <k3bdevice.h>
+#include <k3bwriterselectionwidget.h>
+#include <k3btempdirselectionwidget.h>
+#include "k3baudiocdtextwidget.h"
+#include <k3bglobals.h>
+#include <k3bstdguiitems.h>
+#include <k3bwritingmodewidget.h>
+#include <k3bexternalbinmanager.h>
+
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qtabwidget.h>
+#include <qlayout.h>
+#include <qvariant.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qgrid.h>
+#include <qtoolbutton.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include <qpoint.h>
+#include <qhbox.h>
+#include <qspinbox.h>
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+
+
+K3bAudioBurnDialog::K3bAudioBurnDialog(K3bAudioDoc* _doc, QWidget *parent, const char *name, bool modal )
+ : K3bProjectBurnDialog( _doc, parent, name, modal ),
+ m_doc(_doc)
+{
+ prepareGui();
+
+ setTitle( i18n("Audio Project"),
+ i18n("1 track (%1 minutes)", "%n tracks (%1 minutes)",
+ m_doc->numOfTracks() ).arg(m_doc->length().toString()) );
+
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ m_optionGroupLayout->addItem( spacer );
+
+ // create cd-text page
+ m_cdtextWidget = new K3bAudioCdTextWidget( this );
+ addPage( m_cdtextWidget, i18n("CD-Text") );
+
+ // create advanced tab
+ // ----------------------------------------------------------
+ QWidget* advancedTab = new QWidget( this );
+ QGridLayout* advancedTabGrid = new QGridLayout( advancedTab );
+ advancedTabGrid->setSpacing( spacingHint() );
+ advancedTabGrid->setMargin( marginHint() );
+
+ QGroupBox* advancedSettingsGroup = new QGroupBox( 1, Qt::Vertical, i18n("Settings"), advancedTab );
+ m_checkNormalize = K3bStdGuiItems::normalizeCheckBox( advancedSettingsGroup );
+
+ QGroupBox* advancedGimmickGroup = new QGroupBox( 1, Qt::Vertical, i18n("Gimmicks"), advancedTab );
+ m_checkHideFirstTrack = new QCheckBox( i18n( "Hide first track" ), advancedGimmickGroup, "m_checkHideFirstTrack" );
+
+ m_audioRippingGroup = new QGroupBox( 3, Qt::Vertical, i18n("Audio Ripping"), advancedTab );
+ QHBox* box = new QHBox( m_audioRippingGroup );
+ box->setSpacing( spacingHint() );
+ box->setStretchFactor(new QLabel( i18n("Paranoia mode:"), box ), 1 );
+ m_comboParanoiaMode = K3bStdGuiItems::paranoiaModeComboBox( box );
+ box = new QHBox( m_audioRippingGroup );
+ box->setSpacing( spacingHint() );
+ box->setStretchFactor( new QLabel( i18n("Read retries:"), box ), 1 );
+ m_spinAudioRippingReadRetries = new QSpinBox( 1, 128, 1, box );
+ m_checkAudioRippingIgnoreReadErrors = new QCheckBox( i18n("Ignore read errors"), m_audioRippingGroup );
+
+ advancedTabGrid->addWidget( advancedSettingsGroup, 0, 0 );
+ advancedTabGrid->addWidget( advancedGimmickGroup, 1, 0 );
+ advancedTabGrid->addWidget( m_audioRippingGroup, 2, 0 );
+ advancedTabGrid->setRowStretch( 3, 1 );
+
+ addPage( advancedTab, i18n("Advanced") );
+
+ connect( m_writerSelectionWidget, SIGNAL(writingAppChanged(int)), this, SLOT(slotToggleAll()) );
+ connect( m_checkNormalize, SIGNAL(toggled(bool)), this, SLOT(slotNormalizeToggled(bool)) );
+ connect( m_checkCacheImage, SIGNAL(toggled(bool)), this, SLOT(slotCacheImageToggled(bool)) );
+ connect( m_writingModeWidget, SIGNAL(writingModeChanged(int)), this, SLOT(slotToggleAll()) );
+
+ // ToolTips
+ // -------------------------------------------------------------------------
+ QToolTip::add( m_checkHideFirstTrack, i18n("Hide the first track in the first pregap") );
+
+ // What's This info
+ // -------------------------------------------------------------------------
+ QWhatsThis::add( m_checkHideFirstTrack,
+ i18n("<p>If this option is checked K3b will <em>hide</em> the first track."
+ "<p>The audio CD standard uses pregaps before every track on the CD. "
+ "By default these last for 2 seconds and are silent. In DAO mode it "
+ "is possible to have longer pregaps that contain some audio. In this case "
+ "the first pregap will contain the complete first track."
+ "<p>You will need to seek back from the beginning of the CD to listen to "
+ "the first track. Try it, it is quite amusing."
+ "<p><b>This feature is only available in DAO mode when writing with cdrdao.") );
+}
+
+K3bAudioBurnDialog::~K3bAudioBurnDialog(){
+}
+
+
+void K3bAudioBurnDialog::slotStartClicked()
+{
+ static_cast<K3bAudioView*>(m_doc->view())->player()->stop();
+ K3bProjectBurnDialog::slotStartClicked();
+}
+
+
+void K3bAudioBurnDialog::saveSettings()
+{
+ K3bProjectBurnDialog::saveSettings();
+
+ m_doc->setTempDir( m_tempDirSelectionWidget->tempPath() );
+ m_doc->setHideFirstTrack( m_checkHideFirstTrack->isChecked() );
+ m_doc->setNormalize( m_checkNormalize->isChecked() );
+
+ // -- save Cd-Text ------------------------------------------------
+ m_cdtextWidget->save( m_doc );
+
+ // audio ripping
+ m_doc->setAudioRippingParanoiaMode( m_comboParanoiaMode->currentText().toInt() );
+ m_doc->setAudioRippingRetries( m_spinAudioRippingReadRetries->value() );
+ m_doc->setAudioRippingIgnoreReadErrors( m_checkAudioRippingIgnoreReadErrors->isChecked() );
+
+ doc()->setTempDir( m_tempDirSelectionWidget->tempPath() );
+}
+
+
+void K3bAudioBurnDialog::readSettings()
+{
+ K3bProjectBurnDialog::readSettings();
+
+ m_checkHideFirstTrack->setChecked( m_doc->hideFirstTrack() );
+ m_checkNormalize->setChecked( m_doc->normalize() );
+
+ // read CD-Text ------------------------------------------------------------
+ m_cdtextWidget->load( m_doc );
+
+ // audio ripping
+ m_comboParanoiaMode->setCurrentItem( m_doc->audioRippingParanoiaMode() );
+ m_checkAudioRippingIgnoreReadErrors->setChecked( m_doc->audioRippingIgnoreReadErrors() );
+ m_spinAudioRippingReadRetries->setValue( m_doc->audioRippingRetries() );
+
+ if( !doc()->tempDir().isEmpty() )
+ m_tempDirSelectionWidget->setTempPath( doc()->tempDir() );
+
+ toggleAll();
+}
+
+
+void K3bAudioBurnDialog::loadK3bDefaults()
+{
+ K3bProjectBurnDialog::loadK3bDefaults();
+
+ m_cdtextWidget->setChecked( true );
+ m_checkHideFirstTrack->setChecked( false );
+ m_checkNormalize->setChecked(false);
+
+ m_comboParanoiaMode->setCurrentItem( 0 );
+ m_checkAudioRippingIgnoreReadErrors->setChecked( true );
+ m_spinAudioRippingReadRetries->setValue( 5 );
+
+ toggleAll();
+}
+
+
+void K3bAudioBurnDialog::loadUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::loadUserDefaults( c );
+
+ m_cdtextWidget->setChecked( c->readBoolEntry( "cd_text", true ) );
+ m_checkHideFirstTrack->setChecked( c->readBoolEntry( "hide_first_track", false ) );
+ m_checkNormalize->setChecked( c->readBoolEntry( "normalize", false ) );
+
+ m_comboParanoiaMode->setCurrentItem( c->readNumEntry( "paranoia mode", 0 ) );
+ m_checkAudioRippingIgnoreReadErrors->setChecked( c->readBoolEntry( "ignore read errors", true ) );
+ m_spinAudioRippingReadRetries->setValue( c->readNumEntry( "read retries", 5 ) );
+
+ toggleAll();
+}
+
+
+void K3bAudioBurnDialog::saveUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::saveUserDefaults( c );
+
+ c->writeEntry( "cd_text", m_cdtextWidget->isChecked() );
+ c->writeEntry( "hide_first_track", m_checkHideFirstTrack->isChecked() );
+ c->writeEntry( "normalize", m_checkNormalize->isChecked() );
+
+ c->writeEntry( "paranoia mode", m_comboParanoiaMode->currentText() );
+ c->writeEntry( "ignore read errors", m_checkAudioRippingIgnoreReadErrors->isChecked() );
+ c->writeEntry( "read retries", m_spinAudioRippingReadRetries->value() );
+}
+
+void K3bAudioBurnDialog::toggleAll()
+{
+ K3bProjectBurnDialog::toggleAll();
+
+ bool cdrecordOnTheFly = false;
+ bool cdrecordCdText = false;
+ if ( k3bcore->externalBinManager()->binObject("cdrecord") ) {
+ cdrecordOnTheFly = k3bcore->externalBinManager()->binObject("cdrecord")->hasFeature( "audio-stdin" );
+ cdrecordCdText = k3bcore->externalBinManager()->binObject("cdrecord")->hasFeature( "cdtext" );
+ }
+
+ // cdrdao always knows onthefly and cdtext
+ bool onTheFly = true;
+ bool cdText = true;
+ if( m_writingModeWidget->writingMode() == K3b::TAO ||
+ m_writingModeWidget->writingMode() == K3b::RAW ||
+ m_writerSelectionWidget->writingApp() == K3b::CDRECORD ) {
+ onTheFly = cdrecordOnTheFly;
+ cdText = cdrecordCdText;
+ m_checkHideFirstTrack->setChecked(false);
+ m_checkHideFirstTrack->setEnabled(false);
+ }
+ else {
+ m_checkHideFirstTrack->setEnabled( !m_checkOnlyCreateImage->isChecked() );
+ m_cdtextWidget->setEnabled( !m_checkOnlyCreateImage->isChecked() );
+ }
+
+ m_checkCacheImage->setEnabled( !m_checkOnlyCreateImage->isChecked() &&
+ onTheFly );
+ if( !onTheFly )
+ m_checkCacheImage->setChecked( true );
+ m_cdtextWidget->setEnabled( !m_checkOnlyCreateImage->isChecked() &&
+ cdText &&
+ m_writingModeWidget->writingMode() != K3b::TAO );
+ if( !cdText || m_writingModeWidget->writingMode() == K3b::TAO )
+ m_cdtextWidget->setChecked(false);
+}
+
+
+void K3bAudioBurnDialog::showEvent( QShowEvent* e )
+{
+ // we only show the audio ripping options when there are audio cd track sources
+ bool showRipOptions = false;
+ if( m_doc->firstTrack() ) {
+ K3bAudioTrack* track = m_doc->firstTrack();
+ K3bAudioDataSource* source = track->firstSource();
+
+ while( source ) {
+
+ if( dynamic_cast<K3bAudioCdTrackSource*>(source) ) {
+ showRipOptions = true;
+ break;
+ }
+
+ // next source
+ source = source->next();
+ if( !source ) {
+ track = track->next();
+ if( track )
+ source = track->firstSource();
+ }
+ }
+ }
+
+ m_audioRippingGroup->setShown( showRipOptions );
+
+ K3bProjectBurnDialog::showEvent(e);
+}
+
+
+void K3bAudioBurnDialog::slotNormalizeToggled( bool on )
+{
+ if( on ) {
+ // we are not able to normalize in on-the-fly mode
+ if( !k3bcore->externalBinManager()->foundBin( "normalize-audio" ) ) {
+ KMessageBox::sorry( this, i18n("<p><b>External program <em>normalize-audio</em> is not installed.</b>"
+ "<p>K3b uses <em>normalize-audio</em> (http://www1.cs.columbia.edu/~cvaill/normalize/) "
+ "to normalize audio tracks. In order to "
+ "use this functionality, please install it first. (sudo apt-get install normalize-audio)") );
+ m_checkNormalize->setChecked( false );
+ }
+ else if( !m_checkCacheImage->isChecked() && !m_checkOnlyCreateImage->isChecked() ) {
+ if( KMessageBox::warningYesNo( this, i18n("<p>K3b is not able to normalize audio tracks when burning on-the-fly. "
+ "The external program used for this task only supports normalizing a set "
+ "of audio files."),
+ QString::null,
+ i18n("Disable normalization"),
+ i18n("Disable on-the-fly burning"),
+ "audioProjectNormalizeOrOnTheFly" ) == KMessageBox::Yes )
+ m_checkNormalize->setChecked( false );
+ else
+ m_checkCacheImage->setChecked( true );
+ }
+ }
+}
+
+
+void K3bAudioBurnDialog::slotCacheImageToggled( bool on )
+{
+ if( !on ) {
+ if( m_checkNormalize->isChecked() ) {
+ if( KMessageBox::warningYesNo( this, i18n("<p>K3b is not able to normalize audio tracks when burning on-the-fly. "
+ "The external program used for this task only supports normalizing a set "
+ "of audio files."),
+ QString::null,
+ i18n("Disable normalization"),
+ i18n("Disable on-the-fly burning"),
+ "audioProjectNormalizeOrOnTheFly" ) == KMessageBox::Yes )
+ m_checkNormalize->setChecked( false );
+ else
+ m_checkCacheImage->setChecked( true );
+ }
+ }
+}
+
+#include "k3baudioburndialog.moc"
diff --git a/src/projects/k3baudioburndialog.h b/src/projects/k3baudioburndialog.h
new file mode 100644
index 0000000..47be09f
--- /dev/null
+++ b/src/projects/k3baudioburndialog.h
@@ -0,0 +1,81 @@
+/*
+ *
+ * $Id: k3baudioburndialog.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 K3BAUDIOBURNDIALOG_H
+#define K3BAUDIOBURNDIALOG_H
+
+
+#include "k3bprojectburndialog.h"
+
+#include <qvariant.h>
+#include <qwidget.h>
+
+class QCheckBox;
+class QComboBox;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QSpinBox;
+class K3bWriterSelectionWidget;
+class K3bTempDirSelectionWidget;
+class K3bAudioDoc;
+class K3bAudioCdTextWidget;
+class QShowEvent;
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bAudioBurnDialog : public K3bProjectBurnDialog
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioBurnDialog(K3bAudioDoc* doc, QWidget *parent=0, const char *name=0, bool modal = true );
+ ~K3bAudioBurnDialog();
+
+ protected:
+ void saveSettings();
+ void readSettings();
+ void loadK3bDefaults();
+ void loadUserDefaults( KConfigBase* );
+ void saveUserDefaults( KConfigBase* );
+ void showEvent( QShowEvent* );
+ void toggleAll();
+
+ protected slots:
+ /**
+ * Reimplemented for internal reasons (shut down the audio player)
+ */
+ void slotStartClicked();
+ void slotCacheImageToggled( bool on );
+ void slotNormalizeToggled( bool on );
+
+ private:
+ /**
+ * We need this here to be able to hide/show the group
+ */
+ QGroupBox* m_audioRippingGroup;
+ QCheckBox* m_checkHideFirstTrack;
+ QCheckBox* m_checkNormalize;
+ QCheckBox* m_checkAudioRippingIgnoreReadErrors;
+ QSpinBox* m_spinAudioRippingReadRetries;
+ QComboBox* m_comboParanoiaMode;
+ K3bAudioCdTextWidget* m_cdtextWidget;
+ K3bAudioDoc* m_doc;
+};
+
+#endif
diff --git a/src/projects/k3baudiocdtextwidget.cpp b/src/projects/k3baudiocdtextwidget.cpp
new file mode 100644
index 0000000..8ee5543
--- /dev/null
+++ b/src/projects/k3baudiocdtextwidget.cpp
@@ -0,0 +1,236 @@
+/*
+ *
+ * $Id: k3baudiocdtextwidget.cpp 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.
+ */
+
+#include "k3baudiocdtextwidget.h"
+#include "base_k3baudiocdtextallfieldswidget.h"
+
+#include "k3baudiodoc.h"
+#include "k3baudiotrack.h"
+#include <k3bcdtextvalidator.h>
+
+#include <qcheckbox.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qptrlist.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+
+#include <klineedit.h>
+#include <klocale.h>
+#include <kdialogbase.h>
+#include <kiconloader.h>
+
+
+class K3bAudioCdTextWidget::AllFieldsDialog : public KDialogBase
+{
+public:
+ AllFieldsDialog( QWidget* parent )
+ : KDialogBase( parent,
+ "cdtext_allfields_dialog",
+ true,
+ i18n("CD-Text"),
+ Ok|Cancel,
+ Ok,
+ true ) {
+ w = new base_K3bAudioCdTextAllFieldsWidget( this );
+ setMainWidget( w );
+ }
+
+ base_K3bAudioCdTextAllFieldsWidget* w;
+};
+
+
+K3bAudioCdTextWidget::K3bAudioCdTextWidget( QWidget* parent, const char* name )
+ : base_K3bAudioCdTextWidget( parent, name ),
+ m_doc(0)
+{
+ m_allFieldsDlg = new AllFieldsDialog( this );
+
+ m_buttonCopyTitle->setPixmap( SmallIcon( "editcopy" ) );
+ m_buttonCopyPerformer->setPixmap( SmallIcon( "editcopy" ) );
+
+ m_allFieldsDlg->w->m_buttonCopyTitle->setPixmap( SmallIcon( "editcopy" ) );
+ m_allFieldsDlg->w->m_buttonCopyPerformer->setPixmap( SmallIcon( "editcopy" ) );
+ m_allFieldsDlg->w->m_buttonCopySongwriter->setPixmap( SmallIcon( "editcopy" ) );
+ m_allFieldsDlg->w->m_buttonCopyComposer->setPixmap( SmallIcon( "editcopy" ) );
+ m_allFieldsDlg->w->m_buttonCopyArranger->setPixmap( SmallIcon( "editcopy" ) );
+
+ QValidator* cdTextVal = new K3bCdTextValidator( this );
+ m_editTitle->setValidator( cdTextVal );
+ m_editPerformer->setValidator( cdTextVal );
+
+ m_allFieldsDlg->w->m_editTitle->setValidator( cdTextVal );
+ m_allFieldsDlg->w->m_editPerformer->setValidator( cdTextVal );
+ m_allFieldsDlg->w->m_editDisc_id->setValidator( cdTextVal );
+ m_allFieldsDlg->w->m_editUpc_ean->setValidator( cdTextVal );
+ m_allFieldsDlg->w->m_editMessage->setValidator( cdTextVal );
+ m_allFieldsDlg->w->m_editArranger->setValidator( cdTextVal );
+ m_allFieldsDlg->w->m_editSongwriter->setValidator( cdTextVal );
+ m_allFieldsDlg->w->m_editComposer->setValidator( cdTextVal );
+
+ connect( m_allFieldsDlg->w->m_buttonCopyTitle, SIGNAL(clicked()),
+ this, SLOT(slotCopyTitle()) );
+ connect( m_allFieldsDlg->w->m_buttonCopyPerformer, SIGNAL(clicked()),
+ this, SLOT(slotCopyPerformer()) );
+ connect( m_allFieldsDlg->w->m_buttonCopyArranger, SIGNAL(clicked()),
+ this, SLOT(slotCopyArranger()) );
+ connect( m_allFieldsDlg->w->m_buttonCopySongwriter, SIGNAL(clicked()),
+ this, SLOT(slotCopySongwriter()) );
+ connect( m_allFieldsDlg->w->m_buttonCopyComposer, SIGNAL(clicked()),
+ this, SLOT(slotCopyComposer()) );
+
+ connect( m_buttonMoreFields, SIGNAL(clicked()),
+ this, SLOT(slotMoreFields()) );
+}
+
+
+K3bAudioCdTextWidget::~K3bAudioCdTextWidget()
+{
+}
+
+void K3bAudioCdTextWidget::load( K3bAudioDoc* doc )
+{
+ m_doc = doc;
+ m_groupCdText->setChecked( doc->cdText() );
+
+ m_editTitle->setText( doc->title() );
+ m_editPerformer->setText( doc->artist() );
+
+ m_allFieldsDlg->w->m_editTitle->setText( doc->title() );
+ m_allFieldsDlg->w->m_editPerformer->setText( doc->artist() );
+ m_allFieldsDlg->w->m_editDisc_id->setText( doc->disc_id() );
+ m_allFieldsDlg->w->m_editUpc_ean->setText( doc->upc_ean() );
+ m_allFieldsDlg->w->m_editArranger->setText( doc->arranger() );
+ m_allFieldsDlg->w->m_editSongwriter->setText( doc->songwriter() );
+ m_allFieldsDlg->w->m_editComposer->setText( doc->composer() );
+ m_allFieldsDlg->w->m_editMessage->setText( doc->cdTextMessage() );
+}
+
+void K3bAudioCdTextWidget::save( K3bAudioDoc* doc )
+{
+ m_doc = doc;
+ doc->writeCdText( m_groupCdText->isChecked() );
+
+ // we save the title and artist values from the main view since
+ // the dialog is only updated before it is shown
+ doc->setTitle( m_editTitle->text() );
+ doc->setArtist( m_editPerformer->text() );
+ doc->setDisc_id( m_allFieldsDlg->w->m_editDisc_id->text() );
+ doc->setUpc_ean( m_allFieldsDlg->w->m_editUpc_ean->text() );
+ doc->setArranger( m_allFieldsDlg->w->m_editArranger->text() );
+ doc->setSongwriter( m_allFieldsDlg->w->m_editSongwriter->text() );
+ doc->setComposer( m_allFieldsDlg->w->m_editComposer->text() );
+ doc->setCdTextMessage( m_allFieldsDlg->w->m_editMessage->text() );
+}
+
+
+void K3bAudioCdTextWidget::slotMoreFields()
+{
+ // update dlg to current state
+ m_allFieldsDlg->w->m_editTitle->setText( m_editTitle->text() );
+ m_allFieldsDlg->w->m_editPerformer->setText( m_editPerformer->text() );
+
+ // save old settings
+ QString title = m_allFieldsDlg->w->m_editTitle->text();
+ QString performer = m_allFieldsDlg->w->m_editPerformer->text();
+ QString disc_id = m_allFieldsDlg->w->m_editDisc_id->text();
+ QString upc_ean = m_allFieldsDlg->w->m_editUpc_ean->text();
+ QString arranger = m_allFieldsDlg->w->m_editArranger->text();
+ QString songwriter = m_allFieldsDlg->w->m_editSongwriter->text();
+ QString composer = m_allFieldsDlg->w->m_editComposer->text();
+ QString message = m_allFieldsDlg->w->m_editMessage->text();
+
+ // exec dlg
+ if( m_allFieldsDlg->exec() == QDialog::Accepted ) {
+ // accept new entries
+ m_editTitle->setText( m_allFieldsDlg->w->m_editTitle->text() );
+ m_editPerformer->setText( m_allFieldsDlg->w->m_editPerformer->text() );
+ }
+ else {
+ // reset
+ m_allFieldsDlg->w->m_editTitle->setText( title );
+ m_allFieldsDlg->w->m_editPerformer->setText( performer );
+ m_allFieldsDlg->w->m_editDisc_id->setText( disc_id );
+ m_allFieldsDlg->w->m_editUpc_ean->setText( upc_ean );
+ m_allFieldsDlg->w->m_editArranger->setText( arranger );
+ m_allFieldsDlg->w->m_editSongwriter->setText( songwriter );
+ m_allFieldsDlg->w->m_editComposer->setText( composer );
+ m_allFieldsDlg->w->m_editMessage->setText( message );
+ }
+}
+
+
+void K3bAudioCdTextWidget::setChecked( bool b )
+{
+ m_groupCdText->setChecked( b );
+}
+
+bool K3bAudioCdTextWidget::isChecked() const
+{
+ return m_groupCdText->isChecked();
+}
+
+
+void K3bAudioCdTextWidget::slotCopyTitle()
+{
+ K3bAudioTrack* track = m_doc->firstTrack();
+ while( track ) {
+ track->setTitle( m_allFieldsDlg->isVisible()
+ ? m_allFieldsDlg->w->m_editTitle->text()
+ : m_editTitle->text() );
+ track = track->next();
+ }
+}
+
+void K3bAudioCdTextWidget::slotCopyPerformer()
+{
+ K3bAudioTrack* track = m_doc->firstTrack();
+ while( track ) {
+ track->setPerformer( m_allFieldsDlg->isVisible()
+ ? m_allFieldsDlg->w->m_editPerformer->text()
+ : m_editPerformer->text() );
+ track = track->next();
+ }
+}
+
+void K3bAudioCdTextWidget::slotCopyArranger()
+{
+ K3bAudioTrack* track = m_doc->firstTrack();
+ while( track ) {
+ track->setArranger( m_allFieldsDlg->w->m_editArranger->text() );
+ track = track->next();
+ }
+}
+
+void K3bAudioCdTextWidget::slotCopySongwriter()
+{
+ K3bAudioTrack* track = m_doc->firstTrack();
+ while( track ) {
+ track->setSongwriter( m_allFieldsDlg->w->m_editSongwriter->text() );
+ track = track->next();
+ }
+}
+
+void K3bAudioCdTextWidget::slotCopyComposer()
+{
+ K3bAudioTrack* track = m_doc->firstTrack();
+ while( track ) {
+ track->setComposer( m_allFieldsDlg->w->m_editComposer->text() );
+ track = track->next();
+ }
+}
+
+
+#include "k3baudiocdtextwidget.moc"
diff --git a/src/projects/k3baudiocdtextwidget.h b/src/projects/k3baudiocdtextwidget.h
new file mode 100644
index 0000000..49b579f
--- /dev/null
+++ b/src/projects/k3baudiocdtextwidget.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * $Id: k3baudiocdtextwidget.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 K3B_AUDIO_CDTEXT_WIDGET_H
+#define K3B_AUDIO_CDTEXT_WIDGET_H
+
+#include "base_k3baudiocdtextwidget.h"
+
+
+class K3bAudioDoc;
+
+
+class K3bAudioCdTextWidget : public base_K3bAudioCdTextWidget
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioCdTextWidget( QWidget* parent = 0, const char* name = 0 );
+ ~K3bAudioCdTextWidget();
+
+ bool isChecked() const;
+
+ public slots:
+ void setChecked( bool );
+ void load( K3bAudioDoc* );
+ void save( K3bAudioDoc* );
+
+ private slots:
+ void slotCopyTitle();
+ void slotCopyPerformer();
+ void slotCopyArranger();
+ void slotCopySongwriter();
+ void slotCopyComposer();
+ void slotMoreFields();
+
+ private:
+ K3bAudioDoc* m_doc;
+
+ class AllFieldsDialog;
+ AllFieldsDialog* m_allFieldsDlg;
+};
+
+#endif
diff --git a/src/projects/k3baudiodatasourceeditwidget.cpp b/src/projects/k3baudiodatasourceeditwidget.cpp
new file mode 100644
index 0000000..d54bb5d
--- /dev/null
+++ b/src/projects/k3baudiodatasourceeditwidget.cpp
@@ -0,0 +1,166 @@
+/*
+ *
+ * $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 "k3baudiodatasourceeditwidget.h"
+#include "k3baudioeditorwidget.h"
+#include <k3bmsfedit.h>
+
+#include <k3baudiodatasource.h>
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qtooltip.h>
+
+#include <klocale.h>
+#include <kdialog.h>
+
+
+K3bAudioDataSourceEditWidget::K3bAudioDataSourceEditWidget( QWidget* parent, const char* name )
+ : QWidget( parent, name ),
+ m_source(0)
+{
+ m_editor = new K3bAudioEditorWidget( this );
+ m_editStartOffset = new K3bMsfEdit( this );
+ m_editEndOffset = new K3bMsfEdit( this );
+
+ QLabel* startLabel = new QLabel( i18n("Start Offset") + ":", this );
+ QLabel* endLabel = new QLabel( i18n("End Offset") + ":", this );
+ endLabel->setAlignment( Qt::AlignRight );
+
+ QGridLayout* grid = new QGridLayout( this );
+ grid->setMargin( 0 );
+ grid->setSpacing( KDialog::spacingHint() );
+
+ grid->addWidget( startLabel, 0, 0 );
+ grid->addWidget( m_editStartOffset, 1, 0 );
+ grid->addMultiCellWidget( m_editor, 0, 1, 1, 1 );
+ grid->addWidget( endLabel, 0, 2 );
+ grid->addWidget( m_editEndOffset, 1, 2 );
+ grid->setColStretch( 1, 1 );
+
+ // setup connections between the msfedits and the editor
+ connect( m_editor, SIGNAL(rangeChanged(int, const K3b::Msf&, const K3b::Msf&)),
+ this, SLOT(slotRangeModified(int, const K3b::Msf&, const K3b::Msf&)) );
+
+ connect( m_editStartOffset, SIGNAL(valueChanged(const K3b::Msf&)),
+ this, SLOT(slotStartOffsetEdited(const K3b::Msf&)) );
+
+ connect( m_editEndOffset, SIGNAL(valueChanged(const K3b::Msf&)),
+ this, SLOT(slotEndOffsetEdited(const K3b::Msf&)) );
+
+ QToolTip::add( m_editor, i18n("Drag the edges of the highlighted area to define the portion of the "
+ "audio source you want to include in the Audio CD track. "
+ "You can also use the input windows to fine-tune your selection.") );
+}
+
+
+K3bAudioDataSourceEditWidget::~K3bAudioDataSourceEditWidget()
+{
+}
+
+
+K3b::Msf K3bAudioDataSourceEditWidget::startOffset() const
+{
+ return m_editor->rangeStart( m_rangeId );
+}
+
+
+K3b::Msf K3bAudioDataSourceEditWidget::endOffset() const
+{
+ return m_editor->rangeEnd( m_rangeId );
+}
+
+
+void K3bAudioDataSourceEditWidget::loadSource( K3bAudioDataSource* source )
+{
+ m_source = source;
+
+ // remove old range
+ m_editor->removeRange( m_rangeId );
+
+ // and add the proper new range
+ // the source's end offset points after the last sector while
+ // the editor widget returns the last used sector
+ m_editor->setLength( source->originalLength() );
+ m_rangeId = m_editor->addRange( source->startOffset(),
+ source->endOffset() == 0
+ ? source->originalLength()-1
+ : source->endOffset()-1,
+ false,
+ false,
+ i18n("Used part of the audio source"),
+ colorGroup().highlight() );
+
+ m_editStartOffset->setMaxValue( source->originalLength().lba() );
+ m_editEndOffset->setMaxValue( source->originalLength().lba() );
+
+ m_editStartOffset->setMsfValue( startOffset() );
+ m_editEndOffset->setMsfValue( endOffset() );
+}
+
+
+void K3bAudioDataSourceEditWidget::saveSource()
+{
+ if( m_source ) {
+ m_source->setStartOffset( startOffset() );
+ // the source's end offset points after the last sector while
+ // the editor widget returns the last used sector
+ m_source->setEndOffset( endOffset()+1 );
+ }
+}
+
+
+void K3bAudioDataSourceEditWidget::setStartOffset( const K3b::Msf& msf )
+{
+ if( m_source ) {
+ m_editor->modifyRange( m_rangeId,
+ msf,
+ endOffset() );
+ }
+}
+
+
+void K3bAudioDataSourceEditWidget::setEndOffset( const K3b::Msf& msf )
+{
+ if( m_source ) {
+ m_editor->modifyRange( m_rangeId,
+ startOffset(),
+ msf );
+ }
+}
+
+
+void K3bAudioDataSourceEditWidget::slotRangeModified( int, const K3b::Msf& start, const K3b::Msf& end )
+{
+ m_editStartOffset->setMsfValue( start );
+ m_editEndOffset->setMsfValue( end );
+}
+
+void K3bAudioDataSourceEditWidget::slotStartOffsetEdited( const K3b::Msf& msf )
+{
+ if( m_source ) {
+ m_editor->modifyRange( m_rangeId, msf, endOffset() );
+ }
+}
+
+
+void K3bAudioDataSourceEditWidget::slotEndOffsetEdited( const K3b::Msf& msf )
+{
+ if( m_source ) {
+ m_editor->modifyRange( m_rangeId, startOffset(), msf );
+ }
+}
+
+#include "k3baudiodatasourceeditwidget.moc"
diff --git a/src/projects/k3baudiodatasourceeditwidget.h b/src/projects/k3baudiodatasourceeditwidget.h
new file mode 100644
index 0000000..4c9d1cb
--- /dev/null
+++ b/src/projects/k3baudiodatasourceeditwidget.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * $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_AUDIODATASOURCE_EDITWIDGET_H_
+#define _K3B_AUDIODATASOURCE_EDITWIDGET_H_
+
+#include <qwidget.h>
+#include <k3bmsf.h>
+
+class K3bAudioDataSource;
+class K3bAudioEditorWidget;
+class K3bMsfEdit;
+
+/**
+ * Widget to modify the start and end offset of a source or simply change
+ * the length of a silence source.
+ */
+class K3bAudioDataSourceEditWidget : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioDataSourceEditWidget( QWidget* parent = 0, const char* name = 0 );
+ ~K3bAudioDataSourceEditWidget();
+
+ K3b::Msf startOffset() const;
+
+ /**
+ * Highest value (mening to use all the data up to the end of the source)
+ * is source::originalLength().
+ *
+ * Be aware that this differs from K3bAudioDataSource::endOffset() which
+ * points after the last used sector for internal reasons.
+ */
+ K3b::Msf endOffset() const;
+
+ public slots:
+ void loadSource( K3bAudioDataSource* );
+ void saveSource();
+
+ void setStartOffset( const K3b::Msf& );
+ void setEndOffset( const K3b::Msf& );
+
+ private slots:
+ void slotRangeModified( int, const K3b::Msf&, const K3b::Msf& );
+ void slotStartOffsetEdited( const K3b::Msf& );
+ void slotEndOffsetEdited( const K3b::Msf& );
+
+ private:
+ K3bAudioDataSource* m_source;
+ int m_rangeId;
+
+ K3bAudioEditorWidget* m_editor;
+ K3bMsfEdit* m_editStartOffset;
+ K3bMsfEdit* m_editEndOffset;
+};
+
+#endif
diff --git a/src/projects/k3baudiodatasourceviewitem.cpp b/src/projects/k3baudiodatasourceviewitem.cpp
new file mode 100644
index 0000000..6cf3004
--- /dev/null
+++ b/src/projects/k3baudiodatasourceviewitem.cpp
@@ -0,0 +1,111 @@
+/*
+ *
+ * $Id: k3baudiodatasourceviewitem.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2004 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 "k3baudiodatasourceviewitem.h"
+#include "k3baudiodatasource.h"
+#include "k3baudiotrackviewitem.h"
+#include "k3baudiozerodata.h"
+
+#include <k3bmsf.h>
+
+#include <kiconloader.h>
+
+
+K3bAudioDataSourceViewItem::K3bAudioDataSourceViewItem( K3bAudioTrackViewItem* parent,
+ K3bAudioDataSourceViewItem* after,
+ K3bAudioDataSource* source )
+ : K3bListViewItem( parent, after ),
+ m_trackViewItem( parent ),
+ m_source( source ),
+ m_animationCounter(1)
+{
+ // italic type
+ QFont f(listView()->font());
+ f.setItalic( true );
+ setFont( 3, f );
+
+ // setMarginVertical( 2 );
+
+ // gray out filename
+ setForegroundColor( 5, listView()->palette().disabled().foreground() );
+
+ // smaller filename
+ f = listView()->font();
+ f.setPointSize( f.pointSize() - 2 );
+ setFont( 5, f );
+
+ // for zero items we make the length editable
+ if( dynamic_cast<K3bAudioZeroData*>( source ) )
+ setEditor( 4, MSF );
+}
+
+
+QString K3bAudioDataSourceViewItem::text( int i ) const
+{
+ switch( i ) {
+ case 3:
+ return m_source->type();
+ case 4:
+ return m_source->length().toString();
+ case 5:
+ return m_source->sourceComment();
+ default:
+ return QString::null;
+ }
+}
+
+
+void K3bAudioDataSourceViewItem::setText( int col, const QString& text )
+{
+ //
+ // See K3bAudioTrackViewItem::setText for an explanation why we have to check if
+ // the value really changed
+ //
+ if( col == 4 ) {
+ if( K3bAudioZeroData* zero = dynamic_cast<K3bAudioZeroData*>( source() ) ) {
+ bool ok;
+ K3b::Msf f = K3b::Msf::fromString( text, &ok );
+ if( ok && f != zero->length() )
+ zero->setLength( f );
+ }
+ }
+ else
+ KListViewItem::setText( col, text );
+}
+
+
+bool K3bAudioDataSourceViewItem::animate()
+{
+ if( source()->length() == 0 && source()->isValid() ) {
+ QString icon = QString( "kde%1" ).arg( m_animationCounter );
+ setPixmap( 4, SmallIcon( icon ) );
+ m_animationCounter++;
+ if ( m_animationCounter > 6 )
+ m_animationCounter = 1;
+ return true;
+ }
+ else {
+ // set status icon
+ setPixmap( 4, ( source()->isValid() ? SmallIcon( "greenled" ) : SmallIcon( "redled" ) ) );
+ return false;
+ }
+}
+
+
+void K3bAudioDataSourceViewItem::setSelected( bool s )
+{
+ if( s || !m_trackViewItem->isSelected() )
+ K3bListViewItem::setSelected(s);
+}
diff --git a/src/projects/k3baudiodatasourceviewitem.h b/src/projects/k3baudiodatasourceviewitem.h
new file mode 100644
index 0000000..14da1de
--- /dev/null
+++ b/src/projects/k3baudiodatasourceviewitem.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * $Id: k3baudiodatasourceviewitem.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2004 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_DATA_SOURCE_VIEWITEM_H_
+#define _K3B_AUDIO_DATA_SOURCE_VIEWITEM_H_
+
+#include <k3blistview.h>
+
+class K3bAudioTrack;
+class K3bAudioDataSource;
+class K3bAudioTrackViewItem;
+
+class K3bAudioDataSourceViewItem : public K3bListViewItem
+{
+ public:
+ K3bAudioDataSourceViewItem( K3bAudioTrackViewItem* parent,
+ K3bAudioDataSourceViewItem* after,
+ K3bAudioDataSource* );
+
+ K3bAudioDataSource* source() const { return m_source; }
+ K3bAudioTrackViewItem* trackViewItem() const { return m_trackViewItem; }
+
+ QString text( int i ) const;
+ void setText( int col, const QString& text );
+
+ bool animate();
+
+ void setSelected( bool s );
+
+ /**
+ * Does nothing becasue we don't want no branches here.
+ */
+ void paintBranches( QPainter*, const QColorGroup &,
+ int, int, int ) {}
+
+ private:
+ K3bAudioTrackViewItem* m_trackViewItem;
+ K3bAudioDataSource* m_source;
+ int m_animationCounter;
+};
+
+#endif
diff --git a/src/projects/k3baudioeditorwidget.cpp b/src/projects/k3baudioeditorwidget.cpp
new file mode 100644
index 0000000..453f76f
--- /dev/null
+++ b/src/projects/k3baudioeditorwidget.cpp
@@ -0,0 +1,877 @@
+/*
+ *
+ * $Id: k3baudioeditorwidget.cpp 630444 2007-02-05 12:43:19Z trueg $
+ * Copyright (C) 2004-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 "k3baudioeditorwidget.h"
+
+#include <qpainter.h>
+#include <qcolor.h>
+#include <qpixmap.h>
+#include <qcursor.h>
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#include <qtooltip.h>
+
+
+
+class K3bAudioEditorWidget::Range
+{
+public:
+ Range( int i,
+ const K3b::Msf& s,
+ const K3b::Msf& e,
+ bool sf,
+ bool ef,
+ const QString& t,
+ const QBrush& b )
+ : id(i),
+ start(s),
+ end(e),
+ startFixed(sf),
+ endFixed(ef),
+ brush(b),
+ toolTip(t) {
+ }
+
+ int id;
+ K3b::Msf start;
+ K3b::Msf end;
+ bool startFixed;
+ bool endFixed;
+ QBrush brush;
+ QString toolTip;
+
+ bool operator<( const K3bAudioEditorWidget::Range& r ) {
+ return start < r.start;
+ }
+ bool operator>( const K3bAudioEditorWidget::Range& r ) {
+ return start > r.start;
+ }
+ bool operator==( const K3bAudioEditorWidget::Range& r ) {
+ return start == r.start;
+ }
+};
+
+
+class K3bAudioEditorWidget::Marker
+{
+public:
+ Marker( int i,
+ const K3b::Msf& msf,
+ bool f,
+ const QColor& c,
+ const QString& t )
+ : id(i),
+ pos(msf),
+ fixed(f),
+ color(c),
+ toolTip(t) {
+ }
+
+ int id;
+ K3b::Msf pos;
+ bool fixed;
+ QColor color;
+ QString toolTip;
+
+ operator K3b::Msf& () { return pos; }
+};
+
+
+class K3bAudioEditorWidget::RangeList : public QPtrList<K3bAudioEditorWidget::Range>
+{
+public:
+ RangeList()
+ : QPtrList<Range>() {
+ }
+
+ RangeList( const RangeList& l )
+ : QPtrList<Range>( l ) {
+ }
+
+ int compareItems( QPtrCollection::Item item1, QPtrCollection::Item item2 ) {
+ if( *static_cast<Range*>(item1) > *static_cast<Range*>(item2) )
+ return 1;
+ else if( *static_cast<Range*>(item1) < *static_cast<Range*>(item2) )
+ return -1;
+ else
+ return 0;
+ }
+};
+
+class K3bAudioEditorWidget::ToolTip : public QToolTip
+{
+public:
+ ToolTip( K3bAudioEditorWidget* w )
+ : QToolTip( w ),
+ m_editorWidget( w ) {
+ }
+
+protected:
+ void maybeTip( const QPoint& p ) {
+ QRect r = m_editorWidget->contentsRect();
+ Marker* m = m_editorWidget->findMarker( p );
+ if( m ) {
+ r.setLeft( p.x() - 1 );
+ r.setRight( p.x() + 1 );
+ tip( r, m->toolTip.isEmpty() ? m->pos.toString() : QString("%1 (%2)").arg(m->toolTip).arg(m->pos.toString()) );
+ }
+ else {
+ Range* range = m_editorWidget->findRange( p );
+ if( range ) {
+ r.setLeft( m_editorWidget->msfToPos( range->start ) );
+ r.setRight( m_editorWidget->msfToPos( range->end ) );
+ tip( r,
+ range->toolTip.isEmpty()
+ ? QString("%1 - %2").arg(range->start.toString()).arg(range->end.toString())
+ : QString("%1 (%2 - %3)").arg(range->toolTip).arg(range->start.toString()).arg(range->end.toString()) );
+ }
+ }
+ }
+
+private:
+ K3bAudioEditorWidget* m_editorWidget;
+};
+
+
+class K3bAudioEditorWidget::Private
+{
+public:
+ Private()
+ : allowOverlappingRanges(true),
+ rangeSelectionEnabled(false),
+ selectedRange(0),
+ movedRange(0) {
+ }
+
+ QBrush selectedRangeBrush;
+
+ bool allowOverlappingRanges;
+ bool rangeSelectionEnabled;
+
+ Range* selectedRange;
+ Range* movedRange;
+ K3b::Msf lastMovePosition;
+
+ RangeList ranges;
+};
+
+
+K3bAudioEditorWidget::K3bAudioEditorWidget( QWidget* parent, const char* name )
+ : QFrame( parent, name, Qt::WNoAutoErase ),
+ m_maxMarkers(1),
+ m_idCnt(1),
+ m_mouseAt(true),
+ m_draggedRange(0),
+ m_draggedMarker(0)
+{
+ d = new Private;
+ d->selectedRangeBrush = colorGroup().highlight();
+
+ setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum );
+ setFrameStyle( StyledPanel|Sunken );
+ setMouseTracking(true);
+ setCursor( Qt::PointingHandCursor );
+
+ m_margin = 5;
+
+ m_toolTip = new ToolTip( this );
+}
+
+
+K3bAudioEditorWidget::~K3bAudioEditorWidget()
+{
+ d->ranges.setAutoDelete(true);
+ m_markers.setAutoDelete(true);
+ d->ranges.clear();
+ m_markers.clear();
+
+ delete d;
+}
+
+
+QSize K3bAudioEditorWidget::minimumSizeHint() const
+{
+ constPolish();
+ // some fixed height minimum and enough space for a tickmark every minute
+ // But never exceed 2/3 of the the screen width, otherwise it just looks ugly
+ // FIXME: this is still bad for long sources and there might be 60 minutes sources!
+
+ int maxWidth = QApplication::desktop()->width()*2/3;
+ int wantedWidth = 2*m_margin + 2*frameWidth() + (m_length.totalFrames()/75/60 + 1) * fontMetrics().width( "000" );
+ return QSize( QMIN( maxWidth, wantedWidth ),
+ 2*m_margin + 12 + 6 /*12 for the tickmarks and 6 for the markers */ + fontMetrics().height() + 2*frameWidth() );
+}
+
+
+QSize K3bAudioEditorWidget::sizeHint() const
+{
+ return minimumSizeHint();
+}
+
+
+void K3bAudioEditorWidget::setLength( const K3b::Msf& length )
+{
+ m_length = length;
+ // TODO: remove markers beyond length
+ // TODO: shorten ranges if nesseccary
+ update();
+}
+
+
+const K3b::Msf K3bAudioEditorWidget::length() const
+{
+ return m_length;
+}
+
+
+void K3bAudioEditorWidget::setSelectedRangeBrush( const QBrush& b )
+{
+ d->selectedRangeBrush = b;
+}
+
+
+const QBrush& K3bAudioEditorWidget::selectedRangeBrush() const
+{
+ return d->selectedRangeBrush;
+}
+
+
+void K3bAudioEditorWidget::setAllowOverlappingRanges( bool b )
+{
+ d->allowOverlappingRanges = b;
+}
+
+
+bool K3bAudioEditorWidget::allowOverlappingRanges() const
+{
+ return d->allowOverlappingRanges;
+}
+
+
+void K3bAudioEditorWidget::enableRangeSelection( bool b )
+{
+ d->rangeSelectionEnabled = b;
+ repaint( false );
+}
+
+
+bool K3bAudioEditorWidget::rangeSelectedEnabled() const
+{
+ return d->selectedRange;
+}
+
+
+void K3bAudioEditorWidget::setSelectedRange( int id )
+{
+ setSelectedRange( getRange( id ) );
+}
+
+
+void K3bAudioEditorWidget::setSelectedRange( K3bAudioEditorWidget::Range* r )
+{
+ d->selectedRange = r;
+ if( rangeSelectedEnabled() ) {
+ repaint( false );
+ emit selectedRangeChanged( d->selectedRange ? d->selectedRange->id : 0 );
+ }
+}
+
+
+int K3bAudioEditorWidget::selectedRange() const
+{
+ if( d->selectedRange )
+ return d->selectedRange->id;
+ else
+ return 0;
+}
+
+
+int K3bAudioEditorWidget::addRange( const K3b::Msf& start, const K3b::Msf& end,
+ bool startFixed, bool endFixed,
+ const QString& toolTip,
+ const QBrush& brush )
+{
+ if( start > end || end > m_length-1 )
+ return -1;
+
+ Range* r = new Range( m_idCnt++, start, end, startFixed, endFixed, toolTip,
+ brush.style() != QBrush::NoBrush ? brush : QBrush(colorGroup().background()) );
+ d->ranges.inSort( r );
+
+ // only update the changed range
+ QRect rect = contentsRect();
+ rect.setLeft( msfToPos( start ) );
+ rect.setRight( msfToPos( end ) );
+ update( rect );
+
+ return r->id;
+}
+
+
+int K3bAudioEditorWidget::findRange( int pos ) const
+{
+ Range* r = findRange( QPoint( pos, 0 ) );
+ if( r )
+ return r->id;
+ else
+ return 0;
+}
+
+
+int K3bAudioEditorWidget::findRangeEdge( int pos, bool* end ) const
+{
+ Range* r = findRangeEdge( QPoint( pos, 0 ), end );
+ if( r )
+ return r->id;
+ else
+ return 0;
+}
+
+
+bool K3bAudioEditorWidget::modifyRange( int identifier, const K3b::Msf& start, const K3b::Msf& end )
+{
+ Range* range = getRange( identifier );
+ if( range ) {
+ if( start > end )
+ return false;
+
+ if( end > m_length )
+ return false;
+
+ range->start = start;
+ range->end = end;
+
+ if( !d->allowOverlappingRanges )
+ fixupOverlappingRanges( range );
+
+ repaint( false );
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
+bool K3bAudioEditorWidget::removeRange( int identifier )
+{
+ if( Range* range = getRange( identifier ) ) {
+ d->ranges.removeRef( range );
+
+ emit rangeRemoved( identifier );
+
+ // repaint only the part of the range
+ QRect rect = contentsRect();
+ rect.setLeft( msfToPos( range->start ) );
+ rect.setRight( msfToPos( range->end ) );
+
+ if( d->selectedRange == range )
+ setSelectedRange( 0 );
+
+ delete range;
+
+ update( rect );
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
+K3b::Msf K3bAudioEditorWidget::rangeStart( int identifier ) const
+{
+ if( Range* range = getRange( identifier ) )
+ return range->start;
+ else
+ return 0;
+}
+
+
+K3b::Msf K3bAudioEditorWidget::rangeEnd( int identifier ) const
+{
+ if( Range* range = getRange( identifier ) )
+ return range->end;
+ else
+ return 0;
+}
+
+
+QValueList<int> K3bAudioEditorWidget::allRanges() const
+{
+ QValueList<int> l;
+ d->ranges.sort();
+ for( QPtrListIterator<Range> it( d->ranges ); *it; ++it )
+ l.append( (*it)->id );
+ return l;
+}
+
+
+void K3bAudioEditorWidget::setMaxNumberOfMarkers( int i )
+{
+ m_maxMarkers = i;
+
+ // remove last markers
+ while( m_markers.count() > QMAX( 1, m_maxMarkers ) ) {
+ removeMarker( m_markers.getLast()->id );
+ }
+}
+
+
+int K3bAudioEditorWidget::addMarker( const K3b::Msf& pos, bool fixed, const QString& toolTip, const QColor& color )
+{
+ if( pos < m_length ) {
+ Marker* m = new Marker( m_idCnt++, pos, fixed, color.isValid() ? color : colorGroup().foreground(), toolTip );
+ m_markers.inSort( m );
+ return m->id;
+ }
+ else
+ return -1;
+}
+
+
+bool K3bAudioEditorWidget::removeMarker( int identifier )
+{
+ if( Marker* m = getMarker( identifier ) ) {
+ m_markers.removeRef( m );
+
+ emit markerRemoved( identifier );
+
+ // TODO: in case a marker is bigger than one pixel this needs to be changed
+ QRect rect = contentsRect();
+ rect.setLeft( msfToPos( m->pos ) );
+ rect.setRight( msfToPos( m->pos ) );
+ delete m;
+
+ update( rect );
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
+bool K3bAudioEditorWidget::moveMarker( int identifier, const K3b::Msf& pos )
+{
+ if( pos < m_length )
+ if( Marker* m = getMarker( identifier ) ) {
+ QRect rect = contentsRect();
+ rect.setLeft( QMIN( msfToPos( pos ), msfToPos( m->pos ) ) );
+ rect.setRight( QMAX( msfToPos( pos ), msfToPos( m->pos ) ) );
+
+ m->pos = pos;
+
+ // TODO: in case a marker is bigger than one pixel this needs to be changed
+ update( rect );
+
+ return true;
+ }
+
+ return false;
+}
+
+
+void K3bAudioEditorWidget::drawContents( QPainter* p )
+{
+ // double buffering
+ QPixmap pix( contentsRect().size() );
+ pix.fill( colorGroup().base() );
+
+ QPainter pixP;
+ pixP.begin( &pix, this );
+
+ QRect drawRect( contentsRect() );
+ drawRect.setLeft( drawRect.left() + m_margin );
+ drawRect.setRight( drawRect.right() - m_margin );
+
+ // from minimumSizeHint()
+// int neededHeight = fontMetrics().height() + 12 + 6;
+
+// drawRect.setTop( drawRect.top() + (drawRect.height() - neededHeight)/2 );
+// drawRect.setHeight( neededHeight );
+
+ drawRect.setTop( drawRect.top() + m_margin );
+ drawRect.setBottom( drawRect.bottom() - m_margin );
+
+ drawAll( &pixP, drawRect );
+
+ pixP.end();
+
+ QRect rect = p->clipRegion().boundingRect();
+ QRect pixRect = rect;
+ pixRect.moveBy( -1*frameWidth(), -1*frameWidth() );
+ bitBlt( this, rect.topLeft(), &pix, pixRect );
+}
+
+
+void K3bAudioEditorWidget::drawAll( QPainter* p, const QRect& drawRect )
+{
+ // we simply draw the ranges one after the other.
+ for( QPtrListIterator<Range> it( d->ranges ); *it; ++it )
+ drawRange( p, drawRect, *it );
+
+ // Hack to make sure the currently selected range is always on top
+ if( d->selectedRange )
+ drawRange( p, drawRect, d->selectedRange );
+
+ for( QPtrListIterator<Marker> it( m_markers ); *it; ++it )
+ drawMarker( p, drawRect, *it );
+
+
+ // left vline
+ p->drawLine( drawRect.left(), drawRect.top(),
+ drawRect.left(), drawRect.bottom() );
+
+ // timeline
+ p->drawLine( drawRect.left(), drawRect.bottom(),
+ drawRect.right(), drawRect.bottom() );
+
+ // right vline
+ p->drawLine( drawRect.right(), drawRect.top(),
+ drawRect.right(), drawRect.bottom() );
+
+ // draw minute markers every minute
+ int minute = 1;
+ int minuteStep = 1;
+ int markerVPos = drawRect.bottom();
+ int maxMarkerWidth = fontMetrics().width( QString::number(m_length.minutes()) );
+ int minNeededSpace = maxMarkerWidth + 1;
+ int x = 0;
+ while( minute*60*75 < m_length ) {
+ int newX = msfToPos( minute*60*75 );
+
+ // only draw the mark if we have anough space
+ if( newX - x >= minNeededSpace ) {
+ p->drawLine( newX, markerVPos, newX, markerVPos-5 );
+ QRect txtRect( newX-(maxMarkerWidth/2),
+ markerVPos - 6 - fontMetrics().height(),
+ maxMarkerWidth,
+ fontMetrics().height() );
+ p->drawText( txtRect, Qt::AlignCenter, QString::number(minute) );
+
+ // FIXME: draw second markers if we have enough space
+
+ x = newX;
+ }
+ else {
+ minute -= minuteStep;
+ if( minuteStep == 1 )
+ minuteStep = 5;
+ else
+ minuteStep *= 2;
+ }
+
+ minute += minuteStep;
+ }
+}
+
+
+void K3bAudioEditorWidget::drawRange( QPainter* p, const QRect& drawRect, K3bAudioEditorWidget::Range* r )
+{
+ p->save();
+
+ int start = msfToPos( r->start );
+ int end = msfToPos( r->end );
+
+ if( rangeSelectedEnabled() && r == d->selectedRange )
+ p->fillRect( start, drawRect.top() + 6 , end-start+1, drawRect.height() - 6, selectedRangeBrush() );
+ else
+ p->fillRect( start, drawRect.top() + 6 , end-start+1, drawRect.height() - 6, r->brush );
+
+ p->drawRect( start, drawRect.top() + 6 , end-start+1, drawRect.height() - 6 );
+
+ p->restore();
+}
+
+
+void K3bAudioEditorWidget::drawMarker( QPainter* p, const QRect& drawRect, K3bAudioEditorWidget::Marker* m )
+{
+ p->save();
+
+ p->setPen( m->color );
+ p->setBrush( m->color );
+
+ int x = msfToPos( m->pos );
+ p->drawLine( x, drawRect.bottom(), x, drawRect.top() );
+
+ QPointArray points( 3 );
+ points.setPoint( 0, x, drawRect.top() + 6 );
+ points.setPoint( 1, x-3, drawRect.top() );
+ points.setPoint( 2, x+3, drawRect.top() );
+ p->drawPolygon( points );
+
+ p->restore();
+}
+
+
+void K3bAudioEditorWidget::fixupOverlappingRanges( Range* r )
+{
+ // copy the list to avoid problems with the iterator
+ RangeList ranges( d->ranges );
+ for( QPtrListIterator<Range> it( ranges ); *it; ++it ) {
+ Range* range = *it;
+ if( range != r ) {
+ // remove the range if it is covered completely
+ if( range->start >= r->start &&
+ range->end <= r->end ) {
+ d->ranges.removeRef( range );
+ emit rangeRemoved( range->id );
+ if( d->selectedRange == range )
+ setSelectedRange( 0 );
+ delete range;
+ }
+ // split the range if it contains r completely
+ else if( r->start >= range->start &&
+ r->end <= range->end ) {
+ // create a new range that spans the part after r
+ addRange( r->end+1, range->end,
+ range->startFixed, range->endFixed,
+ range->toolTip,
+ range->brush );
+
+ // modify the old range to only span the part before r
+ range->end = r->start-1;
+ emit rangeChanged( range->id, range->start, range->end );
+ }
+ else if( range->start >= r->start && range->start <= r->end ) {
+ range->start = r->end+1;
+ emit rangeChanged( range->id, range->start, range->end );
+ }
+ else if( range->end >= r->start && range->end <= r->end ) {
+ range->end = r->start-1;
+ emit rangeChanged( range->id, range->start, range->end );
+ }
+ }
+ }
+}
+
+
+void K3bAudioEditorWidget::mousePressEvent( QMouseEvent* e )
+{
+ m_draggedRange = 0;
+ m_draggedMarker = 0;
+
+ bool end;
+ if( Range* r = findRangeEdge( e->pos(), &end ) ) {
+ m_draggedRange = r;
+ m_draggingRangeEnd = end;
+ setSelectedRange( r );
+ }
+ else {
+ Range* r = findRange( e->pos() );
+ d->movedRange = r;
+ d->lastMovePosition = posToMsf( e->pos().x() );
+ setSelectedRange( r );
+ m_draggedMarker = findMarker( e->pos() );
+ }
+
+ QFrame::mousePressEvent(e);
+}
+
+
+void K3bAudioEditorWidget::mouseReleaseEvent( QMouseEvent* e )
+{
+ if( !d->allowOverlappingRanges ) {
+ //
+ // modify and even delete ranges that we touched
+ //
+ if( m_draggedRange ) {
+ fixupOverlappingRanges( m_draggedRange );
+ repaint( false );
+ }
+ else if( d->movedRange ) {
+ fixupOverlappingRanges( d->movedRange );
+ repaint( false );
+ }
+ }
+
+ m_draggedRange = 0;
+ m_draggedMarker = 0;
+ d->movedRange = 0;
+
+ QFrame::mouseReleaseEvent(e);
+}
+
+
+void K3bAudioEditorWidget::mouseDoubleClickEvent( QMouseEvent* e )
+{
+ QFrame::mouseDoubleClickEvent(e);
+}
+
+
+void K3bAudioEditorWidget::mouseMoveEvent( QMouseEvent* e )
+{
+ if( m_mouseAt )
+ emit mouseAt( posToMsf( e->pos().x() ) );
+
+ if( e->state() & Qt::LeftButton ) {
+ if( m_draggedRange ) {
+ // determine the position the range's end was dragged to and its other end
+ K3b::Msf msfPos = QMAX( 0, QMIN( posToMsf( e->pos().x() ), m_length-1 ) );
+ K3b::Msf otherEnd = ( m_draggingRangeEnd ? m_draggedRange->start : m_draggedRange->end );
+
+ // move it to the new pos
+ if( m_draggingRangeEnd )
+ m_draggedRange->end = msfPos;
+ else
+ m_draggedRange->start = msfPos;
+
+ // if we pass the other end switch them
+ if( m_draggedRange->start > m_draggedRange->end ) {
+ K3b::Msf buf = m_draggedRange->start;
+ m_draggedRange->start = m_draggedRange->end;
+ m_draggedRange->end = buf;
+ m_draggingRangeEnd = !m_draggingRangeEnd;
+ }
+
+ emit rangeChanged( m_draggedRange->id, m_draggedRange->start, m_draggedRange->end );
+
+ repaint( false );
+ }
+ else if( m_draggedMarker ) {
+ m_draggedMarker->pos = posToMsf( e->pos().x() );
+ emit markerMoved( m_draggedMarker->id, m_draggedMarker->pos );
+
+ repaint( false );
+ }
+ else if( d->movedRange ) {
+ int diff = posToMsf( e->pos().x() ).lba() - d->lastMovePosition.lba();
+ if( d->movedRange->end + diff >= m_length )
+ diff = m_length.lba() - d->movedRange->end.lba() - 1;
+ else if( d->movedRange->start - diff < 0 )
+ diff = -1 * d->movedRange->start.lba();
+ d->movedRange->start += diff;
+ d->movedRange->end += diff;
+
+// if( !d->allowOverlappingRanges )
+// fixupOverlappingRanges( d->movedRange );
+
+ d->lastMovePosition = posToMsf( e->pos().x() );
+
+ emit rangeChanged( d->movedRange->id, d->movedRange->start, d->movedRange->end );
+
+ repaint( false );
+ }
+ }
+ else if( findRangeEdge( e->pos() ) || findMarker( e->pos() ) )
+ setCursor( Qt::SizeHorCursor );
+ else
+ setCursor( Qt::PointingHandCursor );
+
+ QFrame::mouseMoveEvent(e);
+}
+
+
+K3bAudioEditorWidget::Range* K3bAudioEditorWidget::getRange( int i ) const
+{
+ for( QPtrListIterator<Range> it( d->ranges ); *it; ++it )
+ if( (*it)->id == i )
+ return *it;
+
+ return 0;
+}
+
+
+K3bAudioEditorWidget::Range* K3bAudioEditorWidget::findRange( const QPoint& p ) const
+{
+ // TODO: binary search; maybe store start and end positions in sorted lists for quick searching
+ // this might be a stupid approach but we do not have many ranges anyway
+ for( QPtrListIterator<Range> it( d->ranges ); *it; ++it ) {
+ Range* range = *it;
+ int start = msfToPos( range->start );
+ int end = msfToPos( range->end );
+
+ if( p.x() >= start && p.x() <= end ) {
+ return range;
+ }
+ }
+ return 0;
+}
+
+
+K3bAudioEditorWidget::Range* K3bAudioEditorWidget::findRangeEdge( const QPoint& p, bool* isEnd ) const
+{
+ // TODO: binary search
+ // this might be a stupid approach but we do not have many ranges anyway
+ for( QPtrListIterator<Range> it( d->ranges ); *it; ++it ) {
+ Range* range = *it;
+ int start = msfToPos( range->start );
+ int end = msfToPos( range->end );
+
+ //
+ // In case two ranges meet at one point moving the mouse cursor deeper into one
+ // range allows for grabbing that end
+ //
+
+ if( p.x() - 3 <= start && p.x() >= start && !range->startFixed ) {
+ if( isEnd )
+ *isEnd = false;
+ return range;
+ }
+ else if( p.x() <= end && p.x() + 3 >= end && !range->endFixed ) {
+ if( isEnd )
+ *isEnd = true;
+ return range;
+ }
+ }
+ return 0;
+}
+
+
+K3bAudioEditorWidget::Marker* K3bAudioEditorWidget::getMarker( int i ) const
+{
+ for( QPtrListIterator<Marker> it( m_markers ); *it; ++it )
+ if( (*it)->id == i )
+ return *it;
+
+ return 0;
+}
+
+
+K3bAudioEditorWidget::Marker* K3bAudioEditorWidget::findMarker( const QPoint& p ) const
+{
+ // TODO: binary search
+ for( QPtrListIterator<Marker> it( m_markers ); *it; ++it ) {
+ Marker* marker = *it;
+ int start = msfToPos( marker->pos );
+
+ if( p.x() - 1 <= start && p.x() + 1 >= start && !marker->fixed )
+ return marker;
+ }
+
+ return 0;
+}
+
+
+// p is in widget coordinates
+K3b::Msf K3bAudioEditorWidget::posToMsf( int p ) const
+{
+ int w = contentsRect().width() - 2*m_margin;
+ int x = QMIN( p-frameWidth()-m_margin, w );
+ return ( (int)((double)(m_length.lba()-1) / (double)w * (double)x) );
+}
+
+
+// returns widget coordinates
+int K3bAudioEditorWidget::msfToPos( const K3b::Msf& msf ) const
+{
+ int w = contentsRect().width() - 2*m_margin;
+ int pos = (int)((double)w / (double)(m_length.lba()-1) * (double)msf.lba());
+ return frameWidth() + m_margin + QMIN( pos, w-1 );
+}
+
+
+#include "k3baudioeditorwidget.moc"
diff --git a/src/projects/k3baudioeditorwidget.h b/src/projects/k3baudioeditorwidget.h
new file mode 100644
index 0000000..6e939d7
--- /dev/null
+++ b/src/projects/k3baudioeditorwidget.h
@@ -0,0 +1,220 @@
+/*
+ *
+ * $Id: k3baudioeditorwidget.h 620140 2007-01-05 12:02:29Z trueg $
+ * Copyright (C) 2004-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_AUDIO_EDITOR_WIDGET_H_
+#define _K3B_AUDIO_EDITOR_WIDGET_H_
+
+#include <qframe.h>
+#include <qptrlist.h>
+
+#include <k3bmsf.h>
+
+
+class QPainter;
+
+
+class K3bAudioEditorWidget : public QFrame
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioEditorWidget( QWidget* parent = 0, const char* name = 0 );
+ ~K3bAudioEditorWidget();
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ /**
+ * For now the Editor has only one parameter: the length data.
+ */
+ void setLength( const K3b::Msf& length );
+
+ const K3b::Msf length() const;
+
+ /**
+ * Add a user editable range.
+ * @param startFixed if true the range's start cannot be changed by the user, only with modifyRange
+ * @param endFixed if true the range's end cannot be changed by the user, only with modifyRange
+ * @param brush if not specified or it has the NoBrush style one is chosen automatically.
+ *
+ * @return -1 on error or an identifier on success (be aware that the highest value for end is length-1)
+ */
+ int addRange( const K3b::Msf& start, const K3b::Msf& end,
+ bool startFixed = false, bool endFixed = false,
+ const QString& toolTip = QString::null,
+ const QBrush& brush = QBrush() );
+
+ /**
+ * \returns the identifier of the range which spans over x position \a pos or
+ * 0 if no range is defined in this region.
+ */
+ int findRange( int pos ) const;
+
+ /**
+ * Searches for a range edge at x position \a pos.
+ * \return The ranges identifier if an edge could be found or 0 if there is no
+ * range edge at the position.
+ */
+ int findRangeEdge( int pos, bool* end = 0 ) const;
+
+ /**
+ * @returns false if the range does not exist or end was bigger than start.
+ */
+ bool modifyRange( int identifier, const K3b::Msf& start, const K3b::Msf& end );
+
+ /**
+ * @returns false if the range does not exist.
+ */
+ bool removeRange( int identifier );
+
+ K3b::Msf rangeStart( int identifier ) const;
+ K3b::Msf rangeEnd( int identifier ) const;
+
+ /**
+ * \return A list of all ranges' identifiers sorted ascending by start
+ * offset
+ */
+ QValueList<int> allRanges() const;
+
+ void setMaxNumberOfMarkers( int );
+
+ /**
+ * @param fixed if true the marker cannot be changed by the user, only with moveMarker
+ * @return -1 on error or an identifier on success.
+ */
+ int addMarker( const K3b::Msf& pos, bool fixed = false,
+ const QString& toolTip = QString::null, const QColor& color = QColor() );
+
+ /**
+ * @return false if the marker does not exist.
+ */
+ bool removeMarker( int identifier );
+
+ /**
+ * @return false if the marker does not exist.
+ */
+ bool moveMarker( int identifier, const K3b::Msf& );
+
+ void enableMouseAtSignal( bool b ) { m_mouseAt = b; }
+
+ /**
+ * By default ranges can overlap. If overlapping ranges are not allowed
+ * the editor widget will modify and delete ranges accordingly.
+ *
+ * Caution: So far setting this will not check if ranges already overlap.
+ */
+ void setAllowOverlappingRanges( bool b );
+
+ /**
+ * Range selection is by default disabled. If it is enabled the editor visually
+ * highlights the last clicked range.
+ *
+ * \sa setSelectedRange
+ */
+ void enableRangeSelection( bool b );
+
+ bool allowOverlappingRanges() const;
+ bool rangeSelectedEnabled() const;
+
+ void setSelectedRange( int id );
+
+ /**
+ * \return The identifier of the currently selected range or 0
+ * if none is selected.
+ */
+ int selectedRange() const;
+
+ K3b::Msf posToMsf( int x ) const;
+ int msfToPos( const K3b::Msf& msf ) const;
+
+ /**
+ * Set the brush to paint the selected range. Default is QColorGroup::Highlight
+ */
+ void setSelectedRangeBrush( const QBrush& );
+ const QBrush& selectedRangeBrush() const;
+
+ signals:
+ /**
+ * Emitted when enabled.
+ */
+ void mouseAt( const K3b::Msf& );
+
+ /**
+ * Emitted when the user changed a range.
+ * This signal is not emitted when a range is changed via modifyRange.
+ */
+ void rangeChanged( int identifier, const K3b::Msf& start, const K3b::Msf& end );
+ void rangeRemoved( int );
+
+ void selectedRangeChanged( int );
+
+ /**
+ * Emitted when the user moves a marker.
+ * This signal is not emitted when a marker is changed via moveMarker.
+ */
+ void markerMoved( int identifier, const K3b::Msf& pos );
+ void markerAdded( int identifier, const K3b::Msf& pos );
+ void markerRemoved( int identifier );
+
+ private:
+ class Range;
+ class RangeList;
+ class Marker;
+ class ToolTip;
+
+ class Private;
+ Private* d;
+
+ void mousePressEvent( QMouseEvent* e );
+ void mouseReleaseEvent( QMouseEvent* e );
+ void mouseDoubleClickEvent( QMouseEvent* e );
+ void mouseMoveEvent( QMouseEvent* e );
+ void drawContents( QPainter* );
+ void drawAll( QPainter*, const QRect& );
+ void drawRange( QPainter* p, const QRect&, Range* r );
+ void drawMarker( QPainter* p, const QRect&, Marker* m );
+
+ /**
+ * Makes sure that \a r does not overlap any other range by modifying and
+ * deleting other ranges.
+ */
+ void fixupOverlappingRanges( Range* r );
+
+ Range* getRange( int i ) const;
+ Marker* getMarker( int i ) const;
+ Range* findRange( const QPoint& p ) const;
+ Range* findRangeEdge( const QPoint& p, bool* end = 0 ) const;
+ Marker* findMarker( const QPoint& p ) const;
+ void setSelectedRange( Range* );
+
+ int m_maxMarkers;
+ K3b::Msf m_length;
+ QPtrList<Marker> m_markers;
+ int m_idCnt;
+ bool m_mouseAt;
+
+ /**
+ * Margin around the timethingy
+ */
+ int m_margin;
+
+ Range* m_draggedRange;
+ bool m_draggingRangeEnd;
+ Marker* m_draggedMarker;
+
+ ToolTip* m_toolTip;
+};
+
+#endif
diff --git a/src/projects/k3baudiotrackaddingdialog.cpp b/src/projects/k3baudiotrackaddingdialog.cpp
new file mode 100644
index 0000000..dfbcbb9
--- /dev/null
+++ b/src/projects/k3baudiotrackaddingdialog.cpp
@@ -0,0 +1,302 @@
+/*
+ *
+ * $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 "k3baudiotrackaddingdialog.h"
+
+#include <k3baudiodoc.h>
+#include <k3baudiotrack.h>
+#include <k3baudiofile.h>
+#include <k3baudiodecoder.h>
+#include <k3bbusywidget.h>
+#include <k3bglobals.h>
+#include <k3bthread.h>
+#include <k3bthreadjob.h>
+#include <k3bcuefileparser.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qfileinfo.h>
+#include <qtimer.h>
+#include <qdir.h>
+
+
+class K3bAudioTrackAddingDialog::AnalyserThread : public K3bThread
+{
+public:
+ AnalyserThread()
+ : K3bThread(),
+ m_decoder(0) {
+ }
+
+ void run() {
+ emitStarted();
+ m_decoder->analyseFile();
+ emitFinished( m_decoder->isValid() );
+ }
+
+ K3bAudioDecoder* m_decoder;
+};
+
+
+K3bAudioTrackAddingDialog::K3bAudioTrackAddingDialog( QWidget* parent, const char* name )
+ : KDialogBase( Plain,
+ i18n("Please be patient..."),
+ Cancel,
+ Cancel,
+ parent,
+ name,
+ true,
+ true ),
+ m_bCanceled(false)
+{
+ QWidget* page = plainPage();
+ QGridLayout* grid = new QGridLayout( page );
+ grid->setSpacing( spacingHint() );
+ grid->setMargin( marginHint() );
+
+ m_infoLabel = new QLabel( page );
+ m_busyWidget = new K3bBusyWidget( page );
+
+ grid->addWidget( m_infoLabel, 0, 0 );
+ grid->addWidget( m_busyWidget, 1, 0 );
+
+ m_analyserThread = new AnalyserThread();
+ m_analyserJob = new K3bThreadJob( m_analyserThread, this, this );
+ connect( m_analyserJob, SIGNAL(finished(bool)), this, SLOT(slotAnalysingFinished(bool)) );
+}
+
+
+K3bAudioTrackAddingDialog::~K3bAudioTrackAddingDialog()
+{
+ delete m_analyserThread;
+}
+
+
+int K3bAudioTrackAddingDialog::addUrls( const KURL::List& urls,
+ K3bAudioDoc* doc,
+ K3bAudioTrack* afterTrack,
+ K3bAudioTrack* parentTrack,
+ K3bAudioDataSource* afterSource,
+ QWidget* parent )
+{
+ if( urls.isEmpty() )
+ return 0;
+
+ K3bAudioTrackAddingDialog dlg( parent );
+ dlg.m_urls = extractUrlList( urls );
+ dlg.m_doc = doc;
+ dlg.m_trackAfter = afterTrack;
+ dlg.m_parentTrack = parentTrack;
+ dlg.m_sourceAfter = afterSource;
+ dlg.m_infoLabel->setText( i18n("Adding files to project \"%1\"...").arg(doc->URL().fileName()) );
+
+ dlg.m_busyWidget->showBusy(true);
+ QTimer::singleShot( 0, &dlg, SLOT(slotAddUrls()) );
+ int ret = dlg.exec();
+
+ QString message;
+ if( !dlg.m_unreadableFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br>%2")
+ .arg( i18n("Insufficient permissions to read the following files") )
+ .arg( dlg.m_unreadableFiles.join( "<br>" ) );
+ if( !dlg.m_notFoundFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br>%2")
+ .arg( i18n("Unable to find the following files") )
+ .arg( dlg.m_notFoundFiles.join( "<br>" ) );
+ if( !dlg.m_nonLocalFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br>%2")
+ .arg( i18n("No non-local files supported") )
+ .arg( dlg.m_unreadableFiles.join( "<br>" ) );
+ if( !dlg.m_unsupportedFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br><i>%2</i><br>%3")
+ .arg( i18n("Unable to handle the following files due to an unsupported format" ) )
+ .arg( i18n("You may manually convert these audio files to wave using another "
+ "application supporting the audio format and then add the wave files "
+ "to the K3b project.") )
+ .arg( dlg.m_unsupportedFiles.join( "<br>" ) );
+
+ if( !message.isEmpty() )
+ KMessageBox::detailedSorry( parent, i18n("Problems while adding files to the project."), message );
+
+ return ret;
+}
+
+
+
+void K3bAudioTrackAddingDialog::slotAddUrls()
+{
+ if( m_bCanceled )
+ return;
+
+ if( m_urls.isEmpty() ) {
+ accept();
+ return;
+ }
+
+ KURL url = m_urls.first();
+ bool valid = true;
+
+ if( url.path().right(3).lower() == "cue" ) {
+ // see if its a cue file
+ K3bCueFileParser parser( url.path() );
+ if( parser.isValid() && parser.toc().contentType() == K3bDevice::AUDIO ) {
+ // remember cue url and set the new audio file url
+ m_cueUrl = url;
+ url = m_urls[0] = KURL::fromPathOrURL( parser.imageFilename() );
+ }
+ }
+
+ m_infoLabel->setText( i18n("Analysing file '%1'...").arg( url.fileName() ) );
+
+ if( !url.isLocalFile() ) {
+ valid = false;
+ m_nonLocalFiles.append( url.path() );
+ }
+ else {
+ QFileInfo fi( url.path() );
+ if( !fi.exists() ) {
+ valid = false;
+ m_notFoundFiles.append( url.path() );
+ }
+ else if( !fi.isReadable() ) {
+ valid = false;
+ m_unreadableFiles.append( url.path() );
+ }
+ }
+
+ if( valid ) {
+ bool reused;
+ K3bAudioDecoder* dec = m_doc->getDecoderForUrl( url, &reused );
+ if( dec ) {
+ m_analyserThread->m_decoder = dec;
+ if( reused )
+ slotAnalysingFinished( true );
+ else
+ m_analyserJob->start();
+ }
+ else {
+ valid = false;
+ m_unsupportedFiles.append( url.path() );
+ }
+ }
+
+ // invalid file, next url
+ if( !valid ) {
+ m_urls.remove( m_urls.begin() );
+ QTimer::singleShot( 0, this, SLOT(slotAddUrls()) );
+ }
+}
+
+
+void K3bAudioTrackAddingDialog::slotAnalysingFinished( bool /*success*/ )
+{
+ if( m_bCanceled ) {
+ // We only started the analyser thread in case the decoder was new
+ // thus, we can safely delete it since no other source needs it.
+ delete m_analyserThread->m_decoder;
+ return;
+ }
+
+ KURL url = m_urls.first();
+ m_urls.remove( m_urls.begin() );
+
+ if( m_cueUrl.isValid() ) {
+ // import the cue file
+ m_doc->importCueFile( m_cueUrl.path(), m_trackAfter, m_analyserThread->m_decoder );
+ m_cueUrl = KURL();
+ }
+ else {
+ // create the track and source items
+ K3bAudioDecoder* dec = m_analyserThread->m_decoder;
+ K3bAudioFile* file = new K3bAudioFile( dec, m_doc );
+ if( m_parentTrack ) {
+ if( m_sourceAfter )
+ file->moveAfter( m_sourceAfter );
+ else
+ file->moveAhead( m_parentTrack->firstSource() );
+ m_sourceAfter = file;
+ }
+ else {
+ K3bAudioTrack* track = new K3bAudioTrack( m_doc );
+ track->setFirstSource( file );
+
+ track->setTitle( dec->metaInfo( K3bAudioDecoder::META_TITLE ) );
+ track->setArtist( dec->metaInfo( K3bAudioDecoder::META_ARTIST ) );
+ track->setSongwriter( dec->metaInfo( K3bAudioDecoder::META_SONGWRITER ) );
+ track->setComposer( dec->metaInfo( K3bAudioDecoder::META_COMPOSER ) );
+ track->setCdTextMessage( dec->metaInfo( K3bAudioDecoder::META_COMMENT ) );
+
+ if( m_trackAfter )
+ track->moveAfter( m_trackAfter );
+ else
+ track->moveAfter( m_doc->lastTrack() );
+
+ m_trackAfter = track;
+ }
+ }
+
+ QTimer::singleShot( 0, this, SLOT(slotAddUrls()) );
+}
+
+
+void K3bAudioTrackAddingDialog::slotCancel()
+{
+ m_bCanceled = true;
+ m_analyserJob->cancel();
+ KDialogBase::slotCancel();
+}
+
+
+KURL::List K3bAudioTrackAddingDialog::extractUrlList( const KURL::List& urls )
+{
+ KURL::List allUrls = urls;
+ KURL::List urlsFromPlaylist;
+ KURL::List::iterator it = allUrls.begin();
+ while( it != allUrls.end() ) {
+
+ const KURL& url = *it;
+ QFileInfo fi( url.path() );
+
+ if( fi.isDir() ) {
+ it = allUrls.remove( it );
+ // add all files in the dir
+ QDir dir(fi.filePath());
+ QStringList entries = dir.entryList( QDir::Files );
+ KURL::List::iterator oldIt = it;
+ // add all files into the list after the current item
+ for( QStringList::iterator dirIt = entries.begin();
+ dirIt != entries.end(); ++dirIt )
+ it = allUrls.insert( oldIt, KURL::fromPathOrURL( dir.absPath() + "/" + *dirIt ) );
+ }
+ else if( K3bAudioDoc::readPlaylistFile( url, urlsFromPlaylist ) ) {
+ it = allUrls.remove( it );
+ KURL::List::iterator oldIt = it;
+ // add all files into the list after the current item
+ for( KURL::List::iterator dirIt = urlsFromPlaylist.begin();
+ dirIt != urlsFromPlaylist.end(); ++dirIt )
+ it = allUrls.insert( oldIt, *dirIt );
+ }
+ else
+ ++it;
+ }
+
+ return allUrls;
+}
+
+#include "k3baudiotrackaddingdialog.moc"
diff --git a/src/projects/k3baudiotrackaddingdialog.h b/src/projects/k3baudiotrackaddingdialog.h
new file mode 100644
index 0000000..4590e95
--- /dev/null
+++ b/src/projects/k3baudiotrackaddingdialog.h
@@ -0,0 +1,106 @@
+/*
+ *
+ * $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_AUDIO_TRACK_ADDING_DIALOG_H_
+#define _K3B_AUDIO_TRACK_ADDING_DIALOG_H_
+
+#include <k3bjobhandler.h>
+#include <kdialogbase.h>
+#include <kurl.h>
+#include <qstringlist.h>
+
+
+class K3bBusyWidget;
+class QLabel;
+class K3bAudioTrack;
+class K3bAudioDataSource;
+class K3bThreadJob;
+class K3bAudioDoc;
+
+
+class K3bAudioTrackAddingDialog : public KDialogBase, public K3bJobHandler
+{
+ Q_OBJECT
+
+ public:
+ ~K3bAudioTrackAddingDialog();
+
+ /**
+ * @reimplemented from K3bJobHandler
+ */
+ int waitForMedia( K3bDevice::Device*,
+ int = K3bDevice::STATE_EMPTY,
+ int = K3bDevice::MEDIA_WRITABLE_CD,
+ const QString& = QString::null ) { return 0; }
+
+ /**
+ * @reimplemented from K3bJobHandler
+ */
+ bool questionYesNo( const QString&,
+ const QString& = QString::null,
+ const QString& = QString::null,
+ const QString& = QString::null ) { return false; }
+
+ /**
+ * reimplemented from K3bJobHandler
+ */
+ void blockingInformation( const QString&,
+ const QString& = QString::null ) {}
+
+ /**
+ * \return \see QDialog::exec()
+ */
+ static int addUrls( const KURL::List& urls,
+ K3bAudioDoc* doc,
+ K3bAudioTrack* afterTrack = 0,
+ K3bAudioTrack* parentTrack = 0,
+ K3bAudioDataSource* afterSource = 0,
+ QWidget* parent = 0 );
+
+ private slots:
+ void slotAddUrls();
+ void slotAnalysingFinished( bool );
+ void slotCancel();
+
+ private:
+ K3bAudioTrackAddingDialog( QWidget* parent = 0, const char* name = 0 );
+
+ static KURL::List extractUrlList( const KURL::List& urls );
+
+ K3bBusyWidget* m_busyWidget;
+ QLabel* m_infoLabel;
+
+ QStringList m_unreadableFiles;
+ QStringList m_notFoundFiles;
+ QStringList m_nonLocalFiles;
+ QStringList m_unsupportedFiles;
+
+ KURL::List m_urls;
+
+ K3bAudioDoc* m_doc;
+ K3bAudioTrack* m_trackAfter;
+ K3bAudioTrack* m_parentTrack;
+ K3bAudioDataSource* m_sourceAfter;
+
+ KURL m_cueUrl;
+
+ bool m_bCanceled;
+
+ class AnalyserThread;
+ AnalyserThread* m_analyserThread;
+ K3bThreadJob* m_analyserJob;
+};
+
+#endif
diff --git a/src/projects/k3baudiotrackdialog.cpp b/src/projects/k3baudiotrackdialog.cpp
new file mode 100644
index 0000000..ecb7796
--- /dev/null
+++ b/src/projects/k3baudiotrackdialog.cpp
@@ -0,0 +1,113 @@
+/*
+ *
+ * $Id: k3baudiotrackdialog.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 <qtextedit.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qframe.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qhbox.h>
+#include <qwhatsthis.h>
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <knuminput.h>
+#include <kmimetype.h>
+#include <kurl.h>
+#include <kio/global.h>
+#include <klineedit.h>
+
+#include "k3baudiotrackdialog.h"
+#include "k3baudioeditorwidget.h"
+#include "k3baudiotrackwidget.h"
+#include "k3baudiotrack.h"
+#include <k3bvalidators.h>
+#include <kcutlabel.h>
+#include <k3bmsf.h>
+#include <k3bcdtextvalidator.h>
+#include <k3baudiodecoder.h>
+#include <k3bmsfedit.h>
+
+
+// TODO: three modes:
+// 1. Only one track with only one source
+// show decoder tech info, cdtext, options and the track editor without showing anything
+// about sources
+// 2. Only one track with multible sources
+// like the above but with the possiblity to edit the sources
+// 3. multible tracks
+// do only show cd-text and options (eventuelle index0)
+
+
+K3bAudioTrackDialog::K3bAudioTrackDialog( QPtrList<K3bAudioTrack>& tracks, QWidget *parent, const char *name )
+ : KDialogBase( KDialogBase::Plain, i18n("Audio Track Properties"),
+ KDialogBase::Ok|KDialogBase::Cancel|KDialogBase::Apply,
+ KDialogBase::Ok, parent, name )
+{
+ m_tracks = tracks;
+
+ setupGui();
+ setupConnections();
+}
+
+K3bAudioTrackDialog::~K3bAudioTrackDialog()
+{
+}
+
+
+void K3bAudioTrackDialog::slotOk()
+{
+ slotApply();
+ done(0);
+}
+
+
+void K3bAudioTrackDialog::slotApply()
+{
+ m_audioTrackWidget->save();
+
+}
+
+
+void K3bAudioTrackDialog::setupGui()
+{
+ QFrame* frame = plainPage();
+
+ QGridLayout* mainLayout = new QGridLayout( frame );
+ mainLayout->setSpacing( spacingHint() );
+ mainLayout->setMargin( 0 );
+
+ m_audioTrackWidget = new K3bAudioTrackWidget( m_tracks, frame );
+ mainLayout->addWidget( m_audioTrackWidget, 0, 0 );
+}
+
+void K3bAudioTrackDialog::setupConnections()
+{
+}
+
+
+void K3bAudioTrackDialog::updateTrackLengthDisplay()
+{
+// K3b::Msf len = m_editTrackEnd->msfValue() - m_editTrackStart->msfValue();
+// m_displayLength->setText( len.toString() );
+// m_displaySize->setText( KIO::convertSize(len.audioBytes()) );
+}
+
+
+
+#include "k3baudiotrackdialog.moc"
diff --git a/src/projects/k3baudiotrackdialog.h b/src/projects/k3baudiotrackdialog.h
new file mode 100644
index 0000000..53edc1c
--- /dev/null
+++ b/src/projects/k3baudiotrackdialog.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * $Id: k3baudiotrackdialog.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 K3BAUDIOTRACKDIALOG_H
+#define K3BAUDIOTRACKDIALOG_H
+
+
+#include <kdialogbase.h>
+
+#include <k3bmsf.h>
+
+#include <qptrlist.h>
+
+class K3bAudioTrack;
+class K3bAudioTrackWidget;
+
+/**
+ *@author Sebastian Trueg
+ */
+
+class K3bAudioTrackDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioTrackDialog( QPtrList<K3bAudioTrack>&, QWidget *parent=0, const char *name=0);
+ ~K3bAudioTrackDialog();
+
+ protected slots:
+ void slotOk();
+ void slotApply();
+
+ void updateTrackLengthDisplay();
+
+ private:
+ QPtrList<K3bAudioTrack> m_tracks;
+
+ K3bAudioTrackWidget* m_audioTrackWidget;
+
+ void setupGui();
+ void setupConnections();
+};
+
+#endif
diff --git a/src/projects/k3baudiotrackplayer.cpp b/src/projects/k3baudiotrackplayer.cpp
new file mode 100644
index 0000000..cac2e7a
--- /dev/null
+++ b/src/projects/k3baudiotrackplayer.cpp
@@ -0,0 +1,365 @@
+/*
+ *
+ * $Id: k3baudiotrackplayer.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2004 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 "k3baudiotrackplayer.h"
+#include <k3baudiodoc.h>
+#include <k3baudiotrack.h>
+#include <k3baudioserver.h>
+
+#include <kactionclasses.h>
+#include <klocale.h>
+
+#include <qslider.h>
+#include <qtimer.h>
+#include <qmutex.h>
+#include <qtooltip.h>
+
+
+class K3bAudioTrackPlayer::Private
+{
+public:
+ KAction* actionPlay;
+ KAction* actionPause;
+ KAction* actionPlayPause;
+ KAction* actionStop;
+ KAction* actionNext;
+ KAction* actionPrev;
+ KAction* actionSeek;
+
+ // just to handle them easily;
+ KActionCollection* actionCollection;
+
+ QSlider* seekSlider;
+ QTimer sliderTimer;
+
+ // used to make sure that no seek and read operation occur in parallel
+ QMutex mutex;
+
+ bool playing;
+ bool paused;
+};
+
+
+K3bAudioTrackPlayer::K3bAudioTrackPlayer( K3bAudioDoc* doc, QObject* parent, const char* name )
+ : QObject( parent, name ),
+ K3bAudioClient(),
+ m_doc( doc ),
+ m_currentTrack( 0 )
+{
+ d = new Private;
+ d->paused = false;
+ d->playing = false;
+
+ // TODO: handle the shortcuts: pass a widget to the action collection (perhaps the trackview?)
+ d->actionCollection = new KActionCollection( 0, this );
+
+ // create the actions
+ // TODO: create shortcuts (is there a way to let the user change them?)
+ d->actionPlay = new KAction( i18n("Play"),
+ "player_play",
+ KShortcut(),
+ this, SLOT(playPause()),
+ d->actionCollection,
+ "play" );
+ d->actionPause = new KAction( i18n("Pause"),
+ "player_pause",
+ KShortcut(),
+ this, SLOT(playPause()),
+ d->actionCollection,
+ "pause" );
+ d->actionPlayPause = new KAction( i18n("Play/Pause"),
+ "player_play",
+ KShortcut(),
+ this, SLOT(playPause()),
+ d->actionCollection,
+ "play_pause" );
+
+ d->actionStop = new KAction( i18n("Stop"),
+ "player_stop",
+ KShortcut(),
+ this, SLOT(stop()),
+ d->actionCollection,
+ "stop" );
+ d->actionNext = new KAction( i18n("Next"),
+ "player_end",
+ KShortcut(),
+ this, SLOT(next()),
+ d->actionCollection,
+ "next" );
+ d->actionPrev = new KAction( i18n("Prev"),
+ "player_start",
+ KShortcut(),
+ this, SLOT(prev()),
+ d->actionCollection,
+ "prev" );
+
+ d->seekSlider = new QSlider( 0, 100, 1, 0, Qt::Horizontal, 0, "audiotrackplayerslider" );
+ connect( d->seekSlider, SIGNAL(sliderMoved(int)), this, SLOT(slotSeek(int)) );
+ // FIXME: maybe it's not such a good idea to use a KWidgetAction here since this way the player
+ // can only be used once in one widget. If the action would always create a new slider we could plug
+ // the action into several toolboxes and also use it in some resizing or track splitting dialogs.
+ d->actionSeek = new KWidgetAction( d->seekSlider,
+ i18n("Seek"),
+ KShortcut(),
+ 0,
+ 0,
+ d->actionCollection,
+ "seek" );
+ // this should be done in KWidgetAction but is not yet
+ connect( d->actionSeek, SIGNAL(enabled(bool)), d->seekSlider, SLOT(setEnabled(bool)) );
+
+ d->actionStop->setEnabled(false);
+ d->actionPause->setEnabled(false);
+ d->actionNext->setEnabled(false);
+ d->actionPrev->setEnabled(false);
+ d->actionSeek->setEnabled(false);
+
+ connect( m_doc, SIGNAL(changed()),
+ this, SLOT(slotDocChanged()) );
+ connect( m_doc, SIGNAL(trackChanged(K3bAudioTrack*)),
+ this, SLOT(slotTrackChanged(K3bAudioTrack*)) );
+ connect( m_doc, SIGNAL(trackRemoved(K3bAudioTrack*)),
+ this, SLOT(slotTrackRemoved(K3bAudioTrack*)) );
+ connect( &d->sliderTimer, SIGNAL(timeout()),
+ this, SLOT(slotUpdateSlider()) );
+
+ // we just stop the player if the audio server has an error. K3bMainWindow will show the error message
+ // This is all very hacky and has to be improved for K3b 2.0. But then we will probably use Phonon anyway...
+ connect( K3bAudioServer::instance(), SIGNAL(error(const QString&)), this, SLOT(stop()) );
+
+ // tooltips
+ d->actionPlay->setToolTip( i18n("Play") );
+ d->actionStop->setToolTip( i18n("Stop") );
+ d->actionPause->setToolTip( i18n("Pause") );
+ d->actionNext->setToolTip( i18n("Next") );
+ d->actionPrev->setToolTip( i18n("Previous") );
+}
+
+
+K3bAudioTrackPlayer::~K3bAudioTrackPlayer()
+{
+ stop();
+ delete d->seekSlider;
+ delete d;
+}
+
+
+KAction* K3bAudioTrackPlayer::action( int action ) const
+{
+ switch( action ) {
+ case ACTION_PLAY:
+ return d->actionPlay;
+ case ACTION_PAUSE:
+ return d->actionPause;
+ case ACTION_PLAY_PAUSE:
+ return d->actionPlayPause;
+ case ACTION_STOP:
+ return d->actionStop;
+ case ACTION_NEXT:
+ return d->actionNext;
+ case ACTION_PREV:
+ return d->actionPrev;
+ case ACTION_SEEK:
+ return d->actionSeek;
+ default:
+ return 0;
+ }
+}
+
+
+void K3bAudioTrackPlayer::playTrack( K3bAudioTrack* track )
+{
+ if( track ) {
+ // we show the currently playing track as a tooltip on the slider
+ QToolTip::remove( d->seekSlider );
+ QToolTip::add( d->seekSlider, i18n("Playing track %1: %2 - %3")
+ .arg(track->trackNumber())
+ .arg(track->artist())
+ .arg(track->title()) );
+ d->seekSlider->setMaxValue( track->length().totalFrames() );
+ m_currentTrack = track;
+ d->paused = true;
+
+ d->actionNext->setEnabled( m_currentTrack->next() != 0 );
+ d->actionPrev->setEnabled( m_currentTrack->prev() != 0 );
+
+ seek(0);
+ playPause();
+
+ emit playingTrack( track );
+ }
+}
+
+
+void K3bAudioTrackPlayer::playPause()
+{
+ if( !m_currentTrack ) {
+ playTrack( m_doc->firstTrack() );
+ }
+ else {
+ if( !d->playing ) {
+ seek( m_currentPosition );
+ d->playing = true;
+ d->actionPlayPause->setIcon( "player_pause" );
+ d->actionPause->setEnabled(true);
+ d->actionPlay->setEnabled(false);
+ d->actionSeek->setEnabled(true);
+ startStreaming();
+ d->sliderTimer.start(1000);
+ }
+ else if( d->paused ) {
+ d->paused = false;
+ d->actionPlayPause->setIcon( "player_pause" );
+ d->actionPause->setEnabled(true);
+ d->actionPlay->setEnabled(false);
+ startStreaming();
+ d->sliderTimer.start(1000);
+
+ emit paused( false );
+ }
+ else {
+ d->paused = true;
+ d->actionPlayPause->setIcon( "player_play" );
+ d->actionPause->setEnabled(false);
+ d->actionPlay->setEnabled(true);
+ stopStreaming();
+ d->sliderTimer.stop();
+
+ emit paused( true );
+ }
+
+ d->actionStop->setEnabled(true);
+ }
+}
+
+
+void K3bAudioTrackPlayer::stop()
+{
+ m_currentTrack = 0;
+ m_currentPosition = 0;
+ stopStreaming();
+ d->paused = false;
+ d->playing = false;
+ d->actionStop->setEnabled(false);
+ d->actionPause->setEnabled(false);
+ d->actionPlay->setEnabled(true);
+ d->actionSeek->setEnabled(false);
+ d->actionNext->setEnabled(false);
+ d->actionPrev->setEnabled(false);
+
+ d->actionPlayPause->setIcon( "player_play" );
+
+ emit stopped();
+}
+
+
+void K3bAudioTrackPlayer::next()
+{
+ if( m_currentTrack && m_currentTrack->next() ) {
+ playTrack( m_currentTrack->next() );
+ }
+}
+
+
+void K3bAudioTrackPlayer::prev()
+{
+ if( m_currentTrack && m_currentTrack->prev() ) {
+ playTrack( m_currentTrack->prev() );
+ }
+}
+
+
+void K3bAudioTrackPlayer::seek( const K3b::Msf& msf )
+{
+ if( m_currentTrack ) {
+ if( msf < m_currentTrack->length() ) {
+ d->mutex.lock();
+ m_currentTrack->seek( msf );
+ m_currentPosition = msf;
+ slotUpdateSlider();
+ d->mutex.unlock();
+ }
+ else
+ next();
+ }
+}
+
+
+void K3bAudioTrackPlayer::slotSeek( int frames )
+{
+ seek( K3b::Msf( frames ) );
+}
+
+
+int K3bAudioTrackPlayer::read( char* data, int maxlen )
+{
+ if( m_currentTrack ) {
+ d->mutex.lock();
+ int len = m_currentTrack->read( data, maxlen );
+ d->mutex.unlock();
+ if( len > 0 ) {
+ m_currentPosition += (int)( (double)len / 2352.0 + 0.5 );
+ }
+ else if( m_currentTrack->next() ) {
+ // play the next track
+ next();
+ return read( data, maxlen );
+ }
+ else {
+ stop();
+ return -1; // no more tracks
+ }
+
+ return len;
+ }
+ else
+ return -1;
+}
+
+
+void K3bAudioTrackPlayer::slotTrackRemoved( K3bAudioTrack* track )
+{
+ if( m_currentTrack == track ) {
+ stop();
+ m_currentTrack = 0;
+ }
+}
+
+
+void K3bAudioTrackPlayer::slotTrackChanged( K3bAudioTrack* track )
+{
+ if( m_currentTrack == track ) {
+ d->seekSlider->setMaxValue( track->length().totalFrames() );
+ }
+}
+
+
+void K3bAudioTrackPlayer::slotUpdateSlider()
+{
+ d->seekSlider->setValue( m_currentPosition.totalFrames() );
+}
+
+
+void K3bAudioTrackPlayer::slotDocChanged()
+{
+ // update the controls in case a new track has been added before or after
+ // the current one and it has been the first or last track
+ if( m_currentTrack ) {
+ d->actionNext->setEnabled( m_currentTrack->next() != 0 );
+ d->actionPrev->setEnabled( m_currentTrack->prev() != 0 );
+ }
+}
+
+#include "k3baudiotrackplayer.moc"
diff --git a/src/projects/k3baudiotrackplayer.h b/src/projects/k3baudiotrackplayer.h
new file mode 100644
index 0000000..92f4f0a
--- /dev/null
+++ b/src/projects/k3baudiotrackplayer.h
@@ -0,0 +1,87 @@
+/*
+ *
+ * $Id: k3baudiotrackplayer.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2004 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_TRACK_PLAYER_H_
+#define _K3B_AUDIO_TRACK_PLAYER_H_
+
+#include <qobject.h>
+
+#include <k3baudioclient.h>
+
+#include <k3bmsf.h>
+
+class K3bAudioDoc;
+class K3bAudioTrack;
+class KAction;
+
+
+class K3bAudioTrackPlayer : public QObject, public K3bAudioClient
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioTrackPlayer( K3bAudioDoc* doc, QObject* parent = 0, const char* name = 0 );
+ ~K3bAudioTrackPlayer();
+
+ K3bAudioTrack* currentPlayingTrack() const { return m_currentTrack; }
+ const K3b::Msf& currentPosition() const { return m_currentPosition; }
+
+ enum Actions {
+ ACTION_PLAY,
+ ACTION_PAUSE,
+ ACTION_PLAY_PAUSE,
+ ACTION_STOP,
+ ACTION_NEXT,
+ ACTION_PREV,
+ ACTION_SEEK
+ };
+
+ KAction* action( int action ) const;
+
+ /**
+ * Reimplemented from K3bAudioClient
+ */
+ int read( char* data, int maxlen );
+
+ public slots:
+ void playTrack( K3bAudioTrack* );
+ void playPause();
+ void stop();
+ void next();
+ void prev();
+ void seek( const K3b::Msf& );
+
+ signals:
+ void playingTrack( K3bAudioTrack* );
+ void paused( bool paused );
+ void stopped();
+
+ private slots:
+ void slotSeek( int );
+ void slotTrackChanged( K3bAudioTrack* track );
+ void slotTrackRemoved( K3bAudioTrack* track );
+ void slotUpdateSlider();
+ void slotDocChanged();
+
+ private:
+ K3bAudioDoc* m_doc;
+ K3bAudioTrack* m_currentTrack;
+ K3b::Msf m_currentPosition;
+
+ class Private;
+ Private* d;
+};
+
+#endif
diff --git a/src/projects/k3baudiotracksplitdialog.cpp b/src/projects/k3baudiotracksplitdialog.cpp
new file mode 100644
index 0000000..1acd370
--- /dev/null
+++ b/src/projects/k3baudiotracksplitdialog.cpp
@@ -0,0 +1,232 @@
+/*
+ *
+ * $Id: k3baudiotracksplitdialog.cpp 630444 2007-02-05 12:43:19Z trueg $
+ * Copyright (C) 2004-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 "k3baudiotracksplitdialog.h"
+#include "k3baudiotrack.h"
+#include "k3baudioeditorwidget.h"
+
+#include <k3bmsf.h>
+#include <k3bmsfedit.h>
+
+#include <klocale.h>
+#include <kactioncollection.h>
+#include <kaction.h>
+#include <kpopupmenu.h>
+
+#include <qlabel.h>
+#include <qframe.h>
+#include <qlayout.h>
+
+
+K3bAudioTrackSplitDialog::K3bAudioTrackSplitDialog( K3bAudioTrack* track, QWidget* parent, const char* name )
+ : KDialogBase( KDialogBase::Plain, i18n("Split Audio Track"),
+ KDialogBase::Ok|KDialogBase::Cancel,
+ KDialogBase::Ok, parent, name ),
+ m_track(track)
+{
+ QFrame* frame = plainPage();
+
+ m_editorWidget = new K3bAudioEditorWidget( frame );
+ m_msfEditStart = new K3bMsfEdit( frame );
+ m_msfEditEnd = new K3bMsfEdit( frame );
+
+ QGridLayout* layout = new QGridLayout( frame );
+ layout->setMargin( 0 );
+ layout->setSpacing( spacingHint() );
+
+ // FIXME: After the string freeze replace the text with a better one explaning how to use this dialog
+ layout->addMultiCellWidget( new QLabel( i18n("Please select the position where the track should be split."),
+ frame ), 0, 0, 0, 3 );
+ layout->addMultiCellWidget( m_editorWidget, 1, 1, 0, 3 );
+ layout->addWidget( m_msfEditStart, 2, 1 );
+ layout->addWidget( new QLabel( " - ", frame ), 2, 2 );
+ layout->addWidget( m_msfEditEnd, 2, 3 );
+ layout->addWidget( new QLabel( i18n("Split track at:"), frame ), 2, 0 );
+ layout->setColStretch( 0, 1 );
+
+ m_editorWidget->setAllowOverlappingRanges( false );
+ m_editorWidget->enableRangeSelection( true );
+ m_editorWidget->installEventFilter( this );
+
+ connect( m_editorWidget, SIGNAL(rangeChanged(int, const K3b::Msf&, const K3b::Msf&)),
+ this, SLOT(slotRangeModified(int, const K3b::Msf&, const K3b::Msf&)) );
+ connect( m_editorWidget, SIGNAL(selectedRangeChanged(int)),
+ this, SLOT(slotRangeSelectionChanged(int)) );
+ connect( m_msfEditStart, SIGNAL(valueChanged(const K3b::Msf&)),
+ this, SLOT(slotMsfEditChanged(const K3b::Msf&)) );
+ connect( m_msfEditEnd, SIGNAL(valueChanged(const K3b::Msf&)),
+ this, SLOT(slotMsfEditChanged(const K3b::Msf&)) );
+
+ setupActions();
+
+ // load the track
+ m_editorWidget->setLength( m_track->length() );
+
+ // default split
+ K3b::Msf mid = m_track->length().lba() / 2;
+ m_editorWidget->addRange( 0, mid-1 );
+ m_editorWidget->addRange( mid, m_track->length()-1 );
+
+ slotRangeSelectionChanged( 0 );
+}
+
+
+K3bAudioTrackSplitDialog::~K3bAudioTrackSplitDialog()
+{
+}
+
+
+void K3bAudioTrackSplitDialog::setupActions()
+{
+ m_actionCollection = new KActionCollection( this );
+ m_popupMenu = new KPopupMenu( this );
+
+ KAction* actionSplitHere = new KAction( i18n("Split Here"), 0,
+ KShortcut(), this, SLOT(slotSplitHere()),
+ actionCollection(), "range_split" );
+ // FIXME: after the message freeze give this action a proper name like "Remove track part"
+ KAction* actionRemoveRange = new KAction( i18n("Remove this Range"), 0,
+ KShortcut(), this, SLOT(slotRemoveRange()),
+ actionCollection(), "range_remove" );
+
+ actionSplitHere->plug( m_popupMenu );
+ actionRemoveRange->plug( m_popupMenu );
+}
+
+
+void K3bAudioTrackSplitDialog::slotRangeModified( int id, const K3b::Msf& start, const K3b::Msf& end )
+{
+ if( id == m_editorWidget->selectedRange() ) {
+ m_msfEditStart->blockSignals( true );
+ m_msfEditEnd->blockSignals( true );
+
+ m_msfEditStart->setMsfValue( start );
+ m_msfEditEnd->setMsfValue( end );
+
+ m_msfEditStart->blockSignals( false );
+ m_msfEditEnd->blockSignals( false );
+ }
+}
+
+
+void K3bAudioTrackSplitDialog::slotMsfEditChanged( const K3b::Msf& )
+{
+ m_editorWidget->modifyRange( m_editorWidget->selectedRange(), m_msfEditStart->msfValue(), m_msfEditEnd->msfValue() );
+}
+
+
+void K3bAudioTrackSplitDialog::slotRangeSelectionChanged( int id )
+{
+ if( id > 0 ) {
+ m_msfEditStart->blockSignals( true );
+ m_msfEditEnd->blockSignals( true );
+
+ m_msfEditStart->setMsfValue( m_editorWidget->rangeStart( id ) );
+ m_msfEditEnd->setMsfValue( m_editorWidget->rangeEnd( id ) );
+ m_msfEditStart->setEnabled( true );
+ m_msfEditEnd->setEnabled( true );
+
+ m_msfEditStart->blockSignals( false );
+ m_msfEditEnd->blockSignals( false );
+ }
+ else {
+ m_msfEditStart->setEnabled( false );
+ m_msfEditEnd->setEnabled( false );
+ }
+}
+
+
+void K3bAudioTrackSplitDialog::splitAt( const QPoint& p )
+{
+ int id = m_editorWidget->findRange( p.x() );
+ if( id ) {
+ K3b::Msf msf = m_editorWidget->posToMsf( p.x() );
+ m_editorWidget->addRange( msf+1, m_editorWidget->rangeEnd( id ) );
+ m_editorWidget->modifyRange( id, m_editorWidget->rangeStart( id ), msf );
+ slotRangeSelectionChanged( m_editorWidget->selectedRange() );
+ }
+}
+
+
+bool K3bAudioTrackSplitDialog::eventFilter( QObject* o, QEvent* e )
+{
+ if( o == m_editorWidget ) {
+ if( e->type() == QEvent::MouseButtonDblClick ) {
+ QMouseEvent* me = static_cast<QMouseEvent*>( e );
+ splitAt( me->pos() );
+ }
+ else if( e->type() == QEvent::ContextMenu ) {
+ QContextMenuEvent* ce = static_cast<QContextMenuEvent*>( e );
+ ce->consume();
+ m_lastClickPosition = ce->pos();
+ if( m_editorWidget->findRange( ce->pos().x() ) > 0 )
+ m_popupMenu->popup( ce->globalPos() );
+ }
+ }
+
+ return KDialogBase::eventFilter( o, e );
+}
+
+
+void K3bAudioTrackSplitDialog::slotSplitHere()
+{
+ splitAt( m_lastClickPosition );
+}
+
+
+void K3bAudioTrackSplitDialog::slotRemoveRange()
+{
+ m_editorWidget->removeRange( m_editorWidget->findRange( m_lastClickPosition.x() ) );
+}
+
+
+void K3bAudioTrackSplitDialog::splitTrack( K3bAudioTrack* track,
+ QWidget* parent,
+ const char* name )
+{
+ K3bAudioTrackSplitDialog d( track, parent, name );
+ if( d.exec() == QDialog::Accepted ) {
+ QValueList<int> ranges = d.m_editorWidget->allRanges();
+ // we split the track at all range ends and just delete those that relate to the gaps in between
+ K3b::Msf pos = 0;
+ for( QValueList<int>::const_iterator it = ranges.constBegin();
+ it != ranges.constEnd(); ++it ) {
+
+ // delete the unwanted part
+ if( d.m_editorWidget->rangeStart( *it ) > pos ) {
+ // split so the range's start is the first frame of the new track
+ K3bAudioTrack* nextTrack = track->split( d.m_editorWidget->rangeStart( *it ) - pos );
+ delete track;
+ track = nextTrack;
+ }
+
+ // create a new track part for the range itself
+ pos = d.m_editorWidget->rangeStart( *it );
+ if( d.m_editorWidget->rangeEnd( *it ) < d.m_editorWidget->length()-1 ) {
+ // split so the range's end is the last frame in the old track
+ // and thus, the range's end + 1 the first frame in the new track
+ track = track->split( d.m_editorWidget->rangeEnd( *it ) - pos + 1 );
+ }
+ pos = d.m_editorWidget->rangeEnd( *it )+1;
+ }
+
+ // remove the last unwanted part
+ if( pos < d.m_editorWidget->length() ) {
+ delete track;
+ }
+ }
+}
+
+#include "k3baudiotracksplitdialog.moc"
diff --git a/src/projects/k3baudiotracksplitdialog.h b/src/projects/k3baudiotracksplitdialog.h
new file mode 100644
index 0000000..c4be91a
--- /dev/null
+++ b/src/projects/k3baudiotracksplitdialog.h
@@ -0,0 +1,71 @@
+/*
+ *
+ * $Id: k3baudiotracksplitdialog.h 620140 2007-01-05 12:02:29Z trueg $
+ * Copyright (C) 2004-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_AUDIO_TRACK_SPLIT_DIALOG_H_
+#define _K3B_AUDIO_TRACK_SPLIT_DIALOG_H_
+
+#include <kdialogbase.h>
+
+namespace K3b {
+ class Msf;
+}
+class K3bAudioTrack;
+class K3bAudioEditorWidget;
+class K3bMsfEdit;
+class KActionCollection;
+class KPopupMenu;
+
+
+/**
+ * Internally used by K3bAudioTrackView to get an msf value from the user.
+ */
+class K3bAudioTrackSplitDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioTrackSplitDialog( K3bAudioTrack*, QWidget* parent = 0, const char* name = 0 );
+ ~K3bAudioTrackSplitDialog();
+
+ bool eventFilter( QObject* o, QEvent* e );
+
+ KActionCollection* actionCollection() const { return m_actionCollection; }
+
+ /**
+ * if this method returns true val is filled with the user selected value.
+ */
+ static void splitTrack( K3bAudioTrack* track, QWidget* parent = 0, const char* name = 0 );
+
+ private slots:
+ void slotRangeModified( int, const K3b::Msf& start, const K3b::Msf& );
+ void slotMsfEditChanged( const K3b::Msf& msf );
+ void slotRangeSelectionChanged( int );
+ void slotSplitHere();
+ void slotRemoveRange();
+ void splitAt( const QPoint& p );
+
+ private:
+ void setupActions();
+
+ K3bAudioEditorWidget* m_editorWidget;
+ K3bMsfEdit* m_msfEditStart;
+ K3bMsfEdit* m_msfEditEnd;
+ K3bAudioTrack* m_track;
+ KActionCollection* m_actionCollection;
+ KPopupMenu* m_popupMenu;
+ QPoint m_lastClickPosition;
+};
+
+#endif
diff --git a/src/projects/k3baudiotracktrmlookupdialog.cpp b/src/projects/k3baudiotracktrmlookupdialog.cpp
new file mode 100644
index 0000000..b537583
--- /dev/null
+++ b/src/projects/k3baudiotracktrmlookupdialog.cpp
@@ -0,0 +1,131 @@
+/*
+ *
+ * $Id: k3baudiotracktrmlookupdialog.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 <config.h>
+
+#ifdef HAVE_MUSICBRAINZ
+
+#include "k3baudiotracktrmlookupdialog.h"
+#include "k3bmusicbrainzjob.h"
+
+#include <k3bbusywidget.h>
+#include <k3baudiotrack.h>
+#include <k3baudiofile.h>
+#include <k3bpassivepopup.h>
+
+#include <kmessagebox.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kglobal.h>
+#include <kdebug.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qframe.h>
+#include <qeventloop.h>
+#include <qpushbutton.h>
+#include <qapplication.h>
+
+
+K3bAudioTrackTRMLookupDialog::K3bAudioTrackTRMLookupDialog( QWidget* parent, const char* name )
+ : KDialogBase( KDialogBase::Plain,
+ i18n("MusicBrainz Query"),
+ KDialogBase::Cancel,
+ KDialogBase::Cancel,
+ parent,
+ name,
+ true,
+ true )
+{
+ QGridLayout* grid = new QGridLayout( plainPage() );
+ grid->setMargin( marginHint() );
+ grid->setSpacing( spacingHint() );
+
+ m_infoLabel = new QLabel( plainPage() );
+ QLabel* pixLabel = new QLabel( plainPage() );
+ pixLabel->setPixmap( KGlobal::iconLoader()->loadIcon( "musicbrainz", KIcon::NoGroup, 64 ) );
+ pixLabel->setScaledContents( false );
+
+ m_busyWidget = new K3bBusyWidget( plainPage() );
+
+ grid->addMultiCellWidget( pixLabel, 0, 1, 0, 0 );
+ grid->addWidget( m_infoLabel, 0, 1 );
+ grid->addWidget( m_busyWidget, 1, 1 );
+
+ m_inLoop = false;
+ m_mbJob = new K3bMusicBrainzJob( this );
+ connect( m_mbJob, SIGNAL(infoMessage(const QString&, int)),
+ this, SLOT(slotMbJobInfoMessage(const QString&, int)) );
+ connect( m_mbJob, SIGNAL(finished(bool)), this, SLOT(slotMbJobFinished(bool)) );
+ connect( m_mbJob, SIGNAL(trackFinished(K3bAudioTrack*, bool)),
+ this, SLOT(slotTrackFinished(K3bAudioTrack*, bool)) );
+}
+
+
+K3bAudioTrackTRMLookupDialog::~K3bAudioTrackTRMLookupDialog()
+{
+}
+
+
+int K3bAudioTrackTRMLookupDialog::lookup( const QPtrList<K3bAudioTrack>& tracks )
+{
+ m_mbJob->setTracks( tracks );
+ m_mbJob->start();
+
+ m_busyWidget->showBusy(true);
+ setModal( true );
+ show();
+ m_inLoop = true;
+ QApplication::eventLoop()->enterLoop();
+
+ return 0;
+}
+
+
+void K3bAudioTrackTRMLookupDialog::slotMbJobInfoMessage( const QString& message, int )
+{
+ m_infoLabel->setText( message );
+}
+
+
+void K3bAudioTrackTRMLookupDialog::slotMbJobFinished( bool )
+{
+ m_busyWidget->showBusy(false);
+ hide();
+ if( m_inLoop )
+ QApplication::eventLoop()->exitLoop();
+}
+
+
+void K3bAudioTrackTRMLookupDialog::slotCancel()
+{
+ actionButton( Cancel )->setEnabled( false );
+ m_mbJob->cancel();
+}
+
+
+void K3bAudioTrackTRMLookupDialog::slotTrackFinished( K3bAudioTrack* track, bool success )
+{
+ if( !success )
+ K3bPassivePopup::showPopup( i18n("Track %1 was not found in the MusicBrainz database.")
+ .arg( track->trackNumber()),
+ i18n("Audio Project") );
+}
+
+#include "k3baudiotracktrmlookupdialog.moc"
+
+#endif
diff --git a/src/projects/k3baudiotracktrmlookupdialog.h b/src/projects/k3baudiotracktrmlookupdialog.h
new file mode 100644
index 0000000..10a0f32
--- /dev/null
+++ b/src/projects/k3baudiotracktrmlookupdialog.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * $Id: k3baudiotracktrmlookupdialog.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_AUDIOTRACK_TRM_LOOKUP_DIALOG_H_
+#define _K3B_AUDIOTRACK_TRM_LOOKUP_DIALOG_H_
+
+#include <kdialogbase.h>
+#include <qptrlist.h>
+
+class QLabel;
+class K3bAudioTrack;
+class K3bMusicBrainzJob;
+class K3bBusyWidget;
+
+
+class K3bAudioTrackTRMLookupDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioTrackTRMLookupDialog( QWidget* parent = 0, const char* name = 0 );
+ ~K3bAudioTrackTRMLookupDialog();
+
+ /**
+ * This will show the dialog and start the lookup
+ */
+ int lookup( const QPtrList<K3bAudioTrack>& tracks );
+
+ private slots:
+ void slotMbJobFinished( bool );
+ void slotMbJobInfoMessage( const QString&, int );
+ void slotTrackFinished( K3bAudioTrack* track, bool success );
+ void slotCancel();
+
+ private:
+ QLabel* m_infoLabel;
+ K3bBusyWidget* m_busyWidget;
+ K3bMusicBrainzJob* m_mbJob;
+ bool m_inLoop;
+};
+
+#endif
diff --git a/src/projects/k3baudiotrackview.cpp b/src/projects/k3baudiotrackview.cpp
new file mode 100644
index 0000000..1af6a5c
--- /dev/null
+++ b/src/projects/k3baudiotrackview.cpp
@@ -0,0 +1,1005 @@
+/*
+ *
+ * $Id: k3baudiotrackview.cpp 689561 2007-07-18 15:19:38Z trueg $
+ * Copyright (C) 2004 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 "k3baudiotrackview.h"
+#include "k3baudiotrackviewitem.h"
+#include "k3baudiodatasourceviewitem.h"
+#include "k3baudiotrack.h"
+#include "k3baudiodatasource.h"
+#include "k3baudiotrackdialog.h"
+#include "k3baudiodoc.h"
+#include "k3baudiozerodata.h"
+#include "k3baudiotracksplitdialog.h"
+#include "k3baudiofile.h"
+#include "k3baudiotrackplayer.h"
+#include "k3baudiocdtrackdrag.h"
+#include "k3baudiocdtracksource.h"
+#include "k3baudiotracktrmlookupdialog.h"
+#include "k3baudiodatasourceeditwidget.h"
+#include "k3baudiotrackaddingdialog.h"
+
+#include <k3bview.h>
+#include <k3blistviewitemanimator.h>
+#include <k3baudiodecoder.h>
+#include <k3bmsfedit.h>
+
+#include <qheader.h>
+#include <qtimer.h>
+#include <qdragobject.h>
+#include <qpoint.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include <qevent.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qvaluelist.h>
+
+#include <kurl.h>
+#include <kurldrag.h>
+#include <klocale.h>
+#include <kaction.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <kdialogbase.h>
+
+
+K3bAudioTrackView::K3bAudioTrackView( K3bAudioDoc* doc, QWidget* parent, const char* name )
+ : K3bListView( parent, name ),
+ m_doc(doc),
+ m_updatingColumnWidths(false),
+ m_currentMouseOverItem(0),
+ m_currentlyPlayingTrack(0)
+{
+ m_player = new K3bAudioTrackPlayer( m_doc, this );
+ connect( m_player, SIGNAL(playingTrack(K3bAudioTrack*)), this,
+ SLOT(showPlayerIndicator(K3bAudioTrack*)) );
+ connect( m_player, SIGNAL(paused(bool)), this, SLOT(togglePauseIndicator(bool)) );
+ connect( m_player, SIGNAL(stopped()), this, SLOT(removePlayerIndicator()) );
+
+ setItemMargin( 5 );
+ setAcceptDrops( true );
+ setDropVisualizer( true );
+ setAllColumnsShowFocus( true );
+ setDragEnabled( true );
+ // setSelectionModeExt( KListView::Konqueror ); // FileManager in KDE3
+ setSelectionModeExt( KListView::Extended );
+ setItemsMovable( false );
+ setAlternateBackground( QColor() ); // disable alternate colors
+
+ setNoItemText( i18n("Use drag'n'drop to add audio files to the project.") + "\n"
+ + i18n("After that press the burn button to write the CD." ) );
+
+ setupColumns();
+ setupActions();
+
+ m_playerItemAnimator = new K3bListViewItemAnimator( this );
+
+ m_animationTimer = new QTimer( this );
+ connect( m_animationTimer, SIGNAL(timeout()), this, SLOT(slotAnimation()) );
+
+ m_autoOpenTrackTimer = new QTimer( this );
+ connect( m_autoOpenTrackTimer, SIGNAL(timeout()), this, SLOT(slotDragTimeout()) );
+
+ connect( this, SIGNAL(dropped(QDropEvent*, QListViewItem*, QListViewItem*)),
+ this, SLOT(slotDropped(QDropEvent*, QListViewItem*, QListViewItem*)) );
+ connect( this, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)),
+ this, SLOT(showPopupMenu(KListView*, QListViewItem*, const QPoint&)) );
+ connect( this, SIGNAL(doubleClicked(QListViewItem*, const QPoint&, int)),
+ this, SLOT(slotProperties()) );
+
+ connect( doc, SIGNAL(changed()),
+ this, SLOT(slotChanged()) );
+ connect( doc, SIGNAL(trackChanged(K3bAudioTrack*)),
+ this, SLOT(slotTrackChanged(K3bAudioTrack*)) );
+ connect( doc, SIGNAL(trackRemoved(K3bAudioTrack*)),
+ this, SLOT(slotTrackRemoved(K3bAudioTrack*)) );
+
+ slotChanged();
+
+ // a little background pix hack because I am simply incapable of doing it another way. :(
+// static QPixmap s_bgPix("/tmp/trueg/audio_bg.png");
+// setK3bBackgroundPixmap( s_bgPix, TOP_LEFT );
+}
+
+
+K3bAudioTrackView::~K3bAudioTrackView()
+{
+}
+
+
+void K3bAudioTrackView::setupColumns()
+{
+ addColumn( i18n("No.") );
+ addColumn( i18n("Artist (CD-Text)") );
+ addColumn( i18n("Title (CD-Text)") );
+ addColumn( i18n("Type") );
+ addColumn( i18n("Length") );
+ addColumn( i18n("Filename") );
+
+ setColumnAlignment( 3, Qt::AlignHCenter );
+ setColumnAlignment( 4, Qt::AlignHCenter );
+
+ setColumnWidthMode( 1, Manual );
+ setColumnWidthMode( 2, Manual );
+ setColumnWidthMode( 3, Manual );
+ setColumnWidthMode( 4, Manual );
+ setColumnWidthMode( 5, Manual );
+
+ header()->setResizeEnabled( false );
+ header()->setClickEnabled( false );
+ setSorting( -1 );
+}
+
+
+void K3bAudioTrackView::setupActions()
+{
+ m_actionCollection = new KActionCollection( this );
+ m_popupMenu = new KPopupMenu( this );
+
+ m_actionProperties = new KAction( i18n("Properties"), "misc",
+ KShortcut(), this, SLOT(slotProperties()),
+ actionCollection(), "track_properties" );
+ m_actionRemove = new KAction( i18n( "Remove" ), "editdelete",
+ Key_Delete, this, SLOT(slotRemove()),
+ actionCollection(), "track_remove" );
+
+ m_actionAddSilence = new KAction( i18n("Add Silence") + "...", "misc",
+ KShortcut(), this, SLOT(slotAddSilence()),
+ actionCollection(), "track_add_silence" );
+ m_actionMergeTracks = new KAction( i18n("Merge Tracks"), "misc",
+ KShortcut(), this, SLOT(slotMergeTracks()),
+ actionCollection(), "track_merge" );
+ m_actionSplitSource = new KAction( i18n("Source to Track"), "misc",
+ KShortcut(), this, SLOT(slotSplitSource()),
+ actionCollection(), "source_split" );
+ m_actionSplitTrack = new KAction( i18n("Split Track..."), 0,
+ KShortcut(), this, SLOT(slotSplitTrack()),
+ actionCollection(), "track_split" );
+ m_actionEditSource = new KAction( i18n("Edit Source..."), 0,
+ KShortcut(), this, SLOT(slotEditSource()),
+ actionCollection(), "source_edit" );
+ m_actionPlayTrack = new KAction( i18n("Play Track"), "player_play",
+ KShortcut(), this, SLOT(slotPlayTrack()),
+ actionCollection(), "track_play" );
+#ifdef HAVE_MUSICBRAINZ
+ KAction* mbAction = new KAction( i18n("Musicbrainz Lookup"), "musicbrainz", 0, this,
+ SLOT(slotQueryMusicBrainz()),
+ actionCollection(), "project_audio_musicbrainz" );
+ mbAction->setToolTip( i18n("Try to determine meta information over the internet") );
+#endif
+}
+
+
+bool K3bAudioTrackView::acceptDrag(QDropEvent* e) const
+{
+ // the first is for built-in item moving, the second for dropping urls, the third for dropping audio tracks
+ return ( KListView::acceptDrag(e) || KURLDrag::canDecode(e) || K3bAudioCdTrackDrag::canDecode(e) );
+}
+
+
+QDragObject* K3bAudioTrackView::dragObject()
+{
+ QPtrList<QListViewItem> list = selectedItems();
+
+ if( list.isEmpty() )
+ return 0;
+
+ KURL::List urls;
+
+ for( QPtrListIterator<QListViewItem> it(list); it.current(); ++it ) {
+ QListViewItem* item = *it;
+ // we simply ignore open track items to not include files twice
+ // we also don't want the invisible source items
+ QListViewItem* parentItem = K3bListView::parentItem(item);
+ if( !item->isOpen() && ( !parentItem || parentItem->isOpen() ) ) {
+ if( K3bAudioDataSourceViewItem* sourceItem = dynamic_cast<K3bAudioDataSourceViewItem*>( item ) ) {
+ if( K3bAudioFile* file = dynamic_cast<K3bAudioFile*>( sourceItem->source() ) )
+ urls.append( KURL::fromPathOrURL(file->filename()) );
+ }
+ else {
+ K3bAudioTrackViewItem* trackItem = static_cast<K3bAudioTrackViewItem*>( item );
+ K3bAudioDataSource* source = trackItem->track()->firstSource();
+ while( source ) {
+ if( K3bAudioFile* file = dynamic_cast<K3bAudioFile*>( source ) )
+ urls.append( KURL::fromPathOrURL(file->filename()) );
+ source = source->next();
+ }
+ }
+ }
+ }
+
+ return new KURLDrag( urls, viewport() );
+}
+
+
+void K3bAudioTrackView::slotDropped( QDropEvent* e, QListViewItem* parent, QListViewItem* after )
+{
+ m_autoOpenTrackTimer->stop();
+
+ if( !e->isAccepted() )
+ return;
+
+ m_dropTrackAfter = 0;
+ m_dropTrackParent = 0;
+ m_dropSourceAfter = 0;
+ if( after ) {
+ if( K3bAudioTrackViewItem* tv = dynamic_cast<K3bAudioTrackViewItem*>( after ) ) {
+ m_dropTrackAfter = tv->track();
+ }
+ else if( K3bAudioDataSourceViewItem* sv = dynamic_cast<K3bAudioDataSourceViewItem*>( after ) ) {
+ m_dropSourceAfter = sv->source();
+ }
+ }
+
+ if( K3bAudioTrackViewItem* tv = dynamic_cast<K3bAudioTrackViewItem*>( parent ) ) {
+ m_dropTrackParent = tv->track();
+ }
+
+ //
+ // In case the sources are not shown we do not want to handle them because the average
+ // user would be confused otherwise
+ //
+ if( m_dropTrackParent && !m_trackItemMap[m_dropTrackParent]->showingSources() ) {
+ kdDebug() << "(K3bAudioTrackView) dropped after track which does not show it's sources." << endl;
+ m_dropTrackAfter = m_dropTrackParent;
+ m_dropTrackParent = 0;
+ }
+
+ if( e->source() == viewport() ) {
+
+ bool copyItems = (e->action() == QDropEvent::Copy);
+
+ // 1. tracks (with some of their sources) -> move complete tracks around
+ // 2. sources (multiple sources) -> move the sources to the destination track
+ // 3. tracks and sources (the latter without their track) -> ignore the latter sources
+ QPtrList<K3bAudioTrack> tracks;
+ QPtrList<K3bAudioDataSource> sources;
+ getSelectedItems( tracks, sources );
+
+ //
+ // remove all sources which belong to one of the selected tracks since they will be
+ // moved along with their tracks
+ //
+ QPtrListIterator<K3bAudioDataSource> srcIt( sources );
+ while( srcIt.current() ) {
+ if( tracks.containsRef( srcIt.current()->track() ) )
+ sources.removeRef( *srcIt );
+ else
+ ++srcIt;
+ }
+
+ //
+ // Now move (or copy) all the tracks
+ //
+ for( QPtrListIterator<K3bAudioTrack> it( tracks ); it.current(); ++it ) {
+ K3bAudioTrack* track = *it;
+ if( m_dropTrackParent ) {
+ m_dropTrackParent->merge( copyItems ? track->copy() : track, m_dropSourceAfter );
+ }
+ else if( m_dropTrackAfter ) {
+ if( copyItems )
+ track->copy()->moveAfter( m_dropTrackAfter );
+ else
+ track->moveAfter( m_dropTrackAfter );
+ }
+ else {
+ if( copyItems )
+ track->copy()->moveAhead( m_doc->firstTrack() );
+ else
+ track->moveAhead( m_doc->firstTrack() );
+ }
+ }
+
+ //
+ // now move (or copy) the sources
+ //
+ for( QPtrListIterator<K3bAudioDataSource> it( sources ); it.current(); ++it ) {
+ K3bAudioDataSource* source = *it;
+ if( m_dropTrackParent ) {
+ if( m_dropSourceAfter ) {
+ if( copyItems )
+ source->copy()->moveAfter( m_dropSourceAfter );
+ else
+ source->moveAfter( m_dropSourceAfter );
+ }
+ else {
+ if( copyItems )
+ source->copy()->moveAhead( m_dropTrackParent->firstSource() );
+ else
+ source->moveAhead( m_dropTrackParent->firstSource() );
+ }
+ }
+ else {
+ // create a new track
+ K3bAudioTrack* track = new K3bAudioTrack( m_doc );
+
+ // special case: the source we remove from the track is the last and the track
+ // will be deleted.
+ if( !copyItems && m_dropTrackAfter == source->track() && m_dropTrackAfter->numberSources() == 1 )
+ m_dropTrackAfter = m_dropTrackAfter->prev();
+
+ if( copyItems )
+ track->addSource( source->copy() );
+ else
+ track->addSource( source );
+
+ if( m_dropTrackAfter ) {
+ track->moveAfter( m_dropTrackAfter );
+ m_dropTrackAfter = track;
+ }
+ else {
+ track->moveAhead( m_doc->firstTrack() );
+ m_dropTrackAfter = track;
+ }
+ }
+ }
+ }
+ else if( K3bAudioCdTrackDrag::canDecode( e ) ) {
+ kdDebug() << "(K3bAudioTrackView) audiocdtrack dropped." << endl;
+ K3bDevice::Toc toc;
+ K3bDevice::Device* dev = 0;
+ K3bCddbResultEntry cddb;
+ QValueList<int> trackNumbers;
+
+ K3bAudioCdTrackDrag::decode( e, toc, trackNumbers, cddb, &dev );
+
+ // for now we just create one source
+ for( QValueList<int>::const_iterator it = trackNumbers.begin();
+ it != trackNumbers.end(); ++it ) {
+ int trackNumber = *it;
+
+ K3bAudioCdTrackSource* source = new K3bAudioCdTrackSource( toc, trackNumber, cddb, dev );
+ if( m_dropTrackParent ) {
+ source->moveAfter( m_dropSourceAfter );
+ if( m_dropSourceAfter )
+ m_dropSourceAfter = source;
+ }
+ else {
+ K3bAudioTrack* track = new K3bAudioTrack();
+ track->setPerformer( cddb.artists[trackNumber-1] );
+ track->setTitle( cddb.titles[trackNumber-1] );
+ track->addSource( source );
+ if( m_dropTrackAfter )
+ track->moveAfter( m_dropTrackAfter );
+ else
+ m_doc->addTrack( track, 0 );
+
+ m_dropTrackAfter = track;
+ }
+ }
+ }
+ else{
+ m_dropUrls.clear();
+ if( KURLDrag::decode( e, m_dropUrls ) ) {
+ //
+ // This is a small (not to ugly) hack to circumvent problems with the
+ // event queues: the url adding dialog will be non-modal regardless of
+ // the settings in case we open it directly.
+ //
+ QTimer::singleShot( 0, this, SLOT(slotAddUrls()) );
+ }
+ }
+
+ showAllSources();
+
+ // now grab that focus
+ setFocus();
+}
+
+
+void K3bAudioTrackView::slotAddUrls()
+{
+ K3bAudioTrackAddingDialog::addUrls( m_dropUrls, m_doc, m_dropTrackAfter, m_dropTrackParent, m_dropSourceAfter, this );
+}
+
+
+void K3bAudioTrackView::slotChanged()
+{
+ kdDebug() << "(K3bAudioTrackView::slotChanged)" << endl;
+ // we only need to add new items here. Everything else is done in the
+ // specific slots below
+ K3bAudioTrack* track = m_doc->firstTrack();
+ bool newTracks = false;
+ while( track ) {
+ bool newTrack;
+ getTrackViewItem( track, &newTrack );
+ if( newTrack )
+ newTracks = true;
+ track = track->next();
+ }
+
+ if( newTracks ) {
+ m_animationTimer->start(200);
+ showAllSources();
+ }
+
+ header()->setShown( m_doc->numOfTracks() > 0 );
+
+ kdDebug() << "(K3bAudioTrackView::slotChanged) finished" << endl;
+}
+
+
+K3bAudioTrackViewItem* K3bAudioTrackView::getTrackViewItem( K3bAudioTrack* track, bool* isNewItem )
+{
+ QMap<K3bAudioTrack*, K3bAudioTrackViewItem*>::iterator itemIt = m_trackItemMap.find(track);
+ if( itemIt == m_trackItemMap.end() ) {
+ kdDebug() << "(K3bAudioTrackView) new track " << track << endl;
+ K3bAudioTrackViewItem* prevItem = 0;
+ if( track->prev() && m_trackItemMap.contains( track->prev() ) )
+ prevItem = m_trackItemMap[track->prev()];
+ K3bAudioTrackViewItem* newItem = new K3bAudioTrackViewItem( this, prevItem, track );
+ //
+ // disable the item until the files have been analysed
+ // so the user may not change the cd-text until the one from the
+ // file is loaded.
+ //
+ // Since for some reason QT thinks it's bad to open disabled items
+ // we need to open it before disabling it
+ //
+ newItem->showSources( track->numberSources() != 1 );
+ newItem->setEnabled( false );
+ m_trackItemMap[track] = newItem;
+
+ if( isNewItem )
+ *isNewItem = true;
+ return newItem;
+ }
+ else {
+ if( isNewItem )
+ *isNewItem = false;
+ return *itemIt;
+ }
+}
+
+
+void K3bAudioTrackView::slotTrackChanged( K3bAudioTrack* track )
+{
+ kdDebug() << "(K3bAudioTrackView::slotTrackChanged( " << track << " )" << endl;
+
+ //
+ // There may be some tracks around that have not been added to the list yet
+ // (and might never). We ignore them until they are in the list and then
+ // we create the item in slotChanged
+ //
+ if( track->inList() ) {
+ K3bAudioTrackViewItem* item = getTrackViewItem(track);
+ item->updateSourceItems();
+
+ if( track->numberSources() > 1 )
+ item->showSources(true);
+
+ // the length might have changed
+ item->repaint();
+
+ // FIXME: only do this if the position really changed
+ // move the item if the position has changed
+ if( track->prev() && m_trackItemMap.contains(track->prev()) )
+ item->moveItem( m_trackItemMap[track->prev()] );
+ else if( !track->prev() ) {
+ takeItem( item );
+ insertItem( item );
+ }
+
+ // start the animation in case new sources have been added
+ m_animationTimer->start( 200 );
+
+ showAllSources();
+ }
+ kdDebug() << "(K3bAudioTrackView::slotTrackChanged( " << track << " ) finished" << endl;
+}
+
+
+void K3bAudioTrackView::slotTrackRemoved( K3bAudioTrack* track )
+{
+ kdDebug() << "(K3bAudioTrackView::slotTrackRemoved( " << track << " )" << endl;
+ if ( m_playerItemAnimator->item() == m_trackItemMap[track] ) {
+ m_playerItemAnimator->stop();
+ }
+ delete m_trackItemMap[track];
+ m_trackItemMap.erase(track);
+}
+
+
+void K3bAudioTrackView::showAllSources()
+{
+ // TODO: add an action to show all sources
+
+ QListViewItem* item = firstChild();
+ while( item ) {
+ if( K3bAudioTrackViewItem* tv = dynamic_cast<K3bAudioTrackViewItem*>( item ) )
+ tv->showSources( tv->track()->numberSources() != 1 );
+ item = item->nextSibling();
+ }
+}
+
+
+void K3bAudioTrackView::keyPressEvent( QKeyEvent* e )
+{
+ // showAllSources();
+
+ K3bListView::keyPressEvent(e);
+}
+
+
+void K3bAudioTrackView::keyReleaseEvent( QKeyEvent* e )
+{
+ // showAllSources();
+
+ K3bListView::keyReleaseEvent(e);
+}
+
+
+void K3bAudioTrackView::contentsMouseMoveEvent( QMouseEvent* e )
+{
+ // showAllSources();
+
+ K3bListView::contentsMouseMoveEvent( e );
+}
+
+
+void K3bAudioTrackView::focusOutEvent( QFocusEvent* e )
+{
+ // showAllSources();
+
+ K3bListView::focusOutEvent( e );
+}
+
+
+void K3bAudioTrackView::resizeEvent( QResizeEvent* e )
+{
+ K3bListView::resizeEvent(e);
+
+ resizeColumns();
+}
+
+
+void K3bAudioTrackView::contentsDragMoveEvent( QDragMoveEvent* event )
+{
+ K3bAudioTrackViewItem* item = findTrackItem( event->pos() );
+ if( m_currentMouseOverItem != item ) {
+ showAllSources(); // hide previous sources
+ m_currentMouseOverItem = item;
+ }
+ if( m_currentMouseOverItem )
+ m_autoOpenTrackTimer->start( 1000 ); // 1 sec
+
+ K3bListView::contentsDragMoveEvent( event );
+}
+
+
+void K3bAudioTrackView::contentsDragLeaveEvent( QDragLeaveEvent* e )
+{
+ m_autoOpenTrackTimer->stop();
+ K3bListView::contentsDragLeaveEvent( e );
+}
+
+
+K3bAudioTrackViewItem* K3bAudioTrackView::findTrackItem( const QPoint& pos ) const
+{
+ QListViewItem* parent = 0;
+ QListViewItem* after = 0;
+ K3bAudioTrackView* that = const_cast<K3bAudioTrackView*>(this);
+ that->findDrop( pos, parent, after );
+ if( parent )
+ return static_cast<K3bAudioTrackViewItem*>( parent );
+ else if( K3bAudioTrackViewItem* tv = dynamic_cast<K3bAudioTrackViewItem*>(after) )
+ return tv;
+ else if( K3bAudioDataSourceViewItem* sv = dynamic_cast<K3bAudioDataSourceViewItem*>(after) )
+ return sv->trackViewItem();
+ else
+ return 0;
+}
+
+
+void K3bAudioTrackView::resizeColumns()
+{
+ if( m_updatingColumnWidths ) {
+ kdDebug() << "(K3bAudioTrackView) already updating column widths." << endl;
+ return;
+ }
+
+ m_updatingColumnWidths = true;
+
+ // now properly resize the columns
+ // minimal width for type, length, pregap
+ // fixed for filename
+ // expand for cd-text
+ int titleWidth = header()->fontMetrics().width( header()->label(1) );
+ int artistWidth = header()->fontMetrics().width( header()->label(2) );
+ int typeWidth = header()->fontMetrics().width( header()->label(3) );
+ int lengthWidth = header()->fontMetrics().width( header()->label(4) );
+ int filenameWidth = header()->fontMetrics().width( header()->label(5) );
+
+ for( QListViewItemIterator it( this ); it.current(); ++it ) {
+ artistWidth = QMAX( artistWidth, it.current()->width( fontMetrics(), this, 1 ) );
+ titleWidth = QMAX( titleWidth, it.current()->width( fontMetrics(), this, 2 ) );
+ typeWidth = QMAX( typeWidth, it.current()->width( fontMetrics(), this, 3 ) );
+ lengthWidth = QMAX( lengthWidth, it.current()->width( fontMetrics(), this, 4 ) );
+ filenameWidth = QMAX( filenameWidth, it.current()->width( fontMetrics(), this, 5 ) );
+ }
+
+ // add a margin
+ typeWidth += 10;
+ lengthWidth += 10;
+
+ // these always need to be completely visible
+ setColumnWidth( 3, typeWidth );
+ setColumnWidth( 4, lengthWidth );
+
+ int remaining = visibleWidth() - typeWidth - lengthWidth - columnWidth(0);
+
+ // now let's see if there is enough space for all
+ if( remaining >= artistWidth + titleWidth + filenameWidth ) {
+ remaining -= filenameWidth;
+ remaining -= (titleWidth + artistWidth);
+ setColumnWidth( 1, artistWidth + remaining/2 );
+ setColumnWidth( 2, titleWidth + remaining/2 );
+ setColumnWidth( 5, filenameWidth );
+ }
+ else if( remaining >= artistWidth + titleWidth + 20 ) {
+ setColumnWidth( 1, artistWidth );
+ setColumnWidth( 2, titleWidth );
+ setColumnWidth( 5, remaining - artistWidth - titleWidth );
+ }
+ else {
+ setColumnWidth( 1, remaining/3 );
+ setColumnWidth( 2, remaining/3 );
+ setColumnWidth( 5, remaining/3 );
+ }
+
+ triggerUpdate();
+ m_updatingColumnWidths = false;
+}
+
+
+void K3bAudioTrackView::slotAnimation()
+{
+ resizeColumns();
+ QListViewItem* item = firstChild();
+
+ bool animate = false;
+
+ while( item ) {
+ K3bAudioTrackViewItem* trackItem = dynamic_cast<K3bAudioTrackViewItem*>(item);
+ if( trackItem->animate() )
+ animate = true;
+ else
+ trackItem->setEnabled( true ); // files analysed, cd-text loaded
+ item = item->nextSibling();
+ }
+
+ if( !animate ) {
+ m_animationTimer->stop();
+ }
+}
+
+
+void K3bAudioTrackView::slotDragTimeout()
+{
+ m_autoOpenTrackTimer->stop();
+
+ if( m_currentMouseOverItem ) {
+ m_currentMouseOverItem->showSources( true );
+ }
+}
+
+
+void K3bAudioTrackView::getSelectedItems( QPtrList<K3bAudioTrack>& tracks,
+ QPtrList<K3bAudioDataSource>& sources )
+{
+ tracks.clear();
+ sources.clear();
+
+ QPtrList<QListViewItem> items = selectedItems();
+ for( QPtrListIterator<QListViewItem> it( items ); it.current(); ++it ) {
+ if( K3bAudioTrackViewItem* tv = dynamic_cast<K3bAudioTrackViewItem*>( *it ) )
+ tracks.append( tv->track() );
+ else {
+ K3bAudioDataSourceViewItem* sv = static_cast<K3bAudioDataSourceViewItem*>( *it );
+ // do not select hidden source items or unfinished source files
+ if( sv->trackViewItem()->showingSources() &&
+ !(sv->source()->isValid() && sv->source()->length() == 0) )
+ sources.append( sv->source() );
+ }
+ }
+}
+
+
+void K3bAudioTrackView::slotRemove()
+{
+ QPtrList<K3bAudioTrack> tracks;
+ QPtrList<K3bAudioDataSource> sources;
+ getSelectedItems( tracks, sources );
+
+ //
+ // remove all sources which belong to one of the selected tracks since they will be
+ // deleted along with their tracks
+ //
+ QPtrListIterator<K3bAudioDataSource> srcIt( sources );
+ while( srcIt.current() ) {
+ if( tracks.containsRef( srcIt.current()->track() ) )
+ sources.removeRef( *srcIt );
+ else
+ ++srcIt;
+ }
+
+ //
+ // Now delete all the tracks
+ //
+ for( QPtrListIterator<K3bAudioTrack> it( tracks ); it.current(); ++it )
+ delete *it;
+
+ //
+ // Now delete all the sources
+ //
+ for( QPtrListIterator<K3bAudioDataSource> it( sources ); it.current(); ++it )
+ delete *it;
+}
+
+
+void K3bAudioTrackView::slotAddSilence()
+{
+ QListViewItem* item = selectedItems().first();
+ if( item ) {
+ //
+ // create a simple dialog for asking the length of the silence
+ //
+ KDialogBase dlg( KDialogBase::Plain,
+ i18n("Add Silence"),
+ KDialogBase::Ok|KDialogBase::Cancel,
+ KDialogBase::Ok,
+ this );
+ QHBoxLayout* dlgLayout = new QHBoxLayout( dlg.plainPage(), 0, KDialog::spacingHint() );
+ dlgLayout->setAutoAdd( true );
+ (void)new QLabel( i18n("Length of silence:"), dlg.plainPage() );
+ K3bMsfEdit* msfEdit = new K3bMsfEdit( dlg.plainPage() );
+ msfEdit->setValue( 150 ); // 2 seconds default
+ msfEdit->setFocus();
+
+ if( dlg.exec() == QDialog::Accepted ) {
+ K3bAudioZeroData* zero = new K3bAudioZeroData( msfEdit->value() );
+ if( K3bAudioTrackViewItem* tv = dynamic_cast<K3bAudioTrackViewItem*>(item) ) {
+ tv->track()->addSource( zero );
+ }
+ else if( K3bAudioDataSourceViewItem* sv = dynamic_cast<K3bAudioDataSourceViewItem*>(item) ) {
+ zero->moveAfter( sv->source() );
+ }
+ }
+ }
+}
+
+
+void K3bAudioTrackView::slotMergeTracks()
+{
+ QPtrList<K3bAudioTrack> tracks;
+ QPtrList<K3bAudioDataSource> sources;
+ getSelectedItems( tracks, sources );
+
+ // we simply merge the selected tracks ignoring any eventually selected sources
+ K3bAudioTrack* firstTrack = tracks.first();
+ tracks.remove();
+ while( K3bAudioTrack* mergeTrack = tracks.first() ) {
+ tracks.remove();
+ firstTrack->merge( mergeTrack, firstTrack->lastSource() );
+ }
+}
+
+
+void K3bAudioTrackView::slotSplitSource()
+{
+ QListViewItem* item = selectedItems().first();
+ if( K3bAudioDataSourceViewItem* sv = dynamic_cast<K3bAudioDataSourceViewItem*>(item) ) {
+ // create a new track
+ K3bAudioTrack* track = new K3bAudioTrack( m_doc );
+ K3bAudioTrack* trackAfter = sv->source()->track();
+ if( trackAfter->numberSources() == 1 )
+ trackAfter = trackAfter->prev();
+ track->addSource( sv->source()->take() );
+ track->moveAfter( trackAfter );
+
+ // let's see if it's a file because in that case we can reuse the metainfo :)
+ // TODO: maybe add meta data to sources
+ if( K3bAudioFile* file = dynamic_cast<K3bAudioFile*>( track->firstSource() ) ) {
+ track->setArtist( file->decoder()->metaInfo( K3bAudioDecoder::META_ARTIST ) );
+ track->setTitle( file->decoder()->metaInfo( K3bAudioDecoder::META_TITLE ) );
+ track->setSongwriter( file->decoder()->metaInfo( K3bAudioDecoder::META_SONGWRITER ) );
+ track->setComposer( file->decoder()->metaInfo( K3bAudioDecoder::META_COMPOSER ) );
+ track->setCdTextMessage( file->decoder()->metaInfo( K3bAudioDecoder::META_COMMENT ) );
+ }
+ }
+}
+
+
+void K3bAudioTrackView::slotSplitTrack()
+{
+ QListViewItem* item = selectedItems().first();
+ if( K3bAudioTrackViewItem* tv = dynamic_cast<K3bAudioTrackViewItem*>(item) ) {
+ K3bAudioTrackSplitDialog::splitTrack( tv->track(), this );
+ }
+}
+
+
+void K3bAudioTrackView::slotEditSource()
+{
+ QListViewItem* item = selectedItems().first();
+
+ K3bAudioDataSource* source = 0;
+ if( K3bAudioDataSourceViewItem* sv = dynamic_cast<K3bAudioDataSourceViewItem*>(item) )
+ source = sv->source();
+ else if( K3bAudioTrackViewItem* tv = dynamic_cast<K3bAudioTrackViewItem*>(item) )
+ source = tv->track()->firstSource();
+
+ if( source ) {
+ KDialogBase dlg( KDialogBase::Plain,
+ i18n("Edit Audio Track Source"),
+ KDialogBase::Ok|KDialogBase::Cancel,
+ KDialogBase::Ok,
+ this,
+ 0,
+ true,
+ true );
+ QVBoxLayout* lay = new QVBoxLayout( dlg.plainPage() );
+ lay->setMargin( 0 );
+ lay->setSpacing( KDialog::spacingHint() );
+ lay->setAutoAdd( true );
+ K3bAudioDataSourceEditWidget* editW = new K3bAudioDataSourceEditWidget( dlg.plainPage() );
+ editW->loadSource( source );
+ if( dlg.exec() == QDialog::Accepted )
+ editW->saveSource();
+ }
+}
+
+
+void K3bAudioTrackView::showPopupMenu( KListView*, QListViewItem* item, const QPoint& pos )
+{
+ QPtrList<K3bAudioTrack> tracks;
+ QPtrList<K3bAudioDataSource> sources;
+ getSelectedItems( tracks, sources );
+
+ int numTracks = tracks.count();
+ int numSources = sources.count();
+
+ // build the menu
+ m_popupMenu->clear();
+
+ if( numTracks >= 1 ) {
+ m_actionPlayTrack->plug( m_popupMenu );
+ m_popupMenu->insertSeparator();
+ }
+
+ if( item )
+ m_actionRemove->plug( m_popupMenu );
+
+ if( numSources + numTracks == 1 )
+ m_actionAddSilence->plug( m_popupMenu );
+
+ if( numSources == 1 && numTracks == 0 ) {
+ m_popupMenu->insertSeparator();
+ m_actionSplitSource->plug( m_popupMenu );
+ m_actionEditSource->plug( m_popupMenu );
+ }
+ else if( numTracks == 1 && numSources == 0 ) {
+ m_popupMenu->insertSeparator();
+
+
+
+ if( K3bAudioTrackViewItem* tv = dynamic_cast<K3bAudioTrackViewItem*>(item) )
+ if( tv->track()->length().lba() > 60 )
+ m_actionSplitTrack->plug( m_popupMenu );
+
+ m_actionEditSource->plug( m_popupMenu );
+
+ }
+ else if( numTracks > 1 ) {
+ m_popupMenu->insertSeparator();
+ m_actionMergeTracks->plug( m_popupMenu );
+ }
+
+ m_actionProperties->plug( m_popupMenu );
+ m_popupMenu->insertSeparator();
+ static_cast<K3bView*>(m_doc->view())->actionCollection()->action( "project_burn" )->plug( m_popupMenu );
+
+ m_popupMenu->popup( pos );
+}
+
+
+void K3bAudioTrackView::slotProperties()
+{
+ QPtrList<K3bAudioTrack> tracks;
+ QPtrList<K3bAudioDataSource> sources;
+ getSelectedItems( tracks, sources );
+
+ // TODO: add tracks from sources to tracks
+
+ if( !tracks.isEmpty() ) {
+ K3bAudioTrackDialog d( tracks, this );
+ d.exec();
+ }
+ else {
+ static_cast<K3bView*>(m_doc->view())->slotProperties();
+ }
+}
+
+
+void K3bAudioTrackView::slotPlayTrack()
+{
+ QPtrList<K3bAudioTrack> tracks;
+ QPtrList<K3bAudioDataSource> sources;
+ getSelectedItems( tracks, sources );
+ if( tracks.count() > 0 )
+ m_player->playTrack( tracks.first() );
+}
+
+
+void K3bAudioTrackView::showPlayerIndicator( K3bAudioTrack* track )
+{
+ removePlayerIndicator();
+ m_currentlyPlayingTrack = track;
+ K3bAudioTrackViewItem* item = getTrackViewItem( track );
+ item->setPixmap( 1, SmallIcon( "player_play" ) );
+ m_playerItemAnimator->setItem( item, 1 );
+}
+
+
+void K3bAudioTrackView::togglePauseIndicator( bool b )
+{
+ if( m_currentlyPlayingTrack ) {
+ if( b )
+ m_playerItemAnimator->setPixmap( SmallIcon( "player_pause" ) );
+ else
+ m_playerItemAnimator->setPixmap( SmallIcon( "player_play" ) );
+ }
+}
+
+
+void K3bAudioTrackView::removePlayerIndicator()
+{
+ if( m_currentlyPlayingTrack )
+ getTrackViewItem( m_currentlyPlayingTrack )->setPixmap( 1, QPixmap() );
+ m_playerItemAnimator->stop();
+ m_currentlyPlayingTrack = 0;
+}
+
+
+void K3bAudioTrackView::slotQueryMusicBrainz()
+{
+#ifdef HAVE_MUSICBRAINZ
+ QPtrList<K3bAudioTrack> tracks;
+ QPtrList<K3bAudioDataSource> sources;
+ getSelectedItems( tracks, sources );
+
+ if( tracks.isEmpty() ) {
+ KMessageBox::sorry( this, i18n("Please select an audio track.") );
+ return;
+ }
+
+ // only one may use the tracks at the same time
+ if( m_currentlyPlayingTrack &&
+ tracks.containsRef( m_currentlyPlayingTrack ) )
+ m_player->stop();
+
+ // now do the lookup on the files.
+ K3bAudioTrackTRMLookupDialog dlg( this );
+ dlg.lookup( tracks );
+#endif
+}
+
+#include "k3baudiotrackview.moc"
diff --git a/src/projects/k3baudiotrackview.h b/src/projects/k3baudiotrackview.h
new file mode 100644
index 0000000..07415b6
--- /dev/null
+++ b/src/projects/k3baudiotrackview.h
@@ -0,0 +1,142 @@
+/*
+ *
+ * $Id: k3baudiotrackview.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2004 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_TRACK_VIEW_H_
+#define _K3B_AUDIO_TRACK_VIEW_H_
+
+#include <k3blistview.h>
+
+#include <qmap.h>
+#include <qptrlist.h>
+#include <kurl.h>
+
+class K3bAudioTrack;
+class K3bAudioTrackViewItem;
+class K3bAudioDataSource;
+class K3bAudioDoc;
+class KActionCollection;
+class KAction;
+class QDropEvent;
+class QKeyEvent;
+class QFocusEvent;
+class QMouseEvent;
+class QDragMoveEvent;
+class QTimer;
+class KPopupMenu;
+class QPainter;
+class K3bListViewItemAnimator;
+class K3bAudioTrackPlayer;
+
+
+class K3bAudioTrackView : public K3bListView
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioTrackView( K3bAudioDoc*, QWidget* parent, const char* name = 0 );
+ ~K3bAudioTrackView();
+
+ KActionCollection* actionCollection() const { return m_actionCollection; }
+
+ K3bAudioTrackPlayer* player() const { return m_player; }
+
+ void getSelectedItems( QPtrList<K3bAudioTrack>& tracks,
+ QPtrList<K3bAudioDataSource>& sources );
+
+ public slots:
+ void showPlayerIndicator( K3bAudioTrack* );
+ void togglePauseIndicator( bool b );
+ void removePlayerIndicator();
+
+ private:
+ void setupColumns();
+ void setupActions();
+ void showAllSources();
+ K3bAudioTrackViewItem* findTrackItem( const QPoint& pos ) const;
+ K3bAudioTrackViewItem* getTrackViewItem( K3bAudioTrack* track, bool* isNew = 0 );
+
+ K3bAudioDoc* m_doc;
+
+ KAction* m_actionProperties;
+ KAction* m_actionRemove;
+ KAction* m_actionAddSilence;
+ KAction* m_actionMergeTracks;
+ KAction* m_actionSplitSource;
+ KAction* m_actionSplitTrack;
+ KAction* m_actionEditSource;
+ KAction* m_actionPlayTrack;
+ KActionCollection* m_actionCollection;
+
+ bool m_updatingColumnWidths;
+
+ QMap<K3bAudioTrack*, K3bAudioTrackViewItem*> m_trackItemMap;
+
+ K3bAudioTrackViewItem* m_currentMouseOverItem;
+ QTimer* m_autoOpenTrackTimer;
+ QTimer* m_animationTimer;
+
+ KPopupMenu* m_popupMenu;
+
+ K3bAudioTrackPlayer* m_player;
+
+ // used for the audiotrackplayer indicator
+ K3bAudioTrack* m_currentlyPlayingTrack;
+
+ // to animate the player icon
+ K3bListViewItemAnimator* m_playerItemAnimator;
+
+ // used for the drop-event hack
+ KURL::List m_dropUrls;
+ K3bAudioTrack* m_dropTrackAfter;
+ K3bAudioTrack* m_dropTrackParent;
+ K3bAudioDataSource* m_dropSourceAfter;
+
+ private slots:
+ void slotAnimation();
+ void slotDropped( QDropEvent* e, QListViewItem* parent, QListViewItem* after );
+ void slotChanged();
+ void slotTrackChanged( K3bAudioTrack* );
+ void slotTrackRemoved( K3bAudioTrack* );
+ void slotDragTimeout();
+
+ // action slots
+ void slotAddSilence();
+ void slotRemove();
+ void slotMergeTracks();
+ void slotSplitSource();
+ void slotSplitTrack();
+ void showPopupMenu( KListView*, QListViewItem* item, const QPoint& pos );
+ void slotProperties();
+ void slotPlayTrack();
+ void slotQueryMusicBrainz();
+ void slotEditSource();
+
+ // drop-event hack slot
+ void slotAddUrls();
+
+ protected:
+ void keyPressEvent( QKeyEvent* e );
+ void keyReleaseEvent( QKeyEvent* e );
+ void focusOutEvent( QFocusEvent* e );
+ void contentsMouseMoveEvent( QMouseEvent* e );
+ void contentsDragMoveEvent( QDragMoveEvent* e );
+ void contentsDragLeaveEvent( QDragLeaveEvent* e );
+ void resizeEvent( QResizeEvent* e );
+ void resizeColumns();
+ bool acceptDrag(QDropEvent* e) const;
+ QDragObject* dragObject();
+};
+
+#endif
diff --git a/src/projects/k3baudiotrackviewitem.cpp b/src/projects/k3baudiotrackviewitem.cpp
new file mode 100644
index 0000000..6918e2a
--- /dev/null
+++ b/src/projects/k3baudiotrackviewitem.cpp
@@ -0,0 +1,229 @@
+/*
+ *
+ * $Id: k3baudiotrackviewitem.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2004 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 "k3baudiotrackviewitem.h"
+#include "k3baudiodatasourceviewitem.h"
+#include "k3baudiodatasource.h"
+#include "k3baudiotrackview.h"
+#include "k3baudiotrack.h"
+#include <k3bcdtextvalidator.h>
+
+#include <kiconloader.h>
+
+#include <qpainter.h>
+
+
+K3bAudioTrackViewItem::K3bAudioTrackViewItem( K3bAudioTrackView* parent,
+ K3bAudioTrackViewItem* after,
+ K3bAudioTrack* track )
+ : K3bListViewItem( parent, after ),
+ m_track( track ),
+ m_alreadyRemoved(false),
+ m_showingSources(false),
+ m_animationCounter(1)
+{
+ // columns
+ // 0 - No.
+ // 1 - Artist (CD-Text)
+ // 2 - Title (CD-Text)
+ // 3 - Type
+ // 4 - Pregap
+ // 5 - Length
+ // 6 - Filename
+
+ // animationIconNumber = 1;
+ setEditor( 1, LINE );
+ setEditor( 2, LINE );
+ setValidator( 1, new K3bCdTextValidator() );
+ setValidator( 2, validator(1) );
+
+ // setMarginVertical( 5 );
+
+ // italic type
+ QFont f(listView()->font());
+ f.setItalic( true );
+ setFont( 3, f );
+
+ // gray out filename
+ setForegroundColor( 5, listView()->palette().disabled().foreground() );
+
+ // smaller filename
+ f = listView()->font();
+ f.setPointSize( f.pointSize() - 2 );
+ setFont( 5, f );
+
+ updateSourceItems();
+}
+
+
+K3bAudioTrackViewItem::~K3bAudioTrackViewItem()
+{
+ delete validator(1);
+}
+
+
+void K3bAudioTrackViewItem::paintCell( QPainter* p, const QColorGroup& cg, int col, int width, int align )
+{
+ K3bListViewItem::paintCell( p, cg, col, width, align );
+
+ // draw the separator
+ if( listView()->firstChild() != this ) {
+ p->save();
+ // FIXME: modify the value from palette().disabled().foreground() to be lighter (or darker, depending on the background color )
+ p->setPen( Qt::lightGray );
+ p->drawLine( 0, 0, width, 0 );
+ p->restore();
+ }
+}
+
+
+void K3bAudioTrackViewItem::paintBranches( QPainter* p, const QColorGroup& cg, int w, int, int h )
+{
+ // we just want empty space
+ p->fillRect( QRect( 0, 0, w, h ), cg.base() );
+}
+
+
+QString K3bAudioTrackViewItem::text(int i) const
+{
+ // to avoid crashes when the track has been deleted and this viewitem is still around
+ if( m_alreadyRemoved )
+ return QString::null;
+
+ //
+ // We add two spaces after all strings (except the once renameable)
+ // to increase readability
+ //
+
+ switch( i )
+ {
+ case 0:
+ return QString::number( m_track->trackNumber() ).rightJustify( 2, ' ' );
+ case 1:
+ return m_track->performer();
+ case 2:
+ return m_track->title();
+ case 3:
+ if( m_showingSources )
+ return QString::null;
+ else
+ return m_track->firstSource()->type();
+ case 4:
+ return m_track->length().toString();
+ case 5:
+ if( m_showingSources )
+ return QString::null;
+ else
+ return m_track->firstSource()->sourceComment();
+ default:
+ return KListViewItem::text(i);
+ }
+}
+
+void K3bAudioTrackViewItem::setText( int col, const QString& text )
+{
+ //
+ // Stupid QListViewItem actually calls setText in paintCell. Thus, once a new item
+ // is created setText is called and in turn the doc is marked as modified since
+ // we call setArtist or setPerformer here! :(
+ //
+ // Quick fix: check if the field actually changed
+ //
+ if( col == 1 ) {
+ // this is the cd-text artist field
+ if( text != m_track->performer() )
+ m_track->setPerformer( text );
+ }
+ else if( col == 2 ) {
+ // this is the cd-text title field
+ if( text != m_track->title() )
+ m_track->setTitle( text );
+ }
+
+ KListViewItem::setText( col, text );
+}
+
+
+void K3bAudioTrackViewItem::showSources( bool show )
+{
+ setOpen(show);
+ m_showingSources = show;
+}
+
+
+void K3bAudioTrackViewItem::updateSourceItems()
+{
+ while( firstChild() )
+ delete firstChild();
+
+ K3bAudioDataSource* source = track()->firstSource();
+ K3bAudioDataSourceViewItem* sourceItem = 0;
+ while( source ) {
+ sourceItem = new K3bAudioDataSourceViewItem( this, sourceItem, source );
+ sourceItem->animate();
+ source = source->next();
+ }
+}
+
+
+bool K3bAudioTrackViewItem::animate()
+{
+ //
+ // We animate if one of the sources have length == 0
+ // otherwise we set the led
+ //
+ bool animate = false;
+ bool valid = true;
+ QListViewItem* item = firstChild();
+ while( item ) {
+ K3bAudioDataSourceViewItem* sourceItem = dynamic_cast<K3bAudioDataSourceViewItem*>( item );
+ animate = animate || sourceItem->animate();
+ valid = valid && sourceItem->source()->isValid();
+ item = item->nextSibling();
+ }
+ if( animate ) {
+ QString icon = QString( "kde%1" ).arg( m_animationCounter );
+ setPixmap( 4, SmallIcon( icon ) );
+ m_animationCounter++;
+ if ( m_animationCounter > 6 )
+ m_animationCounter = 1;
+ }
+ else {
+ // set status icon
+ setPixmap( 4, ( valid ? SmallIcon( "greenled" ) : SmallIcon( "redled" ) ) );
+ }
+ return animate;
+}
+
+
+void K3bAudioTrackViewItem::setSelected( bool s )
+{
+ K3bListViewItem::setSelected(s);
+
+ // we also select or unselect all source items
+ QListViewItem* item = firstChild();
+ while( item ) {
+ item->setSelected(s);
+ item = item->nextSibling();
+ }
+}
+
+
+void K3bAudioTrackViewItem::insertItem( QListViewItem* item )
+{
+ K3bListViewItem::insertItem( item );
+ if( isSelected() )
+ item->setSelected(true);
+}
diff --git a/src/projects/k3baudiotrackviewitem.h b/src/projects/k3baudiotrackviewitem.h
new file mode 100644
index 0000000..9eb6065
--- /dev/null
+++ b/src/projects/k3baudiotrackviewitem.h
@@ -0,0 +1,66 @@
+/*
+ *
+ * $Id: k3baudiotrackviewitem.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2004 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_TRACK_VIEWITEM_H_
+#define _K3B_AUDIO_TRACK_VIEWITEM_H_
+
+#include <k3blistview.h>
+
+class K3bAudioTrackView;
+class K3bAudioTrack;
+
+
+class K3bAudioTrackViewItem : public K3bListViewItem
+{
+ public:
+ K3bAudioTrackViewItem( K3bAudioTrackView* parent,
+ K3bAudioTrackViewItem* after,
+ K3bAudioTrack* track );
+ ~K3bAudioTrackViewItem();
+
+ /**
+ * If one of the sources still have length 0 we animate.
+ */
+ bool animate();
+
+ K3bAudioTrack* track() const { return m_track; }
+
+ void updateSourceItems();
+ bool showingSources() const { return m_showingSources; }
+ void showSources( bool show );
+ void setText( int col, const QString& text );
+ QString text( int i ) const;
+
+ /**
+ * @reimpl
+ */
+ void setSelected( bool s );
+ /**
+ * @reimpl
+ */
+ void insertItem( QListViewItem* item );
+
+ void paintBranches( QPainter*, const QColorGroup &, int, int, int );
+ void paintCell( QPainter* p, const QColorGroup& cg, int col, int width, int align );
+
+ private:
+ K3bAudioTrack* m_track;
+ bool m_alreadyRemoved;
+ bool m_showingSources;
+
+ int m_animationCounter;
+};
+
+#endif
diff --git a/src/projects/k3baudiotrackwidget.cpp b/src/projects/k3baudiotrackwidget.cpp
new file mode 100644
index 0000000..a5a3971
--- /dev/null
+++ b/src/projects/k3baudiotrackwidget.cpp
@@ -0,0 +1,162 @@
+/*
+ *
+ * $Id: k3baudiotrackwidget.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2004 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 "k3baudiotrackwidget.h"
+#include "k3baudioeditorwidget.h"
+#include "k3baudiotrack.h"
+
+#include <k3bmsfedit.h>
+#include <k3bvalidators.h>
+#include <k3bcdtextvalidator.h>
+
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qwidgetstack.h>
+#include <qgroupbox.h>
+#include <qtabwidget.h>
+
+#include <klineedit.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+
+
+K3bAudioTrackWidget::K3bAudioTrackWidget( const QPtrList<K3bAudioTrack>& tracks,
+ QWidget* parent, const char* name )
+ : base_K3bAudioTrackWidget( parent, name ),
+ m_tracks(tracks)
+{
+ m_labelPostGap->setBuddy( m_editPostGap );
+
+ QToolTip::add( m_labelPostGap, QToolTip::textFor( m_editPostGap ) );
+ QWhatsThis::add( m_labelPostGap, QWhatsThis::textFor( m_editPostGap ) );
+
+ // no post-gap for the last track
+ m_editPostGap->setDisabled( tracks.count() == 1 && !tracks.getFirst()->next() );
+
+ K3bCdTextValidator* val = new K3bCdTextValidator( this );
+ m_editSongwriter->setValidator( val );
+ m_editArranger->setValidator( val );
+ m_editComposer->setValidator( val );
+ m_editMessage->setValidator( val );
+ m_editTitle->setValidator( val );
+ m_editPerformer->setValidator( val );
+ m_editIsrc->setValidator( K3bValidators::isrcValidator( this ) );
+
+ load();
+}
+
+
+K3bAudioTrackWidget::~K3bAudioTrackWidget()
+{
+}
+
+
+void K3bAudioTrackWidget::load()
+{
+ if( !m_tracks.isEmpty() ) {
+
+ K3bAudioTrack* track = m_tracks.first();
+
+ m_editPostGap->setMsfValue( track->postGap() );
+
+ m_editTitle->setText( track->title() );
+ m_editPerformer->setText( track->artist() );
+ m_editArranger->setText( track->arranger() );
+ m_editSongwriter->setText( track->songwriter() );
+ m_editComposer->setText( track->composer() );
+ m_editIsrc->setText( track->isrc() );
+ m_editMessage->setText( track->cdTextMessage() );
+
+ m_checkCopyPermitted->setChecked( !track->copyProtection() );
+ m_checkPreemphasis->setChecked( track->preEmp() );
+
+ // load CD-Text for all other tracks
+ for( track = m_tracks.next(); track != 0; track = m_tracks.next() ) {
+
+ // FIXME: handle different post-gaps
+ // m_editPostGap->setMsfValue( track->postGap() );
+
+ if( track->title() != m_editTitle->text() )
+ m_editTitle->setText( QString::null );
+
+ if( track->artist() != m_editPerformer->text() )
+ m_editPerformer->setText( QString::null );
+
+ if( track->arranger() != m_editArranger->text() )
+ m_editArranger->setText( QString::null );
+
+ if( track->songwriter() != m_editSongwriter->text() )
+ m_editSongwriter->setText( QString::null );
+
+ if( track->composer() != m_editComposer->text() )
+ m_editComposer->setText( QString::null );
+
+ if( track->isrc() != m_editIsrc->text() )
+ m_editIsrc->setText( QString::null );
+
+ if( track->cdTextMessage() != m_editMessage->text() )
+ m_editMessage->setText( QString::null );
+ }
+
+ if( m_tracks.count() > 1 ) {
+ m_checkCopyPermitted->setNoChange();
+ m_checkPreemphasis->setNoChange();
+ }
+ }
+
+ m_editTitle->setFocus();
+}
+
+
+void K3bAudioTrackWidget::save()
+{
+ // save CD-Text, preemphasis, and copy protection for all tracks. no problem
+ for( K3bAudioTrack* track = m_tracks.first(); track != 0; track = m_tracks.next() ) {
+
+ if( m_editTitle->isModified() )
+ track->setTitle( m_editTitle->text() );
+
+ if( m_editPerformer->isModified() )
+ track->setArtist( m_editPerformer->text() );
+
+ if( m_editArranger->isModified() )
+ track->setArranger( m_editArranger->text() );
+
+ if( m_editSongwriter->isModified() )
+ track->setSongwriter( m_editSongwriter->text() );
+
+ if( m_editComposer->isModified() )
+ track->setComposer( m_editComposer->text() );
+
+ if( m_editIsrc->isModified() )
+ track->setIsrc( m_editIsrc->text() );
+
+ if( m_editMessage->isModified() )
+ track->setCdTextMessage( m_editMessage->text() );
+
+ if( m_checkCopyPermitted->state() != QButton::NoChange )
+ track->setCopyProtection( !m_checkCopyPermitted->isChecked() );
+
+ if( m_checkPreemphasis->state() != QButton::NoChange )
+ track->setPreEmp( m_checkPreemphasis->isChecked() );
+
+ track->setIndex0( track->length() - m_editPostGap->msfValue() );
+ }
+}
+
+#include "k3baudiotrackwidget.moc"
diff --git a/src/projects/k3baudiotrackwidget.h b/src/projects/k3baudiotrackwidget.h
new file mode 100644
index 0000000..8f02fbb
--- /dev/null
+++ b/src/projects/k3baudiotrackwidget.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * $Id: k3baudiotrackwidget.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2004 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_TRACK_WIDGET_H_
+#define _K3B_AUDIO_TRACK_WIDGET_H_
+
+#include "base_k3baudiotrackwidget.h"
+
+#include <k3bmsf.h>
+
+#include <qptrlist.h>
+
+
+class K3bAudioTrack;
+
+
+/**
+ * This class is used internally by K3bAudioTrackDialog.
+ */
+class K3bAudioTrackWidget : public base_K3bAudioTrackWidget
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioTrackWidget( const QPtrList<K3bAudioTrack>& tracks,
+ QWidget* parent = 0, const char* name = 0 );
+ ~K3bAudioTrackWidget();
+
+ public slots:
+ void save();
+ void load();
+
+ QPtrList<K3bAudioTrack> m_tracks;
+};
+
+#endif
diff --git a/src/projects/k3baudioview.cpp b/src/projects/k3baudioview.cpp
new file mode 100644
index 0000000..3cfe0c0
--- /dev/null
+++ b/src/projects/k3baudioview.cpp
@@ -0,0 +1,136 @@
+/*
+ *
+ * $Id: k3baudioview.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 <config.h>
+
+#include "k3baudioview.h"
+#include "k3baudiotrackview.h"
+#include "k3baudioburndialog.h"
+#include "k3baudiotrackplayer.h"
+#include "k3baudioburndialog.h"
+#include "k3baudiotrackaddingdialog.h"
+#include <k3bapplication.h>
+
+#include <k3baudiodoc.h>
+#include <k3baudiotrack.h>
+#include <k3baudiofile.h>
+#include <k3bpluginmanager.h>
+
+// this is not here becasue of base_*.ui troubles
+#include "../rip/k3baudioprojectconvertingdialog.h"
+
+#include <k3bfillstatusdisplay.h>
+#include <k3bmsf.h>
+#include <k3btoolbox.h>
+#include <kactionclasses.h>
+#include <k3bprojectplugin.h>
+
+// QT-includes
+#include <qlayout.h>
+#include <qstring.h>
+
+// KDE-includes
+#include <klocale.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+
+
+
+K3bAudioView::K3bAudioView( K3bAudioDoc* pDoc, QWidget* parent, const char *name )
+ : K3bView( pDoc, parent, name )
+{
+ m_doc = pDoc;
+
+ m_songlist = new K3bAudioTrackView( m_doc, this );
+ setMainWidget( m_songlist );
+ fillStatusDisplay()->showTime();
+
+ // add button for the audio conversion
+ KAction* conversionAction = new KAction( i18n("Convert Tracks"), "redo", 0, this, SLOT(slotAudioConversion()),
+ actionCollection(), "project_audio_convert" );
+ conversionAction->setToolTip( i18n("Convert audio tracks to other audio formats." ) );
+
+ toolBox()->addButton( conversionAction );
+ toolBox()->addSeparator();
+
+ toolBox()->addButton( m_songlist->player()->action( K3bAudioTrackPlayer::ACTION_PLAY ) );
+ toolBox()->addButton( m_songlist->player()->action( K3bAudioTrackPlayer::ACTION_PAUSE ) );
+ toolBox()->addButton( m_songlist->player()->action( K3bAudioTrackPlayer::ACTION_STOP ) );
+ toolBox()->addSpacing();
+ toolBox()->addButton( m_songlist->player()->action( K3bAudioTrackPlayer::ACTION_PREV ) );
+ toolBox()->addButton( m_songlist->player()->action( K3bAudioTrackPlayer::ACTION_NEXT ) );
+ toolBox()->addSpacing();
+ toolBox()->addWidgetAction( static_cast<KWidgetAction*>(m_songlist->player()->action( K3bAudioTrackPlayer::ACTION_SEEK )) );
+ toolBox()->addSeparator();
+
+#ifdef HAVE_MUSICBRAINZ
+ kdDebug() << "(K3bAudioView) m_songlist->actionCollection()->actions().count() " << m_songlist->actionCollection()->actions().count() << endl;
+ toolBox()->addButton( m_songlist->actionCollection()->action( "project_audio_musicbrainz" ) );
+ toolBox()->addSeparator();
+#endif
+
+ addPluginButtons( K3bProjectPlugin::AUDIO_CD );
+
+ toolBox()->addStretch();
+
+ // this is just for testing (or not?)
+ // most likely every project type will have it's rc file in the future
+ // we only add the additional actions since K3bView already added the default actions
+ setXML( "<!DOCTYPE kpartgui SYSTEM \"kpartgui.dtd\">"
+ "<kpartgui name=\"k3bproject\" version=\"1\">"
+ "<MenuBar>"
+ " <Menu name=\"project\"><text>&amp;Project</text>"
+ " <Action name=\"project_audio_convert\"/>"
+#ifdef HAVE_MUSICBRAINZ
+ " <Action name=\"project_audio_musicbrainz\"/>"
+#endif
+ " </Menu>"
+ "</MenuBar>"
+ "</kpartgui>", true );
+}
+
+K3bAudioView::~K3bAudioView()
+{
+}
+
+
+void K3bAudioView::init()
+{
+ if( k3bcore->pluginManager()->plugins( "AudioDecoder" ).isEmpty() )
+ KMessageBox::error( this, i18n("No audio decoder plugins found. You will not be able to add any files "
+ "to the audio project!") );
+}
+
+
+K3bProjectBurnDialog* K3bAudioView::newBurnDialog( QWidget* parent, const char* name )
+{
+ return new K3bAudioBurnDialog( m_doc, parent, name, true );
+}
+
+
+void K3bAudioView::slotAudioConversion()
+{
+ K3bAudioProjectConvertingDialog dlg( m_doc, this );
+ dlg.exec();
+}
+
+
+void K3bAudioView::addUrls( const KURL::List& urls )
+{
+ K3bAudioTrackAddingDialog::addUrls( urls, m_doc, 0, 0, 0, this );
+}
+
+#include "k3baudioview.moc"
diff --git a/src/projects/k3baudioview.h b/src/projects/k3baudioview.h
new file mode 100644
index 0000000..99740a3
--- /dev/null
+++ b/src/projects/k3baudioview.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * $Id: k3baudioview.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 K3BAUDIOVIEW_H
+#define K3BAUDIOVIEW_H
+
+#include <k3bview.h>
+#include "k3baudiotrackview.h"
+
+#include <qstringlist.h>
+
+
+class K3bAudioDoc;
+class K3bAudioTrack;
+class K3bAudioTrackView;
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bAudioView : public K3bView
+{
+ Q_OBJECT
+
+ public:
+ K3bAudioView( K3bAudioDoc* pDoc, QWidget* parent, const char *name = 0 );
+ ~K3bAudioView();
+
+ K3bAudioTrackPlayer* player() const { return m_songlist->player(); }
+
+ public slots:
+ void addUrls( const KURL::List& );
+
+ protected:
+ K3bProjectBurnDialog* newBurnDialog( QWidget* parent = 0, const char* name = 0 );
+
+ void init();
+
+ private slots:
+ void slotAudioConversion();
+
+ private:
+ K3bAudioDoc* m_doc;
+
+ K3bAudioTrackView* m_songlist;
+};
+
+#endif
diff --git a/src/projects/k3bbootimagedialog.cpp b/src/projects/k3bbootimagedialog.cpp
new file mode 100644
index 0000000..c311082
--- /dev/null
+++ b/src/projects/k3bbootimagedialog.cpp
@@ -0,0 +1,45 @@
+/*
+ *
+ * $Id: k3bbootimagedialog.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 "k3bbootimagedialog.h"
+#include "k3bbootimageview.h"
+
+#include <klocale.h>
+
+
+K3bBootImageDialog::K3bBootImageDialog( K3bDataDoc* doc,
+ QWidget* parent,
+ const char* name,
+ bool modal )
+ : KDialogBase( parent, name, modal, i18n("Boot Images"), Ok )
+{
+ m_bootImageView = new K3bBootImageView( doc, this );
+ setMainWidget( m_bootImageView );
+}
+
+
+K3bBootImageDialog::~K3bBootImageDialog()
+{
+}
+
+
+void K3bBootImageDialog::slotOk()
+{
+ // m_bootImageView->save();
+ done( Ok );
+}
+
+#include "k3bbootimagedialog.moc"
diff --git a/src/projects/k3bbootimagedialog.h b/src/projects/k3bbootimagedialog.h
new file mode 100644
index 0000000..161c4b5
--- /dev/null
+++ b/src/projects/k3bbootimagedialog.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * $Id: k3bbootimagedialog.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 K3BBOOTIMAGE_DIALOG_H
+#define K3BBOOTIMAGE_DIALOG_H
+
+#include <kdialogbase.h>
+
+class K3bBootImageView;
+class K3bDataDoc;
+
+
+class K3bBootImageDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ K3bBootImageDialog( K3bDataDoc*,
+ QWidget* parent = 0,
+ const char* name = 0,
+ bool modal = true );
+ ~K3bBootImageDialog();
+
+ private slots:
+ void slotOk();
+
+ private:
+ K3bBootImageView* m_bootImageView;
+};
+
+#endif
diff --git a/src/projects/k3bbootimageview.cpp b/src/projects/k3bbootimageview.cpp
new file mode 100644
index 0000000..22907df
--- /dev/null
+++ b/src/projects/k3bbootimageview.cpp
@@ -0,0 +1,273 @@
+/*
+ *
+ * $Id: k3bbootimageview.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 "k3bbootimageview.h"
+
+#include "k3bdatadoc.h"
+#include "k3bbootitem.h"
+#include <k3bintvalidator.h>
+
+#include <klocale.h>
+#include <klistview.h>
+#include <kfiledialog.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+
+#include <qpushbutton.h>
+#include <qstring.h>
+#include <qgroupbox.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qregexp.h>
+
+
+
+class K3bBootImageView::PrivateBootImageViewItem : public KListViewItem
+{
+public:
+ PrivateBootImageViewItem( K3bBootItem* image, QListView* parent )
+ : KListViewItem( parent ),
+ m_image( image ) {
+
+ }
+
+ PrivateBootImageViewItem( K3bBootItem* image, QListView* parent, QListViewItem* after )
+ : KListViewItem( parent, after ),
+ m_image( image ) {
+
+ }
+
+ QString text( int col ) const {
+ if( col == 0 ) {
+ if( m_image->imageType() == K3bBootItem::FLOPPY )
+ return i18n("Floppy");
+ else if( m_image->imageType() == K3bBootItem::HARDDISK )
+ return i18n("Harddisk");
+ else
+ return i18n("None");
+ }
+ else if( col == 1 )
+ return QString( "%1 KB" ).arg( m_image->size()/1024 );
+ else if( col == 2 )
+ return m_image->localPath();
+ else
+ return QString::null;
+ }
+
+ K3bBootItem* bootImage() const { return m_image; }
+
+private:
+ K3bBootItem* m_image;
+};
+
+
+K3bBootImageView::K3bBootImageView( K3bDataDoc* doc, QWidget* parent, const char* name )
+ : base_K3bBootImageView( parent, name ),
+ m_doc(doc)
+{
+ connect( m_buttonNew, SIGNAL(clicked()),
+ this, SLOT(slotNewBootImage()) );
+ connect( m_buttonDelete, SIGNAL(clicked()),
+ this, SLOT(slotDeleteBootImage()) );
+ connect( m_buttonToggleOptions, SIGNAL(clicked()),
+ this, SLOT(slotToggleOptions()) );
+ connect( m_viewImages, SIGNAL(selectionChanged()),
+ this, SLOT(slotSelectionChanged()) );
+ connect( m_radioNoEmulation, SIGNAL(toggled(bool)),
+ this, SLOT(slotNoEmulationToggled(bool)) );
+
+ K3bIntValidator* v = new K3bIntValidator( this );
+ m_editLoadSegment->setValidator( v );
+ m_editLoadSize->setValidator( v );
+
+ updateBootImages();
+
+ showAdvancedOptions( false );
+ loadBootItemSettings(0);
+}
+
+K3bBootImageView::~K3bBootImageView()
+{
+}
+
+
+void K3bBootImageView::slotToggleOptions()
+{
+ showAdvancedOptions( !m_groupOptions->isVisible() );
+}
+
+
+void K3bBootImageView::showAdvancedOptions( bool show )
+{
+ if( show ) {
+ m_groupOptions->show();
+ m_buttonToggleOptions->setText( i18n("Hide Advanced Options") );
+ }
+ else {
+ m_groupOptions->hide();
+ m_buttonToggleOptions->setText( i18n("Show Advanced Options") );
+ }
+}
+
+
+void K3bBootImageView::slotNewBootImage()
+{
+ QString file = KFileDialog::getOpenFileName( QString::null, QString::null, this, i18n("Please Choose Boot Image") );
+ if( !file.isEmpty() ) {
+ KIO::filesize_t fsize = K3b::filesize( file );
+ int boottype = K3bBootItem::FLOPPY;
+ if( fsize != 1200*1024 &&
+ fsize != 1440*1024 &&
+ fsize != 2880*1024 ) {
+ switch( KMessageBox::warningYesNoCancel( this,
+ i18n("<p>The file you selected is not a floppy image (floppy images are "
+ "of size 1200 KB, 1440 KB, or 2880 KB). You may still use boot images "
+ "of other sizes by emulating a harddisk or disabling emulation completely. "
+ "<p>If you are not familiar with terms like 'harddisk emulation' you most "
+ "likely want to use a floppy image here. Floppy images can be created by "
+ "directly extracting them from a real floppy disk:"
+ "<pre>dd if=/dev/floppy of=/tmp/floppy.img</pre>"
+ "or by using one of the many boot floppy generators that can be found on "
+ "<a href=\"http://www.google.com/search?q=linux+boot+floppy&ie=UTF-8&oe=UTF-8\">the internet</a>."),
+ i18n("No Floppy image selected"),
+ i18n("Use harddisk emulation"),
+ i18n("Use no emulation"),
+ QString::null,
+ KMessageBox::AllowLink ) ) {
+ case KMessageBox::Yes:
+ boottype = K3bBootItem::HARDDISK;
+ break;
+ case KMessageBox::No:
+ boottype = K3bBootItem::NONE;
+ break;
+ default:
+ return;
+ }
+ }
+
+ m_doc->createBootItem( file )->setImageType( boottype );
+ updateBootImages();
+ }
+}
+
+
+void K3bBootImageView::slotDeleteBootImage()
+{
+ QListViewItem* item = m_viewImages->selectedItem();
+ if( item ) {
+ K3bBootItem* i = ((PrivateBootImageViewItem*)item)->bootImage();
+ delete item;
+ m_doc->removeItem( i );
+ }
+}
+
+
+void K3bBootImageView::slotSelectionChanged()
+{
+ QListViewItem* item = m_viewImages->selectedItem();
+ if( item )
+ loadBootItemSettings( ((PrivateBootImageViewItem*)item)->bootImage() );
+ else
+ loadBootItemSettings( 0 );
+}
+
+
+void K3bBootImageView::updateBootImages()
+{
+ m_viewImages->clear();
+ for( QPtrListIterator<K3bBootItem> it( m_doc->bootImages() ); it.current(); ++it ) {
+ (void)new PrivateBootImageViewItem( *it, m_viewImages,
+ m_viewImages->lastItem() );
+ }
+}
+
+
+void K3bBootImageView::loadBootItemSettings( K3bBootItem* item )
+{
+ // this is needed to prevent the slots to change stuff
+ m_loadingItem = true;
+
+ if( item ) {
+ m_groupOptions->setEnabled(true);
+ m_groupImageType->setEnabled(true);
+
+ m_checkNoBoot->setChecked( item->noBoot() );
+ m_checkInfoTable->setChecked( item->bootInfoTable() );
+ m_editLoadSegment->setText( "0x" + QString::number( item->loadSegment(), 16 ) );
+ m_editLoadSize->setText( "0x" + QString::number( item->loadSize(), 16 ) );
+
+ if( item->imageType() == K3bBootItem::FLOPPY )
+ m_radioFloppy->setChecked(true);
+ else if( item->imageType() == K3bBootItem::HARDDISK )
+ m_radioHarddisk->setChecked(true);
+ else
+ m_radioNoEmulation->setChecked(true);
+
+ // force floppy size
+ KIO::filesize_t fsize = K3b::filesize( item->localPath() );
+ m_radioFloppy->setDisabled( fsize != 1200*1024 &&
+ fsize != 1440*1024 &&
+ fsize != 2880*1024 );
+ }
+ else {
+ m_groupOptions->setEnabled(false);
+ m_groupImageType->setEnabled(false);
+ }
+
+ m_loadingItem = false;
+}
+
+
+void K3bBootImageView::slotOptionsChanged()
+{
+ if( !m_loadingItem ) {
+ QListViewItem* item = m_viewImages->selectedItem();
+ if( item ) {
+ K3bBootItem* i = ((PrivateBootImageViewItem*)item)->bootImage();
+
+ i->setNoBoot( m_checkNoBoot->isChecked() );
+ i->setBootInfoTable( m_checkInfoTable->isChecked() );
+
+ // TODO: create some class K3bIntEdit : public QLineEdit
+ bool ok = true;
+ i->setLoadSegment( K3bIntValidator::toInt( m_editLoadSegment->text(), &ok ) );
+ if( !ok )
+ kdDebug() << "(K3bBootImageView) parsing number failed: " << m_editLoadSegment->text().lower() << endl;
+ i->setLoadSize( K3bIntValidator::toInt( m_editLoadSize->text(), &ok ) );
+ if( !ok )
+ kdDebug() << "(K3bBootImageView) parsing number failed: " << m_editLoadSize->text().lower() << endl;
+
+ if( m_radioFloppy->isChecked() )
+ i->setImageType( K3bBootItem::FLOPPY );
+ else if( m_radioHarddisk->isChecked() )
+ i->setImageType( K3bBootItem::HARDDISK );
+ else
+ i->setImageType( K3bBootItem::NONE );
+ }
+ }
+}
+
+
+void K3bBootImageView::slotNoEmulationToggled( bool on )
+{
+ // it makes no sense to combine no emulation and no boot!
+ // the base_widget takes care of the disabling
+ if( on )
+ m_checkNoBoot->setChecked(false);
+}
+
+#include "k3bbootimageview.moc"
diff --git a/src/projects/k3bbootimageview.h b/src/projects/k3bbootimageview.h
new file mode 100644
index 0000000..cf41de1
--- /dev/null
+++ b/src/projects/k3bbootimageview.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * $Id: k3bbootimageview.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_BOOTIMAGEVIEW_H
+#define K3B_BOOTIMAGEVIEW_H
+
+#include "base_k3bbootimageview.h"
+
+class K3bDataDoc;
+class K3bBootItem;
+
+
+class K3bBootImageView : public base_K3bBootImageView
+{
+ Q_OBJECT
+
+public:
+ K3bBootImageView( K3bDataDoc* doc, QWidget* parent = 0, const char* name = 0 );
+ ~K3bBootImageView();
+
+ private slots:
+ void slotNewBootImage();
+ void slotDeleteBootImage();
+ void slotToggleOptions();
+ void slotSelectionChanged();
+
+ /* reimplemeted from base_...*/
+ void slotOptionsChanged();
+
+ void slotNoEmulationToggled( bool );
+
+ private:
+ void updateBootImages();
+ void showAdvancedOptions( bool );
+ void loadBootItemSettings( K3bBootItem* );
+
+ class PrivateBootImageViewItem;
+
+ K3bDataDoc* m_doc;
+
+ bool m_loadingItem;
+};
+
+#endif
diff --git a/src/projects/k3bdataadvancedimagesettingswidget.cpp b/src/projects/k3bdataadvancedimagesettingswidget.cpp
new file mode 100644
index 0000000..ac24813
--- /dev/null
+++ b/src/projects/k3bdataadvancedimagesettingswidget.cpp
@@ -0,0 +1,352 @@
+/*
+ *
+ * $Id: k3bdataadvancedimagesettingswidget.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 "k3bdataadvancedimagesettingswidget.h"
+
+#include "k3bisooptions.h"
+
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qheader.h>
+#include <qwhatsthis.h>
+#include <qpoint.h>
+#include <qpainter.h>
+#include <qpalette.h>
+#include <qvalidator.h>
+#include <qregexp.h>
+
+#include <klistview.h>
+#include <kcombobox.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+
+static const char * mkisofsCharacterSets[] = { "cp10081",
+ "cp10079",
+ "cp10029",
+ "cp10007",
+ "cp10006",
+ "cp10000",
+ "koi8-u",
+ "koi8-r",
+ "cp1251",
+ "cp1250",
+ "cp874",
+ "cp869",
+ "cp866",
+ "cp865",
+ "cp864",
+ "cp863",
+ "cp862",
+ "cp861",
+ "cp860",
+ "cp857",
+ "cp855",
+ "cp852",
+ "cp850",
+ "cp775",
+ "cp737",
+ "cp437",
+ "iso8859-15",
+ "iso8859-14",
+ "iso8859-9",
+ "iso8859-8",
+ "iso8859-7",
+ "iso8859-6",
+ "iso8859-5",
+ "iso8859-4",
+ "iso8859-3",
+ "iso8859-2",
+ "iso8859-1",
+ 0 }; // terminating zero
+
+
+
+class K3bDataAdvancedImageSettingsWidget::PrivateIsoWhatsThis : public QWhatsThis
+{
+public:
+ PrivateIsoWhatsThis( K3bDataAdvancedImageSettingsWidget* w )
+ : QWhatsThis( w->m_viewIsoSettings->viewport() ) {
+ this->w = w;
+ }
+
+ QString text( const QPoint& p ) {
+ QListViewItem* i = w->m_viewIsoSettings->selectedItem(); // dies funktioniert nur bei rechtsklick
+ QListViewItem* i2 = w->m_viewIsoSettings->itemAt( p ); // dies funktioniert nur bei action whatsthis
+
+ if( i2 != 0 )
+ kdDebug() << "at p " << i2->text(0) << endl;
+
+ if( i == w->m_checkAllowUntranslatedFilenames )
+ return i18n( "Force all options below" );
+ else if( i == w->m_radioIsoLevel1 ||
+ i == w->m_radioIsoLevel2 ||
+ i == w->m_radioIsoLevel3 ||
+ i == w->m_isoLevelController )
+ return i18n( "<p>Set the ISO-9660 conformance level.\n"
+ "<ul>\n"
+ "<li>Level 1: Files may only consist of one section and filenames are restricted "
+ "to 8.3 characters.</li>\n"
+ "<li>Level 2: Files may only consist of one section.</li>\n"
+ "<li>Level 3: No restrictions.</li>\n"
+ "</ul>\n"
+ "<p>With all ISO-9660 levels, all filenames are restricted to upper case letters, "
+ "numbers and the underscore (_). The maximum filename length is 31 characters, the "
+ "directory nesting level is restricted to 8 and the maximum path length is limited "
+ "to 255 characters. (These restrictions may be violated with the additional ISO-9660 K3b offers)." );
+ else
+ return i18n("Set special ISO9660 Filesystem preferences.");
+ }
+
+private:
+ K3bDataAdvancedImageSettingsWidget* w;
+};
+
+
+
+class K3bDataAdvancedImageSettingsWidget::PrivateCheckViewItem : public QCheckListItem
+{
+public:
+ PrivateCheckViewItem( QListView* parent, const QString& text, Type tt = Controller )
+ : QCheckListItem( parent, text, tt ) {
+ }
+
+ PrivateCheckViewItem( QListViewItem* parent, const QString& text, Type tt = Controller )
+ : QCheckListItem( parent, text, tt ) {
+ }
+
+protected:
+ void stateChange( bool on ) {
+ // enable or disable all children
+ QListViewItem* item = firstChild();
+ while( item ) {
+ if( PrivateCheckViewItem* pi = dynamic_cast<PrivateCheckViewItem*>(item) )
+ pi->setEnabled( !on );
+ item = item->nextSibling();
+ }
+ }
+};
+
+
+K3bDataAdvancedImageSettingsWidget::K3bDataAdvancedImageSettingsWidget( QWidget* parent, const char* name )
+ : base_K3bAdvancedDataImageSettings( parent, name )
+{
+ m_viewIsoSettings->header()->hide();
+ m_viewIsoSettings->setSorting( -1 );
+
+ // create WhatsThis for the isoSettings view
+ (void)new PrivateIsoWhatsThis( this );
+
+ // create all the view items
+ QCheckListItem* iso9660Root = new QCheckListItem( m_viewIsoSettings,
+ i18n("IS09660 Settings"),
+ QCheckListItem::Controller );
+ QCheckListItem* rrRoot = new QCheckListItem( m_viewIsoSettings,
+ iso9660Root,
+ i18n("Rock Ridge Settings"),
+ QCheckListItem::Controller );
+ QCheckListItem* jolietRoot = new QCheckListItem( m_viewIsoSettings,
+ rrRoot,
+ i18n("Joliet Settings"),
+ QCheckListItem::Controller );
+ QCheckListItem* miscRoot = new QCheckListItem( m_viewIsoSettings,
+ jolietRoot,
+ i18n("Misc Settings"),
+ QCheckListItem::Controller );
+
+ // ISO9660 settings
+ m_checkAllowUntranslatedFilenames = new PrivateCheckViewItem( iso9660Root,
+ i18n( "Allow untranslated ISO9660 filenames" ),
+ QCheckListItem::CheckBox );
+ m_checkAllowMaxLengthFilenames = new PrivateCheckViewItem( m_checkAllowUntranslatedFilenames,
+ i18n( "Allow max length ISO9660 filenames (37 characters)" ),
+ QCheckListItem::CheckBox );
+ m_checkAllowFullAscii = new PrivateCheckViewItem( m_checkAllowUntranslatedFilenames,
+ i18n( "Allow full ASCII charset for ISO9660 filenames" ),
+ QCheckListItem::CheckBox );
+ m_checkAllowOther = new PrivateCheckViewItem( m_checkAllowUntranslatedFilenames,
+ i18n( "Allow ~ and # in ISO9660 filenames" ),
+ QCheckListItem::CheckBox );
+ m_checkAllowLowercaseCharacters = new PrivateCheckViewItem( m_checkAllowUntranslatedFilenames,
+ i18n( "Allow lowercase characters in ISO9660 filenames" ),
+ QCheckListItem::CheckBox );
+ m_checkAllowMultiDot = new PrivateCheckViewItem( m_checkAllowUntranslatedFilenames,
+ i18n( "Allow multiple dots in ISO9660 filenames" ),
+ QCheckListItem::CheckBox );
+ m_checkAllow31CharFilenames = new PrivateCheckViewItem( m_checkAllowUntranslatedFilenames,
+ i18n( "Allow 31 character ISO9660 filenames" ),
+ QCheckListItem::CheckBox );
+ m_checkAllowBeginningPeriod = new PrivateCheckViewItem( m_checkAllowUntranslatedFilenames,
+ i18n( "Allow leading period in ISO9660 filenames" ),
+ QCheckListItem::CheckBox );
+ m_checkOmitVersionNumbers = new PrivateCheckViewItem( m_checkAllowUntranslatedFilenames,
+ i18n( "Omit version numbers in ISO9660 filenames" ),
+ QCheckListItem::CheckBox );
+ m_checkOmitTrailingPeriod = new PrivateCheckViewItem( m_checkAllowUntranslatedFilenames,
+ i18n( "Omit trailing period in ISO9660 filenames" ),
+ QCheckListItem::CheckBox );
+
+ m_checkAllowUntranslatedFilenames->setOpen(true);
+ m_isoLevelController = new QCheckListItem( iso9660Root,
+ m_checkAllowUntranslatedFilenames,
+ i18n("ISO Level") );
+
+ m_radioIsoLevel3 = new QCheckListItem( m_isoLevelController,
+ i18n("Level %1").arg(3),
+ QCheckListItem::RadioButton );
+ m_radioIsoLevel2 = new QCheckListItem( m_isoLevelController,
+ i18n("Level %1").arg(2),
+ QCheckListItem::RadioButton );
+ m_radioIsoLevel1 = new QCheckListItem( m_isoLevelController,
+ i18n("Level %1").arg(1),
+ QCheckListItem::RadioButton );
+
+ m_isoLevelController->setOpen(true);
+
+ // Joliet Settings
+ m_checkJolietLong = new QCheckListItem( jolietRoot,
+ i18n("Allow 103 character Joliet filenames"),
+ QCheckListItem::CheckBox );
+
+ // Rock Ridge Settings
+ m_checkCreateTransTbl = new QCheckListItem( rrRoot,
+ i18n( "Create TRANS.TBL files" ),
+ QCheckListItem::CheckBox );
+ m_checkHideTransTbl = new QCheckListItem( rrRoot, m_checkCreateTransTbl,
+ i18n( "Hide TRANS.TBL files in Joliet" ),
+ QCheckListItem::CheckBox );
+
+ // Misc Settings
+// m_checkFollowSymbolicLinks = new QCheckListItem( m_viewIsoSettings,
+// i18n( "Follow symbolic links" ),
+// QCheckListItem::CheckBox );
+
+ m_checkDoNotCacheInodes = new QCheckListItem( miscRoot,
+ i18n("Do not cache inodes" ),
+ QCheckListItem::CheckBox );
+
+ iso9660Root->setOpen( true );
+ jolietRoot->setOpen( true );
+ rrRoot->setOpen( true );
+ miscRoot->setOpen( true );
+
+
+ m_comboInputCharset->setValidator( new QRegExpValidator( QRegExp("[\\w_-]*"), this ) );
+
+ // fill charset combo
+ for( int i = 0; mkisofsCharacterSets[i]; i++ ) {
+ m_comboInputCharset->insertItem( QString( mkisofsCharacterSets[i] ) );
+ }
+
+ connect( m_checkJoliet, SIGNAL(toggled(bool)), this, SLOT(slotJolietToggled(bool)) );
+}
+
+
+K3bDataAdvancedImageSettingsWidget::~K3bDataAdvancedImageSettingsWidget()
+{
+}
+
+
+void K3bDataAdvancedImageSettingsWidget::load( const K3bIsoOptions& o )
+{
+ m_checkRockRidge->setChecked( o.createRockRidge() );
+ m_checkJoliet->setChecked( o.createJoliet() );
+ m_checkUdf->setChecked( o.createUdf() );
+
+ switch( o.ISOLevel() ) {
+ case 1:
+ m_radioIsoLevel1->setOn(true);
+ break;
+ case 2:
+ m_radioIsoLevel2->setOn(true);
+ break;
+ case 3:
+ m_radioIsoLevel3->setOn(true);
+ break;
+ }
+
+ m_checkForceInputCharset->setChecked( o.forceInputCharset() );
+ m_comboInputCharset->setEditText( o.inputCharset() );
+ m_checkPreservePermissions->setChecked( o.preserveFilePermissions() );
+
+ // RR settings
+ m_checkCreateTransTbl->setOn( o.createTRANS_TBL() );
+ m_checkHideTransTbl->setOn( o.hideTRANS_TBL() );
+
+ // iso9660 settings
+ m_checkAllowUntranslatedFilenames->setOn( o.ISOuntranslatedFilenames() );
+ m_checkAllow31CharFilenames->setOn( o.ISOallow31charFilenames() );
+ m_checkAllowMaxLengthFilenames->setOn( o.ISOmaxFilenameLength() );
+ m_checkAllowBeginningPeriod->setOn( o.ISOallowPeriodAtBegin() );
+ m_checkAllowFullAscii->setOn( o.ISOrelaxedFilenames() );
+ m_checkOmitVersionNumbers->setOn( o.ISOomitVersionNumbers() );
+ m_checkOmitTrailingPeriod->setOn( o.ISOomitTrailingPeriod() );
+ m_checkAllowOther->setOn( o.ISOnoIsoTranslate() );
+ m_checkAllowMultiDot->setOn( o.ISOallowMultiDot() );
+ m_checkAllowLowercaseCharacters->setOn( o.ISOallowLowercase() );
+
+ // joliet settings
+ m_checkJolietLong->setOn( o.jolietLong() );
+
+ // misc (FIXME: should not be here)
+ m_checkDoNotCacheInodes->setOn( o.doNotCacheInodes() );
+
+ slotJolietToggled( m_checkJoliet->isChecked() );
+}
+
+
+void K3bDataAdvancedImageSettingsWidget::save( K3bIsoOptions& o )
+{
+ o.setCreateRockRidge( m_checkRockRidge->isChecked() );
+ o.setCreateJoliet( m_checkJoliet->isChecked() );
+ o.setCreateUdf( m_checkUdf->isChecked() );
+
+ // save iso-level
+ if( m_radioIsoLevel3->isOn() )
+ o.setISOLevel( 3 );
+ else if( m_radioIsoLevel2->isOn() )
+ o.setISOLevel( 2 );
+ else
+ o.setISOLevel( 1 );
+
+ o.setForceInputCharset( m_checkForceInputCharset->isChecked() );
+ o.setInputCharset( m_comboInputCharset->currentText() );
+ o.setPreserveFilePermissions( m_checkPreservePermissions->isChecked() );
+
+ o.setCreateTRANS_TBL( m_checkCreateTransTbl->isOn() );
+ o.setHideTRANS_TBL( m_checkHideTransTbl->isOn() );
+ o.setISOuntranslatedFilenames( m_checkAllowUntranslatedFilenames->isOn() );
+ o.setISOallow31charFilenames( m_checkAllow31CharFilenames->isOn() );
+ o.setISOmaxFilenameLength( m_checkAllowMaxLengthFilenames->isOn() );
+ o.setISOallowPeriodAtBegin( m_checkAllowBeginningPeriod->isOn() );
+ o.setISOrelaxedFilenames( m_checkAllowFullAscii->isOn() );
+ o.setISOomitVersionNumbers( m_checkOmitVersionNumbers->isOn() );
+ o.setISOomitTrailingPeriod( m_checkOmitTrailingPeriod->isOn() );
+ o.setISOnoIsoTranslate( m_checkAllowOther->isOn() );
+ o.setISOallowMultiDot( m_checkAllowMultiDot->isOn() );
+ o.setISOallowLowercase( m_checkAllowLowercaseCharacters->isOn() );
+ // o.setFollowSymbolicLinks( m_checkFollowSymbolicLinks->isOn() );
+ o.setJolietLong( m_checkJolietLong->isOn() );
+ o.setDoNotCacheInodes( m_checkDoNotCacheInodes->isOn() );
+}
+
+
+void K3bDataAdvancedImageSettingsWidget::slotJolietToggled( bool on )
+{
+ m_checkJolietLong->setEnabled( on );
+}
+
+#include "k3bdataadvancedimagesettingswidget.moc"
diff --git a/src/projects/k3bdataadvancedimagesettingswidget.h b/src/projects/k3bdataadvancedimagesettingswidget.h
new file mode 100644
index 0000000..eb442e3
--- /dev/null
+++ b/src/projects/k3bdataadvancedimagesettingswidget.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * $Id: k3bdataadvancedimagesettingswidget.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_ADVANCED_IMAGE_SETTINGS_WIDGET_H
+#define K3B_DATA_ADVANCED_IMAGE_SETTINGS_WIDGET_H
+
+
+#include "base_k3badvanceddataimagesettings.h"
+
+class K3bIsoOptions;
+class QCheckListItem;
+
+
+class K3bDataAdvancedImageSettingsWidget : public base_K3bAdvancedDataImageSettings
+{
+ Q_OBJECT
+
+ public:
+ K3bDataAdvancedImageSettingsWidget( QWidget* parent = 0, const char* name = 0 );
+ ~K3bDataAdvancedImageSettingsWidget();
+
+ void load( const K3bIsoOptions& );
+ void save( K3bIsoOptions& );
+
+ private slots:
+ void slotJolietToggled( bool on );
+
+ private:
+ QCheckListItem* m_checkAllowUntranslatedFilenames;
+ QCheckListItem* m_checkAllowMaxLengthFilenames;
+ QCheckListItem* m_checkAllowFullAscii;
+ QCheckListItem* m_checkAllowOther;
+ QCheckListItem* m_checkAllowLowercaseCharacters;
+ QCheckListItem* m_checkAllowMultiDot;
+ QCheckListItem* m_checkOmitVersionNumbers;
+ QCheckListItem* m_checkOmitTrailingPeriod;
+ QCheckListItem* m_checkCreateTransTbl;
+ QCheckListItem* m_checkHideTransTbl;
+ QCheckListItem* m_checkFollowSymbolicLinks;
+ QCheckListItem* m_checkAllow31CharFilenames;
+ QCheckListItem* m_checkAllowBeginningPeriod;
+ QCheckListItem* m_checkJolietLong;
+ QCheckListItem* m_checkDoNotCacheInodes;
+
+ QCheckListItem* m_isoLevelController;
+ QCheckListItem* m_radioIsoLevel1;
+ QCheckListItem* m_radioIsoLevel2;
+ QCheckListItem* m_radioIsoLevel3;
+
+ class PrivateCheckViewItem;
+ class PrivateIsoWhatsThis;
+
+ friend class PrivateIsoWhatsThis;
+};
+
+
+#endif
diff --git a/src/projects/k3bdataburndialog.cpp b/src/projects/k3bdataburndialog.cpp
new file mode 100644
index 0000000..d920fd4
--- /dev/null
+++ b/src/projects/k3bdataburndialog.cpp
@@ -0,0 +1,289 @@
+/*
+ *
+ * $Id: k3bdataburndialog.cpp 690207 2007-07-20 10:40:19Z 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 "k3bdataburndialog.h"
+#include "k3bdataimagesettingswidget.h"
+#include "k3bdatavolumedescwidget.h"
+#include "k3bdatamultisessioncombobox.h"
+#include "k3bdataview.h"
+
+#include <k3bisooptions.h>
+#include <k3bdatadoc.h>
+#include <k3bdevice.h>
+#include <k3bwriterselectionwidget.h>
+#include <k3btempdirselectionwidget.h>
+#include <k3bjob.h>
+#include <k3bcore.h>
+#include <k3bstdguiitems.h>
+#include <k3bdatamodewidget.h>
+#include <k3bglobals.h>
+#include <k3bwritingmodewidget.h>
+
+#include <qcheckbox.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qlayout.h>
+#include <qvariant.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qpoint.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qfileinfo.h>
+#include <qtabwidget.h>
+#include <qspinbox.h>
+#include <qfile.h>
+
+#include <kmessagebox.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kfiledialog.h>
+#include <kcombobox.h>
+#include <kio/global.h>
+
+
+#include "k3bfilecompilationsizehandler.h"
+
+
+K3bDataBurnDialog::K3bDataBurnDialog(K3bDataDoc* _doc, QWidget *parent, const char *name, bool modal )
+ : K3bProjectBurnDialog( _doc, parent, name, modal )
+{
+ prepareGui();
+
+ setTitle( i18n("Data Project"), i18n("Size: %1").arg( KIO::convertSize(_doc->size()) ) );
+
+ // for now we just put the verify checkbox on the main page...
+ m_checkVerify = K3bStdGuiItems::verifyCheckBox( m_optionGroup );
+ m_optionGroupLayout->addWidget( m_checkVerify );
+
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ m_optionGroupLayout->addItem( spacer );
+
+ // create image settings tab
+ m_imageSettingsWidget = new K3bDataImageSettingsWidget( this );
+ addPage( m_imageSettingsWidget, i18n("Filesystem") );
+
+ setupSettingsTab();
+
+ connect( m_comboMultisession, SIGNAL(activated(int)),
+ this, SLOT(slotMultiSessionModeChanged()) );
+
+ m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY|K3bDevice::STATE_INCOMPLETE );
+
+ m_tempDirSelectionWidget->setSelectionMode( K3bTempDirSelectionWidget::FILE );
+ QString path = _doc->tempDir();
+ if( !path.isEmpty() ) {
+ m_tempDirSelectionWidget->setTempPath( path );
+ }
+ if( !_doc->isoOptions().volumeID().isEmpty() ) {
+ m_tempDirSelectionWidget->setDefaultImageFileName( _doc->isoOptions().volumeID() + ".iso" );
+ }
+
+ connect( m_imageSettingsWidget->m_editVolumeName, SIGNAL(textChanged(const QString&)),
+ m_tempDirSelectionWidget, SLOT(setDefaultImageFileName(const QString&)) );
+}
+
+K3bDataBurnDialog::~K3bDataBurnDialog()
+{
+}
+
+
+void K3bDataBurnDialog::saveSettings()
+{
+ K3bProjectBurnDialog::saveSettings();
+
+ // save iso image settings
+ K3bIsoOptions o = ((K3bDataDoc*)doc())->isoOptions();
+ m_imageSettingsWidget->save( o );
+ ((K3bDataDoc*)doc())->setIsoOptions( o );
+
+ // save image file path
+ ((K3bDataDoc*)doc())->setTempDir( m_tempDirSelectionWidget->tempPath() );
+
+ // save multisession settings
+ ((K3bDataDoc*)doc())->setMultiSessionMode( m_comboMultisession->multiSessionMode() );
+
+ ((K3bDataDoc*)doc())->setDataMode( m_dataModeWidget->dataMode() );
+
+ ((K3bDataDoc*)doc())->setVerifyData( m_checkVerify->isChecked() );
+}
+
+
+void K3bDataBurnDialog::readSettings()
+{
+ K3bProjectBurnDialog::readSettings();
+
+ // read multisession
+ m_comboMultisession->setMultiSessionMode( ((K3bDataDoc*)doc())->multiSessionMode() );
+
+ if( !doc()->tempDir().isEmpty() )
+ m_tempDirSelectionWidget->setTempPath( doc()->tempDir() );
+ else
+ m_tempDirSelectionWidget->setTempPath( K3b::defaultTempPath() + doc()->name() + ".iso" );
+
+ m_checkVerify->setChecked( ((K3bDataDoc*)doc())->verifyData() );
+
+ m_imageSettingsWidget->load( ((K3bDataDoc*)doc())->isoOptions() );
+
+ m_dataModeWidget->setDataMode( ((K3bDataDoc*)doc())->dataMode() );
+
+ toggleAll();
+}
+
+
+void K3bDataBurnDialog::setupSettingsTab()
+{
+ QWidget* frame = new QWidget( this );
+ QGridLayout* frameLayout = new QGridLayout( frame );
+ frameLayout->setSpacing( spacingHint() );
+ frameLayout->setMargin( marginHint() );
+
+ m_groupDataMode = new QGroupBox( 1, Qt::Vertical, i18n("Datatrack Mode"), frame );
+ m_dataModeWidget = new K3bDataModeWidget( m_groupDataMode );
+
+ QGroupBox* groupMultiSession = new QGroupBox( 1, Qt::Vertical, i18n("Multisession Mode"), frame );
+ m_comboMultisession = new K3bDataMultiSessionCombobox( groupMultiSession );
+
+ frameLayout->addWidget( m_groupDataMode, 0, 0 );
+ frameLayout->addWidget( groupMultiSession, 1, 0 );
+ frameLayout->setRowStretch( 2, 1 );
+
+ addPage( frame, i18n("Misc") );
+}
+
+
+void K3bDataBurnDialog::slotStartClicked()
+{
+ if( m_checkOnlyCreateImage->isChecked() ||
+ m_checkCacheImage->isChecked() ) {
+ QFileInfo fi( m_tempDirSelectionWidget->tempPath() );
+ if( fi.isDir() )
+ m_tempDirSelectionWidget->setTempPath( fi.filePath() + "/image.iso" );
+
+ if( QFile::exists( m_tempDirSelectionWidget->tempPath() ) ) {
+ if( KMessageBox::warningContinueCancel( this,
+ i18n("Do you want to overwrite %1?").arg(m_tempDirSelectionWidget->tempPath()),
+ i18n("File Exists"), i18n("Overwrite") )
+ == KMessageBox::Continue ) {
+ // delete the file here to avoid problems with free space in K3bProjectBurnDialog::slotStartClicked
+ QFile::remove( m_tempDirSelectionWidget->tempPath() );
+ }
+ else
+ return;
+ }
+ }
+
+ if( m_writingModeWidget->writingMode() == K3b::DAO &&
+ m_comboMultisession->multiSessionMode() != K3bDataDoc::NONE &&
+ m_writerSelectionWidget->writingApp() == K3b::CDRECORD )
+ if( KMessageBox::warningContinueCancel( this,
+ i18n("Most writers do not support writing "
+ "multisession CDs in DAO mode.") )
+ == KMessageBox::Cancel )
+ return;
+
+
+ K3bProjectBurnDialog::slotStartClicked();
+}
+
+
+void K3bDataBurnDialog::loadK3bDefaults()
+{
+ K3bProjectBurnDialog::loadK3bDefaults();
+
+ m_dataModeWidget->setDataMode( K3b::DATA_MODE_AUTO );
+
+ m_imageSettingsWidget->load( K3bIsoOptions::defaults() );
+ m_comboMultisession->setMultiSessionMode( K3bDataDoc::AUTO );
+ m_checkVerify->setChecked( false );
+
+ toggleAll();
+}
+
+
+void K3bDataBurnDialog::loadUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::loadUserDefaults(c);
+
+ m_dataModeWidget->loadConfig(c);
+ m_comboMultisession->loadConfig( c );
+
+ K3bIsoOptions o = K3bIsoOptions::load( c );
+ m_imageSettingsWidget->load( o );
+
+ m_checkVerify->setChecked( c->readBoolEntry( "verify data", false ) );
+
+ toggleAll();
+}
+
+
+void K3bDataBurnDialog::saveUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::saveUserDefaults(c);
+
+ m_dataModeWidget->saveConfig(c);
+ m_comboMultisession->saveConfig( c );
+
+ K3bIsoOptions o;
+ m_imageSettingsWidget->save( o );
+ o.save( c );
+
+ c->writeEntry( "verify data", m_checkVerify->isChecked() );
+}
+
+
+void K3bDataBurnDialog::toggleAll()
+{
+ K3bProjectBurnDialog::toggleAll();
+
+ if( m_checkSimulate->isChecked() || m_checkOnlyCreateImage->isChecked() ) {
+ m_checkVerify->setChecked(false);
+ m_checkVerify->setEnabled(false);
+ }
+ else
+ m_checkVerify->setEnabled(true);
+
+ m_comboMultisession->setDisabled( m_checkOnlyCreateImage->isChecked() );
+ m_dataModeWidget->setDisabled( m_checkOnlyCreateImage->isChecked() );
+}
+
+
+void K3bDataBurnDialog::slotMultiSessionModeChanged()
+{
+ if( m_comboMultisession->multiSessionMode() == K3bDataDoc::CONTINUE ||
+ m_comboMultisession->multiSessionMode() == K3bDataDoc::FINISH )
+ m_spinCopies->setEnabled(false);
+
+ // wait for the proper medium
+ // we have to do this in another slot than toggleAll to avoid an endless loop
+ // FIXME: K3bInteractionDialog::slotToggleAll is endless loop protected
+ if( m_comboMultisession->multiSessionMode() == K3bDataDoc::NONE )
+ m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY );
+ else if( m_comboMultisession->multiSessionMode() == K3bDataDoc::CONTINUE ||
+ m_comboMultisession->multiSessionMode() == K3bDataDoc::FINISH )
+ m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_INCOMPLETE );
+ else
+ m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY|K3bDevice::STATE_INCOMPLETE );
+}
+
+
+#include "k3bdataburndialog.moc"
diff --git a/src/projects/k3bdataburndialog.h b/src/projects/k3bdataburndialog.h
new file mode 100644
index 0000000..1d1e994
--- /dev/null
+++ b/src/projects/k3bdataburndialog.h
@@ -0,0 +1,75 @@
+/*
+ *
+ * $Id: k3bdataburndialog.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 K3BDATABURNDIALOG_H
+#define K3BDATABURNDIALOG_H
+
+#include "k3bprojectburndialog.h"
+
+class QCheckBox;
+class KComboBox;
+class QGroupBox;
+class QLabel;
+class QToolButton;
+class QRadioButton;
+class QButtonGroup;
+class K3bWriterSelectionWidget;
+class K3bTempDirSelectionWidget;
+class K3bDataDoc;
+class KLineEdit;
+class K3bDataImageSettingsWidget;
+class K3bDataModeWidget;
+class K3bDataMultiSessionCombobox;
+
+
+/**
+ *@author Sebastian Trueg
+ */
+
+class K3bDataBurnDialog : public K3bProjectBurnDialog
+{
+ Q_OBJECT
+
+ public:
+ K3bDataBurnDialog(K3bDataDoc*, QWidget *parent=0, const char *name=0, bool modal = true );
+ ~K3bDataBurnDialog();
+
+ protected:
+ void setupSettingsTab();
+ void loadK3bDefaults();
+ void loadUserDefaults( KConfigBase* );
+ void saveUserDefaults( KConfigBase* );
+ void toggleAll();
+
+ // --- settings tab ---------------------------
+ K3bDataImageSettingsWidget* m_imageSettingsWidget;
+ // ----------------------------------------------
+
+ QGroupBox* m_groupDataMode;
+ K3bDataModeWidget* m_dataModeWidget;
+ K3bDataMultiSessionCombobox* m_comboMultisession;
+
+ QCheckBox* m_checkVerify;
+
+ protected slots:
+ void slotStartClicked();
+ void saveSettings();
+ void readSettings();
+
+ void slotMultiSessionModeChanged();
+};
+
+#endif
diff --git a/src/projects/k3bdatadirtreeview.cpp b/src/projects/k3bdatadirtreeview.cpp
new file mode 100644
index 0000000..4a7ec18
--- /dev/null
+++ b/src/projects/k3bdatadirtreeview.cpp
@@ -0,0 +1,506 @@
+/*
+ *
+ * $Id: k3bdatadirtreeview.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 "k3bdatadirtreeview.h"
+#include "k3bdatafileview.h"
+#include "k3bdataview.h"
+#include "k3bdatadoc.h"
+#include "k3bdataitem.h"
+#include "k3bdiritem.h"
+#include "k3bdatapropertiesdialog.h"
+#include "k3bdataviewitem.h"
+#include "k3bdataurladdingdialog.h"
+#include <k3bview.h>
+#include <k3bvalidators.h>
+
+#include <qdragobject.h>
+#include <qheader.h>
+#include <qtimer.h>
+
+#include <klocale.h>
+#include <kaction.h>
+#include <kurldrag.h>
+#include <kinputdialog.h>
+#include <kiconloader.h>
+#include <kshortcut.h>
+
+#include <kdebug.h>
+
+
+class K3bDataDirTreeView::Private
+{
+public:
+ Private()
+ : animatedDirItem(0),
+ dropDirItem(0) {
+ }
+
+ K3bDataDirViewItem* animatedDirItem;
+ K3bDataDirViewItem* dropDirItem;
+ int animationCounter;
+ QPixmap beforeAniPixmap;
+
+ // used for the urladdingdialog hack
+ KURL::List addUrls;
+ K3bDirItem* addParentDir;
+
+ QString lastUpdateVolumeId;
+
+ QValidator* iso9660Validator;
+ QValidator* asciiValidator;
+};
+
+
+K3bDataDirTreeView::K3bDataDirTreeView( K3bView* view, K3bDataDoc* doc, QWidget* parent )
+ : K3bListView( parent ), m_view(view)
+{
+ d = new Private();
+
+ m_fileView = 0;
+
+ setAcceptDrops( true );
+ setDropVisualizer( false );
+ setDropHighlighter( true );
+ setRootIsDecorated( false );
+ setFullWidth( true );
+ setDragEnabled( true );
+ setItemsMovable( false );
+ setAlternateBackground( QColor() );
+ // setSorting(-1);
+
+ addColumn( i18n("Directory") );
+ header()->hide();
+
+ m_doc = doc;
+
+ m_root = new K3bDataRootViewItem( doc, this );
+ m_itemMap.insert( doc->root(), m_root );
+
+ connect( m_doc, SIGNAL(changed()), this, SLOT(slotDocChanged()) );
+ connect( this, SIGNAL(clicked(QListViewItem*)), this, SLOT(slotExecuted(QListViewItem*)) );
+ connect( this, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(slotExecuted(QListViewItem*)) );
+ connect( m_doc, SIGNAL(itemRemoved(K3bDataItem*)), this, SLOT(slotDataItemRemoved(K3bDataItem*)) );
+ connect( m_doc, SIGNAL(itemAdded(K3bDataItem*)), this, SLOT(slotItemAdded(K3bDataItem*)) );
+ connect( this, SIGNAL(contextMenu(KListView*,QListViewItem*, const QPoint&)),
+ this, SLOT(showPopupMenu(KListView*,QListViewItem*, const QPoint&)) );
+ connect( this, SIGNAL(dropped(QDropEvent*, QListViewItem*, QListViewItem*)),
+ this, SLOT(slotDropped(QDropEvent*, QListViewItem*, QListViewItem*)) );
+
+ setupActions();
+}
+
+
+K3bDataDirTreeView::~K3bDataDirTreeView()
+{
+ delete d;
+}
+
+
+void K3bDataDirTreeView::slotExecuted( QListViewItem* item )
+{
+ if( K3bDataDirViewItem* viewItem = dynamic_cast<K3bDataDirViewItem*>(item) )
+ emit dirSelected( viewItem->dirItem() );
+}
+
+
+bool K3bDataDirTreeView::acceptDrag(QDropEvent* e) const{
+ return ( e->source() == viewport() || KURLDrag::canDecode(e) ||
+ ( m_fileView && e->source() == m_fileView->viewport() ) );
+}
+
+
+void K3bDataDirTreeView::contentsDragMoveEvent( QDragMoveEvent* e )
+{
+ K3bListView::contentsDragMoveEvent( e );
+
+ // highlight the folder the items would be added to
+ if( d->dropDirItem )
+ d->dropDirItem->highlightIcon( false );
+
+ d->dropDirItem = dynamic_cast<K3bDataDirViewItem*>( itemAt(contentsToViewport(e->pos())) );
+ if( !d->dropDirItem )
+ d->dropDirItem = m_root;
+
+ d->dropDirItem->highlightIcon( true );
+}
+
+
+void K3bDataDirTreeView::contentsDragLeaveEvent( QDragLeaveEvent* e )
+{
+ K3bListView::contentsDragLeaveEvent( e );
+
+ // remove any highlighting
+ if( d->dropDirItem ) {
+ d->dropDirItem->highlightIcon( false );
+ d->dropDirItem = 0;
+ }
+}
+
+
+void K3bDataDirTreeView::slotDropped( QDropEvent* e, QListViewItem*, QListViewItem* )
+{
+ // remove any highlighting
+ if( d->dropDirItem ) {
+ d->dropDirItem->highlightIcon( false );
+ d->dropDirItem = 0;
+ }
+
+ if( !e->isAccepted() )
+ return;
+
+ // determine K3bDirItem to add the items to
+ if( K3bDataDirViewItem* dirViewItem = dynamic_cast<K3bDataDirViewItem*>( itemAt(contentsToViewport(e->pos())) ) ) {
+ d->addParentDir = dirViewItem->dirItem();
+ }
+ else {
+ d->addParentDir = m_doc->root();
+ }
+
+ if( d->addParentDir ) {
+
+ // startDropAnimation( parent );
+
+ // check if items have been moved
+ if( m_fileView &&
+ e->source() == m_fileView->viewport() ) {
+ // move all selected items
+ QPtrList<QListViewItem> selectedViewItems = m_fileView->selectedItems();
+ QValueList<K3bDataItem*> selectedDataItems;
+ QPtrListIterator<QListViewItem> it( selectedViewItems );
+ for( ; it.current(); ++it ) {
+ K3bDataViewItem* dataViewItem = dynamic_cast<K3bDataViewItem*>( it.current() );
+ if( dataViewItem )
+ selectedDataItems.append( dataViewItem->dataItem() );
+ else
+ kdDebug() << "no dataviewitem" << endl;
+ }
+
+ K3bDataUrlAddingDialog::copyMoveItems( selectedDataItems, d->addParentDir, this, e->action() == QDropEvent::Copy );
+ }
+ else if( e->source() == viewport() ) {
+ // move the selected dir
+ if( K3bDataDirViewItem* dirItem = dynamic_cast<K3bDataDirViewItem*>( selectedItem() ) ) {
+ QValueList<K3bDataItem*> selectedDataItems;
+ selectedDataItems.append( dirItem->dirItem() );
+ K3bDataUrlAddingDialog::copyMoveItems( selectedDataItems, d->addParentDir, this, e->action() == QDropEvent::Copy );
+ }
+ }
+ else {
+ // seems that new items have been dropped
+ d->addUrls.clear();
+ if( KURLDrag::decode( e, d->addUrls ) ) {
+ //
+ // This is a small (not to ugly) hack to circumvent problems with the
+ // event queues: the url adding dialog will be non-modal regardless of
+ // the settings in case we open it directly.
+ //
+ QTimer::singleShot( 0, this, SLOT(slotAddUrls()) );
+ }
+ }
+ }
+
+ // now grab that focus
+ setFocus();
+}
+
+
+void K3bDataDirTreeView::slotAddUrls()
+{
+ K3bDataUrlAddingDialog::addUrls( d->addUrls, d->addParentDir, this );
+}
+
+
+void K3bDataDirTreeView::slotItemAdded( K3bDataItem* item )
+{
+ if( item->isDir() ) {
+ //
+ // We assume that we do not already have an item for the dir since the itemAdded signal
+ // should only be emitted once for every item
+ //
+ K3bDirItem* dirItem = static_cast<K3bDirItem*>( item );
+ K3bDataDirViewItem* parentViewItem = m_itemMap[dirItem->parent()];
+ K3bDataDirViewItem* newDirItem = new K3bDataDirViewItem( dirItem, parentViewItem );
+ m_itemMap.insert( dirItem, newDirItem );
+ }
+}
+
+
+void K3bDataDirTreeView::slotDataItemRemoved( K3bDataItem* item )
+{
+ if( item->isDir() ) {
+ K3bDirItem* dirItem = static_cast<K3bDirItem*>( item );
+ QMapIterator<K3bDirItem*, K3bDataDirViewItem*> it = m_itemMap.find( dirItem );
+ if( it != m_itemMap.end() ) {
+ K3bDataDirViewItem* viewItem = it.data();
+ m_itemMap.remove( it );
+
+ // we don't get removedInfo for the child items
+ // so we need to remove them here
+ QPtrListIterator<K3bDataItem> it( dirItem->children() );
+ for( ; it.current(); ++it ) {
+ if( it.current()->isDir() )
+ slotDataItemRemoved( it.current() );
+ }
+
+ delete viewItem;
+ }
+ }
+}
+
+
+void K3bDataDirTreeView::setCurrentDir( K3bDirItem* dirItem )
+{
+ QMapIterator<K3bDirItem*, K3bDataDirViewItem*> it = m_itemMap.find( dirItem );
+ if( it != m_itemMap.end() ) {
+ setCurrentItem( it.data() );
+ it.data()->setOpen(true);
+ if( it.data() != root() )
+ it.data()->parent()->setOpen(true);
+ }
+ else {
+ kdDebug() << "Tried to set unknown dirItem to current" << endl;
+ }
+}
+
+
+void K3bDataDirTreeView::setupActions()
+{
+ m_actionCollection = new KActionCollection( this );
+
+ m_actionProperties = new KAction( i18n("Properties"), "misc", 0, this, SLOT(slotProperties()),
+ actionCollection(), "properties" );
+ m_actionNewDir = new KAction( i18n("New Directory..."), "folder_new", CTRL+Key_N, this, SLOT(slotNewDir()),
+ actionCollection(), "new_dir" );
+ m_actionRemove = new KAction( i18n("Remove"), "editdelete", Key_Delete, this, SLOT(slotRemoveItem()),
+ actionCollection(), "remove" );
+ KShortcut renameShortCut( Key_F2 );
+ renameShortCut.append( KShortcut(CTRL+Key_R) ); // backwards compatibility
+ m_actionRename = new KAction( i18n("Rename"), "edit", renameShortCut, this, SLOT(slotRenameItem()),
+ actionCollection(), "rename" );
+
+ m_popupMenu = new KActionMenu( m_actionCollection, "contextMenu" );
+ m_popupMenu->insert( m_actionRename );
+ m_popupMenu->insert( m_actionRemove );
+ m_popupMenu->insert( m_actionNewDir );
+ m_popupMenu->insert( new KActionSeparator( this ) );
+ m_popupMenu->insert( m_actionProperties );
+ m_popupMenu->insert( new KActionSeparator( this ) );
+ m_popupMenu->insert( m_view->actionCollection()->action("project_burn") );
+}
+
+
+void K3bDataDirTreeView::showPopupMenu( KListView*, QListViewItem* item, const QPoint& point )
+{
+ if( item ) {
+ if( K3bDataViewItem* di = dynamic_cast<K3bDataViewItem*>(item) ) {
+ m_actionRemove->setEnabled( di->dataItem()->isRemoveable() );
+ m_actionRename->setEnabled( di->dataItem()->isRenameable() );
+ }
+ else {
+ m_actionRemove->setEnabled( false );
+ m_actionRename->setEnabled( false );
+ }
+ m_actionProperties->setEnabled( true );
+ }
+ else {
+ m_actionRemove->setEnabled( false );
+ m_actionRename->setEnabled( false );
+ m_actionProperties->setEnabled( false );
+ }
+
+ m_popupMenu->popup( point );
+}
+
+
+void K3bDataDirTreeView::slotNewDir()
+{
+ if( K3bDataDirViewItem* vI = dynamic_cast<K3bDataDirViewItem*>(currentItem()) ) {
+ K3bDirItem* parent = vI->dirItem();
+
+ QString name;
+ bool ok;
+
+ name = KInputDialog::getText( i18n("New Directory"),
+ i18n("Please insert the name for the new directory:"),
+ i18n("New Directory"), &ok, this );
+
+ while( ok && K3bDataDoc::nameAlreadyInDir( name, parent ) ) {
+ name = KInputDialog::getText( i18n("New Directory"),
+ i18n("A file with that name already exists. "
+ "Please insert the name for the new directory:"),
+ i18n("New Directory"), &ok, this );
+ }
+
+ if( !ok )
+ return;
+
+
+ m_doc->addEmptyDir( name, parent );
+ }
+}
+
+
+void K3bDataDirTreeView::slotRenameItem()
+{
+ showEditor( (K3bListViewItem*)currentItem(), 0 );
+}
+
+
+void K3bDataDirTreeView::slotRemoveItem()
+{
+ if( currentItem() ) {
+ if( K3bDataDirViewItem* dirViewItem = dynamic_cast<K3bDataDirViewItem*>( currentItem() ) )
+ m_doc->removeItem( dirViewItem->dirItem() );
+ }
+}
+
+
+void K3bDataDirTreeView::slotProperties()
+{
+ K3bDataViewItem* viewItem = dynamic_cast<K3bDataViewItem*>( currentItem() );
+ if( viewItem && currentItem() != root() ) {
+ K3bDataPropertiesDialog d( viewItem->dataItem(), this );
+ if( d.exec() ) {
+ repaint();
+ if( m_fileView )
+ m_fileView->repaint();
+ }
+ }
+ else
+ m_view->slotProperties();
+}
+
+
+void K3bDataDirTreeView::startDropAnimation( K3bDirItem* dir )
+{
+ stopDropAnimation();
+
+ K3bDataDirViewItem* vI = m_itemMap[dir];
+ if( vI ) {
+ d->animationCounter = 0;
+ d->animatedDirItem = vI;
+ d->beforeAniPixmap = QPixmap( *vI->pixmap(0) );
+ QTimer::singleShot( 0, this, SLOT(slotDropAnimate()) );
+ }
+}
+
+
+void K3bDataDirTreeView::slotDropAnimate()
+{
+ if( d->animatedDirItem ) {
+ if( d->animationCounter > 5 )
+ stopDropAnimation();
+ else {
+ switch(d->animationCounter) {
+ case 0:
+ d->animatedDirItem->setPixmap( 0, SmallIcon( "folder_cyan" ) );
+ break;
+ case 1:
+ d->animatedDirItem->setPixmap( 0, SmallIcon( "folder_green" ) );
+ break;
+ case 2:
+ d->animatedDirItem->setPixmap( 0, SmallIcon( "folder_yellow" ) );
+ break;
+ case 3:
+ d->animatedDirItem->setPixmap( 0, SmallIcon( "folder_orange" ) );
+ break;
+ case 4:
+ d->animatedDirItem->setPixmap( 0, SmallIcon( "folder_red" ) );
+ break;
+ case 5:
+ d->animatedDirItem->setPixmap( 0, SmallIcon( "folder_violet" ) );
+ break;
+ }
+
+ d->animationCounter++;
+ QTimer::singleShot( 300, this, SLOT(slotDropAnimate()) );
+ }
+ }
+}
+
+
+void K3bDataDirTreeView::stopDropAnimation()
+{
+ if( d->animatedDirItem ) {
+ d->animatedDirItem->setPixmap( 0, d->beforeAniPixmap );
+ d->animatedDirItem = 0;
+ }
+}
+
+
+// FIXME: remove this
+void K3bDataDirTreeView::checkForNewItems()
+{
+ K3bDataItem* item = m_root->dirItem()->nextSibling();
+ while( item != 0 )
+ {
+ // check if we have an entry and if not, create one
+ // we can assume that a listViewItem for the parent exists
+ // since we go top to bottom
+ if( item->isDir() )
+ {
+ K3bDirItem* dirItem = dynamic_cast<K3bDirItem*>( item );
+
+ QMapIterator<K3bDirItem*, K3bDataDirViewItem*> itDirItem = m_itemMap.find( dirItem );
+ if( itDirItem == m_itemMap.end() ) {
+ K3bDataDirViewItem* parentViewItem = m_itemMap[dirItem->parent()];
+ K3bDataDirViewItem* newDirItem = new K3bDataDirViewItem( dirItem, parentViewItem );
+ m_itemMap.insert( dirItem, newDirItem );
+ }
+ else {
+ // check if parent still correct (to get moved items)
+ K3bDataDirViewItem* dirViewItem = itDirItem.data();
+ K3bDataDirViewItem* parentViewItem = (K3bDataDirViewItem*)dirViewItem->parent();
+ K3bDataDirViewItem* dirParentViewItem = m_itemMap[dirItem->parent()];
+ if( dirParentViewItem != parentViewItem ) {
+ // reparent it
+ parentViewItem->takeItem( dirViewItem );
+ dirParentViewItem->insertItem( dirViewItem );
+ }
+ }
+ }
+
+ item = item->nextSibling();
+ }
+
+
+ // check the directory depth
+ QListViewItemIterator it(root());
+ while( it.current() != 0 ) {
+ if( K3bDataDirViewItem* dirViewItem = dynamic_cast<K3bDataDirViewItem*>(it.current()) )
+ if( it.current() != m_root ) {
+ K3bDirItem* dirItem = dirViewItem->dirItem();
+ dirViewItem->setPixmap( 0, dirItem->depth() > 7 ? SmallIcon( "folder_red" ) : SmallIcon( "folder" ) );
+ }
+
+ ++it;
+ }
+
+ // always show the first level
+ m_root->setOpen( true );
+}
+
+
+void K3bDataDirTreeView::slotDocChanged()
+{
+ // avoid flicker
+ if( d->lastUpdateVolumeId != m_doc->isoOptions().volumeID() ) {
+ d->lastUpdateVolumeId = m_doc->isoOptions().volumeID();
+ root()->repaint();
+ }
+}
+
+#include "k3bdatadirtreeview.moc"
diff --git a/src/projects/k3bdatadirtreeview.h b/src/projects/k3bdatadirtreeview.h
new file mode 100644
index 0000000..c79a9c6
--- /dev/null
+++ b/src/projects/k3bdatadirtreeview.h
@@ -0,0 +1,115 @@
+/*
+ *
+ * $Id: k3bdatadirtreeview.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 K3BDATADIRTREEVIEW_H
+#define K3BDATADIRTREEVIEW_H
+
+
+#include <k3blistview.h>
+#include <kurl.h>
+
+#include <qmap.h>
+
+class K3bDataView;
+class K3bDataDoc;
+class K3bDataDirViewItem;
+class K3bDirItem;
+class K3bDataItem;
+class K3bDataFileView;
+class KActionCollection;
+class KActionMenu;
+class KAction;
+class K3bView;
+class QDragMoveEvent;
+class QDragLeaveEvent;
+
+
+/**
+ *@author Sebastian Trueg
+ */
+
+class K3bDataDirTreeView : public K3bListView
+{
+ Q_OBJECT
+
+ public:
+ K3bDataDirTreeView( K3bView*, K3bDataDoc*, QWidget* parent );
+ virtual ~K3bDataDirTreeView();
+
+ K3bDataDirViewItem* root() { return m_root; }
+
+ void setFileView( K3bDataFileView* view ) { m_fileView = view; }
+
+ KActionCollection* actionCollection() const { return m_actionCollection; }
+
+ public slots:
+ void checkForNewItems();
+ void setCurrentDir( K3bDirItem* );
+
+ signals:
+ // void urlsDropped( const KURL::List&, QListViewItem* parent );
+ void dirSelected( K3bDirItem* );
+
+ protected:
+ bool acceptDrag(QDropEvent* e) const;
+ void contentsDragMoveEvent( QDragMoveEvent* e );
+ void contentsDragLeaveEvent( QDragLeaveEvent* e );
+
+ KActionCollection* m_actionCollection;
+ KActionMenu* m_popupMenu;
+ KAction* m_actionRemove;
+ KAction* m_actionRename;
+ KAction* m_actionNewDir;
+ KAction* m_actionProperties;
+
+ protected slots:
+ virtual void slotDropped( QDropEvent* e, QListViewItem* after, QListViewItem* parent );
+
+ private:
+ void setupActions();
+ void startDropAnimation( K3bDirItem* );
+ void stopDropAnimation();
+
+ K3bView* m_view;
+
+ K3bDataDoc* m_doc;
+ K3bDataDirViewItem* m_root;
+ K3bDataFileView* m_fileView;
+
+ /**
+ * We save the dirItems in a map to have a fast way
+ * for checking for new or removed items
+ */
+ QMap<K3bDirItem*, K3bDataDirViewItem*> m_itemMap;
+
+ class Private;
+ Private* d;
+
+ private slots:
+ void slotExecuted( QListViewItem* );
+ void slotDataItemRemoved( K3bDataItem* );
+ void showPopupMenu( KListView*, QListViewItem* _item, const QPoint& );
+ void slotRenameItem();
+ void slotRemoveItem();
+ void slotNewDir();
+ void slotProperties();
+ void slotDropAnimate();
+ void slotItemAdded( K3bDataItem* );
+ void slotAddUrls();
+ void slotDocChanged();
+};
+
+#endif
diff --git a/src/projects/k3bdatafileview.cpp b/src/projects/k3bdatafileview.cpp
new file mode 100644
index 0000000..4c06bde
--- /dev/null
+++ b/src/projects/k3bdatafileview.cpp
@@ -0,0 +1,483 @@
+/*
+ *
+ * $Id: k3bdatafileview.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 "k3bdatafileview.h"
+#include "k3bdataview.h"
+#include <k3bdatadoc.h>
+#include <k3bdataitem.h>
+#include <k3bdiritem.h>
+#include <k3bfileitem.h>
+#include <k3bspecialdataitem.h>
+#include <k3bsessionimportitem.h>
+#include "k3bdataurladdingdialog.h"
+#include <k3bvalidators.h>
+#include "k3bdatapropertiesdialog.h"
+#include "k3bdatadirtreeview.h"
+#include "k3bdataviewitem.h"
+#include <k3bview.h>
+
+
+#include <qdragobject.h>
+#include <qpainter.h>
+#include <qfontmetrics.h>
+#include <qtimer.h>
+#include <qheader.h>
+#include <qfileinfo.h>
+
+#include <klocale.h>
+#include <kaction.h>
+#include <kurldrag.h>
+#include <kinputdialog.h>
+#include <kdebug.h>
+#include <kshortcut.h>
+#include <krun.h>
+#include <kdeversion.h>
+
+
+K3bDataFileView::K3bDataFileView( K3bView* view, K3bDataDirTreeView* dirTreeView, K3bDataDoc* doc, QWidget* parent )
+ : K3bListView( parent ),
+ m_view(view),
+ m_dropDirItem(0)
+{
+ m_treeView = dirTreeView;
+
+ setAcceptDrops( true );
+ setDropVisualizer( false );
+ setDropHighlighter( true );
+ setDragEnabled( true );
+ setItemsMovable( false );
+ setAllColumnsShowFocus( true );
+ setShowSortIndicator( true );
+
+ setNoItemText( i18n("Use drag'n'drop to add files and directories to the project.\n"
+ "To remove or rename files use the context menu.\n"
+ "After that press the burn button to write the CD.") );
+
+
+ addColumn( i18n("Name") );
+ addColumn( i18n("Type") );
+ addColumn( i18n("Size") );
+ addColumn( i18n("Local Path") );
+ addColumn( i18n("Link") );
+
+ setSelectionModeExt( KListView::Extended );
+
+ m_doc = doc;
+ m_currentDir = doc->root();
+ checkForNewItems();
+
+ connect( m_treeView, SIGNAL(dirSelected(K3bDirItem*)), this, SLOT(slotSetCurrentDir(K3bDirItem*)) );
+ connect( m_doc, SIGNAL(itemRemoved(K3bDataItem*)), this, SLOT(slotDataItemRemoved(K3bDataItem*)) );
+ connect( m_doc, SIGNAL(itemAdded(K3bDataItem*)), this, SLOT(slotItemAdded(K3bDataItem*)) );
+ connect( this, SIGNAL(executed(QListViewItem*)), this, SLOT(slotExecuted(QListViewItem*)) );
+ connect( this, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)),
+ this, SLOT(showPopupMenu(KListView*, QListViewItem*, const QPoint&)) );
+ connect( this, SIGNAL(dropped(QDropEvent*, QListViewItem*, QListViewItem*)),
+ this, SLOT(slotDropped(QDropEvent*, QListViewItem*, QListViewItem*)) );
+ connect( this, SIGNAL(doubleClicked(QListViewItem*, const QPoint&, int)),
+ this, SLOT(slotDoubleClicked(QListViewItem*)) );
+
+ setupActions();
+}
+
+
+K3bDataFileView::~K3bDataFileView()
+{
+}
+
+
+K3bDirItem* K3bDataFileView::currentDir() const
+{
+ if( !m_currentDir )
+ m_currentDir = m_doc->root();
+ return m_currentDir;
+}
+
+
+void K3bDataFileView::slotSetCurrentDir( K3bDirItem* dir )
+{
+ if( dir ) {
+ m_currentDir = dir;
+ clearItems();
+ checkForNewItems();
+ }
+}
+
+
+void K3bDataFileView::clearItems()
+{
+ m_itemMap.clear();
+ K3bListView::clear();
+}
+
+
+void K3bDataFileView::slotItemAdded( K3bDataItem* item )
+{
+ if( item->parent() == currentDir() ) {
+ K3bDataViewItem* vi = 0;
+ if( item->isDir() )
+ vi = new K3bDataDirViewItem( static_cast<K3bDirItem*>(item), this );
+ else if( item->isFile() )
+ vi = new K3bDataFileViewItem( static_cast<K3bFileItem*>(item), this );
+ else if( item->isSpecialFile() )
+ vi = new K3bSpecialDataViewItem( static_cast<K3bSpecialDataItem*>(item), this );
+ else if( item->isFromOldSession() )
+ vi = new K3bSessionImportViewItem( static_cast<K3bSessionImportItem*>(item), this );
+ else
+ kdDebug() << "(K3bDataFileView) ERROR: unknown data item type" << endl;
+
+ if( vi )
+ m_itemMap[item] = vi;
+ }
+}
+
+
+void K3bDataFileView::slotDataItemRemoved( K3bDataItem* item )
+{
+ if( item->isDir() ) {
+ if( static_cast<K3bDirItem*>(item)->isSubItem( currentDir() ) ) {
+ slotSetCurrentDir( m_doc->root() );
+ }
+ }
+
+ if( m_itemMap.contains( item ) ) {
+ delete m_itemMap[item];
+ m_itemMap.remove(item);
+ }
+}
+
+
+void K3bDataFileView::checkForNewItems()
+{
+ hideEditor();
+
+ // add items that are not there yet
+ for( QPtrListIterator<K3bDataItem> it( m_currentDir->children() ); it.current(); ++it ) {
+ if( !m_itemMap.contains( it.current() ) ) {
+ slotItemAdded( it.current() );
+ }
+ }
+
+ // now check if some of the items have been moved out of the currently showing dir.
+ for( QListViewItemIterator it( this ); it.current(); ++it ) {
+ K3bDataViewItem* dataViewItem = dynamic_cast<K3bDataViewItem*>( it.current() );
+ if( dataViewItem && dataViewItem->dataItem()->parent() != currentDir() )
+ delete dataViewItem;
+ }
+}
+
+
+QDragObject* K3bDataFileView::dragObject()
+{
+ QPtrList<QListViewItem> selectedViewItems = selectedItems();
+ KURL::List urls;
+ for( QPtrListIterator<QListViewItem> it( selectedViewItems ); it.current(); ++it ) {
+ K3bDataViewItem* dataViewItem = dynamic_cast<K3bDataViewItem*>( it.current() );
+ if( dataViewItem ) {
+ urls.append( KURL::fromPathOrURL(dataViewItem->dataItem()->localPath()) );
+ }
+ else
+ kdDebug() << "no dataviewitem" << endl;
+ }
+
+ if( urls.isEmpty() )
+ return 0;
+
+ return KURLDrag::newDrag( urls, viewport() );
+}
+
+
+bool K3bDataFileView::acceptDrag(QDropEvent* e) const
+{
+ return ( e->source() == viewport() ||
+ KURLDrag::canDecode(e) ||
+ e->source() == m_treeView->viewport() );
+}
+
+
+void K3bDataFileView::contentsDragMoveEvent( QDragMoveEvent* e )
+{
+ K3bListView::contentsDragMoveEvent( e );
+
+ // highlight the folder the items would be added to
+ if( m_dropDirItem )
+ m_dropDirItem->highlightIcon( false );
+
+ m_dropDirItem = dynamic_cast<K3bDataDirViewItem*>( itemAt(contentsToViewport(e->pos())) );
+ if( m_dropDirItem )
+ m_dropDirItem->highlightIcon( true );
+}
+
+
+void K3bDataFileView::contentsDragLeaveEvent( QDragLeaveEvent* e )
+{
+ K3bListView::contentsDragLeaveEvent( e );
+
+ // remove any highlighting
+ if( m_dropDirItem ) {
+ m_dropDirItem->highlightIcon( false );
+ m_dropDirItem = 0;
+ }
+}
+
+
+void K3bDataFileView::slotDropped( QDropEvent* e, QListViewItem*, QListViewItem* )
+{
+ // remove any highlighting
+ if( m_dropDirItem ) {
+ m_dropDirItem->highlightIcon( false );
+ m_dropDirItem = 0;
+ }
+
+ if( !e->isAccepted() )
+ return;
+
+ // determine K3bDirItem to add the items to
+ m_addParentDir = currentDir();
+
+ if( K3bDataDirViewItem* dirViewItem = dynamic_cast<K3bDataDirViewItem*>( itemAt(contentsToViewport(e->pos())) ) ) {
+ // only add to a dir if we drop directly on the name
+ if( header()->sectionAt( e->pos().x() ) == 0 )
+ m_addParentDir = dirViewItem->dirItem();
+ }
+
+ if( m_addParentDir ) {
+
+ // check if items have been moved
+ if( e->source() == viewport() ) {
+ // move all selected items
+ QPtrList<QListViewItem> selectedViewItems = selectedItems();
+ QValueList<K3bDataItem*> selectedDataItems;
+ QPtrListIterator<QListViewItem> it( selectedViewItems );
+ for( ; it.current(); ++it ) {
+ K3bDataViewItem* dataViewItem = dynamic_cast<K3bDataViewItem*>( it.current() );
+ if( dataViewItem )
+ selectedDataItems.append( dataViewItem->dataItem() );
+ else
+ kdDebug() << "no dataviewitem" << endl;
+ }
+
+ K3bDataUrlAddingDialog::copyMoveItems( selectedDataItems, m_addParentDir, this, e->action() == QDropEvent::Copy );
+ }
+ else if( e->source() == m_treeView->viewport() ) {
+ // move the selected dir
+ if( K3bDataDirViewItem* dirItem = dynamic_cast<K3bDataDirViewItem*>( m_treeView->selectedItem() ) ) {
+ QValueList<K3bDataItem*> selectedDataItems;
+ selectedDataItems.append( dirItem->dirItem() );
+ K3bDataUrlAddingDialog::copyMoveItems( selectedDataItems, m_addParentDir, this, e->action() == QDropEvent::Copy );
+ }
+ }
+ else {
+ // seems that new items have been dropped
+ m_addUrls.clear();
+ if( KURLDrag::decode( e, m_addUrls ) ) {
+ //
+ // This is a small (not to ugly) hack to circumvent problems with the
+ // event queues: the url adding dialog will be non-modal regardless of
+ // the settings in case we open it directly.
+ //
+ QTimer::singleShot( 0, this, SLOT(slotAddUrls()) );
+ }
+ }
+ }
+
+ // now grab that focus
+ setFocus();
+}
+
+
+void K3bDataFileView::slotAddUrls()
+{
+ K3bDataUrlAddingDialog::addUrls( m_addUrls, m_addParentDir, this );
+}
+
+
+void K3bDataFileView::slotExecuted( QListViewItem* item )
+{
+ if( K3bDataDirViewItem* k = dynamic_cast<K3bDataDirViewItem*>( item ) ) {
+ hideEditor(); // disable the K3bListView Editor
+ slotSetCurrentDir( k->dirItem() );
+ emit dirSelected( currentDir() );
+ }
+}
+
+
+void K3bDataFileView::setupActions()
+{
+ m_actionCollection = new KActionCollection( this );
+
+ m_actionProperties = new KAction( i18n("Properties"), "misc", 0, this, SLOT(slotProperties()),
+ actionCollection(), "properties" );
+ m_actionNewDir = new KAction( i18n("New Directory..."), "folder_new", CTRL+Key_N, this, SLOT(slotNewDir()),
+ actionCollection(), "new_dir" );
+ m_actionRemove = new KAction( i18n("Remove"), "editdelete", Key_Delete, this, SLOT(slotRemoveItem()),
+ actionCollection(), "remove" );
+ KShortcut renameShortCut( Key_F2 );
+ renameShortCut.append( KShortcut(CTRL+Key_R) ); // backwards compatibility
+ m_actionRename = new KAction( i18n("Rename"), "edit", renameShortCut, this, SLOT(slotRenameItem()),
+ actionCollection(), "rename" );
+ m_actionParentDir = new KAction( i18n("Parent Directory"), "up", 0, this, SLOT(slotParentDir()),
+ actionCollection(), "parent_dir" );
+ m_actionOpen = new KAction( i18n("Open"), "fileopen", 0, this, SLOT(slotOpen()),
+ actionCollection(), "open" );
+
+ m_popupMenu = new KActionMenu( m_actionCollection, "contextMenu" );
+ m_popupMenu->insert( m_actionParentDir );
+ m_popupMenu->insert( new KActionSeparator( this ) );
+ m_popupMenu->insert( m_actionRename );
+ m_popupMenu->insert( m_actionRemove );
+ m_popupMenu->insert( m_actionNewDir );
+ m_popupMenu->insert( new KActionSeparator( this ) );
+ m_popupMenu->insert( m_actionOpen );
+ m_popupMenu->insert( new KActionSeparator( this ) );
+ m_popupMenu->insert( m_actionProperties );
+ m_popupMenu->insert( new KActionSeparator( this ) );
+ m_popupMenu->insert( m_view->actionCollection()->action("project_burn") );
+}
+
+
+void K3bDataFileView::showPopupMenu( KListView*, QListViewItem* item, const QPoint& point )
+{
+ if( item ) {
+ K3bDataItem* di = static_cast<K3bDataViewItem*>(item)->dataItem();
+ m_actionRemove->setEnabled( di->isRemoveable() );
+ m_actionRename->setEnabled( di->isRenameable() );
+ if( currentDir() == m_doc->root() )
+ m_actionParentDir->setEnabled( false );
+ else
+ m_actionParentDir->setEnabled( true );
+ m_actionOpen->setEnabled( di->isFile() );
+ }
+ else {
+ m_actionRemove->setEnabled( false );
+ m_actionRename->setEnabled( false );
+ m_actionOpen->setEnabled( false );
+ }
+
+ m_popupMenu->popup( point );
+}
+
+
+void K3bDataFileView::slotNewDir()
+{
+ K3bDirItem* parent = currentDir();
+
+ QString name;
+ bool ok;
+
+ name = KInputDialog::getText( i18n("New Directory"),
+ i18n("Please insert the name for the new directory:"),
+ i18n("New Directory"), &ok, this );
+
+ while( ok && K3bDataDoc::nameAlreadyInDir( name, parent ) ) {
+ name = KInputDialog::getText( i18n("New Directory"),
+ i18n("A file with that name already exists. "
+ "Please insert the name for the new directory:"),
+ i18n("New Directory"), &ok, this );
+ }
+
+ if( !ok )
+ return;
+
+
+ m_doc->addEmptyDir( name, parent );
+}
+
+
+void K3bDataFileView::slotRenameItem()
+{
+ if( currentItem() )
+ showEditor( (K3bListViewItem*)currentItem(), 0 );
+}
+
+
+void K3bDataFileView::slotRemoveItem()
+{
+ QPtrList<QListViewItem> items = selectedItems();
+ QPtrListIterator<QListViewItem> it( items );
+ for(; it.current(); ++it ) {
+ if( K3bDataViewItem* d = dynamic_cast<K3bDataViewItem*>( it.current() ) )
+ m_doc->removeItem( d->dataItem() );
+ }
+}
+
+
+void K3bDataFileView::slotParentDir()
+{
+ if( currentDir() != m_doc->root() ) {
+ slotSetCurrentDir( currentDir()->parent() );
+
+ emit dirSelected( currentDir() );
+ }
+}
+
+
+void K3bDataFileView::slotProperties()
+{
+ K3bDataItem* dataItem = 0;
+
+ // get selected item
+ if( K3bDataViewItem* viewItem = dynamic_cast<K3bDataViewItem*>( selectedItems().first() ) ) {
+ dataItem = viewItem->dataItem();
+ }
+ else {
+ // default to current dir
+ dataItem = currentDir();
+ }
+
+ if( dataItem ) {
+ K3bDataPropertiesDialog d( dataItem, this );
+ d.exec();
+ }
+ else
+ m_view->slotProperties();
+}
+
+
+void K3bDataFileView::slotOpen()
+{
+ if( K3bDataViewItem* viewItem = dynamic_cast<K3bDataViewItem*>( selectedItems().first() ) ) {
+ K3bDataItem* item = viewItem->dataItem();
+ if( item->isFile() ) {
+ K3bDataFileViewItem* fvi = static_cast<K3bDataFileViewItem*>( viewItem );
+ if( fvi->mimeType() &&
+#if KDE_IS_VERSION(3,3,0)
+ !KRun::isExecutableFile( KURL::fromPathOrURL(item->localPath()),
+ fvi->mimeType()->name() )
+#else
+ !QFileInfo( item->localPath() ).isExecutable()
+#endif
+ )
+ KRun::runURL( KURL::fromPathOrURL(item->localPath()),
+ fvi->mimeType()->name() );
+ else
+ KRun::displayOpenWithDialog( KURL::fromPathOrURL(item->localPath()) );
+ }
+ }
+}
+
+
+void K3bDataFileView::slotDoubleClicked( QListViewItem* )
+{
+ if( K3bDataViewItem* viewItem = dynamic_cast<K3bDataViewItem*>( selectedItems().first() ) ) {
+ if( !viewItem->dataItem()->isDir() ) {
+ K3bDataPropertiesDialog d( viewItem->dataItem(), this );
+ d.exec();
+ }
+ }
+}
+
+#include "k3bdatafileview.moc"
diff --git a/src/projects/k3bdatafileview.h b/src/projects/k3bdatafileview.h
new file mode 100644
index 0000000..580af96
--- /dev/null
+++ b/src/projects/k3bdatafileview.h
@@ -0,0 +1,115 @@
+/*
+ *
+ * $Id: k3bdatafileview.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 K3BDATAFILEVIEW_H
+#define K3BDATAFILEVIEW_H
+
+#include <k3blistview.h>
+
+#include <kurl.h>
+
+#include <qmap.h>
+
+
+class K3bDataDoc;
+class K3bDirItem;
+class K3bDataView;
+class K3bDataViewItem;
+class K3bDataItem;
+class QDropEvent;
+class KActionCollection;
+class KActionMenu;
+class KAction;
+class K3bDataDirTreeView;
+class K3bDataDirViewItem;
+class K3bView;
+class QPainter;
+class QDragMoveEvent;
+class QDragLeaveEvent;
+
+/**
+ *@author Sebastian Trueg
+ */
+
+class K3bDataFileView : public K3bListView
+{
+ Q_OBJECT
+
+ public:
+ K3bDataFileView( K3bView*, K3bDataDirTreeView*, K3bDataDoc*, QWidget* parent );
+ ~K3bDataFileView();
+
+ K3bDirItem* currentDir() const;
+
+ KActionCollection* actionCollection() const { return m_actionCollection; }
+
+ signals:
+ void dirSelected( K3bDirItem* );
+
+ public slots:
+ void slotSetCurrentDir( K3bDirItem* );
+ void checkForNewItems();
+
+ private slots:
+ void slotDataItemRemoved( K3bDataItem* );
+ void slotExecuted( QListViewItem* );
+ void slotDropped( QDropEvent* e, QListViewItem* after, QListViewItem* parent );
+ void showPopupMenu( KListView*, QListViewItem* _item, const QPoint& );
+ void slotRenameItem();
+ void slotRemoveItem();
+ void slotNewDir();
+ void slotParentDir();
+ void slotProperties();
+ void slotDoubleClicked( QListViewItem* item );
+ void slotItemAdded( K3bDataItem* );
+ void slotAddUrls();
+ void slotOpen();
+
+ protected:
+ bool acceptDrag(QDropEvent* e) const;
+ void contentsDragMoveEvent( QDragMoveEvent* e );
+ void contentsDragLeaveEvent( QDragLeaveEvent* e );
+ QDragObject* dragObject();
+
+ private:
+ void clearItems();
+ void setupActions();
+
+ KActionCollection* m_actionCollection;
+ KActionMenu* m_popupMenu;
+ KAction* m_actionParentDir;
+ KAction* m_actionRemove;
+ KAction* m_actionRename;
+ KAction* m_actionNewDir;
+ KAction* m_actionProperties;
+ KAction* m_actionOpen;
+
+ K3bView* m_view;
+
+ K3bDataDoc* m_doc;
+ mutable K3bDirItem* m_currentDir;
+ K3bDataDirTreeView* m_treeView;
+
+ K3bDataDirViewItem* m_dropDirItem;
+
+ QMap<K3bDataItem*, K3bDataViewItem*> m_itemMap;
+
+ // used for the urladdingdialog hack
+ KURL::List m_addUrls;
+ K3bDirItem* m_addParentDir;
+};
+
+#endif
diff --git a/src/projects/k3bdataimagesettingswidget.cpp b/src/projects/k3bdataimagesettingswidget.cpp
new file mode 100644
index 0000000..331e1eb
--- /dev/null
+++ b/src/projects/k3bdataimagesettingswidget.cpp
@@ -0,0 +1,400 @@
+/*
+ *
+ * $Id: k3bdataimagesettingswidget.cpp 691413 2007-07-23 16:01:13Z 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 "k3bdataimagesettingswidget.h"
+#include "k3bdataadvancedimagesettingswidget.h"
+#include "k3bdatavolumedescwidget.h"
+
+#include "k3bisooptions.h"
+
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qpushbutton.h>
+#include <qwhatsthis.h>
+#include <qlayout.h>
+
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kdialogbase.h>
+#include <kdebug.h>
+
+
+// indices for the filesystems combobox
+static const int FS_LINUX_ONLY = 0;
+static const int FS_LINUX_AND_WIN = 1;
+static const int FS_UDF = 2;
+static const int FS_DOS_COMP = 3;
+static const int FS_CUSTOM = 4;
+static const int FS_MAX = 5;
+
+static const char* s_fsPresetNames[] = {
+ I18N_NOOP("Linux/Unix only"),
+ I18N_NOOP("Linux/Unix + Windows"),
+ I18N_NOOP("Very large files (UDF)"),
+ I18N_NOOP("DOS Compatibility"),
+ I18N_NOOP("Custom")
+};
+
+static bool s_fsPresetsInitialized = false;
+static K3bIsoOptions s_fsPresets[FS_CUSTOM];
+
+// indices for the whitespace treatment combobox
+static const int WS_NO_CHANGE = 0;
+static const int WS_STRIP = 1;
+static const int WS_EXTENDED_STRIP = 2;
+static const int WS_REPLACE = 3;
+
+// indices for the symlink handling combobox
+static const int SYM_NO_CHANGE = 0;
+static const int SYM_DISCARD_BROKEN = 1;
+static const int SYM_DISCARD_ALL = 2;
+static const int SYM_FOLLOW = 3;
+
+
+//
+// returns true if the part of the options that is presented in the advanced custom
+// settings dialog is equal. used to determine if some preset is used.
+//
+static bool compareAdvancedOptions( const K3bIsoOptions& o1, const K3bIsoOptions& o2 )
+{
+ return ( o1.forceInputCharset() == o2.forceInputCharset() &&
+ ( !o1.forceInputCharset() || o1.inputCharset() == o2.inputCharset() ) &&
+ o1.createRockRidge() == o2.createRockRidge() &&
+ o1.createJoliet() == o2.createJoliet() &&
+ o1.createUdf() == o2.createUdf() &&
+ o1.ISOallowLowercase() == o2.ISOallowLowercase() &&
+ o1.ISOallowPeriodAtBegin() == o2.ISOallowPeriodAtBegin() &&
+ o1.ISOallow31charFilenames() == o2.ISOallow31charFilenames() &&
+ o1.ISOomitVersionNumbers() == o2.ISOomitVersionNumbers() &&
+ o1.ISOomitTrailingPeriod() == o2.ISOomitTrailingPeriod() &&
+ o1.ISOmaxFilenameLength() == o2.ISOmaxFilenameLength() &&
+ o1.ISOrelaxedFilenames() == o2.ISOrelaxedFilenames() &&
+ o1.ISOnoIsoTranslate() == o2.ISOnoIsoTranslate() &&
+ o1.ISOallowMultiDot() == o2.ISOallowMultiDot() &&
+ o1.ISOuntranslatedFilenames() == o2.ISOuntranslatedFilenames() &&
+ o1.createTRANS_TBL() == o2.createTRANS_TBL() &&
+ o1.hideTRANS_TBL() == o2.hideTRANS_TBL() &&
+ o1.jolietLong() == o2.jolietLong() &&
+ o1.ISOLevel() == o2.ISOLevel() &&
+ o1.preserveFilePermissions() == o2.preserveFilePermissions() &&
+ o1.doNotCacheInodes() == o2.doNotCacheInodes() );
+}
+
+
+static void initializePresets()
+{
+ // Linux-only
+ s_fsPresets[FS_LINUX_ONLY].setCreateJoliet( false );
+ s_fsPresets[FS_LINUX_ONLY].setISOallow31charFilenames( true );
+
+ // Linux + Windows
+ s_fsPresets[FS_LINUX_AND_WIN].setCreateJoliet( true );
+ s_fsPresets[FS_LINUX_AND_WIN].setJolietLong( true );
+ s_fsPresets[FS_LINUX_AND_WIN].setISOallow31charFilenames( true );
+
+ // UDF
+ s_fsPresets[FS_UDF].setCreateJoliet( false );
+ s_fsPresets[FS_UDF].setCreateUdf( true );
+ s_fsPresets[FS_UDF].setISOallow31charFilenames( true );
+
+ // DOS comp
+ s_fsPresets[FS_DOS_COMP].setCreateJoliet( false );
+ s_fsPresets[FS_DOS_COMP].setCreateRockRidge( false );
+ s_fsPresets[FS_DOS_COMP].setISOallow31charFilenames( false );
+ s_fsPresets[FS_DOS_COMP].setISOLevel( 1 );
+
+ s_fsPresetsInitialized = true;
+}
+
+
+
+class K3bDataImageSettingsWidget::CustomFilesystemsDialog : public KDialogBase
+{
+public:
+ CustomFilesystemsDialog( QWidget* parent )
+ : KDialogBase( parent,
+ "custom_filesystems_dialog",
+ true,
+ i18n("Custom Data Project Filesystems"),
+ Ok|Cancel,
+ Ok,
+ true ) {
+ w = new K3bDataAdvancedImageSettingsWidget( this );
+ setMainWidget( w );
+ }
+
+ K3bDataAdvancedImageSettingsWidget* w;
+};
+
+
+class K3bDataImageSettingsWidget::VolumeDescDialog : public KDialogBase
+{
+public:
+ VolumeDescDialog( QWidget* parent )
+ : KDialogBase( parent,
+ "voldesc_dialog",
+ true,
+ i18n("Volume Descriptor"),
+ Ok|Cancel,
+ Ok,
+ true ) {
+ w = new K3bDataVolumeDescWidget( this );
+ setMainWidget( w );
+
+ // give ourselves a reasonable size
+ QSize s = sizeHint();
+ s.setWidth( QMAX(s.width(), 300) );
+ resize( s );
+ }
+
+ K3bDataVolumeDescWidget* w;
+};
+
+
+
+K3bDataImageSettingsWidget::K3bDataImageSettingsWidget( QWidget* parent, const char* name )
+ : base_K3bDataImageSettings( parent, name ),
+ m_fileSystemOptionsShown(true)
+{
+ layout()->setMargin( KDialog::marginHint() );
+
+ m_customFsDlg = new CustomFilesystemsDialog( this );
+ m_volDescDlg = new VolumeDescDialog( this );
+
+ connect( m_buttonCustomFilesystems, SIGNAL(clicked()),
+ this, SLOT(slotCustomFilesystems()) );
+ connect( m_buttonMoreVolDescFields, SIGNAL(clicked()),
+ this, SLOT(slotMoreVolDescFields()) );
+ connect( m_comboSpaceHandling, SIGNAL(activated(int)),
+ this, SLOT(slotSpaceHandlingChanged(int)) );
+
+ for( int i = 0; i < FS_MAX; ++i )
+ m_comboFilesystems->insertItem( i18n( s_fsPresetNames[i] ) );
+
+ if( !s_fsPresetsInitialized )
+ initializePresets();
+
+ QWhatsThis::add( m_comboFilesystems,
+ i18n("<p><b>File System Presets</b>"
+ "<p>K3b provides the following file system Presets which allow for a quick selection "
+ "of the most frequently used settings.")
+ + "<p><b>" + i18n(s_fsPresetNames[0]) + "</b><br>"
+ + i18n("The file system is optimized for usage on Linux/Unix systems. This mainly means that "
+ "it uses the Rock Ridge extensions to provide long filenames, symbolic links, and POSIX "
+ "compatible file permissions.")
+ + "<p><b>" + i18n(s_fsPresetNames[1]) + "</b><br>"
+ + i18n("In addition to the settings for Linux/Unix the file system contains a Joliet tree which "
+ "allows for long file names on Windows which does not support the Rock Ridget extensions. "
+ "Be aware that the file name length is restricted to 103 characters.")
+ + "<p><b>" + i18n(s_fsPresetNames[2]) + "</b><br>"
+ + i18n("The file system has additional UDF entries attached to it. This raises the maximal file "
+ "size to 4 GB. Be aware that the UDF support in K3b is limited.")
+ + "<p><b>" + i18n(s_fsPresetNames[3]) + "</b><br>"
+ + i18n("The file system is optimized for compatibility with old systems. That means file names "
+ "are restricted to 8.3 characters and no symbolic links or file permissions are supported.") );
+}
+
+
+K3bDataImageSettingsWidget::~K3bDataImageSettingsWidget()
+{
+}
+
+
+void K3bDataImageSettingsWidget::showFileSystemOptions( bool b )
+{
+ m_groupFileSystem->setShown(b);
+ m_groupSymlinks->setShown(b);
+ m_groupWhitespace->setShown(b);
+
+ m_fileSystemOptionsShown = b;
+}
+
+
+void K3bDataImageSettingsWidget::slotSpaceHandlingChanged( int i )
+{
+ m_editReplace->setEnabled( i == WS_REPLACE );
+}
+
+
+void K3bDataImageSettingsWidget::slotCustomFilesystems()
+{
+ // load settings in custom window
+ if( m_comboFilesystems->currentItem() != FS_CUSTOM ) {
+ m_customFsDlg->w->load( s_fsPresets[m_comboFilesystems->currentItem()] );
+ }
+
+ // store the current settings in case the user cancels the changes
+ K3bIsoOptions o;
+ m_customFsDlg->w->save( o );
+
+ if( m_customFsDlg->exec() == QDialog::Accepted ) {
+ slotFilesystemsChanged();
+ }
+ else {
+ // reload the old settings discarding any changes
+ m_customFsDlg->w->load( o );
+ }
+}
+
+
+void K3bDataImageSettingsWidget::slotFilesystemsChanged()
+{
+ if( !m_fileSystemOptionsShown )
+ return;
+
+ // new custom entry
+ QStringList s;
+ if( m_customFsDlg->w->m_checkRockRidge->isChecked() )
+ s += i18n("Rock Ridge");
+ if( m_customFsDlg->w->m_checkJoliet->isChecked() )
+ s += i18n("Joliet");
+ if( m_customFsDlg->w->m_checkUdf->isChecked() )
+ s += i18n("UDF");
+ if( s.isEmpty() )
+ m_comboFilesystems->changeItem( i18n("Custom (ISO9660 only)"), FS_CUSTOM );
+ else
+ m_comboFilesystems->changeItem( i18n("Custom (%1)").arg( s.join(", ") ), FS_CUSTOM );
+
+ // see if any of the presets is loaded
+ m_comboFilesystems->setCurrentItem( FS_CUSTOM );
+ K3bIsoOptions o;
+ m_customFsDlg->w->save( o );
+ for( int i = 0; i < FS_CUSTOM; ++i ) {
+ if( compareAdvancedOptions( o, s_fsPresets[i] ) ) {
+ kdDebug() << "(K3bDataImageSettingsWidget) found preset settings: " << s_fsPresetNames[i] << endl;
+ m_comboFilesystems->setCurrentItem( i );
+ break;
+ }
+ }
+
+ if( m_comboFilesystems->currentItem() == FS_CUSTOM ) {
+ if( !m_customFsDlg->w->m_checkRockRidge->isChecked() ) {
+ KMessageBox::information( this,
+ i18n("<p>Be aware that it is not recommended to disable the Rock Ridge "
+ "Extensions. There is no disadvantage in enabling Rock Ridge (except "
+ "for a very small space overhead) but a lot of advantages."
+ "<p>Without Rock Ridge Extensions symbolic links are not supported "
+ "and will always be followed as if the \"Follow Symbolic Links\" option "
+ "was enabled."),
+ i18n("Rock Ridge Extensions Disabled"),
+ "warning_about_rock_ridge" );
+ }
+
+ if( !m_customFsDlg->w->m_checkJoliet->isChecked() )
+ KMessageBox::information( this,
+ i18n("<p>Be aware that without the Joliet extensions Windows "
+ "systems will not be able to display long filenames. You "
+ "will only see the ISO9660 filenames."
+ "<p>If you do not intend to use the CD/DVD on a Windows "
+ "system it is safe to disable Joliet."),
+ i18n("Joliet Extensions Disabled"),
+ "warning_about_joliet" );
+ }
+}
+
+
+void K3bDataImageSettingsWidget::slotMoreVolDescFields()
+{
+ // update dlg to current state
+ m_volDescDlg->w->m_editVolumeName->setText( m_editVolumeName->text() );
+
+ // remember old settings
+ K3bIsoOptions o;
+ m_volDescDlg->w->save( o );
+
+ // exec dlg
+ if( m_volDescDlg->exec() == QDialog::Accepted ) {
+ // accept new entries
+ m_volDescDlg->w->save( o );
+ m_editVolumeName->setText( o.volumeID() );
+ }
+ else {
+ // restore old settings
+ m_volDescDlg->w->load( o );
+ }
+}
+
+
+void K3bDataImageSettingsWidget::load( const K3bIsoOptions& o )
+{
+ m_customFsDlg->w->load( o );
+ m_volDescDlg->w->load( o );
+
+ slotFilesystemsChanged();
+
+ if( o.discardBrokenSymlinks() )
+ m_comboSymlinkHandling->setCurrentItem( SYM_DISCARD_BROKEN );
+ else if( o.discardSymlinks() )
+ m_comboSymlinkHandling->setCurrentItem( SYM_DISCARD_ALL );
+ else if( o.followSymbolicLinks() )
+ m_comboSymlinkHandling->setCurrentItem( SYM_FOLLOW );
+ else
+ m_comboSymlinkHandling->setCurrentItem( SYM_NO_CHANGE );
+
+ switch( o.whiteSpaceTreatment() ) {
+ case K3bIsoOptions::strip:
+ m_comboSpaceHandling->setCurrentItem( WS_STRIP );
+ break;
+ case K3bIsoOptions::extended:
+ m_comboSpaceHandling->setCurrentItem( WS_EXTENDED_STRIP );
+ break;
+ case K3bIsoOptions::replace:
+ m_comboSpaceHandling->setCurrentItem( WS_REPLACE );
+ break;
+ default:
+ m_comboSpaceHandling->setCurrentItem( WS_NO_CHANGE );
+ }
+ slotSpaceHandlingChanged( m_comboSpaceHandling->currentItem() );
+
+ m_editReplace->setText( o.whiteSpaceTreatmentReplaceString() );
+
+ m_editVolumeName->setText( o.volumeID() );
+}
+
+
+void K3bDataImageSettingsWidget::save( K3bIsoOptions& o )
+{
+ if( m_comboFilesystems->currentItem() != FS_CUSTOM )
+ m_customFsDlg->w->load( s_fsPresets[m_comboFilesystems->currentItem()] );
+ m_customFsDlg->w->save( o );
+
+ m_volDescDlg->w->save( o );
+
+ o.setDiscardSymlinks( m_comboSymlinkHandling->currentItem() == SYM_DISCARD_ALL );
+ o.setDiscardBrokenSymlinks( m_comboSymlinkHandling->currentItem() == SYM_DISCARD_BROKEN );
+ o.setFollowSymbolicLinks( m_comboSymlinkHandling->currentItem() == SYM_FOLLOW );
+
+ switch( m_comboSpaceHandling->currentItem() ) {
+ case WS_STRIP:
+ o.setWhiteSpaceTreatment( K3bIsoOptions::strip );
+ break;
+ case WS_EXTENDED_STRIP:
+ o.setWhiteSpaceTreatment( K3bIsoOptions::extended );
+ break;
+ case WS_REPLACE:
+ o.setWhiteSpaceTreatment( K3bIsoOptions::replace );
+ break;
+ default:
+ o.setWhiteSpaceTreatment( K3bIsoOptions::noChange );
+ }
+ o.setWhiteSpaceTreatmentReplaceString( m_editReplace->text() );
+
+ o.setVolumeID( m_editVolumeName->text() );
+}
+
+#include "k3bdataimagesettingswidget.moc"
diff --git a/src/projects/k3bdataimagesettingswidget.h b/src/projects/k3bdataimagesettingswidget.h
new file mode 100644
index 0000000..e16226f
--- /dev/null
+++ b/src/projects/k3bdataimagesettingswidget.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * $Id: k3bdataimagesettingswidget.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_DATAIMAGE_SETTINGS_WIDGET_H
+#define K3B_DATAIMAGE_SETTINGS_WIDGET_H
+
+
+#include "base_k3bdataimagesettings.h"
+
+class K3bIsoOptions;
+
+
+class K3bDataImageSettingsWidget : public base_K3bDataImageSettings
+{
+ Q_OBJECT
+
+ public:
+ K3bDataImageSettingsWidget( QWidget* parent = 0, const char* name = 0 );
+ ~K3bDataImageSettingsWidget();
+
+ void load( const K3bIsoOptions& );
+ void save( K3bIsoOptions& );
+
+ void showFileSystemOptions( bool );
+
+ private slots:
+ void slotSpaceHandlingChanged( int i );
+ void slotCustomFilesystems();
+ void slotMoreVolDescFields();
+ void slotFilesystemsChanged();
+
+ private:
+ class CustomFilesystemsDialog;
+ class VolumeDescDialog;
+ CustomFilesystemsDialog* m_customFsDlg;
+ VolumeDescDialog* m_volDescDlg;
+
+ bool m_fileSystemOptionsShown;
+};
+
+
+#endif
diff --git a/src/projects/k3bdatamultisessioncombobox.cpp b/src/projects/k3bdatamultisessioncombobox.cpp
new file mode 100644
index 0000000..57dd818
--- /dev/null
+++ b/src/projects/k3bdatamultisessioncombobox.cpp
@@ -0,0 +1,177 @@
+/*
+ *
+ * $Id: k3bdatamultisessioncombobox.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 "k3bdatamultisessioncombobox.h"
+
+#include <klocale.h>
+#include <kconfig.h>
+
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+
+
+static const int s_autoIndex = 0;
+static const int s_noneIndex = 1;
+static const int s_startIndex = 2;
+static const int s_continueIndex = 3;
+static const int s_finishIndex = 4;
+
+
+K3bDataMultiSessionCombobox::K3bDataMultiSessionCombobox( QWidget* parent, const char* name )
+ : QComboBox( parent, name ),
+ m_forceNoMultiSession(false)
+{
+ init( false );
+
+ QToolTip::add( this, i18n("Select the Multisession Mode for the project.") );
+ QWhatsThis::add( this, i18n("<p><b>Multisession Mode</b>"
+ "<p><b>Auto</b><br>"
+ "Let K3b decide which mode to use. The decision will be based "
+ "on the size of the project (does it fill the whole media) and "
+ "the state of the inserted media (appendable or not)."
+ "<p><b>No Multisession</b><br>"
+ "Create a single-session CD or DVD and close the disk."
+ "<p><b>Start Multisession</b><br>"
+ "Start a multisession CD or DVD, not closing the disk to "
+ "allow further sessions to be apppended."
+ "<p><b>Continue Multisession</b><br>"
+ "Continue an appendable data CD (as for example created in "
+ "<em>Start Multisession</em> mode) and add another session "
+ "without closing the disk to "
+ "allow further sessions to be apppended."
+ "<p><b>Finish Multisession</b><br>"
+ "Continue an appendable data CD (as for example created in "
+ "<em>Start Multisession</em> mode), add another session, "
+ "and close the disk."
+ "<p><em>In the case of DVD+RW and DVD-RW restricted overwrite media "
+ "K3b will not actually create multiple sessions but grow the "
+ "file system to include the new data.</em>") );
+}
+
+
+K3bDataMultiSessionCombobox::~K3bDataMultiSessionCombobox()
+{
+}
+
+
+void K3bDataMultiSessionCombobox::init( bool force )
+{
+ m_forceNoMultiSession = force;
+
+ clear();
+
+ insertItem( i18n("Auto"), s_autoIndex );
+ insertItem( i18n("No Multisession"), s_noneIndex );
+ if( !m_forceNoMultiSession ) {
+ insertItem( i18n("Start Multisession"), s_startIndex );
+ insertItem( i18n("Continue Multisession "), s_continueIndex );
+ insertItem( i18n("Finish Multisession "), s_finishIndex );
+ }
+}
+
+
+K3bDataDoc::MultiSessionMode K3bDataMultiSessionCombobox::multiSessionMode() const
+{
+ switch( currentItem() ) {
+ case s_noneIndex:
+ return K3bDataDoc::NONE;
+ case s_startIndex:
+ return K3bDataDoc::START;
+ case s_continueIndex:
+ return K3bDataDoc::CONTINUE;
+ case s_finishIndex:
+ return K3bDataDoc::FINISH;
+ default:
+ return K3bDataDoc::AUTO;
+ }
+}
+
+
+void K3bDataMultiSessionCombobox::saveConfig( KConfigBase* c )
+{
+ QString s;
+ switch( currentItem() ) {
+ case s_autoIndex:
+ s = "auto";
+ break;
+ case s_noneIndex:
+ s = "none";
+ break;
+ case s_startIndex:
+ s = "start";
+ break;
+ case s_continueIndex:
+ s = "continue";
+ break;
+ case s_finishIndex:
+ s = "finish";
+ break;
+ }
+
+ c->writeEntry( "multisession mode", s );
+}
+
+
+void K3bDataMultiSessionCombobox::loadConfig( KConfigBase* c )
+{
+ QString s = c->readEntry( "multisession mode" );
+ if( s == "none" )
+ setMultiSessionMode( K3bDataDoc::NONE );
+ else if( s == "start" )
+ setMultiSessionMode( K3bDataDoc::START );
+ else if( s == "continue" )
+ setMultiSessionMode( K3bDataDoc::CONTINUE );
+ else if( s == "finish" )
+ setMultiSessionMode( K3bDataDoc::FINISH );
+ else
+ setMultiSessionMode( K3bDataDoc::AUTO );
+}
+
+
+void K3bDataMultiSessionCombobox::setMultiSessionMode( K3bDataDoc::MultiSessionMode m )
+{
+ switch( m ) {
+ case K3bDataDoc::AUTO:
+ setCurrentItem( s_autoIndex );
+ break;
+ case K3bDataDoc::NONE:
+ setCurrentItem( s_noneIndex );
+ break;
+ case K3bDataDoc::START:
+ if( !m_forceNoMultiSession )
+ setCurrentItem( s_startIndex );
+ break;
+ case K3bDataDoc::CONTINUE:
+ if( !m_forceNoMultiSession )
+ setCurrentItem( s_continueIndex );
+ break;
+ case K3bDataDoc::FINISH:
+ if( !m_forceNoMultiSession )
+ setCurrentItem( s_finishIndex );
+ break;
+ }
+}
+
+
+void K3bDataMultiSessionCombobox::setForceNoMultisession( bool f )
+{
+ if( f != m_forceNoMultiSession ) {
+ K3bDataDoc::MultiSessionMode m = multiSessionMode();
+ init( f );
+ setMultiSessionMode( m );
+ }
+}
+
+#include "k3bdatamultisessioncombobox.moc"
diff --git a/src/projects/k3bdatamultisessioncombobox.h b/src/projects/k3bdatamultisessioncombobox.h
new file mode 100644
index 0000000..cb44989
--- /dev/null
+++ b/src/projects/k3bdatamultisessioncombobox.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * $Id: k3bdatamultisessioncombobox.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_DATA_MULTISESSION_COMBOBOX_H_
+#define _K3B_DATA_MULTISESSION_COMBOBOX_H_
+
+#include <qcombobox.h>
+#include <k3bdatadoc.h>
+
+class KConfigBase;
+
+
+class K3bDataMultiSessionCombobox : public QComboBox
+{
+ Q_OBJECT
+
+ public:
+ K3bDataMultiSessionCombobox( QWidget* parent = 0, const char* name = 0 );
+ ~K3bDataMultiSessionCombobox();
+
+ /**
+ * returnes K3bDataDoc::multiSessionModes
+ */
+ K3bDataDoc::MultiSessionMode multiSessionMode() const;
+
+ void setForceNoMultisession( bool );
+
+ void saveConfig( KConfigBase* );
+ void loadConfig( KConfigBase* );
+
+ public slots:
+ void setMultiSessionMode( K3bDataDoc::MultiSessionMode );
+
+ private:
+ void init( bool forceNo );
+
+ bool m_forceNoMultiSession;
+};
+
+#endif
diff --git a/src/projects/k3bdatapropertiesdialog.cpp b/src/projects/k3bdatapropertiesdialog.cpp
new file mode 100644
index 0000000..39fec61
--- /dev/null
+++ b/src/projects/k3bdatapropertiesdialog.cpp
@@ -0,0 +1,248 @@
+/*
+ *
+ * $Id: k3bdatapropertiesdialog.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 "k3bdatapropertiesdialog.h"
+
+#include "k3bdiritem.h"
+#include "k3bfileitem.h"
+#include <kcutlabel.h>
+#include <k3bvalidators.h>
+
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qframe.h>
+#include <qcheckbox.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qtabwidget.h>
+#include <qvalidator.h>
+
+#include <klineedit.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmimetype.h>
+#include <kurl.h>
+#include <kio/global.h>
+#include <kfileitem.h>
+
+
+
+K3bDataPropertiesDialog::K3bDataPropertiesDialog( K3bDataItem* dataItem, QWidget* parent, const char* name )
+ : KDialogBase( Plain, i18n("File Properties"), Ok|Cancel, Ok, parent, name, true, false )
+{
+ m_dataItem = dataItem;
+
+ QLabel* labelMimeType = new QLabel( plainPage() );
+ QLabel* extraInfoLabel = new QLabel( plainPage() );
+ m_editName = new KLineEdit( plainPage() );
+ m_labelType = new QLabel( plainPage() );
+ m_labelLocation = new KCutLabel( plainPage() );
+ m_labelSize = new QLabel( plainPage() );
+ m_labelBlocks = new QLabel( plainPage() );
+ m_labelLocalName = new KCutLabel( plainPage() );
+ m_labelLocalLocation = new KCutLabel( plainPage() );
+
+
+ QGridLayout* grid = new QGridLayout( plainPage() );
+ grid->setSpacing( spacingHint() );
+ grid->setMargin( marginHint() );
+
+ grid->addWidget( labelMimeType, 0, 0 );
+ grid->addWidget( m_editName, 0, 2 );
+ QFrame* line = new QFrame( plainPage() );
+ line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ grid->addMultiCellWidget( line, 1, 1, 0, 2 );
+ grid->addWidget( new QLabel( i18n("Type:"), plainPage() ), 2, 0 );
+ grid->addWidget( new QLabel( i18n("Location:"), plainPage() ), 4, 0 );
+ grid->addWidget( new QLabel( i18n("Size:"), plainPage() ), 5, 0 );
+ grid->addWidget( new QLabel( i18n("Used blocks:"), plainPage() ), 6, 0 );
+ grid->addWidget( m_labelType, 2, 2 );
+ grid->addWidget( extraInfoLabel, 3, 2 );
+ grid->addWidget( m_labelLocation, 4, 2 );
+ grid->addWidget( m_labelSize, 5, 2 );
+ grid->addWidget( m_labelBlocks, 6, 2 );
+ line = new QFrame( plainPage() );
+ line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ grid->addMultiCellWidget( line, 7, 7, 0, 2 );
+ QLabel* label1 = new QLabel( i18n("Local name:"), plainPage() );
+ grid->addWidget( label1, 8, 0 );
+ QLabel* label2 = new QLabel( i18n("Local location:"), plainPage() );
+ grid->addWidget( label2, 9, 0 );
+ grid->addWidget( m_labelLocalName, 8, 2 );
+ grid->addWidget( m_labelLocalLocation, 9, 2 );
+
+ grid->addColSpacing( 1, 50 );
+ grid->setColStretch( 2, 1 );
+
+
+
+ if( K3bFileItem* fileItem = dynamic_cast<K3bFileItem*>(dataItem) ) {
+ KFileItem kFileItem( KFileItem::Unknown, KFileItem::Unknown, KURL::fromPathOrURL(fileItem->localPath()) );
+ labelMimeType->setPixmap( kFileItem.pixmap(KIcon::SizeLarge) );
+ if( fileItem->isSymLink() )
+ m_labelType->setText( i18n("Link to %1").arg(kFileItem.mimeComment()) );
+ else
+ m_labelType->setText( kFileItem.mimeComment() );
+ m_labelLocalName->setText( kFileItem.name() );
+ QString localLocation = kFileItem.url().path(-1);
+ localLocation.truncate( localLocation.findRev('/') );
+ m_labelLocalLocation->setText( localLocation );
+ m_labelSize->setText( KIO::convertSize(dataItem->size()) );
+ }
+ else if( K3bDirItem* dirItem = dynamic_cast<K3bDirItem*>(dataItem) ) {
+ labelMimeType->setPixmap( KMimeType::pixmapForURL( KURL( "/" )) );
+ m_labelType->setText( i18n("Directory") );
+ label1->hide();
+ label2->hide();
+ m_labelLocalName->hide();
+ m_labelLocalLocation->hide();
+ line->hide();
+ m_labelSize->setText( KIO::convertSize(dataItem->size()) + "\n(" +
+ i18n("in 1 file", "in %n files", dirItem->numFiles()) + " " +
+ i18n("and 1 directory", "and %n directories", dirItem->numDirs()) + ")" );
+ }
+ else {
+ labelMimeType->setPixmap( DesktopIcon("unknown", KIcon::SizeLarge) );
+ m_labelType->setText( i18n("Special file") );
+ m_labelLocalName->hide();
+ m_labelLocalLocation->hide();
+ label1->hide();
+ label2->hide();
+ line->hide();
+ m_labelSize->setText( KIO::convertSize(dataItem->size()) );
+ }
+
+ m_editName->setText( dataItem->k3bName() );
+ m_labelBlocks->setText( QString::number(dataItem->blocks().lba()) );
+
+ QString location = "/" + dataItem->k3bPath();
+ if( location[location.length()-1] == '/' )
+ location.truncate( location.length()-1 );
+ location.truncate( location.findRev('/') );
+ if( location.isEmpty() )
+ location = "/";
+ m_labelLocation->setText( location );
+ extraInfoLabel->setText( QString( "(%1)" ).arg(dataItem->extraInfo()) );
+ if( dataItem->extraInfo().isEmpty() )
+ extraInfoLabel->hide();
+
+ // OPTIONS
+ // /////////////////////////////////////////////////
+ QTabWidget* optionTab = new QTabWidget( plainPage() );
+ line = new QFrame( plainPage() );
+ line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+
+ grid->addMultiCellWidget( line, 10, 10, 0, 2 );
+ grid->addMultiCellWidget( optionTab, 12, 12, 0, 2 );
+ grid->setRowStretch( 11, 1 );
+
+ QWidget* hideBox = new QWidget( optionTab );
+ QGridLayout* hideBoxGrid = new QGridLayout( hideBox );
+ hideBoxGrid->setSpacing( spacingHint() );
+ hideBoxGrid->setMargin( marginHint() );
+ m_checkHideOnRockRidge = new QCheckBox( i18n("Hide on Rockridge"), hideBox );
+ m_checkHideOnJoliet = new QCheckBox( i18n("Hide on Joliet"), hideBox );
+ hideBoxGrid->addWidget( m_checkHideOnRockRidge, 0, 0 );
+ hideBoxGrid->addWidget( m_checkHideOnJoliet, 1, 0 );
+ hideBoxGrid->setRowStretch( 2, 1 );
+// grid->addMultiCellWidget( m_checkHideOnRockRidge, 10, 10, 0, 2 );
+// grid->addMultiCellWidget( m_checkHideOnJoliet, 11, 11, 0, 2 );
+
+ QWidget* sortingBox = new QWidget( optionTab );
+ QGridLayout* sortingBoxGrid = new QGridLayout( sortingBox );
+ sortingBoxGrid->setSpacing( spacingHint() );
+ sortingBoxGrid->setMargin( marginHint() );
+ m_editSortWeight = new KLineEdit( sortingBox );
+ m_editSortWeight->setValidator( new QIntValidator( -2147483647, 2147483647, m_editSortWeight ) );
+ m_editSortWeight->setAlignment( Qt::AlignRight );
+ sortingBoxGrid->addWidget( new QLabel( i18n("Sort weight:"), sortingBox ), 0, 0 );
+ sortingBoxGrid->addWidget( m_editSortWeight, 0, 1 );
+ sortingBoxGrid->setColStretch( 1, 1 );
+ sortingBoxGrid->setRowStretch( 1, 1 );
+
+ optionTab->addTab( hideBox, i18n("Settings") );
+ optionTab->addTab( sortingBox, i18n("Advanced") );
+
+
+ m_checkHideOnJoliet->setChecked( dataItem->hideOnJoliet() );
+ m_checkHideOnRockRidge->setChecked( dataItem->hideOnRockRidge() );
+ m_editSortWeight->setText( QString::number(dataItem->sortWeight()) );
+
+ // if the parent is hidden the value cannot be changed (see K3bDataItem::setHide...)
+ if( dataItem->parent() ) {
+ m_checkHideOnRockRidge->setDisabled( dataItem->parent()->hideOnRockRidge() );
+ m_checkHideOnJoliet->setDisabled( dataItem->parent()->hideOnJoliet() );
+ }
+
+ if( !dataItem->isHideable() ) {
+ m_checkHideOnJoliet->setDisabled(true);
+ m_checkHideOnRockRidge->setDisabled(true);
+ // line->hide();
+ }
+
+ QToolTip::add( m_checkHideOnRockRidge, i18n("Hide this file in the RockRidge filesystem") );
+ QToolTip::add( m_checkHideOnJoliet, i18n("Hide this file in the Joliet filesystem") );
+ QToolTip::add( m_editSortWeight, i18n("Modify the physical sorting") );
+ QWhatsThis::add( m_checkHideOnRockRidge, i18n("<p>If this option is checked, the file or directory "
+ "(and its entire contents) will be hidden on the "
+ "ISO9660 and RockRidge filesystem.</p>"
+ "<p>This is useful, for example, for having different README "
+ "files for RockRidge and Joliet, which can be managed "
+ "by hiding README.joliet on RockRidge and README.rr "
+ "on the Joliet filesystem.</p>") );
+ QWhatsThis::add( m_checkHideOnJoliet, i18n("<p>If this option is checked, the file or directory "
+ "(and its entire contents) will be hidden on the "
+ "Joliet filesystem.</p>"
+ "<p>This is useful, for example, for having different README "
+ "files for RockRidge and Joliet, which can be managed "
+ "by hiding README.joliet on RockRidge and README.rr "
+ "on the Joliet filesystem.</p>") );
+ QWhatsThis::add( m_editSortWeight, i18n("<p>This value modifies the physical sort order of the files "
+ "in the ISO9660 filesystem. A higher weighting means that the "
+ "file will be located closer to the beginning of the image "
+ "(and the disk)."
+ "<p>This option is useful in order to optimize the data layout "
+ "on a CD/DVD."
+ "<p><b>Caution:</b> This does not sort the order of the file "
+ "names that appear in the ISO9660 directory."
+ "It sorts the order in which the file data is "
+ "written to the image.") );
+
+ m_editName->setValidator( K3bValidators::iso9660Validator( false, this ) );
+ m_editName->setReadOnly( !dataItem->isRenameable() );
+ m_editName->setFocus();
+}
+
+
+K3bDataPropertiesDialog::~K3bDataPropertiesDialog()
+{
+}
+
+
+void K3bDataPropertiesDialog::slotOk()
+{
+ // save filename
+ m_dataItem->setK3bName( m_editName->text() );
+ m_dataItem->setHideOnRockRidge( m_checkHideOnRockRidge->isChecked() );
+ m_dataItem->setHideOnJoliet( m_checkHideOnJoliet->isChecked() );
+ m_dataItem->setSortWeight( m_editSortWeight->text().toInt() );
+
+ KDialogBase::slotOk();
+}
+
+
+#include "k3bdatapropertiesdialog.moc"
diff --git a/src/projects/k3bdatapropertiesdialog.h b/src/projects/k3bdatapropertiesdialog.h
new file mode 100644
index 0000000..eb585ce
--- /dev/null
+++ b/src/projects/k3bdatapropertiesdialog.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * $Id: k3bdatapropertiesdialog.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 K3BDATAPROPERTIESDIALOG_H
+#define K3BDATAPROPERTIESDIALOG_H
+
+#include <kdialogbase.h>
+
+class K3bDataItem;
+
+class KLineEdit;
+class QPushButton;
+class QLabel;
+class QCheckBox;
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bDataPropertiesDialog : public KDialogBase
+{
+Q_OBJECT
+
+ public:
+ K3bDataPropertiesDialog( K3bDataItem*, QWidget* parent = 0, const char* name = 0 );
+ ~K3bDataPropertiesDialog();
+
+ protected slots:
+ void slotOk();
+
+ private:
+ KLineEdit* m_editName;
+ QLabel* m_labelType;
+ QLabel* m_labelLocation;
+ QLabel* m_labelSize;
+ QLabel* m_labelBlocks;
+
+ QLabel* m_labelLocalName;
+ QLabel* m_labelLocalLocation;
+
+ QCheckBox* m_checkHideOnRockRidge;
+ QCheckBox* m_checkHideOnJoliet;
+ KLineEdit* m_editSortWeight;
+
+ K3bDataItem* m_dataItem;
+};
+
+#endif
diff --git a/src/projects/k3bdatasessionimportdialog.cpp b/src/projects/k3bdatasessionimportdialog.cpp
new file mode 100644
index 0000000..f6f1b85
--- /dev/null
+++ b/src/projects/k3bdatasessionimportdialog.cpp
@@ -0,0 +1,137 @@
+/*
+ *
+ * $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 "k3bdatasessionimportdialog.h"
+#include "k3bmediaselectioncombobox.h"
+
+#include <k3bdatadoc.h>
+#include <k3bapplication.h>
+#include <k3biso9660.h>
+#include <k3bmediacache.h>
+#include <k3b.h>
+
+#include <qpushbutton.h>
+#include <qcursor.h>
+#include <qapplication.h>
+
+#include <klocale.h>
+#include <kmessagebox.h>
+
+
+K3bDataSessionImportDialog::K3bDataSessionImportDialog( QWidget* parent )
+ : KDialogBase( parent,
+ "session_import_dialog",
+ true,
+ i18n("Session Import"),
+ KDialogBase::Ok|KDialogBase::Cancel,
+ KDialogBase::Ok,
+ false )
+{
+ m_comboMedia = new K3bMediaSelectionComboBox( this );
+ setMainWidget( m_comboMedia );
+
+ connect( m_comboMedia, SIGNAL(selectionChanged(K3bDevice::Device*)),
+ this, SLOT(slotSelectionChanged(K3bDevice::Device*)) );
+}
+
+
+K3bDataSessionImportDialog::~K3bDataSessionImportDialog()
+{
+}
+
+
+void K3bDataSessionImportDialog::importSession( K3bDataDoc* doc )
+{
+ m_doc = doc;
+
+ if( doc ) {
+ m_comboMedia->setWantedMediumType( m_doc->type() == K3bDoc::DVD
+ ? K3bDevice::MEDIA_WRITABLE_DVD
+ : K3bDevice::MEDIA_WRITABLE_CD );
+ }
+ else
+ m_comboMedia->setWantedMediumType( K3bDevice::MEDIA_WRITABLE );
+
+ m_comboMedia->setWantedMediumState( K3bDevice::STATE_INCOMPLETE );
+
+ slotSelectionChanged( m_comboMedia->selectedDevice() );
+}
+
+
+void K3bDataSessionImportDialog::slotOk()
+{
+ // find the selected device, show a busy mouse cursor and call K3bDataDoc::importSession
+ if( K3bDevice::Device* dev = m_comboMedia->selectedDevice() ) {
+ QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
+
+ //
+ // Mkisofs does not properly import joliet filenames from an old session
+ //
+ // See bug 79215 for details
+ //
+ K3bIso9660 iso( dev );
+ if( iso.open() ) {
+ if( iso.firstRRDirEntry() == 0 && iso.jolietLevel() > 0 )
+ KMessageBox::sorry( this,
+ i18n("<p>K3b found session containing Joliet information for long filenames "
+ "but no Rock Ridge extensions."
+ "<p>The filenames in the imported session will be converted to a restricted "
+ "character set in the new session. This character set is based on the ISO9660 "
+ "settings in the K3b project. K3b is not able to display these converted filenames yet."),
+ i18n("Session Import Warning") );
+ iso.close();
+ }
+
+ if( !m_doc ) {
+ if( k3bappcore->mediaCache()->diskInfo( dev ).isDvdMedia() )
+ m_doc = static_cast<K3bDataDoc*>( k3bappcore->k3bMainWindow()->slotNewDvdDoc() );
+ else
+ m_doc = static_cast<K3bDataDoc*>( k3bappcore->k3bMainWindow()->slotNewDataDoc() );
+ }
+
+ m_doc->setBurner( dev );
+ m_doc->importSession( dev );
+
+ QApplication::restoreOverrideCursor();
+
+ done( 0 );
+ }
+ else
+ done( 1 );
+}
+
+
+void K3bDataSessionImportDialog::slotCancel()
+{
+ KDialogBase::slotCancel();
+}
+
+
+void K3bDataSessionImportDialog::slotSelectionChanged( K3bDevice::Device* dev )
+{
+ actionButton( KDialogBase::Ok )->setEnabled( dev != 0 );
+}
+
+
+K3bDataDoc* K3bDataSessionImportDialog::importSession( K3bDataDoc* doc, QWidget* parent )
+{
+ K3bDataSessionImportDialog dlg( parent );
+ dlg.importSession( doc );
+ dlg.exec();
+ return dlg.m_doc;
+}
+
+
+#include "k3bdatasessionimportdialog.moc"
diff --git a/src/projects/k3bdatasessionimportdialog.h b/src/projects/k3bdatasessionimportdialog.h
new file mode 100644
index 0000000..77c074f
--- /dev/null
+++ b/src/projects/k3bdatasessionimportdialog.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * $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_SESSION_IMPORT_DIALOG_H_
+#define _K3B_SESSION_IMPORT_DIALOG_H_
+
+#include <kdialogbase.h>
+
+#include <qptrlist.h>
+#include <qmap.h>
+
+#include <k3bdevice.h>
+
+
+class QLabel;
+class KListBox;
+class K3bDataDoc;
+class K3bMediaSelectionComboBox;
+
+
+class K3bDataSessionImportDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Import a session into the project.
+ * If the project is a DVD data project only DVD media are
+ * presented for selection.
+ *
+ * \param doc if 0 a new project will be created.
+ *
+ * \return the project
+ */
+ static K3bDataDoc* importSession( K3bDataDoc* doc, QWidget* parent );
+
+ private slots:
+ void slotOk();
+ void slotCancel();
+
+ void importSession( K3bDataDoc* doc );
+ void slotSelectionChanged( K3bDevice::Device* );
+
+ private:
+ K3bDataSessionImportDialog( QWidget* parent = 0 );
+ ~K3bDataSessionImportDialog();
+
+ K3bDataDoc* m_doc;
+ K3bMediaSelectionComboBox* m_comboMedia;
+};
+
+#endif
diff --git a/src/projects/k3bdataurladdingdialog.cpp b/src/projects/k3bdataurladdingdialog.cpp
new file mode 100644
index 0000000..2edb43b
--- /dev/null
+++ b/src/projects/k3bdataurladdingdialog.cpp
@@ -0,0 +1,826 @@
+/*
+ *
+ * $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 <k3bglobals.h>
+
+#include "k3bdataurladdingdialog.h"
+#include "k3bencodingconverter.h"
+
+#include <qtimer.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+
+#include <k3bdatadoc.h>
+#include <k3bdiritem.h>
+#include <k3bcore.h>
+#include <k3bfileitem.h>
+#include <k3bmultichoicedialog.h>
+#include <k3bvalidators.h>
+#include <k3bglobals.h>
+#include <k3bisooptions.h>
+#include <k3b.h>
+#include <k3bapplication.h>
+#include <k3biso9660.h>
+#include <k3bdirsizejob.h>
+#include <k3binteractiondialog.h>
+#include <k3bthread.h>
+#include <k3bsignalwaiter.h>
+#include <k3bexternalbinmanager.h>
+
+#include <klocale.h>
+#include <kurl.h>
+#include <kinputdialog.h>
+#include <kmessagebox.h>
+#include <kiconloader.h>
+#include <kglobal.h>
+#include <kstdguiitem.h>
+#include <kconfig.h>
+#include <ksqueezedtextlabel.h>
+#include <kprogress.h>
+
+#include <unistd.h>
+
+
+K3bDataUrlAddingDialog::K3bDataUrlAddingDialog( K3bDataDoc* doc, QWidget* parent, const char* name )
+ : KDialogBase( Plain,
+ i18n("Adding files to project '%1'").arg(doc->URL().fileName()),
+ Cancel,
+ Cancel,
+ parent,
+ name,
+ true,
+ true ),
+ m_bExistingItemsReplaceAll(false),
+ m_bExistingItemsIgnoreAll(false),
+ m_bFolderLinksFollowAll(false),
+ m_bFolderLinksAddAll(false),
+ m_iAddHiddenFiles(0),
+ m_iAddSystemFiles(0),
+ m_bCanceled(false),
+ m_totalFiles(0),
+ m_filesHandled(0),
+ m_lastProgress(0)
+{
+ m_encodingConverter = new K3bEncodingConverter();
+
+ QWidget* page = plainPage();
+ QGridLayout* grid = new QGridLayout( page );
+ grid->setSpacing( spacingHint() );
+ grid->setMargin( 0 );
+
+ m_counterLabel = new QLabel( page );
+ m_infoLabel = new KSqueezedTextLabel( i18n("Adding files to project '%1'")
+ .arg(doc->URL().fileName()) + "...", page );
+ m_progressWidget = new KProgress( 0, page );
+
+ grid->addWidget( m_counterLabel, 0, 1 );
+ grid->addWidget( m_infoLabel, 0, 0 );
+ grid->addMultiCellWidget( m_progressWidget, 1, 1, 0, 1 );
+
+ m_dirSizeJob = new K3bDirSizeJob( this );
+ connect( m_dirSizeJob, SIGNAL(finished(bool)),
+ this, SLOT(slotDirSizeDone(bool)) );
+
+ // try to start with a reasonable size
+ resize( (int)( fontMetrics().width( caption() ) * 1.5 ), sizeHint().height() );
+}
+
+
+K3bDataUrlAddingDialog::~K3bDataUrlAddingDialog()
+{
+ delete m_encodingConverter;
+}
+
+
+int K3bDataUrlAddingDialog::addUrls( const KURL::List& urls,
+ K3bDirItem* dir,
+ QWidget* parent )
+{
+ if( urls.isEmpty() )
+ return 0;
+
+ //
+ // A common mistake by beginners is to try to burn an iso image
+ // with a data project. Let's warn them
+ //
+ if( urls.count() == 1 ) {
+ K3bIso9660 isoF( urls.first().path() );
+ if( isoF.open() ) {
+ if( KMessageBox::warningYesNo( parent,
+ i18n("<p>The file you are about to add to the project is an ISO9660 image. As such "
+ "it can be burned to a medium directly since it already contains a file "
+ "system.<br>"
+ "Are you sure you want to add this file to the project?"),
+ i18n("Adding image file to project"),
+ i18n("Add the file to the project"),
+ i18n("Burn the image directly") ) == KMessageBox::No ) {
+ // very rough dvd image size test
+ if( K3b::filesize( urls.first() ) > 1000*1024*1024 )
+ k3bappcore->k3bMainWindow()->slotWriteDvdIsoImage( urls.first() );
+ else
+ k3bappcore->k3bMainWindow()->slotWriteCdImage( urls.first() );
+ return 0;
+ }
+ }
+ }
+
+ K3bDataUrlAddingDialog dlg( dir->doc(), parent );
+ dlg.m_urls = urls;
+ for( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it )
+ dlg.m_urlQueue.append( qMakePair( K3b::convertToLocalUrl(*it), dir ) );
+
+ dlg.slotAddUrls();
+ int ret = QDialog::Accepted;
+ if( !dlg.m_urlQueue.isEmpty() ) {
+ dlg.m_dirSizeJob->setUrls( urls );
+ dlg.m_dirSizeJob->setFollowSymlinks( dir->doc()->isoOptions().followSymbolicLinks() );
+ dlg.m_dirSizeJob->start();
+ ret = dlg.exec();
+ }
+
+ // make sure the dir size job is finished
+ dlg.m_dirSizeJob->cancel();
+ K3bSignalWaiter::waitForJob( dlg.m_dirSizeJob );
+
+ QString message = dlg.resultMessage();
+ if( !message.isEmpty() )
+ KMessageBox::detailedSorry( parent, i18n("Problems while adding files to the project."), message );
+
+ return ret;
+}
+
+
+QString K3bDataUrlAddingDialog::resultMessage() const
+{
+ QString message;
+ if( !m_unreadableFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br>%2")
+ .arg( i18n("Insufficient permissions to read the following files") )
+ .arg( m_unreadableFiles.join( "<br>" ) );
+ if( !m_notFoundFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br>%2")
+ .arg( i18n("Unable to find the following files") )
+ .arg( m_notFoundFiles.join( "<br>" ) );
+ if( !m_nonLocalFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br>%2")
+ .arg( i18n("No non-local files supported") )
+ .arg( m_unreadableFiles.join( "<br>" ) );
+ if( !m_tooBigFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br>%2")
+ .arg( i18n("It is not possible to add files bigger than %1").arg(KIO::convertSize(0xFFFFFFFF)) )
+ .arg( m_tooBigFiles.join( "<br>" ) );
+ if( !m_mkisofsLimitationRenamedFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br>%2")
+ .arg( i18n("Some filenames had to be modified due to limitations in mkisofs") )
+ .arg( m_mkisofsLimitationRenamedFiles.join( "<br>" ) );
+ if( !m_invalidFilenameEncodingFiles.isEmpty() )
+ message += QString("<p><b>%1:</b><br>%2")
+ .arg( i18n("The following filenames have an invalid encoding. You may fix this "
+ "with the convmv tool") )
+ .arg( m_invalidFilenameEncodingFiles.join( "<br>" ) );
+
+ return message;
+}
+
+
+int K3bDataUrlAddingDialog::moveItems( const QValueList<K3bDataItem*>& items,
+ K3bDirItem* dir,
+ QWidget* parent )
+{
+ return copyMoveItems( items, dir, parent, false );
+}
+
+
+int K3bDataUrlAddingDialog::copyItems( const QValueList<K3bDataItem*>& items,
+ K3bDirItem* dir,
+ QWidget* parent )
+{
+ return copyMoveItems( items, dir, parent, true );
+}
+
+
+int K3bDataUrlAddingDialog::copyMoveItems( const QValueList<K3bDataItem*>& items,
+ K3bDirItem* dir,
+ QWidget* parent,
+ bool copy )
+{
+ if( items.isEmpty() )
+ return 0;
+
+ K3bDataUrlAddingDialog dlg( dir->doc(), parent );
+ dlg.m_infoLabel->setText( i18n("Moving files to project \"%1\"...").arg(dir->doc()->URL().fileName()) );
+ dlg.m_copyItems = copy;
+
+ for( QValueList<K3bDataItem*>::const_iterator it = items.begin(); it != items.end(); ++it ) {
+ dlg.m_items.append( qMakePair( *it, dir ) );
+ ++dlg.m_totalFiles;
+ if( (*it)->isDir() ) {
+ dlg.m_totalFiles += static_cast<K3bDirItem*>( *it )->numFiles();
+ dlg.m_totalFiles += static_cast<K3bDirItem*>( *it )->numDirs();
+ }
+ }
+
+ dlg.slotCopyMoveItems();
+ int ret = QDialog::Accepted;
+ if( !dlg.m_items.isEmpty() ) {
+ dlg.m_progressWidget->setTotalSteps( dlg.m_totalFiles );
+ ret = dlg.exec();
+ }
+
+ return ret;
+}
+
+
+void K3bDataUrlAddingDialog::slotCancel()
+{
+ m_bCanceled = true;
+ m_dirSizeJob->cancel();
+ KDialogBase::slotCancel();
+}
+
+
+void K3bDataUrlAddingDialog::slotAddUrls()
+{
+ if( m_bCanceled )
+ return;
+
+ // add next url
+ KURL url = m_urlQueue.first().first;
+ K3bDirItem* dir = m_urlQueue.first().second;
+ m_urlQueue.remove( m_urlQueue.begin() );
+ //
+ // HINT:
+ // we only use QFileInfo::absFilePath() and QFileInfo::isHidden()
+ // both do not cause QFileInfo to stat, thus no speed improvement
+ // can come from removing QFileInfo usage here.
+ //
+ QFileInfo info(url.path());
+ QString absFilePath( info.absFilePath() );
+ QString resolved( absFilePath );
+
+ bool valid = true;
+ k3b_struct_stat statBuf, resolvedStatBuf;
+ bool isSymLink = false;
+ bool isDir = false;
+ bool isFile = false;
+
+ ++m_filesHandled;
+
+#if 0
+ m_infoLabel->setText( url.path() );
+ if( m_totalFiles == 0 )
+ m_counterLabel->setText( QString("(%1)").arg(m_filesHandled) );
+ else
+ m_counterLabel->setText( QString("(%1/%2)").arg(m_filesHandled).arg(m_totalFiles) );
+#endif
+
+ //
+ // 1. Check if we want and can add the url
+ //
+
+ if( !url.isLocalFile() ) {
+ valid = false;
+ m_nonLocalFiles.append( url.path() );
+ }
+
+ else if( k3b_lstat( QFile::encodeName(absFilePath), &statBuf ) != 0 ) {
+ valid = false;
+ m_notFoundFiles.append( url.path() );
+ }
+
+ else if( !m_encodingConverter->encodedLocally( QFile::encodeName( url.path() ) ) ) {
+ valid = false;
+ m_invalidFilenameEncodingFiles.append( url.path() );
+ }
+
+ else {
+ isSymLink = S_ISLNK(statBuf.st_mode);
+ isFile = S_ISREG(statBuf.st_mode);
+ isDir = S_ISDIR(statBuf.st_mode);
+
+ // symlinks are always readable and can always be added to a project
+ // but we need to know if the symlink points to a directory
+ if( isSymLink ) {
+ resolved = K3b::resolveLink( absFilePath );
+ k3b_stat( QFile::encodeName(resolved), &resolvedStatBuf );
+ isDir = S_ISDIR(resolvedStatBuf.st_mode);
+ }
+
+ else {
+ if( ::access( QFile::encodeName( absFilePath ), R_OK ) != 0 ) {
+ valid = false;
+ m_unreadableFiles.append( url.path() );
+ }
+ else if( isFile && (unsigned long long)statBuf.st_size >= 0xFFFFFFFFULL ) {
+ if ( !k3bcore->externalBinManager()->binObject( "mkisofs" )->hasFeature( "no-4gb-limit" ) ) {
+ valid = false;
+ m_tooBigFiles.append( url.path() );
+ }
+ }
+ }
+
+ // FIXME: if we do not add hidden dirs the progress gets messed up!
+
+ //
+ // check for hidden and system files
+ //
+ if( valid ) {
+ if( info.isHidden() && !addHiddenFiles() )
+ valid = false;
+ if( S_ISCHR(statBuf.st_mode) ||
+ S_ISBLK(statBuf.st_mode) ||
+ S_ISFIFO(statBuf.st_mode) ||
+ S_ISSOCK(statBuf.st_mode) )
+ if( !addSystemFiles() )
+ valid = false;
+ if( isSymLink )
+ if( S_ISCHR(resolvedStatBuf.st_mode) ||
+ S_ISBLK(resolvedStatBuf.st_mode) ||
+ S_ISFIFO(resolvedStatBuf.st_mode) ||
+ S_ISSOCK(resolvedStatBuf.st_mode) )
+ if( !addSystemFiles() )
+ valid = false;
+ }
+ }
+
+
+ //
+ // 2. Handle the url
+ //
+
+ QString newName = url.fileName();
+
+ // filenames cannot end in backslashes (mkisofs problem. See comments in k3bisoimager.cpp (escapeGraftPoint()))
+ bool bsAtEnd = false;
+ while( newName[newName.length()-1] == '\\' ) {
+ newName.truncate( newName.length()-1 );
+ bsAtEnd = true;
+ }
+ if( bsAtEnd )
+ m_mkisofsLimitationRenamedFiles.append( url.path() + " -> " + newName );
+
+ // backup dummy name
+ if( newName.isEmpty() )
+ newName = "1";
+
+ K3bDirItem* newDirItem = 0;
+
+ //
+ // The source is valid. Now check if the project already contains a file with that name
+ // and if so handle it properly
+ //
+ if( valid ) {
+ if( K3bDataItem* oldItem = dir->find( newName ) ) {
+ //
+ // reuse an existing dir
+ //
+ if( oldItem->isDir() && isDir )
+ newDirItem = dynamic_cast<K3bDirItem*>(oldItem);
+
+ //
+ // we cannot replace files in the old session with dirs and vice versa (I think)
+ // files are handled in K3bFileItem constructor and dirs handled above
+ //
+ else if( oldItem->isFromOldSession() &&
+ isDir != oldItem->isDir() ) {
+ if( !getNewName( newName, dir, newName ) )
+ valid = false;
+ }
+
+ else if( m_bExistingItemsIgnoreAll )
+ valid = false;
+
+ else if( oldItem->localPath() == resolved ) {
+ //
+ // Just ignore if the same file is added again
+ //
+ valid = false;
+ }
+
+ else if( m_bExistingItemsReplaceAll ) {
+ // if we replace an item from an old session the K3bFileItem constructor takes care
+ // of replacing the item
+ if( !oldItem->isFromOldSession() )
+ delete oldItem;
+ }
+
+ //
+ // Let the user choose
+ //
+ else {
+ switch( K3bMultiChoiceDialog::choose( i18n("File already exists"),
+ i18n("<p>File <em>%1</em> already exists in "
+ "project folder <em>%2</em>.")
+ .arg(newName)
+ .arg('/' + dir->k3bPath()),
+ QMessageBox::Warning,
+ this,
+ 0,
+ 6,
+ KGuiItem( i18n("Replace"),
+ QString::null,
+ i18n("Replace the existing file") ),
+ KGuiItem( i18n("Replace All"),
+ QString::null,
+ i18n("Always replace existing files") ),
+ KGuiItem( i18n("Ignore"),
+ QString::null,
+ i18n("Keep the existing file") ),
+ KGuiItem( i18n("Ignore All"),
+ QString::null,
+ i18n("Always keep the existing file") ),
+ KGuiItem( i18n("Rename"),
+ QString::null,
+ i18n("Rename the new file") ),
+ KStdGuiItem::cancel() ) ) {
+ case 2: // replace all
+ m_bExistingItemsReplaceAll = true;
+ // fallthrough
+ case 1: // replace
+ // if we replace an item from an old session the K3bFileItem constructor takes care
+ // of replacing the item
+ if( !oldItem->isFromOldSession() )
+ delete oldItem;
+ break;
+ case 4: // ignore all
+ m_bExistingItemsIgnoreAll = true;
+ // fallthrough
+ case 3: // ignore
+ valid = false;
+ break;
+ case 5: // rename
+ if( !getNewName( newName, dir, newName ) )
+ valid = false;
+ break;
+ case 6: // cancel
+ slotCancel();
+ return;
+ }
+ }
+ }
+ }
+
+
+ //
+ // One more thing to warn the user about: We cannot follow links to folders since that
+ // would change the doc. So we simply ask the user what to do with a link to a folder
+ //
+ if( valid ) {
+ // let's see if this link starts a loop
+ // that means if it points to some folder above this one
+ // if so we cannot follow it anyway
+ if( isDir && isSymLink && !absFilePath.startsWith( resolved ) ) {
+ bool followLink = dir->doc()->isoOptions().followSymbolicLinks() || m_bFolderLinksFollowAll;
+ if( !followLink && !m_bFolderLinksAddAll ) {
+ switch( K3bMultiChoiceDialog::choose( i18n("Adding link to folder"),
+ i18n("<p>'%1' is a symbolic link to folder '%2'."
+ "<p>If you intend to make K3b follow symbolic links you should consider letting K3b do this now "
+ "since K3b will not be able to do so afterwards because symbolic links to folders inside a "
+ "K3b project cannot be resolved."
+ "<p><b>If you do not intend to enable the option <em>follow symbolic links</em> you may safely "
+ "ignore this warning and choose to add the link to the project.</b>")
+ .arg(absFilePath)
+ .arg(resolved ),
+ QMessageBox::Warning,
+ this,
+ 0,
+ 5,
+ i18n("Follow link now"),
+ i18n("Always follow links"),
+ i18n("Add link to project"),
+ i18n("Always add links"),
+ KStdGuiItem::cancel() ) ) {
+ case 2:
+ m_bFolderLinksFollowAll = true;
+ case 1:
+ followLink = true;
+ break;
+ case 4:
+ m_bFolderLinksAddAll = true;
+ case 3:
+ followLink = false;
+ break;
+ case 5:
+ slotCancel();
+ return;
+ }
+ }
+
+ if( followLink ) {
+ absFilePath = resolved;
+ isSymLink = false;
+
+ // count the files in the followed dir
+ if( m_dirSizeJob->active() )
+ m_dirSizeQueue.append( KURL::fromPathOrURL(absFilePath) );
+ else {
+ m_progressWidget->setTotalSteps( 0 );
+ m_dirSizeJob->setUrls( KURL::fromPathOrURL(absFilePath) );
+ m_dirSizeJob->start();
+ }
+ }
+ }
+ }
+
+
+ //
+ // Project valid also (we overwrite or renamed)
+ // now create the new item
+ //
+ if( valid ) {
+ //
+ // Set the volume id from the first added url
+ // only if the doc was not changed yet
+ //
+ if( m_urls.count() == 1 &&
+ !dir->doc()->isModified() &&
+ !dir->doc()->isSaved() ) {
+ dir->doc()->setVolumeID( K3b::removeFilenameExtension( newName ) );
+ }
+
+ if( isDir && !isSymLink ) {
+ if( !newDirItem ) { // maybe we reuse an already existing dir
+ newDirItem = new K3bDirItem( newName , dir->doc(), dir );
+ newDirItem->setLocalPath( url.path() ); // HACK: see k3bdiritem.h
+ }
+
+ QDir newDir( absFilePath );
+ int dirFilter = QDir::All|QDir::Hidden|QDir::System;
+
+ QStringList dlist = newDir.entryList( dirFilter );
+ const QString& dot = KGlobal::staticQString( "." );
+ const QString& dotdot = KGlobal::staticQString( ".." );
+ dlist.remove( dot );
+ dlist.remove( dotdot );
+
+ for( QStringList::Iterator it = dlist.begin(); it != dlist.end(); ++it ) {
+ m_urlQueue.append( qMakePair( KURL::fromPathOrURL(absFilePath + '/' + *it), newDirItem ) );
+ }
+ }
+ else {
+ (void)new K3bFileItem( &statBuf, &resolvedStatBuf, url.path(), dir->doc(), dir, newName );
+ }
+ }
+
+ if( m_urlQueue.isEmpty() ) {
+ m_dirSizeJob->cancel();
+ m_progressWidget->setProgress( 100 );
+ accept();
+ }
+ else {
+ updateProgress();
+ QTimer::singleShot( 0, this, SLOT(slotAddUrls()) );
+ }
+}
+
+
+void K3bDataUrlAddingDialog::slotCopyMoveItems()
+{
+ if( m_bCanceled )
+ return;
+
+ //
+ // Pop first item from the item list
+ //
+ K3bDataItem* item = m_items.first().first;
+ K3bDirItem* dir = m_items.first().second;
+ m_items.remove( m_items.begin() );
+
+ ++m_filesHandled;
+ m_infoLabel->setText( item->k3bPath() );
+ if( m_totalFiles == 0 )
+ m_counterLabel->setText( QString("(%1)").arg(m_filesHandled) );
+ else
+ m_counterLabel->setText( QString("(%1/%2)").arg(m_filesHandled).arg(m_totalFiles) );
+
+
+ if( dir == item->parent() ) {
+ kdDebug() << "(K3bDataUrlAddingDialog) trying to move an item into its own parent dir." << endl;
+ }
+ else if( dir == item ) {
+ kdDebug() << "(K3bDataUrlAddingDialog) trying to move an item into itselft." << endl;
+ }
+ else {
+ //
+ // Let's see if an item with that name alredy exists
+ //
+ if( K3bDataItem* oldItem = dir->find( item->k3bName() ) ) {
+ //
+ // reuse an existing dir: move all child items into the old dir
+ //
+ if( oldItem->isDir() && item->isDir() ) {
+ const QPtrList<K3bDataItem>& cl = dynamic_cast<K3bDirItem*>( item )->children();
+ for( QPtrListIterator<K3bDataItem> it( cl ); *it; ++it )
+ m_items.append( qMakePair( *it, dynamic_cast<K3bDirItem*>( oldItem ) ) );
+
+ // FIXME: we need to remove the old dir item
+ }
+
+ //
+ // we cannot replace files in the old session with dirs and vice versa (I think)
+ // files are handled in K3bFileItem constructor and dirs handled above
+ //
+ else if( oldItem->isFromOldSession() &&
+ item->isDir() != oldItem->isDir() ) {
+ QString newName;
+ if( getNewName( newName, dir, newName ) ) {
+ if( m_copyItems )
+ item = item->copy();
+ item->setK3bName( newName );
+ dir->addDataItem( item );
+ }
+ }
+
+ else if( m_bExistingItemsReplaceAll ) {
+ //
+ // if we replace an item from an old session K3bDirItem::addDataItem takes care
+ // of replacing the item
+ //
+ if( !oldItem->isFromOldSession() )
+ delete oldItem;
+ if( m_copyItems )
+ item = item->copy();
+ dir->addDataItem( item );
+ }
+
+ else if( !m_bExistingItemsIgnoreAll ) {
+ switch( K3bMultiChoiceDialog::choose( i18n("File already exists"),
+ i18n("<p>File <em>%1</em> already exists in "
+ "project folder <em>%2</em>.")
+ .arg( item->k3bName() )
+ .arg("/" + dir->k3bPath()),
+ QMessageBox::Warning,
+ this,
+ 0,
+ 6,
+ KGuiItem( i18n("Replace"),
+ QString::null,
+ i18n("Replace the existing file") ),
+ KGuiItem( i18n("Replace All"),
+ QString::null,
+ i18n("Always replace existing files") ),
+ KGuiItem( i18n("Ignore"),
+ QString::null,
+ i18n("Keep the existing file") ),
+ KGuiItem( i18n("Ignore All"),
+ QString::null,
+ i18n("Always keep the existing file") ),
+ KGuiItem( i18n("Rename"),
+ QString::null,
+ i18n("Rename the new file") ),
+ KStdGuiItem::cancel() ) ) {
+ case 2: // replace all
+ m_bExistingItemsReplaceAll = true;
+ // fallthrough
+ case 1: // replace
+ //
+ // if we replace an item from an old session K3bDirItem::addDataItem takes care
+ // of replacing the item
+ //
+ if( !oldItem->isFromOldSession() )
+ delete oldItem;
+ if( m_copyItems )
+ item = item->copy();
+ dir->addDataItem( item );
+ break;
+ case 4: // ignore all
+ m_bExistingItemsIgnoreAll = true;
+ // fallthrough
+ case 3: // ignore
+ // do nothing
+ break;
+ case 5: {// rename
+ QString newName;
+ if( getNewName( newName, dir, newName ) ) {
+ if( m_copyItems )
+ item = item->copy();
+ item->setK3bName( newName );
+ dir->addDataItem( item );
+ }
+ break;
+ }
+ case 6: // cancel
+ slotCancel();
+ return;
+ }
+ }
+ }
+
+ //
+ // No old item with the same name
+ //
+ else {
+ if( m_copyItems )
+ item = item->copy();
+ dir->addDataItem( item );
+ }
+ }
+
+ if( m_items.isEmpty() ) {
+ m_dirSizeJob->cancel();
+ accept();
+ }
+ else {
+ updateProgress();
+ QTimer::singleShot( 0, this, SLOT(slotCopyMoveItems()) );
+ }
+}
+
+
+bool K3bDataUrlAddingDialog::getNewName( const QString& oldName, K3bDirItem* dir, QString& newName )
+{
+ bool ok = true;
+ newName = oldName;
+ QValidator* validator = K3bValidators::iso9660Validator( false, this );
+ do {
+ newName = KInputDialog::getText( i18n("Enter New Filename"),
+ i18n("A file with that name already exists. Please enter a new name:"),
+ newName, &ok, this, "renamedialog", validator );
+
+ } while( ok && dir->find( newName ) );
+
+ delete validator;
+
+ return ok;
+}
+
+
+bool K3bDataUrlAddingDialog::addHiddenFiles()
+{
+ if( m_iAddHiddenFiles == 0 ) {
+ // FIXME: the isVisible() stuff makes the static addUrls method not return (same below)
+ if( KMessageBox::questionYesNo( /*isVisible() ? */this/* : parentWidget()*/,
+ i18n("Do you also want to add hidden files?"),
+ i18n("Hidden Files"), i18n("Add"), i18n("Do Not Add") ) == KMessageBox::Yes )
+ m_iAddHiddenFiles = 1;
+ else
+ m_iAddHiddenFiles = -1;
+ }
+
+ return ( m_iAddHiddenFiles == 1 );
+}
+
+
+bool K3bDataUrlAddingDialog::addSystemFiles()
+{
+ if( m_iAddSystemFiles == 0 ) {
+ if( KMessageBox::questionYesNo( /*isVisible() ? */this/* : parentWidget()*/,
+ i18n("Do you also want to add system files "
+ "(FIFOs, sockets, device files, and broken symlinks)?"),
+ i18n("System Files"), i18n("Add"), i18n("Do Not Add") ) == KMessageBox::Yes )
+ m_iAddSystemFiles = 1;
+ else
+ m_iAddSystemFiles = -1;
+ }
+
+ return ( m_iAddSystemFiles == 1 );
+}
+
+
+void K3bDataUrlAddingDialog::slotDirSizeDone( bool success )
+{
+ if( success ) {
+ m_totalFiles += m_dirSizeJob->totalFiles() + m_dirSizeJob->totalDirs();
+ if( m_dirSizeQueue.isEmpty() ) {
+ m_progressWidget->setTotalSteps( 100 );
+ updateProgress();
+ }
+ else {
+ m_dirSizeJob->setUrls( m_dirSizeQueue.back() );
+ m_dirSizeQueue.pop_back();
+ m_dirSizeJob->start();
+ }
+ }
+}
+
+
+void K3bDataUrlAddingDialog::updateProgress()
+{
+ if( m_totalFiles > 0 ) {
+ unsigned int p = 100*m_filesHandled/m_totalFiles;
+ if( p > m_lastProgress ) {
+ m_lastProgress = p;
+ m_progressWidget->setProgress( p );
+ }
+ }
+ else {
+ // make sure the progress bar shows something
+ m_progressWidget->setProgress( m_filesHandled );
+ }
+}
+
+#include "k3bdataurladdingdialog.moc"
diff --git a/src/projects/k3bdataurladdingdialog.h b/src/projects/k3bdataurladdingdialog.h
new file mode 100644
index 0000000..cb7c0ac
--- /dev/null
+++ b/src/projects/k3bdataurladdingdialog.h
@@ -0,0 +1,110 @@
+/*
+ *
+ * $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_DATA_URL_ADDING_DIALOG_H_
+#define _K3B_DATA_URL_ADDING_DIALOG_H_
+
+#include <kdialogbase.h>
+#include <kurl.h>
+#include <qstringlist.h>
+#include <qpair.h>
+#include <qdir.h>
+
+class KProgress;
+class QLabel;
+class K3bDataItem;
+class K3bDirItem;
+class K3bEncodingConverter;
+class K3bDirSizeJob;
+class K3bDataDoc;
+
+
+class K3bDataUrlAddingDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ ~K3bDataUrlAddingDialog();
+
+ /**
+ * \return \see QDialog::exec()
+ */
+ static int addUrls( const KURL::List& urls, K3bDirItem* dir = 0,
+ QWidget* parent = 0 );
+
+ static int moveItems( const QValueList<K3bDataItem*>& items, K3bDirItem* dir,
+ QWidget* parent = 0 );
+
+ static int copyItems( const QValueList<K3bDataItem*>& items, K3bDirItem* dir,
+ QWidget* parent = 0 );
+
+ static int copyMoveItems( const QValueList<K3bDataItem*>& items, K3bDirItem* dir,
+ QWidget* parent, bool copy );
+
+ private slots:
+ void slotAddUrls();
+ void slotCopyMoveItems();
+ void slotCancel();
+ void slotDirSizeDone( bool );
+ void updateProgress();
+
+ private:
+ K3bDataUrlAddingDialog( K3bDataDoc* doc, QWidget* parent = 0, const char* name = 0 );
+
+ bool getNewName( const QString& oldName, K3bDirItem* dir, QString& newName );
+
+ bool addHiddenFiles();
+ bool addSystemFiles();
+
+ QString resultMessage() const;
+
+ KProgress* m_progressWidget;
+ QLabel* m_infoLabel;
+ QLabel* m_counterLabel;
+ K3bEncodingConverter* m_encodingConverter;
+
+ KURL::List m_urls;
+ QValueList< QPair<KURL, K3bDirItem*> > m_urlQueue;
+
+ QValueList< QPair<K3bDataItem*, K3bDirItem*> > m_items;
+
+ QValueList<KURL> m_dirSizeQueue;
+
+ bool m_bExistingItemsReplaceAll;
+ bool m_bExistingItemsIgnoreAll;
+ bool m_bFolderLinksFollowAll;
+ bool m_bFolderLinksAddAll;
+ int m_iAddHiddenFiles;
+ int m_iAddSystemFiles;
+
+ QStringList m_unreadableFiles;
+ QStringList m_notFoundFiles;
+ QStringList m_nonLocalFiles;
+ QStringList m_tooBigFiles;
+ QStringList m_mkisofsLimitationRenamedFiles;
+ QStringList m_invalidFilenameEncodingFiles;
+
+ bool m_bCanceled;
+
+ bool m_copyItems;
+
+ KIO::filesize_t m_totalFiles;
+ KIO::filesize_t m_filesHandled;
+ K3bDirSizeJob* m_dirSizeJob;
+
+ unsigned int m_lastProgress;
+};
+
+#endif
diff --git a/src/projects/k3bdataview.cpp b/src/projects/k3bdataview.cpp
new file mode 100644
index 0000000..9539b5c
--- /dev/null
+++ b/src/projects/k3bdataview.cpp
@@ -0,0 +1,196 @@
+/*
+ *
+ * $Id: k3bdataview.cpp 731898 2007-11-02 08:22:18Z 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 "k3bdataview.h"
+#include "k3bdatadoc.h"
+#include "k3bdataburndialog.h"
+#include "k3bbootimageview.h"
+#include "k3bdatadirtreeview.h"
+#include "k3bdatafileview.h"
+#include "k3bdataurladdingdialog.h"
+#include "k3bdatasessionimportdialog.h"
+#include "k3bdiritem.h"
+#include <k3bdevice.h>
+#include <k3bdeviceselectiondialog.h>
+#include <k3bfillstatusdisplay.h>
+#include <k3bcore.h>
+#include <k3bprojectplugin.h>
+#include <k3btoolbox.h>
+#include <k3bvalidators.h>
+
+#include <klocale.h>
+#include <kurl.h>
+#include <kapplication.h>
+#include <kpopupmenu.h>
+#include <kaction.h>
+#include <kmessagebox.h>
+#include <kio/global.h>
+#include <kio/job.h>
+#include <kdialogbase.h>
+
+#include <qpixmap.h>
+#include <qsplitter.h>
+#include <qlayout.h>
+#include <qdragobject.h>
+#include <qheader.h>
+#include <qptrlist.h>
+#include <qlineedit.h>
+
+#include <assert.h>
+#include <kdebug.h>
+
+
+K3bDataView::K3bDataView(K3bDataDoc* doc, QWidget *parent, const char *name )
+ : K3bView(doc, parent,name)
+{
+ m_doc = doc;
+
+ // --- setup GUI ---------------------------------------------------
+ QSplitter* mainSplitter = new QSplitter( this );
+ m_dataDirTree = new K3bDataDirTreeView( this, doc, mainSplitter );
+ m_dataFileView = new K3bDataFileView( this, m_dataDirTree, doc, mainSplitter );
+ m_dataDirTree->setFileView( m_dataFileView );
+ setMainWidget( mainSplitter );
+
+
+ connect( m_dataFileView, SIGNAL(dirSelected(K3bDirItem*)),
+ m_dataDirTree, SLOT(setCurrentDir(K3bDirItem*)) );
+ connect( m_doc, SIGNAL(changed()), this, SLOT(slotDocChanged()) );
+
+ m_dataDirTree->checkForNewItems();
+ m_dataFileView->checkForNewItems();
+
+
+ // the data actions
+ KAction* actionImportSession = new KAction(i18n("&Import Session..."), "gear", 0, this, SLOT(importSession()),
+ actionCollection(), "project_data_import_session" );
+ KAction* actionClearSession = new KAction(i18n("&Clear Imported Session"), "gear", 0, this,
+ SLOT(clearImportedSession()), actionCollection(),
+ "project_data_clear_imported_session" );
+ KAction* actionEditBootImages = new KAction(i18n("&Edit Boot Images..."), "cdtrack", 0, this,
+ SLOT(editBootImages()), actionCollection(),
+ "project_data_edit_boot_images" );
+
+ actionImportSession->setToolTip( i18n("Import a previously burned session into the current project") );
+ actionClearSession->setToolTip( i18n("Remove the imported items from a previous session") );
+ actionEditBootImages->setToolTip( i18n("Modify the bootable settings of the current project") );
+
+ toolBox()->addButton( actionImportSession );
+ toolBox()->addButton( actionClearSession );
+ toolBox()->addButton( actionEditBootImages );
+ toolBox()->addSeparator();
+ toolBox()->addButton( m_dataFileView->actionCollection()->action("parent_dir") );
+ toolBox()->addSeparator();
+
+ addPluginButtons( K3bProjectPlugin::DATA_CD );
+
+ toolBox()->addStretch();
+
+ m_volumeIDEdit = new QLineEdit( doc->isoOptions().volumeID(), toolBox() );
+ m_volumeIDEdit->setValidator( new K3bLatin1Validator( m_volumeIDEdit ) );
+ toolBox()->addLabel( i18n("Volume Name:") );
+ toolBox()->addSpacing();
+ toolBox()->addWidget( m_volumeIDEdit );
+ connect( m_volumeIDEdit, SIGNAL(textChanged(const QString&)),
+ m_doc,
+ SLOT(setVolumeID(const QString&)) );
+
+ // this is just for testing (or not?)
+ // most likely every project type will have it's rc file in the future
+ // we only add the additional actions since K3bView already added the default actions
+ setXML( "<!DOCTYPE kpartgui SYSTEM \"kpartgui.dtd\">"
+ "<kpartgui name=\"k3bproject\" version=\"1\">"
+ "<MenuBar>"
+ " <Menu name=\"project\"><text>&amp;Project</text>"
+ " <Action name=\"project_data_import_session\"/>"
+ " <Action name=\"project_data_clear_imported_session\"/>"
+ " <Action name=\"project_data_edit_boot_images\"/>"
+ " </Menu>"
+ "</MenuBar>"
+ "</kpartgui>", true );
+}
+
+
+K3bDataView::~K3bDataView(){
+}
+
+
+K3bDirItem* K3bDataView::currentDir() const
+{
+ return m_dataFileView->currentDir();
+}
+
+
+void K3bDataView::importSession()
+{
+ K3bDataSessionImportDialog::importSession( m_doc, this );
+}
+
+
+void K3bDataView::clearImportedSession()
+{
+ m_doc->clearImportedSession();
+}
+
+
+void K3bDataView::editBootImages()
+{
+ KDialogBase* d = new KDialogBase( this, "", true, i18n("Edit Boot Images"),
+ KDialogBase::Ok, KDialogBase::Ok, true );
+ d->setMainWidget( new K3bBootImageView( m_doc, d ) );
+ d->exec();
+ delete d;
+}
+
+
+K3bProjectBurnDialog* K3bDataView::newBurnDialog( QWidget* parent, const char* name )
+{
+ return new K3bDataBurnDialog( m_doc, parent, name, true );
+}
+
+
+void K3bDataView::slotBurn()
+{
+ // Little hack which at least handles most situations (better in 1.1):
+ // If a session has been importet we cannot use the file count since that
+ // includes imported items
+ if( m_doc->sessionImported() && m_doc->burningSize() == 0 ||
+ m_doc->root()->numFiles() == 0 ) {
+ KMessageBox::information( this, i18n("Please add files to your project first."),
+ i18n("No Data to Burn"), QString::null, false );
+ }
+ else {
+ K3bProjectBurnDialog* dlg = newBurnDialog( this );
+ dlg->execBurnDialog(true);
+ delete dlg;
+ }
+}
+
+
+void K3bDataView::slotDocChanged()
+{
+ // do not update the editor in case it changed the volume id itself
+ if( m_doc->isoOptions().volumeID() != m_volumeIDEdit->text() )
+ m_volumeIDEdit->setText( m_doc->isoOptions().volumeID() );
+}
+
+
+void K3bDataView::addUrls( const KURL::List& urls )
+{
+ K3bDataUrlAddingDialog::addUrls( urls, m_dataFileView->currentDir() );
+}
+
+#include "k3bdataview.moc"
diff --git a/src/projects/k3bdataview.h b/src/projects/k3bdataview.h
new file mode 100644
index 0000000..bb9154e
--- /dev/null
+++ b/src/projects/k3bdataview.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * $Id: k3bdataview.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 K3BDATAVIEW_H
+#define K3BDATAVIEW_H
+
+#include <k3bview.h>
+
+class K3bDataDoc;
+class K3bDataItem;
+class K3bFileItem;
+class K3bDirItem;
+class K3bDataDirTreeView;
+class K3bDataFileView;
+class QLineEdit;
+
+
+namespace KIO {
+ class Job;
+}
+namespace K3bDevice {
+ class Device;
+}
+
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bDataView : public K3bView
+{
+ Q_OBJECT
+
+ public:
+ K3bDataView(K3bDataDoc* doc, QWidget *parent=0, const char *name=0);
+ virtual ~K3bDataView();
+
+ K3bDirItem* currentDir() const;
+
+ public slots:
+ void slotBurn();
+ void importSession();
+ void clearImportedSession();
+ void editBootImages();
+
+ void slotDocChanged();
+
+ void addUrls( const KURL::List& );
+
+ protected:
+ K3bDataDirTreeView* m_dataDirTree;
+ K3bDataFileView* m_dataFileView;
+ QLineEdit* m_volumeIDEdit;
+
+ virtual K3bProjectBurnDialog* newBurnDialog( QWidget* parent = 0, const char* name = 0 );
+
+ private:
+ K3bDataDoc* m_doc;
+
+ // used for mounting when importing old session
+ K3bDevice::Device* m_device;
+};
+
+
+#endif
diff --git a/src/projects/k3bdataviewitem.cpp b/src/projects/k3bdataviewitem.cpp
new file mode 100644
index 0000000..78c044d
--- /dev/null
+++ b/src/projects/k3bdataviewitem.cpp
@@ -0,0 +1,340 @@
+/*
+ *
+ * $Id: k3bdataviewitem.cpp 689533 2007-07-18 14:19:39Z 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 "k3bdataviewitem.h"
+
+#include "k3bfileitem.h"
+#include "k3bdiritem.h"
+#include "k3bspecialdataitem.h"
+#include "k3bsessionimportitem.h"
+#include "k3bdatadoc.h"
+#include <k3bvalidators.h>
+
+#include <kio/global.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmimetype.h>
+#include <kurl.h>
+#include <kpixmapeffect.h>
+#include <kpixmap.h>
+
+#include <qpainter.h>
+#include <qpalette.h>
+#include <qfileinfo.h>
+
+
+K3bDataViewItem::K3bDataViewItem( K3bDataItem* item, QListView* parent )
+ : K3bListViewItem( parent ),
+ m_dataItem(item)
+{
+ init();
+}
+
+K3bDataViewItem::K3bDataViewItem( K3bDataItem* item, QListViewItem* parent )
+ : K3bListViewItem( parent ),
+ m_dataItem(item)
+{
+ init();
+}
+
+K3bDataViewItem::~K3bDataViewItem()
+{}
+
+
+void K3bDataViewItem::init()
+{
+ setEditor( 0, LINE );
+ static QValidator* s_validator = K3bValidators::iso9660Validator();
+ setValidator( 0, s_validator );
+}
+
+void K3bDataViewItem::paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align )
+{
+ QColorGroup _cg = cg;
+
+ if( !dataItem()->isRemoveable() && dataItem()->doc()->root() != dataItem() ) {
+ _cg.setColor( QColorGroup::Text, listView()->palette().disabled().foreground() );
+ }
+
+ if( column == 0 ) {
+ QFontMetrics fm = p->fontMetrics();
+
+ if( dataItem()->hideOnRockRidge() ) {
+ int tw = QMAX( fm.width( "rr" ) + 2*listView()->itemMargin(), height() );
+ p->fillRect( width-tw, 0, tw, height(), isSelected() ? _cg.highlight() : _cg.brush(QColorGroup::Base) );
+ p->setPen( isSelected() ? _cg.highlightedText() : red );
+ p->drawEllipse( width-tw, 0, tw, height() );
+ p->drawText( width-tw, 0, tw, height(), Qt::AlignCenter, "rr" );
+ width -= tw;
+ }
+
+ if( dataItem()->hideOnJoliet() ) {
+ int tw = QMAX( fm.width( "j" ) + 2*listView()->itemMargin(), height() );
+ p->fillRect( width-tw, 0, tw, height(), isSelected() ? _cg.highlight() : _cg.brush(QColorGroup::Base) );
+ p->setPen( isSelected() ? _cg.highlightedText() : blue );
+ p->drawEllipse( width-tw, 0, tw, height() );
+ p->drawText( width-tw, 0, tw, height(), Qt::AlignCenter, "j" );
+ width -= tw;
+ }
+ }
+ else if( column == 4 ) {
+ if( dataItem()->isSymLink() ) {
+ if( !dataItem()->doc()->isoOptions().followSymbolicLinks() &&
+ dataItem()->doc()->isoOptions().createRockRidge() &&
+ !dataItem()->isValid() ) {
+ // paint the link in red
+ _cg.setColor( QColorGroup::Text, Qt::red );
+ }
+ }
+ }
+
+ K3bListViewItem::paintCell( p, _cg, column, width, align );
+}
+
+
+void K3bDataViewItem::setText( int col, const QString& text )
+{
+ if( col == 0 && dataItem()->isRenameable() ) {
+ dataItem()->setK3bName( text );
+ }
+ K3bListViewItem::setText( col, text );
+}
+
+
+QString K3bDataViewItem::key( int col, bool a ) const
+{
+ if( col == 2 ) {
+ // to have correct sorting we need to justify the size in bytes
+ // 100 TB should be enough for the next year... ;-)
+
+ if( a )
+ return ( dataItem()->isDir() ? QString("0") : QString("1") )
+ + QString::number( dataItem()->size() ).rightJustify( 16, '0' );
+ else
+ return ( dataItem()->isDir() ? QString("1") : QString("0") )
+ + QString::number( dataItem()->size() ).rightJustify( 16, '0' );
+ }
+
+ if( a )
+ return ( dataItem()->isDir() ? QString("0") : QString("1") ) + text(col);
+ else
+ return ( dataItem()->isDir() ? QString("1") : QString("0") ) + text(col);
+}
+
+
+K3bDataDirViewItem::K3bDataDirViewItem( K3bDirItem* dir, QListView* parent )
+ : K3bDataViewItem( dir, parent )
+{
+ m_dirItem = dir;
+ setPixmap( 0, dir->depth() > 7 ? SmallIcon( "folder_red" ) : SmallIcon( "folder" ) );
+}
+
+
+K3bDataDirViewItem::K3bDataDirViewItem( K3bDirItem* dir, QListViewItem* parent )
+ : K3bDataViewItem( dir, parent )
+{
+ m_dirItem = dir;
+ setPixmap( 0, dir->depth() > 7 ? SmallIcon( "folder_red" ) : SmallIcon( "folder" ) );
+}
+
+
+K3bDataDirViewItem::~K3bDataDirViewItem()
+{
+}
+
+
+void K3bDataDirViewItem::dragEntered()
+{
+ setOpen( true );
+}
+
+
+QString K3bDataDirViewItem::text( int index ) const
+{
+ switch( index ) {
+ case 0:
+ return m_dirItem->k3bName();
+ case 1:
+ return i18n("Directory");
+ case 2:
+ return KIO::convertSize( m_dirItem->size() );
+ default:
+ return "";
+ }
+}
+
+
+void K3bDataDirViewItem::highlightIcon( bool b )
+{
+ if( m_pixmap.isNull() )
+ m_pixmap = *pixmap(0);
+
+ if( b )
+ setPixmap( 0, KPixmapEffect::selectedPixmap( m_pixmap, listView()->colorGroup().highlight() ) );
+ else
+ setPixmap( 0, m_pixmap );
+}
+
+
+
+K3bDataFileViewItem::K3bDataFileViewItem( K3bFileItem* file, QListView* parent )
+ : K3bDataViewItem( file, parent )
+{
+ init( file );
+}
+
+
+K3bDataFileViewItem::K3bDataFileViewItem( K3bFileItem* file, QListViewItem* parent )
+ : K3bDataViewItem( file, parent )
+{
+ init( file );
+}
+
+
+void K3bDataFileViewItem::init( K3bFileItem* file )
+{
+ m_fileItem = file;
+
+ // determine the mimetype
+ m_pMimeType = KMimeType::findByURL( KURL::fromPathOrURL(file->localPath()) );
+ if( !m_pMimeType )
+ setPixmap( 0, DesktopIcon( "unknown", 16, KIcon::DefaultState ) );
+ else
+ setPixmap( 0, m_pMimeType->pixmap( KURL::fromPathOrURL(file->localPath()), KIcon::Desktop, 16, KIcon::DefaultState ) );
+}
+
+
+QString K3bDataFileViewItem::text( int index ) const
+{
+ switch( index ) {
+ case 0:
+ return m_fileItem->k3bName();
+ case 1:
+ {
+ QString comment = m_pMimeType->comment( KURL::fromPathOrURL(m_fileItem->localPath()), true );
+ if( comment.isEmpty() )
+ comment = m_pMimeType->name();
+
+ if( m_fileItem->isSymLink() )
+ return i18n("Link to %1").arg(comment);
+ else
+ return comment;
+ }
+ case 2:
+ return KIO::convertSize( m_fileItem->size() );
+ case 3:
+ return m_fileItem->localPath();
+ case 4: {
+ if( !m_fileItem->isSymLink() ) {
+ return QString::null;
+ }
+
+ QString s;
+ if ( m_fileItem->doc()->isoOptions().followSymbolicLinks() ) {
+ s = K3b::resolveLink( m_fileItem->localPath() );
+ }
+ else {
+ s = QFileInfo( m_fileItem->localPath() ).readLink();
+ }
+
+ if( !m_fileItem->isValid() ) {
+ s += " (" + i18n("outside of project") + ")";
+ }
+
+ return s;
+ }
+ default:
+ return "";
+ }
+}
+
+
+
+K3bDataRootViewItem::K3bDataRootViewItem( K3bDataDoc* doc, QListView* parent )
+ : K3bDataDirViewItem( doc->root(), parent )
+{
+ m_doc = doc;
+ setPixmap( 0, SmallIcon( "cdrom_unmount" ) );
+ setValidator( 0, new K3bLatin1Validator() );
+}
+
+
+K3bDataRootViewItem::~K3bDataRootViewItem()
+{
+ delete validator(0);
+}
+
+
+QString K3bDataRootViewItem::text( int index ) const
+{
+ switch( index ) {
+ case 0:
+ return ( m_doc->isoOptions().volumeID().isEmpty() ? i18n("root") : m_doc->isoOptions().volumeID() );
+ default:
+ return "";
+ }
+}
+
+
+void K3bDataRootViewItem::setText( int col, const QString& text )
+{
+ if( col == 0 )
+ m_doc->setVolumeID( text );
+
+ K3bDataViewItem::setText( col, text );
+}
+
+
+K3bSpecialDataViewItem::K3bSpecialDataViewItem( K3bSpecialDataItem* item, QListView* parent )
+ : K3bDataViewItem( item, parent )
+{
+ setPixmap( 0, SmallIcon("unknown") );
+}
+
+QString K3bSpecialDataViewItem::text( int col ) const
+{
+ switch( col ) {
+ case 0:
+ return dataItem()->k3bName();
+ case 1:
+ return ((K3bSpecialDataItem*)dataItem())->mimeType();
+ case 2:
+ return KIO::convertSize( dataItem()->size() );
+ default:
+ return "";
+ }
+}
+
+
+
+K3bSessionImportViewItem::K3bSessionImportViewItem( K3bSessionImportItem* item, QListView* parent )
+ : K3bDataViewItem( item, parent )
+{
+ setPixmap( 0, SmallIcon("unknown") );
+}
+
+QString K3bSessionImportViewItem::text( int col ) const
+{
+ switch( col ) {
+ case 0:
+ return dataItem()->k3bName();
+ case 1:
+ return i18n("From previous session");
+ case 2:
+ return KIO::convertSize( dataItem()->size() );
+ default:
+ return "";
+ }
+}
diff --git a/src/projects/k3bdataviewitem.h b/src/projects/k3bdataviewitem.h
new file mode 100644
index 0000000..60d68d2
--- /dev/null
+++ b/src/projects/k3bdataviewitem.h
@@ -0,0 +1,135 @@
+/*
+ *
+ * $Id: k3bdataviewitem.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 K3BDATAVIEWITEM_H
+#define K3BDATAVIEWITEM_H
+
+#include <k3blistview.h>
+#include <kmimetype.h>
+
+class K3bDataItem;
+class K3bFileItem;
+class K3bDirItem;
+class K3bDataDoc;
+class K3bSpecialDataItem;
+class K3bSessionImportItem;
+
+class QPainter;
+class QColorGroup;
+
+
+
+class K3bDataViewItem : public K3bListViewItem
+{
+ public:
+ K3bDataViewItem( K3bDataItem*, QListView* parent );
+ K3bDataViewItem( K3bDataItem*, QListViewItem* parent );
+ virtual ~K3bDataViewItem();
+
+ virtual K3bDataItem* dataItem() const { return m_dataItem; }
+
+ void setText( int col, const QString& text );
+
+ /**
+ * reimplemented to have directories always sorted before files
+ */
+ QString key( int, bool ) const;
+
+ virtual void paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align );
+
+ private:
+ void init();
+
+ K3bDataItem* m_dataItem;
+};
+
+
+class K3bDataDirViewItem : public K3bDataViewItem
+{
+ public:
+ K3bDataDirViewItem( K3bDirItem* dir, QListView* parent );
+ K3bDataDirViewItem( K3bDirItem* dir, QListViewItem* parent );
+ ~K3bDataDirViewItem();
+
+ virtual QString text( int ) const;
+
+ K3bDirItem* dirItem() const { return m_dirItem; }
+
+ void highlightIcon( bool );
+
+ protected:
+ virtual void dragEntered();
+
+ private:
+ K3bDirItem* m_dirItem;
+ QPixmap m_pixmap;
+};
+
+
+class K3bDataFileViewItem : public K3bDataViewItem
+{
+ public:
+ K3bDataFileViewItem( K3bFileItem*, QListView* parent );
+ K3bDataFileViewItem( K3bFileItem*, QListViewItem* parent );
+ ~K3bDataFileViewItem() {}
+
+ QString text( int ) const;
+
+ K3bFileItem* fileItem() const { return m_fileItem; }
+
+ const KMimeType::Ptr mimeType() const { return m_pMimeType; }
+
+ private:
+ void init( K3bFileItem* );
+
+ K3bFileItem* m_fileItem;
+ KMimeType::Ptr m_pMimeType;
+};
+
+
+class K3bDataRootViewItem : public K3bDataDirViewItem
+{
+ public:
+ K3bDataRootViewItem( K3bDataDoc*, QListView* parent );
+ ~K3bDataRootViewItem();
+
+ QString text( int ) const;
+
+ /** reimplemented from QListViewItem */
+ void setText(int col, const QString& text );
+
+ private:
+ K3bDataDoc* m_doc;
+};
+
+
+class K3bSpecialDataViewItem : public K3bDataViewItem
+{
+ public:
+ K3bSpecialDataViewItem( K3bSpecialDataItem*, QListView* );
+
+ QString text( int ) const;
+};
+
+
+class K3bSessionImportViewItem : public K3bDataViewItem
+{
+ public:
+ K3bSessionImportViewItem( K3bSessionImportItem*, QListView* );
+
+ QString text( int ) const;
+};
+
+#endif
diff --git a/src/projects/k3bdatavolumedescwidget.cpp b/src/projects/k3bdatavolumedescwidget.cpp
new file mode 100644
index 0000000..1edbc7b
--- /dev/null
+++ b/src/projects/k3bdatavolumedescwidget.cpp
@@ -0,0 +1,93 @@
+/*
+ *
+ * $Id: k3bdatavolumedescwidget.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 "k3bdatavolumedescwidget.h"
+
+#include "k3bisooptions.h"
+#include <k3bvalidators.h>
+
+#include <qlineedit.h>
+#include <qspinbox.h>
+#include <qlabel.h>
+#include <qtoolbutton.h>
+
+
+K3bDataVolumeDescWidget::K3bDataVolumeDescWidget( QWidget* parent, const char* name )
+ : base_K3bDataVolumeDescWidget( parent, name )
+{
+ // the maximal number of characters that can be inserted are set in the ui file!
+
+ QValidator* isoValidator = new K3bLatin1Validator( this );
+
+ m_editVolumeName->setValidator( isoValidator );
+ m_editVolumeSetName->setValidator( isoValidator );
+ m_editPublisher->setValidator( isoValidator );
+ m_editPreparer->setValidator( isoValidator );
+ m_editSystem->setValidator( isoValidator );
+ m_editApplication->setValidator( isoValidator );
+
+ connect( m_spinVolumeSetSize, SIGNAL(valueChanged(int)),
+ this, SLOT(slotVolumeSetSizeChanged(int)) );
+
+ // for now we hide the volume set size stuff since it's not working anymore in mkisofs 2.01a34
+ textLabel1->hide();
+ textLabel2->hide();
+ m_spinVolumeSetSize->hide();
+ m_spinVolumeSetNumber->hide();
+
+ // FIXME: show the buttons and allow the selection of a file from the project
+ m_buttonFindAbstract->hide();
+ m_buttonFindCopyright->hide();
+ m_buttonFindBiblio->hide();
+}
+
+
+K3bDataVolumeDescWidget::~K3bDataVolumeDescWidget()
+{
+}
+
+
+void K3bDataVolumeDescWidget::load( const K3bIsoOptions& o )
+{
+ m_editVolumeName->setText( o.volumeID() );
+ m_editVolumeSetName->setText( o.volumeSetId() );
+ m_spinVolumeSetSize->setValue( o.volumeSetSize() );
+ m_spinVolumeSetNumber->setValue( o.volumeSetNumber() );
+ m_editPublisher->setText( o.publisher() );
+ m_editPreparer->setText( o.preparer() );
+ m_editSystem->setText( o.systemId() );
+ m_editApplication->setText( o.applicationID() );
+}
+
+
+void K3bDataVolumeDescWidget::save( K3bIsoOptions& o )
+{
+ o.setVolumeID( m_editVolumeName->text() );
+ o.setVolumeSetId( m_editVolumeSetName->text() );
+ o.setVolumeSetSize( 1/*m_spinVolumeSetSize->value() */);
+ o.setVolumeSetNumber( 1/*m_spinVolumeSetNumber->value() */);
+ o.setPublisher( m_editPublisher->text() );
+ o.setPreparer( m_editPreparer->text() );
+ o.setSystemId( m_editSystem->text() );
+ o.setApplicationID( m_editApplication->text() );
+}
+
+
+void K3bDataVolumeDescWidget::slotVolumeSetSizeChanged( int i )
+{
+ m_spinVolumeSetNumber->setMaxValue( i );
+}
+
+#include "k3bdatavolumedescwidget.moc"
diff --git a/src/projects/k3bdatavolumedescwidget.h b/src/projects/k3bdatavolumedescwidget.h
new file mode 100644
index 0000000..8b4a388
--- /dev/null
+++ b/src/projects/k3bdatavolumedescwidget.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * $Id: k3bdatavolumedescwidget.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_VOLUMEDESC_WIDGET_H
+#define K3B_DATA_VOLUMEDESC_WIDGET_H
+
+
+#include "base_k3bdatavolumedescwidget.h"
+
+class K3bIsoOptions;
+
+
+class K3bDataVolumeDescWidget : public base_K3bDataVolumeDescWidget
+{
+ Q_OBJECT
+
+ public:
+ K3bDataVolumeDescWidget( QWidget* parent = 0, const char* name = 0 );
+ ~K3bDataVolumeDescWidget();
+
+ void load( const K3bIsoOptions& );
+ void save( K3bIsoOptions& );
+
+ private slots:
+ void slotVolumeSetSizeChanged( int );
+};
+
+#endif
diff --git a/src/projects/k3bdvdburndialog.cpp b/src/projects/k3bdvdburndialog.cpp
new file mode 100644
index 0000000..873afbf
--- /dev/null
+++ b/src/projects/k3bdvdburndialog.cpp
@@ -0,0 +1,300 @@
+/*
+ *
+ * $Id: k3bdvdburndialog.cpp 690207 2007-07-20 10:40:19Z 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 "k3bdvdburndialog.h"
+#include "k3bdvddoc.h"
+#include "k3bdatamultisessioncombobox.h"
+
+#include <k3bdevice.h>
+#include <k3bwriterselectionwidget.h>
+#include <k3btempdirselectionwidget.h>
+#include <k3bcore.h>
+#include <k3bwritingmodewidget.h>
+#include <k3bglobals.h>
+#include <k3bdataimagesettingswidget.h>
+#include <k3bisooptions.h>
+#include <k3bstdguiitems.h>
+#include <k3bglobalsettings.h>
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kio/global.h>
+#include <kmessagebox.h>
+
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qspinbox.h>
+
+
+K3bDvdBurnDialog::K3bDvdBurnDialog( K3bDvdDoc* doc, QWidget *parent, const char *name, bool modal )
+ : K3bProjectBurnDialog( doc, parent, name, modal, true ),
+ m_doc( doc )
+{
+ prepareGui();
+
+ setTitle( i18n("DVD Project"), i18n("Size: %1").arg( KIO::convertSize(doc->size()) ) );
+
+ // for now we just put the verify checkbox on the main page...
+ m_checkVerify = K3bStdGuiItems::verifyCheckBox( m_optionGroup );
+ m_optionGroupLayout->addWidget( m_checkVerify );
+
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ m_optionGroupLayout->addItem( spacer );
+
+ // create image settings tab
+ m_imageSettingsWidget = new K3bDataImageSettingsWidget( this );
+ addPage( m_imageSettingsWidget, i18n("Filesystem") );
+
+ setupSettingsTab();
+
+ m_tempDirSelectionWidget->setSelectionMode( K3bTempDirSelectionWidget::FILE );
+
+ m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY|K3bDevice::STATE_INCOMPLETE );
+
+ QString path = doc->tempDir();
+ if( !path.isEmpty() ) {
+ m_tempDirSelectionWidget->setTempPath( path );
+ }
+ if( !doc->isoOptions().volumeID().isEmpty() ) {
+ m_tempDirSelectionWidget->setDefaultImageFileName( doc->isoOptions().volumeID() + ".iso" );
+ }
+
+ connect( m_imageSettingsWidget->m_editVolumeName, SIGNAL(textChanged(const QString&)),
+ m_tempDirSelectionWidget, SLOT(setDefaultImageFileName(const QString&)) );
+}
+
+
+K3bDvdBurnDialog::~K3bDvdBurnDialog()
+{
+}
+
+
+void K3bDvdBurnDialog::setupSettingsTab()
+{
+ QWidget* frame = new QWidget( this );
+ QGridLayout* frameLayout = new QGridLayout( frame );
+ frameLayout->setSpacing( spacingHint() );
+ frameLayout->setMargin( marginHint() );
+
+ // Multisession
+ // ////////////////////////////////////////////////////////////////////////
+ QGroupBox* groupMultiSession = new QGroupBox( 1, Qt::Vertical, i18n("Multisession Mode"), frame );
+ m_comboMultisession = new K3bDataMultiSessionCombobox( groupMultiSession );
+
+ frameLayout->addWidget( groupMultiSession, 0, 0 );
+ frameLayout->setRowStretch( 1, 1 );
+
+ addPage( frame, i18n("Misc") );
+
+ connect( m_comboMultisession, SIGNAL(activated(int)),
+ this, SLOT(slotMultiSessionModeChanged()) );
+}
+
+
+void K3bDvdBurnDialog::saveSettings()
+{
+ K3bProjectBurnDialog::saveSettings();
+
+ // save iso image settings
+ K3bIsoOptions o = m_doc->isoOptions();
+ m_imageSettingsWidget->save( o );
+ m_doc->setIsoOptions( o );
+
+ // save image file path
+ m_doc->setTempDir( m_tempDirSelectionWidget->tempPath() );
+
+ // save multisession settings
+ m_doc->setMultiSessionMode( m_comboMultisession->multiSessionMode() );
+
+ m_doc->setVerifyData( m_checkVerify->isChecked() );
+}
+
+
+void K3bDvdBurnDialog::readSettings()
+{
+ K3bProjectBurnDialog::readSettings();
+
+ // read multisession
+ m_comboMultisession->setMultiSessionMode( m_doc->multiSessionMode() );
+
+ if( !doc()->tempDir().isEmpty() )
+ m_tempDirSelectionWidget->setTempPath( doc()->tempDir() );
+ else
+ m_tempDirSelectionWidget->setTempPath( K3b::defaultTempPath() + doc()->name() + ".iso" );
+
+ m_checkVerify->setChecked( m_doc->verifyData() );
+
+ m_imageSettingsWidget->load( m_doc->isoOptions() );
+
+ // for now we do not support dual layer multisession (growisofs does not handle layer jump yet)
+ // in case overburn is enabled we allow some made up max size
+ // before we force a DL medium
+ if( doc()->size() > 4700372992LL &&
+ ( !k3bcore->globalSettings()->overburn() ||
+ doc()->size() > 4900000000LL ) )
+ m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_DVD_DL );
+ else
+ m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_DVD );
+
+ toggleAll();
+}
+
+
+void K3bDvdBurnDialog::toggleAll()
+{
+ K3bProjectBurnDialog::toggleAll();
+
+ // Multisession in DAO is not possible
+ if( m_writingModeWidget->writingMode() == K3b::DAO ) {
+ if( m_comboMultisession->multiSessionMode() == K3bDataDoc::START ||
+ m_comboMultisession->multiSessionMode() == K3bDataDoc::CONTINUE ||
+ m_comboMultisession->multiSessionMode() == K3bDataDoc::FINISH )
+ KMessageBox::information( this, i18n("It is not possible to write multisession DVDs in DAO mode."
+ "Multisession has been disabled."),
+ i18n("DVD multisession"),
+ "dvd_multisession_no_dao" );
+
+ m_comboMultisession->setEnabled(false);
+ }
+ else {
+// // for some reason I don't know yet when writing multisession volume set size needs to be 1
+// if( m_comboMultisession->multiSessionMode() != K3bDataDoc::NONE ) {
+// m_volumeDescWidget->m_spinVolumeSetSize->setValue( 1 );
+// m_volumeDescWidget->m_spinVolumeSetSize->setEnabled( false );
+// }
+// else {
+// m_volumeDescWidget->m_spinVolumeSetSize->setEnabled( true );
+// }
+
+ m_comboMultisession->setEnabled(true);
+
+// if( !m_checkOnTheFly->isChecked() ) {
+// // no continue and finish multisession in non-the-fly mode since
+// // we can only continue ms with growisofsimager
+// if( m_comboMultisession->multiSessionMode() == K3bDataDoc::START ||
+// m_comboMultisession->multiSessionMode() == K3bDataDoc::FINISH ||
+// m_comboMultisession->multiSessionMode() == K3bDataDoc::CONTINUE ) {
+// KMessageBox::information( this, i18n("K3b does only support writing multisession DVDs on-the-fly. "
+// "Multisession has been disabled."),
+// i18n("DVD Multisession"),
+// "dvd_multisession_only_on_the_fly" );
+// }
+// m_comboMultisession->setForceNoMultisession( true );
+// }
+// else {
+// m_comboMultisession->setForceNoMultisession( false );
+// }
+ }
+
+ if( m_checkSimulate->isChecked() || m_checkOnlyCreateImage->isChecked() ) {
+ m_checkVerify->setChecked(false);
+ m_checkVerify->setEnabled(false);
+ }
+ else
+ m_checkVerify->setEnabled(true);
+}
+
+
+void K3bDvdBurnDialog::slotMultiSessionModeChanged()
+{
+ if( m_comboMultisession->multiSessionMode() == K3bDataDoc::CONTINUE ||
+ m_comboMultisession->multiSessionMode() == K3bDataDoc::FINISH )
+ m_spinCopies->setEnabled(false);
+
+ // wait for the proper medium
+ // we have to do this in another slot than toggleAllOptions to avoid an endless loop
+ if( m_comboMultisession->multiSessionMode() == K3bDataDoc::NONE )
+ m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY );
+ else if( m_comboMultisession->multiSessionMode() == K3bDataDoc::CONTINUE ||
+ m_comboMultisession->multiSessionMode() == K3bDataDoc::FINISH )
+ m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_INCOMPLETE );
+ else
+ m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY|K3bDevice::STATE_INCOMPLETE );
+}
+
+
+void K3bDvdBurnDialog::loadK3bDefaults()
+{
+ K3bProjectBurnDialog::loadK3bDefaults();
+
+ m_imageSettingsWidget->load( K3bIsoOptions::defaults() );
+ m_checkVerify->setChecked( false );
+
+ m_comboMultisession->setMultiSessionMode( K3bDataDoc::AUTO );
+
+ toggleAll();
+}
+
+
+void K3bDvdBurnDialog::loadUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::loadUserDefaults(c);
+
+ K3bIsoOptions o = K3bIsoOptions::load( c );
+ m_imageSettingsWidget->load( o );
+
+ m_comboMultisession->loadConfig( c );
+
+ m_checkVerify->setChecked( c->readBoolEntry( "verify data", false ) );
+
+ toggleAll();
+}
+
+
+void K3bDvdBurnDialog::saveUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::saveUserDefaults(c);
+
+ K3bIsoOptions o;
+ m_imageSettingsWidget->save( o );
+ o.save( c );
+
+ m_comboMultisession->saveConfig( c );
+
+ c->writeEntry( "verify data", m_checkVerify->isChecked() );
+}
+
+
+void K3bDvdBurnDialog::slotStartClicked()
+{
+ if( m_checkOnlyCreateImage->isChecked() ||
+ m_checkCacheImage->isChecked() ) {
+ QFileInfo fi( m_tempDirSelectionWidget->tempPath() );
+ if( fi.isDir() )
+ m_tempDirSelectionWidget->setTempPath( fi.filePath() + "/image.iso" );
+
+ if( QFile::exists( m_tempDirSelectionWidget->tempPath() ) ) {
+ if( KMessageBox::warningContinueCancel( this,
+ i18n("Do you want to overwrite %1?").arg(m_tempDirSelectionWidget->tempPath()),
+ i18n("File Exists"), i18n("Overwrite") )
+ == KMessageBox::Continue ) {
+ // delete the file here to avoid problems with free space in K3bProjectBurnDialog::slotStartClicked
+ QFile::remove( m_tempDirSelectionWidget->tempPath() );
+ }
+ else
+ return;
+ }
+ }
+
+ K3bProjectBurnDialog::slotStartClicked();
+}
+
+#include "k3bdvdburndialog.moc"
diff --git a/src/projects/k3bdvdburndialog.h b/src/projects/k3bdvdburndialog.h
new file mode 100644
index 0000000..deb9620
--- /dev/null
+++ b/src/projects/k3bdvdburndialog.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * $Id: k3bdvdburndialog.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_DVD_BURNDIALOG_H_
+#define _K3B_DVD_BURNDIALOG_H_
+
+#include "k3bprojectburndialog.h"
+
+
+class K3bDvdDoc;
+class K3bDataImageSettingsWidget;
+class QGroupBox;
+class QRadioButton;
+class QButtonGroup;
+class QCheckBox;
+class K3bDataMultiSessionCombobox;
+
+
+class K3bDvdBurnDialog : public K3bProjectBurnDialog
+{
+ Q_OBJECT
+
+ public:
+ K3bDvdBurnDialog( K3bDvdDoc*, QWidget *parent = 0, const char *name = 0, bool modal = true );
+ ~K3bDvdBurnDialog();
+
+ protected slots:
+ void slotMultiSessionModeChanged();
+
+ void saveSettings();
+ void readSettings();
+
+ protected:
+ void slotStartClicked();
+ void loadK3bDefaults();
+ void loadUserDefaults( KConfigBase* );
+ void saveUserDefaults( KConfigBase* );
+ void toggleAll();
+
+ private:
+ void setupSettingsTab();
+
+ // --- settings tab ---------------------------
+ K3bDataImageSettingsWidget* m_imageSettingsWidget;
+ // ----------------------------------------------
+
+ // --- multisession tab -------------------------
+ K3bDataMultiSessionCombobox* m_comboMultisession;
+ // ---------------------------------------------
+
+ QCheckBox* m_checkVerify;
+
+ K3bDvdDoc* m_doc;
+};
+
+#endif
diff --git a/src/projects/k3bdvdview.cpp b/src/projects/k3bdvdview.cpp
new file mode 100644
index 0000000..512ec4b
--- /dev/null
+++ b/src/projects/k3bdvdview.cpp
@@ -0,0 +1,48 @@
+/*
+ *
+ * $Id: k3bdvdview.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 "k3bdvdview.h"
+#include "k3bdvddoc.h"
+#include "k3bdvdburndialog.h"
+#include <k3bfillstatusdisplay.h>
+#include <k3bdatafileview.h>
+
+#include <klocale.h>
+
+
+K3bDvdView::K3bDvdView( K3bDvdDoc* doc, QWidget *parent, const char *name )
+ : K3bDataView( doc, parent, name )
+{
+ m_doc = doc;
+
+ fillStatusDisplay()->showDvdSizes(true);
+
+ m_dataFileView->setNoItemText( i18n("Use drag'n'drop to add files and directories to the project.\n"
+ "To remove or rename files use the context menu.\n"
+ "After that press the burn button to write the DVD.") );
+}
+
+
+K3bDvdView::~K3bDvdView()
+{
+}
+
+
+K3bProjectBurnDialog* K3bDvdView::newBurnDialog( QWidget* parent, const char* name )
+{
+ return new K3bDvdBurnDialog( m_doc, parent, name, true );
+}
+
+#include "k3bdvdview.moc"
diff --git a/src/projects/k3bdvdview.h b/src/projects/k3bdvdview.h
new file mode 100644
index 0000000..d9f30f3
--- /dev/null
+++ b/src/projects/k3bdvdview.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * $Id: k3bdvdview.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_DVDVIEW_H_
+#define _K3B_DVDVIEW_H_
+
+#include <k3bdataview.h>
+
+class K3bDvdDoc;
+
+
+class K3bDvdView : public K3bDataView
+{
+ Q_OBJECT
+
+ public:
+ K3bDvdView( K3bDvdDoc* doc, QWidget *parent = 0, const char *name = 0 );
+ ~K3bDvdView();
+
+ protected:
+ virtual K3bProjectBurnDialog* newBurnDialog( QWidget* parent = 0, const char* name = 0 );
+
+ private:
+ K3bDvdDoc* m_doc;
+};
+
+#endif
diff --git a/src/projects/k3bencodingconverter.cpp b/src/projects/k3bencodingconverter.cpp
new file mode 100644
index 0000000..460abbe
--- /dev/null
+++ b/src/projects/k3bencodingconverter.cpp
@@ -0,0 +1,130 @@
+/*
+ *
+ * $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 <config.h>
+
+#include "k3bencodingconverter.h"
+
+#include <qwidget.h>
+#include <qlayout.h>
+
+#include <kdebug.h>
+
+#ifdef HAVE_ICONV_H
+#include <langinfo.h>
+#include <iconv.h>
+#endif
+
+
+class K3bEncodingConverter::Private
+{
+ public:
+ iconv_t ic;
+ QString localEncoding;
+ QString lastEncoding;
+};
+
+
+K3bEncodingConverter::K3bEncodingConverter()
+{
+ d = new Private;
+#ifdef HAVE_ICONV_H
+ char* codec = nl_langinfo( CODESET );
+ d->localEncoding = QString::fromLocal8Bit( codec );
+ kdDebug() << "(K3bDataUrlAddingDialog) using locale codec: " << codec << endl;
+ d->ic = ::iconv_open( "UCS-2BE", codec );
+#endif
+}
+
+
+K3bEncodingConverter::~K3bEncodingConverter()
+{
+#ifdef HAVE_ICONV_H
+ ::iconv_close( d->ic );
+#endif
+ delete d;
+}
+
+
+bool K3bEncodingConverter::encodedLocally( const QCString& s )
+{
+#ifdef HAVE_ICONV_H
+ QCString utf8Encoded( s.length()*2 );
+#if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
+ const char* in = s.data();
+#else
+ char* in = s.data();
+#endif
+ char* out = utf8Encoded.data();
+ size_t inSize = s.length();
+ size_t outSize = utf8Encoded.size();
+ return( (size_t)-1 != ::iconv( d->ic, &in, &inSize, &out, &outSize ) );
+#else
+ return true;
+#endif
+}
+
+
+bool K3bEncodingConverter::fixEncoding( const QCString& s, QCString& result, QWidget* parent, bool cache )
+{
+#ifdef IMPLEMENT_THIS_METHOD // HAVE_ICONV_H
+ if( !d->lastEncoding.isEmpty() ) {
+ //
+ // try converting with the last encoding
+ //
+ if( convert( s, result, d->lastEncoding, d->localEncoding )
+ && encodedLocally( result ) ) {
+ return true;
+ }
+ }
+
+
+
+ if( cache ) {
+
+ }
+ else
+ d->lastEncoding = QString::null;
+#else
+ return false;
+#endif
+}
+
+
+bool K3bEncodingConverter::convert( const QCString& s, QCString& result, const QString& from, const QString& to )
+{
+ bool r = false;
+
+#ifdef HAVE_ICONV_H
+ iconv_t ic = ::iconv_open( to.local8Bit(), from.local8Bit() );
+
+ result.resize( s.length() * 2 );
+#if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
+ const char* in = s.data();
+#else
+ char* in = s.data();
+#endif
+ char* out = result.data();
+ size_t inSize = s.length();
+ size_t outSize = result.size();
+
+ if( (size_t)-1 != ::iconv( ic, &in, &inSize, &out, &outSize ) )
+ r = true;
+
+ ::iconv_close( ic );
+#endif
+
+ return r;
+}
diff --git a/src/projects/k3bencodingconverter.h b/src/projects/k3bencodingconverter.h
new file mode 100644
index 0000000..e40003c
--- /dev/null
+++ b/src/projects/k3bencodingconverter.h
@@ -0,0 +1,59 @@
+/*
+ *
+ * $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_ENCODING_CONVERTER_H_
+#define _K3B_ENCODING_CONVERTER_H_
+
+#include <qcstring.h>
+#include <qstring.h>
+
+class QWidget;
+
+class K3bEncodingConverter
+{
+ public:
+ K3bEncodingConverter();
+ ~K3bEncodingConverter();
+
+ /**
+ * Check if a string is encoded using the local codeset
+ *
+ * \return True if the string is encoded in the local encoding.
+ */
+ bool encodedLocally( const QCString& );
+
+ /**
+ * Tries to fix the encoding of a string to fit the local
+ * encoding.
+ * It presents a dialog to the user that let's them choose
+ * the proper encoding based on example conversions.
+ *
+ * \param s The string to be fixed.
+ * \param parent The parent widget to be used when showing the encoding selection dialog.
+ * \param cacheEncoding If true the codeset used for successful conversion is cached and
+ * reused for the next call to fixEncoding.
+ *
+ * \return True if the conversion was successful.
+ */
+ bool fixEncoding( const QCString& s, QCString& result, QWidget* parent = 0, bool cacheEncoding = true );
+
+ private:
+ bool convert( const QCString& s, QCString& result, const QString& from, const QString& to );
+
+ class Private;
+ Private* d;
+};
+
+#endif
diff --git a/src/projects/k3bfillstatusdisplay.cpp b/src/projects/k3bfillstatusdisplay.cpp
new file mode 100644
index 0000000..2d39bc7
--- /dev/null
+++ b/src/projects/k3bfillstatusdisplay.cpp
@@ -0,0 +1,759 @@
+/*
+ *
+ * $Id: k3bfillstatusdisplay.cpp 768504 2008-01-30 08:53:22Z 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 "k3bfillstatusdisplay.h"
+#include "k3bdoc.h"
+
+#include <k3bapplication.h>
+#include <k3bmediaselectiondialog.h>
+#include <k3bdevice.h>
+#include <k3bdevicemanager.h>
+#include <k3bdevice.h>
+#include <k3bmsf.h>
+#include <k3bradioaction.h>
+#include <k3bmediacache.h>
+
+#include <qevent.h>
+#include <qpainter.h>
+#include <qcolor.h>
+#include <qrect.h>
+#include <qfont.h>
+#include <qfontmetrics.h>
+#include <qvalidator.h>
+#include <qtoolbutton.h>
+#include <qtooltip.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qtimer.h>
+
+#include <kaction.h>
+#include <kpopupmenu.h>
+#include <klocale.h>
+#include <kinputdialog.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <kio/global.h>
+#include <kmessagebox.h>
+#include <kglobal.h>
+#include <kpixmapeffect.h>
+
+
+static const int DEFAULT_CD_SIZE_74 = 74*60*75;
+static const int DEFAULT_CD_SIZE_80 = 80*60*75;
+static const int DEFAULT_CD_SIZE_100 = 100*60*75;
+static const int DEFAULT_DVD_SIZE_4_4 = 2295104;
+static const int DEFAULT_DVD_SIZE_8_0 = 4173824;
+
+class K3bFillStatusDisplayWidget::Private
+{
+public:
+ K3b::Msf cdSize;
+ bool showTime;
+ K3bDoc* doc;
+};
+
+
+K3bFillStatusDisplayWidget::K3bFillStatusDisplayWidget( K3bDoc* doc, QWidget* parent )
+ : QWidget( parent, 0, WRepaintNoErase )
+{
+ d = new Private();
+ d->doc = doc;
+ setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred ) );
+}
+
+
+K3bFillStatusDisplayWidget::~K3bFillStatusDisplayWidget()
+{
+ delete d;
+}
+
+
+const K3b::Msf& K3bFillStatusDisplayWidget::cdSize() const
+{
+ return d->cdSize;
+}
+
+
+void K3bFillStatusDisplayWidget::setShowTime( bool b )
+{
+ d->showTime = b;
+ update();
+}
+
+
+void K3bFillStatusDisplayWidget::setCdSize( const K3b::Msf& size )
+{
+ d->cdSize = size;
+ update();
+}
+
+
+QSize K3bFillStatusDisplayWidget::sizeHint() const
+{
+ return minimumSizeHint();
+}
+
+
+QSize K3bFillStatusDisplayWidget::minimumSizeHint() const
+{
+ int margin = 2;
+ QFontMetrics fm( font() );
+ return QSize( -1, fm.height() + 2 * margin );
+}
+
+
+void K3bFillStatusDisplayWidget::mousePressEvent( QMouseEvent* e )
+{
+ if( e->button() == Qt::RightButton )
+ emit contextMenu( e->globalPos() );
+}
+
+
+void K3bFillStatusDisplayWidget::paintEvent( QPaintEvent* )
+{
+ // double buffer
+ QPixmap buffer( size() );
+ buffer.fill( colorGroup().base() );
+ QPainter p;
+ p.begin( &buffer, this );
+ p.setPen( Qt::black ); // we use a fixed bar color (which is not very nice btw, so we also fix the text color)
+
+ long long docSize;
+ long long cdSize;
+ long long maxValue;
+ long tolerance;
+
+ if( d->showTime ) {
+ docSize = d->doc->length().totalFrames() / 75 / 60;
+ cdSize = d->cdSize.totalFrames() / 75 / 60;
+ maxValue = (cdSize > docSize ? cdSize : docSize) + 10;
+ tolerance = 1;
+ }
+ else {
+ docSize = d->doc->size()/1024/1024;
+ cdSize = d->cdSize.mode1Bytes()/1024/1024;
+ maxValue = (cdSize > docSize ? cdSize : docSize) + 100;
+ tolerance = 10;
+ }
+
+ // so split width() in maxValue pieces
+ double one = (double)rect().width() / (double)maxValue;
+ QRect crect( rect() );
+ crect.setWidth( (int)(one*(double)docSize) );
+
+ p.setClipping(true);
+ p.setClipRect(crect);
+
+ p.fillRect( crect, Qt::green );
+
+ QRect oversizeRect(crect);
+ // draw yellow if cdSize - tolerance < docSize
+ if( docSize > cdSize - tolerance ) {
+ oversizeRect.setLeft( oversizeRect.left() + (int)(one * (cdSize - tolerance)) );
+ p.fillRect( oversizeRect, Qt::yellow );
+ KPixmap pix;
+ pix.resize( rect().height()*2, rect().height() );
+ KPixmapEffect::gradient( pix, green, yellow, KPixmapEffect::HorizontalGradient, 0 );
+ p.drawPixmap( oversizeRect.left() - pix.width()/2, 0, pix );
+ }
+
+ // draw red if docSize > cdSize + tolerance
+ if( docSize > cdSize + tolerance ) {
+ oversizeRect.setLeft( oversizeRect.left() + (int)(one * tolerance*2) );
+ p.fillRect( oversizeRect, Qt::red );
+ KPixmap pix;
+ pix.resize( rect().height()*2, rect().height() );
+ KPixmapEffect::gradient( pix, yellow, red, KPixmapEffect::HorizontalGradient, 0 );
+ p.drawPixmap( oversizeRect.left() - pix.width()/2, 0, pix );
+ }
+
+ p.setClipping(false);
+
+ // ====================================================================================
+ // Now the colored bar is painted
+ // Continue with the texts
+ // ====================================================================================
+
+ // first we determine the text to display
+ // ====================================================================================
+ QString docSizeText;
+ if( d->showTime )
+ docSizeText = d->doc->length().toString(false) + " " + i18n("min");
+ else
+ docSizeText = KIO::convertSize( d->doc->size() );
+
+ QString overSizeText;
+ if( d->cdSize.mode1Bytes() >= d->doc->size() )
+ overSizeText = i18n("Available: %1 of %2")
+ .arg( d->showTime
+ ? i18n("%1 min").arg((K3b::Msf( cdSize*60*75 ) - d->doc->length()).toString(false))
+ : KIO::convertSize( QMAX( (cdSize * 1024LL * 1024LL) - (long long)d->doc->size(), 0LL ) ) )
+ .arg( d->showTime
+ ? i18n("%1 min").arg(K3b::Msf( cdSize*60*75 ).toString(false))
+ : KIO::convertSizeFromKB( cdSize * 1024 ) );
+ else
+ overSizeText = i18n("Capacity exceeded by %1")
+ .arg( d->showTime
+ ? i18n("%1 min").arg( (d->doc->length() - K3b::Msf( cdSize*60*75 ) ).toString(false))
+ : KIO::convertSize( (long long)d->doc->size() - (cdSize * 1024LL * 1024LL) ) );
+ // ====================================================================================
+
+ // draw the medium size marker
+ // ====================================================================================
+ int mediumSizeMarkerPos = rect().left() + (int)(one*cdSize);
+ p.drawLine( mediumSizeMarkerPos, rect().bottom(),
+ mediumSizeMarkerPos, rect().top() + ((rect().bottom()-rect().top())/2) );
+ // ====================================================================================
+
+
+
+ // we want to draw the docSizeText centered in the filled area
+ // if there is not enough space we just align it left
+ // ====================================================================================
+ int docSizeTextPos = 0;
+ int docSizeTextLength = fontMetrics().width(docSizeText);
+ if( docSizeTextLength + 5 > crect.width() ) {
+ docSizeTextPos = crect.left() + 5; // a little margin
+ }
+ else {
+ docSizeTextPos = ( crect.width() - docSizeTextLength ) / 2;
+
+ // make sure the text does not cross the medium size marker
+ if( docSizeTextPos <= mediumSizeMarkerPos && mediumSizeMarkerPos <= docSizeTextPos + docSizeTextLength )
+ docSizeTextPos = QMAX( crect.left() + 5, mediumSizeMarkerPos - docSizeTextLength - 5 );
+ }
+ // ====================================================================================
+
+ // draw the over size text
+ // ====================================================================================
+ QFont fnt(font());
+ fnt.setPointSize( QMAX( 8, fnt.pointSize()-4 ) );
+ fnt.setBold(false);
+
+ QRect overSizeTextRect( rect() );
+ int overSizeTextLength = QFontMetrics(fnt).width(overSizeText);
+ if( overSizeTextLength + 5 > overSizeTextRect.width() - (int)(one*cdSize) ) {
+ // we don't have enough space on the right, so we paint to the left of the line
+ overSizeTextRect.setLeft( (int)(one*cdSize) - overSizeTextLength - 5 );
+ }
+ else {
+ overSizeTextRect.setLeft( mediumSizeMarkerPos + 5 );
+ }
+
+ // make sure the two text do not overlap (this does not cover all cases though)
+ if( overSizeTextRect.left() < docSizeTextPos + docSizeTextLength )
+ docSizeTextPos = QMAX( crect.left() + 5, QMIN( overSizeTextRect.left() - docSizeTextLength - 5, mediumSizeMarkerPos - docSizeTextLength - 5 ) );
+
+ QRect docTextRect( rect() );
+ docTextRect.setLeft( docSizeTextPos );
+ p.drawText( docTextRect, Qt::AlignLeft | Qt::AlignVCenter, docSizeText );
+
+ p.setFont(fnt);
+ p.drawText( overSizeTextRect, Qt::AlignLeft | Qt::AlignVCenter, overSizeText );
+ // ====================================================================================
+
+ p.end();
+
+ bitBlt( this, 0, 0, &buffer );
+}
+
+
+
+// ----------------------------------------------------------------------------------------------------
+
+
+class K3bFillStatusDisplay::ToolTip : public QToolTip
+{
+public:
+ ToolTip( K3bDoc* doc, QWidget* parent )
+ : QToolTip( parent, 0 ),
+ m_doc(doc) {
+ }
+
+ void maybeTip( const QPoint& ) {
+ tip( parentWidget()->rect(),
+ KIO::convertSize( m_doc->size() ) +
+ " (" + KGlobal::locale()->formatNumber( m_doc->size(), 0 ) + "), " +
+ m_doc->length().toString(false) + " " + i18n("min") +
+ " (" + i18n("Right click for media sizes") + ")");
+ }
+
+private:
+ K3bDoc* m_doc;
+};
+
+class K3bFillStatusDisplay::Private
+{
+public:
+ KActionCollection* actionCollection;
+ KRadioAction* actionShowMinutes;
+ KRadioAction* actionShowMegs;
+ KRadioAction* actionAuto;
+ KRadioAction* action74Min;
+ KRadioAction* action80Min;
+ KRadioAction* action100Min;
+ KRadioAction* actionDvd4_7GB;
+ KRadioAction* actionDvdDoubleLayer;
+ K3bRadioAction* actionCustomSize;
+ K3bRadioAction* actionDetermineSize;
+ KAction* actionSaveUserDefaults;
+ KAction* actionLoadUserDefaults;
+
+ KPopupMenu* popup;
+ KPopupMenu* dvdPopup;
+
+ QToolButton* buttonMenu;
+
+ K3bFillStatusDisplayWidget* displayWidget;
+
+ bool showDvdSizes;
+ bool showTime;
+
+ K3bDoc* doc;
+
+ QTimer updateTimer;
+};
+
+
+K3bFillStatusDisplay::K3bFillStatusDisplay( K3bDoc* doc, QWidget *parent, const char *name )
+ : QFrame(parent,name)
+{
+ d = new Private;
+ d->doc = doc;
+
+ m_toolTip = new ToolTip( doc, this );
+
+ setFrameStyle( Panel | Sunken );
+
+ d->displayWidget = new K3bFillStatusDisplayWidget( doc, this );
+// d->buttonMenu = new QToolButton( this );
+// d->buttonMenu->setIconSet( SmallIconSet("cdrom_unmount") );
+// d->buttonMenu->setAutoRaise(true);
+// QToolTip::add( d->buttonMenu, i18n("Fill display properties") );
+// connect( d->buttonMenu, SIGNAL(clicked()), this, SLOT(slotMenuButtonClicked()) );
+
+ QGridLayout* layout = new QGridLayout( this );
+ layout->setSpacing(5);
+ layout->setMargin(frameWidth());
+ layout->addWidget( d->displayWidget, 0, 0 );
+ // layout->addWidget( d->buttonMenu, 0, 1 );
+ layout->setColStretch( 0, 1 );
+
+ setupPopupMenu();
+
+ showDvdSizes( false );
+
+ connect( d->doc, SIGNAL(changed()), this, SLOT(slotDocChanged()) );
+ connect( &d->updateTimer, SIGNAL(timeout()), this, SLOT(slotUpdateDisplay()) );
+ connect( k3bappcore->mediaCache(), SIGNAL(mediumChanged(K3bDevice::Device*)),
+ this, SLOT(slotMediumChanged(K3bDevice::Device*)) );
+}
+
+K3bFillStatusDisplay::~K3bFillStatusDisplay()
+{
+ delete d;
+ delete m_toolTip;
+}
+
+
+void K3bFillStatusDisplay::setupPopupMenu()
+{
+ d->actionCollection = new KActionCollection( this );
+
+ // we use a nother popup for the dvd sizes
+ d->popup = new KPopupMenu( this, "popup" );
+ d->dvdPopup = new KPopupMenu( this, "dvdpopup" );
+
+ d->actionShowMinutes = new KRadioAction( i18n("Minutes"), 0, this, SLOT(showTime()),
+ d->actionCollection, "fillstatus_show_minutes" );
+ d->actionShowMegs = new KRadioAction( i18n("Megabytes"), 0, this, SLOT(showSize()),
+ d->actionCollection, "fillstatus_show_megabytes" );
+
+ d->actionShowMegs->setExclusiveGroup( "show_size_in" );
+ d->actionShowMinutes->setExclusiveGroup( "show_size_in" );
+
+ d->actionAuto = new KRadioAction( i18n("Auto"), 0, this, SLOT(slotAutoSize()),
+ d->actionCollection, "fillstatus_auto" );
+ d->action74Min = new KRadioAction( i18n("%1 MB").arg(650), 0, this, SLOT(slot74Minutes()),
+ d->actionCollection, "fillstatus_74minutes" );
+ d->action80Min = new KRadioAction( i18n("%1 MB").arg(700), 0, this, SLOT(slot80Minutes()),
+ d->actionCollection, "fillstatus_80minutes" );
+ d->action100Min = new KRadioAction( i18n("%1 MB").arg(880), 0, this, SLOT(slot100Minutes()),
+ d->actionCollection, "fillstatus_100minutes" );
+ d->actionDvd4_7GB = new KRadioAction( KIO::convertSizeFromKB((int)(4.4*1024.0*1024.0)), 0, this, SLOT(slotDvd4_7GB()),
+ d->actionCollection, "fillstatus_dvd_4_7gb" );
+ d->actionDvdDoubleLayer = new KRadioAction( KIO::convertSizeFromKB((int)(8.0*1024.0*1024.0)),
+ 0, this, SLOT(slotDvdDoubleLayer()),
+ d->actionCollection, "fillstatus_dvd_double_layer" );
+ d->actionCustomSize = new K3bRadioAction( i18n("Custom..."), 0, this, SLOT(slotCustomSize()),
+ d->actionCollection, "fillstatus_custom_size" );
+ d->actionCustomSize->setAlwaysEmitActivated(true);
+ d->actionDetermineSize = new K3bRadioAction( i18n("From Medium..."), "cdrom_unmount", 0,
+ this, SLOT(slotDetermineSize()),
+ d->actionCollection, "fillstatus_size_from_disk" );
+ d->actionDetermineSize->setAlwaysEmitActivated(true);
+
+ d->actionAuto->setExclusiveGroup( "cd_size" );
+ d->action74Min->setExclusiveGroup( "cd_size" );
+ d->action80Min->setExclusiveGroup( "cd_size" );
+ d->action100Min->setExclusiveGroup( "cd_size" );
+ d->actionDvd4_7GB->setExclusiveGroup( "cd_size" );
+ d->actionDvdDoubleLayer->setExclusiveGroup( "cd_size" );
+ d->actionCustomSize->setExclusiveGroup( "cd_size" );
+ d->actionDetermineSize->setExclusiveGroup( "cd_size" );
+
+ d->actionLoadUserDefaults = new KAction( i18n("User Defaults"), "", 0,
+ this, SLOT(slotLoadUserDefaults()),
+ d->actionCollection, "load_user_defaults" );
+ d->actionSaveUserDefaults = new KAction( i18n("Save User Defaults"), "", 0,
+ this, SLOT(slotSaveUserDefaults()),
+ d->actionCollection, "save_user_defaults" );
+
+ KAction* dvdSizeInfoAction = new KAction( i18n("Why 4.4 instead of 4.7?"), "", 0,
+ this, SLOT(slotWhy44()),
+ d->actionCollection, "why_44_gb" );
+
+ d->popup->insertTitle( i18n("Show Size In") );
+ d->actionShowMinutes->plug( d->popup );
+ d->actionShowMegs->plug( d->popup );
+ d->popup->insertTitle( i18n("CD Size") );
+ d->actionAuto->plug( d->popup );
+ d->action74Min->plug( d->popup );
+ d->action80Min->plug( d->popup );
+ d->action100Min->plug( d->popup );
+ d->actionCustomSize->plug( d->popup );
+ d->actionDetermineSize->plug( d->popup );
+ d->popup->insertSeparator();
+ d->actionLoadUserDefaults->plug( d->popup );
+ d->actionSaveUserDefaults->plug( d->popup );
+
+ d->dvdPopup->insertTitle( i18n("DVD Size") );
+ dvdSizeInfoAction->plug( d->dvdPopup );
+ d->actionAuto->plug( d->dvdPopup );
+ d->actionDvd4_7GB->plug( d->dvdPopup );
+ d->actionDvdDoubleLayer->plug( d->dvdPopup );
+ d->actionCustomSize->plug( d->dvdPopup );
+ d->actionDetermineSize->plug( d->dvdPopup );
+ d->dvdPopup->insertSeparator();
+ d->actionLoadUserDefaults->plug( d->dvdPopup );
+ d->actionSaveUserDefaults->plug( d->dvdPopup );
+
+ connect( d->displayWidget, SIGNAL(contextMenu(const QPoint&)), this, SLOT(slotPopupMenu(const QPoint&)) );
+}
+
+
+void K3bFillStatusDisplay::showSize()
+{
+ d->actionShowMegs->setChecked( true );
+
+ d->action74Min->setText( i18n("%1 MB").arg(650) );
+ d->action80Min->setText( i18n("%1 MB").arg(700) );
+ d->action100Min->setText( i18n("%1 MB").arg(880) );
+
+ d->showTime = false;
+ d->displayWidget->setShowTime(false);
+}
+
+void K3bFillStatusDisplay::showTime()
+{
+ d->actionShowMinutes->setChecked( true );
+
+ d->action74Min->setText( i18n("unused", "%n minutes", 74) );
+ d->action80Min->setText( i18n("unused", "%n minutes", 80) );
+ d->action100Min->setText( i18n("unused", "%n minutes", 100) );
+
+ d->showTime = true;
+ d->displayWidget->setShowTime(true);
+}
+
+
+void K3bFillStatusDisplay::showDvdSizes( bool b )
+{
+ d->showDvdSizes = b;
+ slotLoadUserDefaults();
+}
+
+
+void K3bFillStatusDisplay::slotAutoSize()
+{
+ slotMediumChanged( 0 );
+}
+
+
+void K3bFillStatusDisplay::slot74Minutes()
+{
+ d->displayWidget->setCdSize( DEFAULT_CD_SIZE_74 );
+}
+
+
+void K3bFillStatusDisplay::slot80Minutes()
+{
+ d->displayWidget->setCdSize( DEFAULT_CD_SIZE_80 );
+}
+
+
+void K3bFillStatusDisplay::slot100Minutes()
+{
+ d->displayWidget->setCdSize( DEFAULT_CD_SIZE_100 );
+}
+
+
+void K3bFillStatusDisplay::slotDvd4_7GB()
+{
+ d->displayWidget->setCdSize( DEFAULT_DVD_SIZE_4_4 );
+}
+
+
+void K3bFillStatusDisplay::slotDvdDoubleLayer()
+{
+ d->displayWidget->setCdSize( DEFAULT_DVD_SIZE_8_0 );
+}
+
+
+void K3bFillStatusDisplay::slotWhy44()
+{
+ QWhatsThis::display( i18n("<p><b>Why does K3b offer 4.4 GB and 8.0 GB instead of 4.7 and 8.5 like "
+ "it says on the media?</b>"
+ "<p>A single layer DVD media has a capacity of approximately "
+ "4.4 GB which equals 4.4*1024<sup>3</sup> bytes. Media producers just "
+ "calculate with 1000 instead of 1024 for advertising reasons.<br>"
+ "This results in 4.4*1024<sup>3</sup>/1000<sup>3</sup> = 4.7 GB.") );
+}
+
+
+void K3bFillStatusDisplay::slotCustomSize()
+{
+ // allow the units to be translated
+ QString gbS = i18n("gb");
+ QString mbS = i18n("mb");
+ QString minS = i18n("min");
+
+ QRegExp rx( "(\\d+\\" + KGlobal::locale()->decimalSymbol() + "?\\d*)(" + gbS + "|" + mbS + "|" + minS + ")?" );
+ bool ok;
+ QString size = KInputDialog::getText( i18n("Custom Size"),
+ i18n("<p>Please specify the size of the media. Use suffixes <b>gb</b>,<b>mb</b>, "
+ "and <b>min</b> for <em>gigabytes</em>, <em>megabytes</em>, and <em>minutes</em>"
+ " respectively."),
+ d->showDvdSizes ? QString("4%14%2").arg(KGlobal::locale()->decimalSymbol()).arg(gbS) :
+ (d->showTime ? QString("74")+minS : QString("650")+mbS),
+ &ok, this, (const char*)0,
+ new QRegExpValidator( rx, this ) );
+ if( ok ) {
+ // determine size
+ if( rx.exactMatch( size ) ) {
+ QString valStr = rx.cap(1);
+ if( valStr.endsWith( KGlobal::locale()->decimalSymbol() ) )
+ valStr += "0";
+ double val = KGlobal::locale()->readNumber( valStr, &ok );
+ if( ok ) {
+ QString s = rx.cap(2);
+ if( s == gbS || (s.isEmpty() && d->showDvdSizes) )
+ val *= 1024*512;
+ else if( s == mbS || (s.isEmpty() && !d->showTime) )
+ val *= 512;
+ else
+ val *= 60*75;
+ d->displayWidget->setCdSize( (int)val );
+ update();
+ }
+ }
+ }
+}
+
+
+void K3bFillStatusDisplay::slotMenuButtonClicked()
+{
+ QSize size = d->showDvdSizes ? d->dvdPopup->sizeHint() : d->popup->sizeHint();
+ slotPopupMenu( d->buttonMenu->mapToGlobal(QPoint(d->buttonMenu->width(), 0)) +
+ QPoint(-1*size.width(), -1*size.height()) );
+}
+
+
+void K3bFillStatusDisplay::slotPopupMenu( const QPoint& p )
+{
+ if( d->showDvdSizes )
+ d->dvdPopup->popup(p);
+ else
+ d->popup->popup(p);
+}
+
+
+void K3bFillStatusDisplay::slotDetermineSize()
+{
+ bool canceled = false;
+ K3bDevice::Device* dev = K3bMediaSelectionDialog::selectMedium( d->showDvdSizes ? K3bDevice::MEDIA_WRITABLE_DVD : K3bDevice::MEDIA_WRITABLE_CD,
+ K3bDevice::STATE_EMPTY|K3bDevice::STATE_INCOMPLETE,
+ parentWidget(),
+ QString::null, QString::null, &canceled );
+
+ if( dev ) {
+ K3b::Msf size = k3bappcore->mediaCache()->diskInfo( dev ).capacity();
+ if( size > 0 ) {
+ d->displayWidget->setCdSize( size );
+ d->actionCustomSize->setChecked(true);
+ update();
+ }
+ else
+ KMessageBox::error( parentWidget(), i18n("Medium is not empty.") );
+ }
+ else if( !canceled )
+ KMessageBox::error( parentWidget(), i18n("No usable medium found.") );
+}
+
+
+void K3bFillStatusDisplay::slotLoadUserDefaults()
+{
+ // load project specific values
+ KConfig* c = k3bcore->config();
+ c->setGroup( "default " + d->doc->typeString() + " settings" );
+
+ // defaults to megabytes
+ d->showTime = c->readBoolEntry( "show minutes", false );
+ d->displayWidget->setShowTime(d->showTime);
+ d->actionShowMegs->setChecked( !d->showTime );
+ d->actionShowMinutes->setChecked( d->showTime );
+
+
+ long size = c->readNumEntry( "default media size", 0 );
+
+ switch( size ) {
+ case 0:
+ // automatic mode
+ d->actionAuto->setChecked( true );
+ break;
+ case 74:
+ d->action74Min->setChecked( true );
+ break;
+ case 80:
+ d->action80Min->setChecked( true );
+ break;
+ case 100:
+ d->action100Min->setChecked( true );
+ break;
+ case 510:
+ d->actionDvd4_7GB->setChecked( true );
+ break;
+ default:
+ d->actionCustomSize->setChecked( true );
+ break;
+ }
+
+ if( size == 0 ) {
+ slotMediumChanged( 0 );
+ }
+ else {
+ d->displayWidget->setCdSize( size*60*75 );
+ }
+}
+
+
+void K3bFillStatusDisplay::slotMediumChanged( K3bDevice::Device* )
+{
+ if( d->actionAuto->isChecked() ) {
+ //
+ // now search for a usable medium
+ // if we find exactly one usable or multiple with the same size
+ // we use that size
+ //
+
+ // TODO: once we have only one data project we need to change this to handle both
+
+ K3bDevice::Device* dev = 0;
+ QPtrList<K3bDevice::Device> devs;
+ if( d->showDvdSizes )
+ devs = k3bcore->deviceManager()->dvdWriter();
+ else
+ devs = k3bcore->deviceManager()->cdWriter();
+
+ for( QPtrListIterator<K3bDevice::Device> it( devs ); *it; ++it ) {
+ const K3bMedium& medium = k3bappcore->mediaCache()->medium( *it );
+
+ if( ( medium.diskInfo().empty() ||
+ medium.diskInfo().appendable() ||
+ medium.diskInfo().rewritable() ) &&
+ ( medium.diskInfo().isDvdMedia() == d->showDvdSizes ) &&
+ d->doc->length() <= medium.diskInfo().capacity() ) {
+
+ // first usable medium
+ if( !dev ) {
+ dev = medium.device();
+ }
+
+ // roughly compare the sizes of the two usable media. If they match, carry on.
+ else if( k3bappcore->mediaCache()->diskInfo( dev ).capacity().lba()/75/60
+ != medium.diskInfo().capacity().lba()/75/60 ) {
+ // different usable media -> fallback
+ dev = 0;
+ break;
+ }
+ // else continue;
+ }
+ }
+
+ if( dev ) {
+ d->displayWidget->setCdSize( k3bappcore->mediaCache()->diskInfo( dev ).capacity().lba() );
+ }
+ else {
+ // default fallback
+ if( d->showDvdSizes ) {
+ if( d->doc->length().lba() > DEFAULT_DVD_SIZE_4_4 )
+ d->displayWidget->setCdSize( DEFAULT_DVD_SIZE_8_0 );
+ else
+ d->displayWidget->setCdSize( DEFAULT_DVD_SIZE_4_4 );
+ }
+ else
+ d->displayWidget->setCdSize( DEFAULT_CD_SIZE_80 );
+ }
+ }
+}
+
+
+void K3bFillStatusDisplay::slotSaveUserDefaults()
+{
+ // save project specific values
+ KConfig* c = k3bcore->config();
+ c->setGroup( "default " + d->doc->typeString() + " settings" );
+
+ c->writeEntry( "show minutes", d->showTime );
+ c->writeEntry( "default media size", d->actionAuto->isChecked() ? 0 : d->displayWidget->cdSize().totalFrames() );
+}
+
+
+void K3bFillStatusDisplay::slotUpdateDisplay()
+{
+ if( d->actionAuto->isChecked() ) {
+ //
+ // also update the medium list in case the docs size exceeds the capacity
+ //
+ slotMediumChanged( 0 );
+ }
+ else {
+ d->displayWidget->update();
+ }
+}
+
+
+void K3bFillStatusDisplay::slotDocChanged()
+{
+ // cache updates
+ if( !d->updateTimer.isActive() ) {
+ slotUpdateDisplay();
+ d->updateTimer.start( 500, false );
+ }
+}
+
+#include "k3bfillstatusdisplay.moc"
diff --git a/src/projects/k3bfillstatusdisplay.h b/src/projects/k3bfillstatusdisplay.h
new file mode 100644
index 0000000..f477faa
--- /dev/null
+++ b/src/projects/k3bfillstatusdisplay.h
@@ -0,0 +1,117 @@
+
+/*
+ *
+ * $Id: k3bfillstatusdisplay.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 K3BFILLSTATUSDISPLAY_H
+#define K3BFILLSTATUSDISPLAY_H
+
+#include <qframe.h>
+#include <qtooltip.h>
+
+
+class QPaintEvent;
+class QMouseEvent;
+class K3bDoc;
+class KToggleAction;
+class KAction;
+class KActionCollection;
+class KPopupMenu;
+class QToolButton;
+
+namespace K3bDevice {
+ class Device;
+}
+namespace K3b {
+ class Msf;
+}
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bFillStatusDisplayWidget : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ K3bFillStatusDisplayWidget( K3bDoc* doc, QWidget* parent );
+ ~K3bFillStatusDisplayWidget();
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ const K3b::Msf& cdSize() const;
+
+ public slots:
+ void setShowTime( bool b );
+ void setCdSize( const K3b::Msf& );
+
+ signals:
+ void contextMenu( const QPoint& );
+
+ protected:
+ void mousePressEvent( QMouseEvent* );
+ void paintEvent(QPaintEvent*);
+
+ private:
+ class Private;
+ Private* d;
+};
+
+
+class K3bFillStatusDisplay : public QFrame {
+
+ Q_OBJECT
+
+ public:
+ K3bFillStatusDisplay(K3bDoc* doc, QWidget *parent=0, const char *name=0);
+ ~K3bFillStatusDisplay();
+
+ public slots:
+ void showSize();
+ void showTime();
+ void showDvdSizes( bool );
+
+ protected:
+ void setupPopupMenu();
+
+ private slots:
+ void slotAutoSize();
+ void slot74Minutes();
+ void slot80Minutes();
+ void slot100Minutes();
+ void slotDvd4_7GB();
+ void slotDvdDoubleLayer();
+ void slotWhy44();
+ void slotCustomSize();
+ void slotMenuButtonClicked();
+ void slotPopupMenu(const QPoint&);
+ void slotDetermineSize();
+ void slotDocChanged();
+ void slotMediumChanged( K3bDevice::Device* dev );
+ void slotUpdateDisplay();
+
+ void slotLoadUserDefaults();
+ void slotSaveUserDefaults();
+
+ private:
+ class ToolTip;
+ ToolTip* m_toolTip;
+ class Private;
+ Private* d;
+};
+
+#endif
diff --git a/src/projects/k3bmixedburndialog.cpp b/src/projects/k3bmixedburndialog.cpp
new file mode 100644
index 0000000..5d5ad28
--- /dev/null
+++ b/src/projects/k3bmixedburndialog.cpp
@@ -0,0 +1,353 @@
+/*
+ *
+ * $Id: k3bmixedburndialog.cpp 627521 2007-01-26 22:39:53Z 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 "k3bmixedburndialog.h"
+#include "k3bmixeddoc.h"
+#include "k3bmixedview.h"
+
+#include <k3bdataimagesettingswidget.h>
+#include <k3bdatadoc.h>
+#include <k3baudiodoc.h>
+#include <k3bdevice.h>
+#include <k3bwriterselectionwidget.h>
+#include <k3btempdirselectionwidget.h>
+#include <k3bisooptions.h>
+#include <k3bglobals.h>
+#include <k3baudiocdtextwidget.h>
+#include <k3bdatamodewidget.h>
+#include <k3bmsf.h>
+#include <k3bstdguiitems.h>
+#include <k3bwritingmodewidget.h>
+#include <k3bexternalbinmanager.h>
+#include <k3bversion.h>
+#include <k3bcore.h>
+#include <k3baudiotrackplayer.h>
+#include <k3bintmapcombobox.h>
+
+#include <qtabwidget.h>
+#include <qcheckbox.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qlayout.h>
+#include <qvariant.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qvbox.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+
+
+K3bMixedBurnDialog::K3bMixedBurnDialog( K3bMixedDoc* doc, QWidget *parent, const char *name, bool modal )
+ : K3bProjectBurnDialog( doc, parent, name, modal ), m_doc(doc)
+{
+ prepareGui();
+
+ setTitle( i18n("Mixed Project"), i18n("1 track (%1 minutes)",
+ "%n tracks (%1 minutes)",
+ m_doc->numOfTracks()).arg(m_doc->length().toString()) );
+
+ m_checkOnlyCreateImage->hide();
+
+ // create cd-text page
+ m_cdtextWidget = new K3bAudioCdTextWidget( this );
+ addPage( m_cdtextWidget, i18n("CD-Text") );
+
+ // create image settings tab
+ m_imageSettingsWidget = new K3bDataImageSettingsWidget( this );
+ addPage( m_imageSettingsWidget, i18n("Filesystem") );
+
+ setupSettingsPage();
+
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ m_optionGroupLayout->addItem( spacer );
+
+ connect( m_checkNormalize, SIGNAL(toggled(bool)), this, SLOT(slotNormalizeToggled(bool)) );
+ connect( m_checkCacheImage, SIGNAL(toggled(bool)), this, SLOT(slotCacheImageToggled(bool)) );
+ connect( m_writerSelectionWidget, SIGNAL(writingAppChanged(int)), this, SLOT(slotToggleAll()) );
+ connect( m_writingModeWidget, SIGNAL(writingModeChanged(int)), this, SLOT(slotToggleAll()) );
+}
+
+
+void K3bMixedBurnDialog::setupSettingsPage()
+{
+ QWidget* w = new QWidget( this );
+
+ QGroupBox* groupDataMode = new QGroupBox( 1, Qt::Vertical, i18n("Datatrack Mode"), w );
+ m_dataModeWidget = new K3bDataModeWidget( groupDataMode );
+
+ QGroupBox* groupNormalize = new QGroupBox( 1, Qt::Vertical, i18n("Misc"), w );
+ m_checkNormalize = K3bStdGuiItems::normalizeCheckBox( groupNormalize );
+
+ QGroupBox* groupMixedType = new QGroupBox( 1, Qt::Vertical, i18n("Mixed Mode Type"), w );
+ m_comboMixedModeType = new K3bIntMapComboBox( groupMixedType );
+
+ m_comboMixedModeType->insertItem( K3bMixedDoc::DATA_SECOND_SESSION,
+ i18n("Data in second session (CD-Extra)"),
+ i18n("<em>Blue book CD</em>"
+ "<br>K3b will create a multisession CD with "
+ "2 sessions. The first session will contain all "
+ "audio tracks and the second session will contain "
+ "a mode 2 form 1 data track."
+ "<br>This mode is based on the <em>Blue book</em> "
+ "standard (also known as <em>Extended Audio CD</em>, "
+ "<em>CD-Extra</em>, or <em>CD Plus</em>) "
+ "and has the advantage that a hifi audio "
+ "CD player will only recognize the first session "
+ "and ignore the second session with the data track."
+ "<br>If the CD is intended to be used in a hifi audio CD player "
+ "this is the recommended mode."
+ "<br>Some older CD-ROMs may have problems reading "
+ "a blue book CD since it is a multisession CD.") );
+ m_comboMixedModeType->insertItem( K3bMixedDoc::DATA_FIRST_TRACK,
+ i18n("Data in first track"),
+ i18n("K3b will write the data track before all "
+ "audio tracks.") );
+ m_comboMixedModeType->insertItem( K3bMixedDoc::DATA_LAST_TRACK,
+ i18n("Data in last track"),
+ i18n("K3b will write the data track after all "
+ "audio tracks.") );
+ m_comboMixedModeType->addGlobalWhatsThisText( QString(),
+ i18n("<b>Caution:</b> The last two modes should only be used for CDs that are unlikely to "
+ "be played on a hifi audio CD player."
+ "<br>It could lead to problems with some older "
+ "hifi audio CD players that try to play the data track.") );
+
+ QGridLayout* grid = new QGridLayout( w );
+ grid->setMargin( marginHint() );
+ grid->setSpacing( spacingHint() );
+ grid->addWidget( groupMixedType, 0, 0 );
+ grid->addWidget( groupDataMode, 1, 0 );
+ grid->addWidget( groupNormalize, 2, 0 );
+ grid->setRowStretch( 3, 1 );
+
+ addPage( w, i18n("Misc") );
+}
+
+
+void K3bMixedBurnDialog::slotStartClicked()
+{
+ // FIXME: this should not be done via the doc. So remove all gui stuff from the doc
+ static_cast<K3bMixedView*>(m_doc->view())->player()->stop();
+ K3bProjectBurnDialog::slotStartClicked();
+}
+
+
+void K3bMixedBurnDialog::saveSettings()
+{
+ K3bProjectBurnDialog::saveSettings();
+
+ m_doc->setMixedType( (K3bMixedDoc::MixedType)m_comboMixedModeType->selectedValue() );
+
+ m_cdtextWidget->save( m_doc->audioDoc() );
+
+ m_doc->audioDoc()->setNormalize( m_checkNormalize->isChecked() );
+
+ // save iso image settings
+ K3bIsoOptions o = m_doc->dataDoc()->isoOptions();
+ m_imageSettingsWidget->save( o );
+ m_doc->dataDoc()->setIsoOptions( o );
+
+ m_doc->dataDoc()->setDataMode( m_dataModeWidget->dataMode() );
+
+ // save image file path
+ m_doc->setTempDir( m_tempDirSelectionWidget->tempPath() );
+}
+
+
+void K3bMixedBurnDialog::readSettings()
+{
+ K3bProjectBurnDialog::readSettings();
+
+ m_checkNormalize->setChecked( m_doc->audioDoc()->normalize() );
+
+ if( !m_doc->tempDir().isEmpty() )
+ m_tempDirSelectionWidget->setTempPath( m_doc->tempDir() );
+
+ m_comboMixedModeType->setSelectedValue( m_doc->mixedType() );
+
+ m_cdtextWidget->load( m_doc->audioDoc() );
+
+ m_imageSettingsWidget->load( m_doc->dataDoc()->isoOptions() );
+
+ m_dataModeWidget->setDataMode( m_doc->dataDoc()->dataMode() );
+
+ toggleAll();
+}
+
+
+void K3bMixedBurnDialog::loadK3bDefaults()
+{
+ K3bProjectBurnDialog::loadK3bDefaults();
+
+ m_cdtextWidget->setChecked( false );
+ m_checkNormalize->setChecked( false );
+
+ m_comboMixedModeType->setSelectedValue( K3bMixedDoc::DATA_SECOND_SESSION );
+
+ m_dataModeWidget->setDataMode( K3b::DATA_MODE_AUTO );
+
+ m_imageSettingsWidget->load( K3bIsoOptions::defaults() );
+
+ toggleAll();
+}
+
+
+void K3bMixedBurnDialog::loadUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::loadUserDefaults( c );
+
+ m_cdtextWidget->setChecked( c->readBoolEntry( "cd_text", false ) );
+ m_checkNormalize->setChecked( c->readBoolEntry( "normalize", false ) );
+
+ // load mixed type
+ if( c->readEntry( "mixed_type" ) == "last_track" )
+ m_comboMixedModeType->setSelectedValue( K3bMixedDoc::DATA_LAST_TRACK );
+ else if( c->readEntry( "mixed_type" ) == "first_track" )
+ m_comboMixedModeType->setSelectedValue( K3bMixedDoc::DATA_FIRST_TRACK );
+ else
+ m_comboMixedModeType->setSelectedValue( K3bMixedDoc::DATA_SECOND_SESSION );
+
+ m_dataModeWidget->loadConfig(c);
+
+ K3bIsoOptions o = K3bIsoOptions::load( c );
+ m_imageSettingsWidget->load( o );
+
+ toggleAll();
+}
+
+
+void K3bMixedBurnDialog::saveUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::saveUserDefaults(c);
+
+ c->writeEntry( "cd_text", m_cdtextWidget->isChecked() );
+ c->writeEntry( "normalize", m_checkNormalize->isChecked() );
+
+ // save mixed type
+ switch( m_comboMixedModeType->selectedValue() ) {
+ case K3bMixedDoc::DATA_LAST_TRACK:
+ c->writeEntry( "mixed_type", "last_track" );
+ break;
+ case K3bMixedDoc::DATA_FIRST_TRACK:
+ c->writeEntry( "mixed_type", "first_track" );
+ break;
+ default:
+ c->writeEntry( "mixed_type", "second_session" );
+ }
+
+ m_dataModeWidget->saveConfig(c);
+
+ K3bIsoOptions o;
+ m_imageSettingsWidget->save( o );
+ o.save( c );
+
+ if( m_tempDirSelectionWidget->isEnabled() ) {
+ m_tempDirSelectionWidget->saveConfig();
+ }
+}
+
+
+void K3bMixedBurnDialog::toggleAll()
+{
+ K3bProjectBurnDialog::toggleAll();
+
+ bool cdrecordOnTheFly = false;
+ bool cdrecordCdText = false;
+ if ( k3bcore->externalBinManager()->binObject("cdrecord") ) {
+ cdrecordOnTheFly = k3bcore->externalBinManager()->binObject("cdrecord")->hasFeature( "audio-stdin" );
+ cdrecordCdText = k3bcore->externalBinManager()->binObject("cdrecord")->hasFeature( "cdtext" );
+ }
+
+ // cdrdao always knows onthefly and cdtext
+ bool onTheFly = true;
+ bool cdText = true;
+ if( m_writingModeWidget->writingMode() == K3b::TAO ||
+ m_writingModeWidget->writingMode() == K3b::RAW ||
+ m_writerSelectionWidget->writingApp() == K3b::CDRECORD ) {
+ onTheFly = cdrecordOnTheFly;
+ cdText = cdrecordCdText;
+ }
+
+ m_checkCacheImage->setEnabled( !m_checkOnlyCreateImage->isChecked() &&
+ onTheFly );
+ if( !onTheFly )
+ m_checkCacheImage->setChecked( true );
+
+ m_cdtextWidget->setEnabled( !m_checkOnlyCreateImage->isChecked() &&
+ cdText &&
+ m_writingModeWidget->writingMode() != K3b::TAO );
+ if( !cdText || m_writingModeWidget->writingMode() == K3b::TAO )
+ m_cdtextWidget->setChecked( false );
+}
+
+
+void K3bMixedBurnDialog::slotNormalizeToggled( bool on )
+{
+ if( on ) {
+ // we are not able to normalize in on-the-fly mode
+ if( !k3bcore->externalBinManager()->foundBin( "normalize" ) ) {
+ KMessageBox::sorry( this, i18n("<p><b>External program <em>normalize-audio</em> is not installed.</b>"
+ "<p>K3b uses <em>normalize-audio</em> (http://www1.cs.columbia.edu/~cvaill/normalize/) "
+ "to normalize audio tracks. In order to "
+ "use this functionality, please install it first (sudo apt-get install normalize-audio.") );
+ m_checkNormalize->setChecked( false );
+ }
+ else if( !m_checkCacheImage->isChecked() && !m_checkOnlyCreateImage->isChecked() ) {
+ if( KMessageBox::warningYesNo( this, i18n("<p>K3b is not able to normalize audio tracks when burning on-the-fly. "
+ "The external program used for this task only supports normalizing a set "
+ "of audio files."),
+ QString::null,
+ i18n("Disable normalization"),
+ i18n("Disable on-the-fly burning"),
+ "audioProjectNormalizeOrOnTheFly" ) == KMessageBox::Yes )
+ m_checkNormalize->setChecked( false );
+ else
+ m_checkCacheImage->setChecked( true );
+ }
+ }
+}
+
+
+void K3bMixedBurnDialog::slotCacheImageToggled( bool on )
+{
+ if( on ) {
+ if( m_checkNormalize->isChecked() ) {
+ if( KMessageBox::warningYesNo( this, i18n("<p>K3b is not able to normalize audio tracks when burning on-the-fly. "
+ "The external program used for this task only supports normalizing a set "
+ "of audio files."),
+ QString::null,
+ i18n("Disable normalization"),
+ i18n("Disable on-the-fly burning"),
+ "audioProjectNormalizeOrOnTheFly" ) == KMessageBox::Yes )
+ m_checkNormalize->setChecked( false );
+ else
+ m_checkCacheImage->setChecked( true );
+ }
+ }
+}
+
+
+#include "k3bmixedburndialog.moc"
+
diff --git a/src/projects/k3bmixedburndialog.h b/src/projects/k3bmixedburndialog.h
new file mode 100644
index 0000000..363d26e
--- /dev/null
+++ b/src/projects/k3bmixedburndialog.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * $Id: k3bmixedburndialog.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 K3BMIXEDBURNDIALOG_H
+#define K3BMIXEDBURNDIALOG_H
+
+#include "k3bprojectburndialog.h"
+
+class QCheckBox;
+class K3bWriterSelectionWidget;
+class K3bTempDirSelectionWidget;
+class K3bMixedDoc;
+class K3bDataImageSettingsWidget;
+class QButtonGroup;
+class QRadioButton;
+class K3bAudioCdTextWidget;
+class K3bDataModeWidget;
+class K3bIntMapComboBox;
+
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bMixedBurnDialog : public K3bProjectBurnDialog
+{
+ Q_OBJECT
+
+ public:
+ K3bMixedBurnDialog( K3bMixedDoc*, QWidget *parent=0, const char *name=0, bool modal = true );
+
+ protected:
+ void loadK3bDefaults();
+ void loadUserDefaults( KConfigBase* );
+ void saveUserDefaults( KConfigBase* );
+ void toggleAll();
+
+ K3bDataImageSettingsWidget* m_imageSettingsWidget;
+ K3bAudioCdTextWidget* m_cdtextWidget;
+
+ protected slots:
+ /**
+ * Reimplemented for internal reasons (shut down the audio player)
+ */
+ void slotStartClicked();
+ void saveSettings();
+ void readSettings();
+
+ void slotCacheImageToggled( bool on );
+ void slotNormalizeToggled( bool on );
+
+ private:
+ void setupSettingsPage();
+ K3bMixedDoc* m_doc;
+
+ K3bIntMapComboBox* m_comboMixedModeType;
+ QRadioButton* m_radioMixedTypeFirstTrack;
+ QRadioButton* m_radioMixedTypeLastTrack;
+ QRadioButton* m_radioMixedTypeSessions;
+
+ QCheckBox* m_checkNormalize;
+
+ K3bDataModeWidget* m_dataModeWidget;
+};
+
+#endif
diff --git a/src/projects/k3bmixeddirtreeview.cpp b/src/projects/k3bmixeddirtreeview.cpp
new file mode 100644
index 0000000..50d818a
--- /dev/null
+++ b/src/projects/k3bmixeddirtreeview.cpp
@@ -0,0 +1,103 @@
+/*
+ *
+ * $Id: k3bmixeddirtreeview.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 "k3bmixeddirtreeview.h"
+
+#include "k3bmixeddoc.h"
+#include "k3baudiotrackaddingdialog.h"
+#include <k3blistview.h>
+#include <k3baudiodoc.h>
+#include <k3bdataviewitem.h>
+
+#include <qevent.h>
+
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <kurldrag.h>
+#include <klocale.h>
+
+
+class K3bMixedDirTreeView::PrivateAudioRootViewItem : public K3bListViewItem
+{
+public:
+ PrivateAudioRootViewItem( K3bMixedDoc* doc, QListView* parent, QListViewItem* after )
+ : K3bListViewItem( parent, after ),
+ m_doc(doc)
+ {
+ setPixmap( 0, SmallIcon("sound") );
+ }
+
+ QString text( int col ) const {
+ if( col == 0 )
+ return i18n("Audio Tracks") + QString(" (%1)").arg(m_doc->audioDoc()->numOfTracks());
+ else
+ return QString::null;
+ }
+
+ private:
+ K3bMixedDoc* m_doc;
+};
+
+
+K3bMixedDirTreeView::K3bMixedDirTreeView( K3bView* view, K3bMixedDoc* doc, QWidget* parent, const char* )
+ : K3bDataDirTreeView( view, doc->dataDoc(), parent ), m_doc(doc)
+{
+ m_audioRootItem = new PrivateAudioRootViewItem( doc, this, root() );
+
+ connect( this, SIGNAL(selectionChanged(QListViewItem*)),
+ this, SLOT(slotSelectionChanged(QListViewItem*)) );
+ connect( m_doc->audioDoc(), SIGNAL(changed()), this, SLOT(slotNewAudioTracks()) );
+}
+
+
+K3bMixedDirTreeView::~K3bMixedDirTreeView()
+{
+}
+
+
+void K3bMixedDirTreeView::slotDropped( QDropEvent* e, QListViewItem* parent, QListViewItem* after )
+{
+ if( !e->isAccepted() )
+ return;
+
+ QListViewItem* droppedItem = itemAt(e->pos());
+ if( droppedItem == m_audioRootItem ) {
+ KURL::List urls;
+ if( KURLDrag::decode( e, urls ) ) {
+ K3bAudioTrackAddingDialog::addUrls( urls, m_doc->audioDoc(), 0, 0, 0, this );
+ }
+ }
+ else
+ K3bDataDirTreeView::slotDropped( e, parent, after );
+}
+
+
+void K3bMixedDirTreeView::slotSelectionChanged( QListViewItem* i )
+{
+ if( i == m_audioRootItem )
+ emit audioTreeSelected();
+ else
+ emit dataTreeSelected();
+}
+
+
+void K3bMixedDirTreeView::slotNewAudioTracks()
+{
+ // update the tracknumber
+ m_audioRootItem->repaint();
+}
+
+#include "k3bmixeddirtreeview.moc"
diff --git a/src/projects/k3bmixeddirtreeview.h b/src/projects/k3bmixeddirtreeview.h
new file mode 100644
index 0000000..8a8bfe9
--- /dev/null
+++ b/src/projects/k3bmixeddirtreeview.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * $Id: k3bmixeddirtreeview.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_MIXED_DIRTREEVIEW_H_
+#define _K3B_MIXED_DIRTREEVIEW_H_
+
+#include <k3bdatadirtreeview.h>
+
+class K3bView;
+class K3bMixedDoc;
+class QDropEvent;
+class QListViewItem;
+
+
+class K3bMixedDirTreeView : public K3bDataDirTreeView
+{
+ Q_OBJECT
+
+ public:
+ K3bMixedDirTreeView( K3bView* view, K3bMixedDoc* doc, QWidget* parent = 0, const char* name = 0 );
+ ~K3bMixedDirTreeView();
+
+ signals:
+ void audioTreeSelected();
+ void dataTreeSelected();
+
+ protected slots:
+ void slotDropped( QDropEvent* e, QListViewItem* after, QListViewItem* parent );
+
+ private slots:
+ void slotSelectionChanged( QListViewItem* i );
+ void slotNewAudioTracks();
+
+ private:
+ K3bMixedDoc* m_doc;
+
+ class PrivateAudioRootViewItem;
+ PrivateAudioRootViewItem* m_audioRootItem;
+};
+
+
+#endif
diff --git a/src/projects/k3bmixedview.cpp b/src/projects/k3bmixedview.cpp
new file mode 100644
index 0000000..68900c7
--- /dev/null
+++ b/src/projects/k3bmixedview.cpp
@@ -0,0 +1,155 @@
+/*
+ *
+ * $Id: k3bmixedview.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 "k3bmixedview.h"
+
+#include "k3bmixeddoc.h"
+#include "k3bmixedburndialog.h"
+#include "k3bmixeddirtreeview.h"
+#include "k3baudiotrackaddingdialog.h"
+#include "k3bdataurladdingdialog.h"
+
+#include <k3baudiotrackplayer.h>
+#include <k3baudiodoc.h>
+#include <k3bdataviewitem.h>
+#include <k3bdatafileview.h>
+#include <k3bdatadoc.h>
+#include <k3baudiotrackview.h>
+#include <k3bfillstatusdisplay.h>
+#include <k3btoolbox.h>
+#include <k3bprojectplugin.h>
+
+#include <qwidgetstack.h>
+#include <qsplitter.h>
+#include <qlayout.h>
+#include <qvaluelist.h>
+
+#include <kdialog.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kactionclasses.h>
+
+
+K3bMixedView::K3bMixedView( K3bMixedDoc* doc, QWidget* parent, const char* name )
+ : K3bView( doc, parent, name ), m_doc(doc)
+{
+ QSplitter* splitter = new QSplitter( this );
+ m_mixedDirTreeView = new K3bMixedDirTreeView( this, doc, splitter );
+ m_widgetStack = new QWidgetStack( splitter );
+ m_dataFileView = new K3bDataFileView( this, m_mixedDirTreeView, doc->dataDoc(), m_widgetStack );
+ m_mixedDirTreeView->setFileView( m_dataFileView );
+ m_audioListView = new K3bAudioTrackView( doc->audioDoc(), m_widgetStack );
+
+ setMainWidget( splitter );
+
+ connect( m_mixedDirTreeView, SIGNAL(audioTreeSelected()),
+ this, SLOT(slotAudioTreeSelected()) );
+ connect( m_mixedDirTreeView, SIGNAL(dataTreeSelected()),
+ this, SLOT(slotDataTreeSelected()) );
+
+ m_widgetStack->raiseWidget( m_dataFileView );
+
+ toolBox()->addButton( m_audioListView->player()->action( K3bAudioTrackPlayer::ACTION_PLAY ) );
+ toolBox()->addButton( m_audioListView->player()->action( K3bAudioTrackPlayer::ACTION_PAUSE ) );
+ toolBox()->addButton( m_audioListView->player()->action( K3bAudioTrackPlayer::ACTION_STOP ) );
+ toolBox()->addSpacing();
+ toolBox()->addButton( m_audioListView->player()->action( K3bAudioTrackPlayer::ACTION_PREV ) );
+ toolBox()->addButton( m_audioListView->player()->action( K3bAudioTrackPlayer::ACTION_NEXT ) );
+ toolBox()->addSpacing();
+ toolBox()->addWidgetAction( static_cast<KWidgetAction*>(m_audioListView->player()->action( K3bAudioTrackPlayer::ACTION_SEEK )) );
+ toolBox()->addSeparator();
+
+#ifdef HAVE_MUSICBRAINZ
+ toolBox()->addButton( m_audioListView->actionCollection()->action( "project_audio_musicbrainz" ) );
+ toolBox()->addSeparator();
+#endif
+
+ addPluginButtons( K3bProjectPlugin::MIXED_CD );
+
+ toolBox()->addStretch();
+
+ m_mixedDirTreeView->checkForNewItems();
+ m_dataFileView->checkForNewItems();
+}
+
+
+K3bMixedView::~K3bMixedView()
+{
+}
+
+
+K3bAudioTrackPlayer* K3bMixedView::player() const
+{
+ return m_audioListView->player();
+}
+
+
+void K3bMixedView::slotAudioTreeSelected()
+{
+ m_widgetStack->raiseWidget( m_audioListView );
+}
+
+
+void K3bMixedView::slotDataTreeSelected()
+{
+ m_widgetStack->raiseWidget( m_dataFileView );
+}
+
+
+K3bDirItem* K3bMixedView::currentDir() const
+{
+ if( m_widgetStack->visibleWidget() == m_dataFileView )
+ return m_dataFileView->currentDir();
+ else
+ return 0;
+}
+
+
+void K3bMixedView::slotBurn()
+{
+ if( m_doc->audioDoc()->numOfTracks() == 0 || m_doc->dataDoc()->size() == 0 ) {
+ KMessageBox::information( this, i18n("Please add files and audio titles to your project first."),
+ i18n("No Data to Burn"), QString::null, false );
+ }
+ else {
+ K3bProjectBurnDialog* dlg = newBurnDialog( this );
+ if( dlg ) {
+ dlg->execBurnDialog(true);
+ delete dlg;
+ }
+ else {
+ kdDebug() << "(K3bDoc) Error: no burndialog available." << endl;
+ }
+ }
+}
+
+
+K3bProjectBurnDialog* K3bMixedView::newBurnDialog( QWidget* parent, const char* name )
+{
+ return new K3bMixedBurnDialog( m_doc, parent, name, true );
+}
+
+
+void K3bMixedView::addUrls( const KURL::List& urls )
+{
+ if( m_widgetStack->visibleWidget() == m_dataFileView )
+ K3bDataUrlAddingDialog::addUrls( urls, currentDir() );
+ else
+ K3bAudioTrackAddingDialog::addUrls( urls, m_doc->audioDoc(), 0, 0, 0, this );
+}
+
+#include "k3bmixedview.moc"
diff --git a/src/projects/k3bmixedview.h b/src/projects/k3bmixedview.h
new file mode 100644
index 0000000..8e52df7
--- /dev/null
+++ b/src/projects/k3bmixedview.h
@@ -0,0 +1,66 @@
+/*
+ *
+ * $Id: k3bmixedview.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_MIXED_VIEW_H
+#define K3B_MIXED_VIEW_H
+
+#include <k3bview.h>
+
+#include <kurl.h>
+
+class K3bMixedDoc;
+class QWidgetStack;
+class K3bDataFileView;
+class K3bMixedDirTreeView;
+class K3bAudioTrackView;
+class QListViewItem;
+class K3bDirItem;
+class K3bAudioTrackPlayer;
+
+
+class K3bMixedView : public K3bView
+{
+ Q_OBJECT
+
+ public:
+ K3bMixedView( K3bMixedDoc* doc, QWidget* parent = 0, const char* name = 0 );
+ ~K3bMixedView();
+
+ K3bDirItem* currentDir() const;
+
+ K3bAudioTrackPlayer* player() const;
+
+ public slots:
+ void slotBurn();
+ void addUrls( const KURL::List& );
+
+ protected:
+ K3bProjectBurnDialog* newBurnDialog( QWidget* parent = 0, const char* name = 0 );
+
+ private slots:
+ void slotAudioTreeSelected();
+ void slotDataTreeSelected();
+
+ private:
+ K3bMixedDoc* m_doc;
+
+ QWidgetStack* m_widgetStack;
+
+ K3bMixedDirTreeView* m_mixedDirTreeView;
+ K3bDataFileView* m_dataFileView;
+ K3bAudioTrackView* m_audioListView;
+};
+
+#endif
diff --git a/src/projects/k3bmovixburndialog.cpp b/src/projects/k3bmovixburndialog.cpp
new file mode 100644
index 0000000..94238a7
--- /dev/null
+++ b/src/projects/k3bmovixburndialog.cpp
@@ -0,0 +1,265 @@
+/*
+ *
+ * $Id: k3bmovixburndialog.cpp 690207 2007-07-20 10:40:19Z 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 "k3bmovixburndialog.h"
+#include "k3bmovixdoc.h"
+#include "k3bmovixprogram.h"
+#include "k3bmovixoptionswidget.h"
+
+#include <k3bdataimagesettingswidget.h>
+#include <k3bexternalbinmanager.h>
+#include <k3bwriterselectionwidget.h>
+#include <k3btempdirselectionwidget.h>
+#include <k3bstdguiitems.h>
+#include <k3bglobals.h>
+#include <k3bdatamodewidget.h>
+#include <k3bisooptions.h>
+#include <k3bwritingmodewidget.h>
+#include <k3bcore.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kio/global.h>
+#include <kapplication.h>
+#include <kconfig.h>
+
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qfileinfo.h>
+
+
+K3bMovixBurnDialog::K3bMovixBurnDialog( K3bMovixDoc* doc, QWidget* parent, const char* name, bool modal )
+ : K3bProjectBurnDialog( doc, parent, name, modal ),
+ m_doc(doc)
+{
+ prepareGui();
+
+ m_tempDirSelectionWidget->setSelectionMode( K3bTempDirSelectionWidget::FILE );
+
+ setTitle( i18n("eMovix CD Project"),
+ i18n("1 file (%1)", "%n files (%1)", m_doc->movixFileItems().count()).arg(KIO::convertSize(m_doc->size())) );
+
+ m_movixOptionsWidget = new K3bMovixOptionsWidget( this );
+ addPage( m_movixOptionsWidget, i18n("eMovix") );
+
+ // create image settings tab
+ m_imageSettingsWidget = new K3bDataImageSettingsWidget( this );
+ addPage( m_imageSettingsWidget, i18n("Filesystem") );
+
+ setupSettingsPage();
+
+ // for now we just put the verify checkbox on the main page...
+ m_checkVerify = K3bStdGuiItems::verifyCheckBox( m_optionGroup );
+ m_optionGroupLayout->addWidget( m_checkVerify );
+
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ m_optionGroupLayout->addItem( spacer );
+
+ m_tempDirSelectionWidget->setSelectionMode( K3bTempDirSelectionWidget::FILE );
+ QString path = m_doc->tempDir();
+ if( !path.isEmpty() ) {
+ m_tempDirSelectionWidget->setTempPath( path );
+ }
+ if( !m_doc->isoOptions().volumeID().isEmpty() ) {
+ m_tempDirSelectionWidget->setDefaultImageFileName( m_doc->isoOptions().volumeID() + ".iso" );
+ }
+
+ connect( m_imageSettingsWidget->m_editVolumeName, SIGNAL(textChanged(const QString&)),
+ m_tempDirSelectionWidget, SLOT(setDefaultImageFileName(const QString&)) );
+}
+
+
+K3bMovixBurnDialog::~K3bMovixBurnDialog()
+{
+}
+
+
+void K3bMovixBurnDialog::setupSettingsPage()
+{
+ QWidget* frame = new QWidget( this );
+ QGridLayout* frameLayout = new QGridLayout( frame );
+ frameLayout->setSpacing( spacingHint() );
+ frameLayout->setMargin( marginHint() );
+
+ QGroupBox* groupDataMode = new QGroupBox( 1, Qt::Vertical, i18n("Datatrack Mode"), frame );
+ m_dataModeWidget = new K3bDataModeWidget( groupDataMode );
+
+ QGroupBox* groupMultisession = new QGroupBox( 1, Qt::Vertical, i18n("Multisession"), frame );
+ m_checkStartMultiSesssion = K3bStdGuiItems::startMultisessionCheckBox( groupMultisession );
+
+ frameLayout->addWidget( groupDataMode, 0, 0 );
+ frameLayout->addWidget( groupMultisession, 1, 0 );
+ frameLayout->setRowStretch( 2, 1 );
+
+ addPage( frame, i18n("Misc") );
+}
+
+
+void K3bMovixBurnDialog::loadK3bDefaults()
+{
+ K3bProjectBurnDialog::loadK3bDefaults();
+
+ m_checkStartMultiSesssion->setChecked( false );
+ m_dataModeWidget->setDataMode( K3b::DATA_MODE_AUTO );
+
+ m_imageSettingsWidget->load( K3bIsoOptions::defaults() );
+
+ m_movixOptionsWidget->loadDefaults();
+
+ m_checkVerify->setChecked( false );
+
+ toggleAll();
+}
+
+
+void K3bMovixBurnDialog::loadUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::loadUserDefaults(c);
+
+ m_checkStartMultiSesssion->setChecked( c->readBoolEntry( "start_multisession", false ) );
+
+ m_dataModeWidget->loadConfig(c);
+
+ K3bIsoOptions o = K3bIsoOptions::load( c );
+ m_imageSettingsWidget->load( o );
+
+ m_movixOptionsWidget->loadConfig(c);
+
+ m_checkVerify->setChecked( c->readBoolEntry( "verify data", false ) );
+
+ toggleAll();
+}
+
+
+void K3bMovixBurnDialog::saveUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::saveUserDefaults(c);
+
+ c->writeEntry( "start_multisession", m_checkStartMultiSesssion->isChecked() );
+
+ m_dataModeWidget->saveConfig(c);
+
+ K3bIsoOptions o;
+ m_imageSettingsWidget->save( o );
+ o.save( c );
+
+ c->writeEntry( "verify data", m_checkVerify->isChecked() );
+
+ m_movixOptionsWidget->saveConfig(c);
+}
+
+
+void K3bMovixBurnDialog::saveSettings()
+{
+ K3bProjectBurnDialog::saveSettings();
+
+ m_movixOptionsWidget->saveSettings( m_doc );
+
+ m_doc->setMultiSessionMode( m_checkStartMultiSesssion->isChecked() ? K3bDataDoc::START : K3bDataDoc::NONE );
+
+ // save iso image settings
+ K3bIsoOptions o = m_doc->isoOptions();
+ m_imageSettingsWidget->save( o );
+ m_doc->setIsoOptions( o );
+
+ m_doc->setDataMode( m_dataModeWidget->dataMode() );
+
+ // save image file path
+ m_doc->setTempDir( m_tempDirSelectionWidget->tempPath() );
+
+ m_doc->setVerifyData( m_checkVerify->isChecked() );
+}
+
+
+void K3bMovixBurnDialog::readSettings()
+{
+ K3bProjectBurnDialog::readSettings();
+
+ m_checkStartMultiSesssion->setChecked( m_doc->multiSessionMode() == K3bDataDoc::START );
+
+ m_checkVerify->setChecked( m_doc->verifyData() );
+
+ m_imageSettingsWidget->load( m_doc->isoOptions() );
+
+ m_dataModeWidget->setDataMode( m_doc->dataMode() );
+
+ if( !doc()->tempDir().isEmpty() )
+ m_tempDirSelectionWidget->setTempPath( doc()->tempDir() );
+ else
+ m_tempDirSelectionWidget->setTempPath( K3b::defaultTempPath() + doc()->name() + ".iso" );
+
+ // first of all we need a movix installation object
+ const K3bMovixBin* bin = dynamic_cast<const K3bMovixBin*>( k3bcore->externalBinManager()->binObject("eMovix") );
+ if( bin ) {
+ m_movixOptionsWidget->init( bin );
+ m_movixOptionsWidget->readSettings( m_doc );
+ }
+ else {
+ KMessageBox::error( this, i18n("Could not find a valid eMovix installation.") );
+ slotCancelClicked();
+ }
+}
+
+
+void K3bMovixBurnDialog::slotStartClicked()
+{
+ if( m_checkOnlyCreateImage->isChecked() ||
+ m_checkCacheImage->isChecked() ) {
+ QFileInfo fi( m_tempDirSelectionWidget->tempPath() );
+ if( fi.isDir() )
+ m_tempDirSelectionWidget->setTempPath( fi.filePath() + "/image.iso" );
+
+ if( QFile::exists( m_tempDirSelectionWidget->tempPath() ) ) {
+ if( KMessageBox::warningContinueCancel( this,
+ i18n("Do you want to overwrite %1?").arg(m_tempDirSelectionWidget->tempPath()),
+ i18n("File Exists"), i18n("Overwrite") )
+ != KMessageBox::Continue )
+ return;
+ }
+ }
+
+ if( m_writingModeWidget->writingMode() == K3b::DAO &&
+ m_checkStartMultiSesssion->isChecked() &&
+ m_writerSelectionWidget->writingApp() == K3b::CDRECORD )
+ if( KMessageBox::warningContinueCancel( this,
+ i18n("Most writers do not support writing "
+ "multisession CDs in DAO mode.") )
+ == KMessageBox::Cancel )
+ return;
+
+
+ K3bProjectBurnDialog::slotStartClicked();
+}
+
+
+void K3bMovixBurnDialog::toggleAll()
+{
+ K3bProjectBurnDialog::toggleAll();
+
+ if( m_checkSimulate->isChecked() || m_checkOnlyCreateImage->isChecked() ) {
+ m_checkVerify->setChecked(false);
+ m_checkVerify->setEnabled(false);
+ }
+ else
+ m_checkVerify->setEnabled(true);
+
+ m_dataModeWidget->setDisabled( m_checkOnlyCreateImage->isChecked() );
+ m_checkStartMultiSesssion->setDisabled( m_checkOnlyCreateImage->isChecked() );
+}
+
+#include "k3bmovixburndialog.moc"
diff --git a/src/projects/k3bmovixburndialog.h b/src/projects/k3bmovixburndialog.h
new file mode 100644
index 0000000..ff237c0
--- /dev/null
+++ b/src/projects/k3bmovixburndialog.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * $Id: k3bmovixburndialog.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_MOVIX_BURN_DIALOG_H_
+#define _K3B_MOVIX_BURN_DIALOG_H_
+
+#include "k3bprojectburndialog.h"
+
+class K3bMovixDoc;
+class K3bMovixOptionsWidget;
+class K3bDataImageSettingsWidget;
+class QCheckBox;
+class K3bDataModeWidget;
+
+
+class K3bMovixBurnDialog : public K3bProjectBurnDialog
+{
+ Q_OBJECT
+
+ public:
+ K3bMovixBurnDialog( K3bMovixDoc* doc, QWidget* parent = 0, const char* name = 0, bool modal = true );
+ ~K3bMovixBurnDialog();
+
+ protected slots:
+ void slotStartClicked();
+
+ protected:
+ void saveSettings();
+ void readSettings();
+ void loadK3bDefaults();
+ void loadUserDefaults( KConfigBase* );
+ void saveUserDefaults( KConfigBase* );
+ void toggleAll();
+
+ private:
+ void setupSettingsPage();
+
+ K3bMovixDoc* m_doc;
+ K3bMovixOptionsWidget* m_movixOptionsWidget;
+ K3bDataImageSettingsWidget* m_imageSettingsWidget;
+
+ QCheckBox* m_checkStartMultiSesssion;
+ K3bDataModeWidget* m_dataModeWidget;
+
+ QCheckBox* m_checkVerify;
+};
+
+
+#endif
+
diff --git a/src/projects/k3bmovixdvdburndialog.cpp b/src/projects/k3bmovixdvdburndialog.cpp
new file mode 100644
index 0000000..3707e3a
--- /dev/null
+++ b/src/projects/k3bmovixdvdburndialog.cpp
@@ -0,0 +1,219 @@
+/*
+ *
+ * $Id: k3bmovixdvdburndialog.cpp 690207 2007-07-20 10:40:19Z 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 "k3bmovixdvdburndialog.h"
+#include "k3bmovixdvddoc.h"
+
+#include <k3bmovixprogram.h>
+#include <k3bmovixoptionswidget.h>
+
+#include <k3bdataimagesettingswidget.h>
+#include <k3bexternalbinmanager.h>
+#include <k3bwriterselectionwidget.h>
+#include <k3btempdirselectionwidget.h>
+#include <k3bstdguiitems.h>
+#include <k3bglobals.h>
+#include <k3bdatamodewidget.h>
+#include <k3bisooptions.h>
+#include <k3bwritingmodewidget.h>
+#include <k3bcore.h>
+#include <k3bglobalsettings.h>
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kio/global.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qfileinfo.h>
+
+
+K3bMovixDvdBurnDialog::K3bMovixDvdBurnDialog( K3bMovixDvdDoc* doc, QWidget* parent, const char* name, bool modal )
+ : K3bProjectBurnDialog( doc, parent, name, modal, true ),
+ m_doc(doc)
+{
+ prepareGui();
+
+ m_tempDirSelectionWidget->setSelectionMode( K3bTempDirSelectionWidget::FILE );
+
+ setTitle( i18n("eMovix DVD Project"),
+ i18n("1 file (%1)", "%n files (%1)", m_doc->movixFileItems().count()).arg(KIO::convertSize(m_doc->size())) );
+
+ m_movixOptionsWidget = new K3bMovixOptionsWidget( this );
+ addPage( m_movixOptionsWidget, i18n("eMovix") );
+
+ // create image settings tab
+ m_imageSettingsWidget = new K3bDataImageSettingsWidget( this );
+ addPage( m_imageSettingsWidget, i18n("Filesystem") );
+
+ // for now we just put the verify checkbox on the main page...
+ m_checkVerify = K3bStdGuiItems::verifyCheckBox( m_optionGroup );
+ m_optionGroupLayout->addWidget( m_checkVerify );
+
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ m_optionGroupLayout->addItem( spacer );
+
+ m_tempDirSelectionWidget->setSelectionMode( K3bTempDirSelectionWidget::FILE );
+ QString path = m_doc->tempDir();
+ if( !path.isEmpty() ) {
+ m_tempDirSelectionWidget->setTempPath( path );
+ }
+ if( !m_doc->isoOptions().volumeID().isEmpty() ) {
+ m_tempDirSelectionWidget->setDefaultImageFileName( m_doc->isoOptions().volumeID() + ".iso" );
+ }
+
+ connect( m_imageSettingsWidget->m_editVolumeName, SIGNAL(textChanged(const QString&)),
+ m_tempDirSelectionWidget, SLOT(setDefaultImageFileName(const QString&)) );
+}
+
+
+K3bMovixDvdBurnDialog::~K3bMovixDvdBurnDialog()
+{
+}
+
+
+void K3bMovixDvdBurnDialog::loadK3bDefaults()
+{
+ K3bProjectBurnDialog::loadK3bDefaults();
+
+ m_imageSettingsWidget->load( K3bIsoOptions::defaults() );
+
+ m_movixOptionsWidget->loadDefaults();
+
+ m_checkVerify->setChecked( false );
+
+ toggleAll();
+}
+
+
+void K3bMovixDvdBurnDialog::loadUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::loadUserDefaults(c);
+
+ K3bIsoOptions o = K3bIsoOptions::load( c );
+ m_imageSettingsWidget->load( o );
+
+ m_movixOptionsWidget->loadConfig(c);
+
+ m_checkVerify->setChecked( c->readBoolEntry( "verify data", false ) );
+
+ toggleAll();
+}
+
+
+void K3bMovixDvdBurnDialog::saveUserDefaults( KConfigBase* c )
+{
+ K3bProjectBurnDialog::saveUserDefaults(c);
+
+ K3bIsoOptions o;
+ m_imageSettingsWidget->save( o );
+ o.save( c );
+
+ c->writeEntry( "verify data", m_checkVerify->isChecked() );
+
+ m_movixOptionsWidget->saveConfig(c);
+}
+
+
+void K3bMovixDvdBurnDialog::saveSettings()
+{
+ K3bProjectBurnDialog::saveSettings();
+
+ m_movixOptionsWidget->saveSettings( m_doc );
+
+ // save iso image settings
+ K3bIsoOptions o = m_doc->isoOptions();
+ m_imageSettingsWidget->save( o );
+ m_doc->setIsoOptions( o );
+
+ m_doc->setVerifyData( m_checkVerify->isChecked() );
+
+ // save image file path
+ m_doc->setTempDir( m_tempDirSelectionWidget->tempPath() );
+}
+
+
+void K3bMovixDvdBurnDialog::readSettings()
+{
+ K3bProjectBurnDialog::readSettings();
+
+ m_imageSettingsWidget->load( m_doc->isoOptions() );
+
+ m_checkVerify->setChecked( m_doc->verifyData() );
+
+ if( !doc()->tempDir().isEmpty() )
+ m_tempDirSelectionWidget->setTempPath( doc()->tempDir() );
+ else
+ m_tempDirSelectionWidget->setTempPath( K3b::defaultTempPath() + doc()->name() + ".iso" );
+
+ // first of all we need a movix installation object
+ const K3bMovixBin* bin = dynamic_cast<const K3bMovixBin*>( k3bcore->externalBinManager()->binObject("eMovix") );
+ if( bin ) {
+ m_movixOptionsWidget->init( bin );
+ m_movixOptionsWidget->readSettings( m_doc );
+ }
+ else {
+ KMessageBox::error( this, i18n("Could not find a valid eMovix installation.") );
+ slotCancelClicked();
+ }
+
+ if( doc()->size() > 4700372992LL &&
+ ( !k3bcore->globalSettings()->overburn() ||
+ doc()->size() > 4900000000LL ) )
+ m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_DVD_DL );
+ else
+ m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_DVD );
+}
+
+
+void K3bMovixDvdBurnDialog::slotStartClicked()
+{
+ if( m_checkOnlyCreateImage->isChecked() ||
+ m_checkCacheImage->isChecked() ) {
+ QFileInfo fi( m_tempDirSelectionWidget->tempPath() );
+ if( fi.isDir() )
+ m_tempDirSelectionWidget->setTempPath( fi.filePath() + "/image.iso" );
+
+ if( QFile::exists( m_tempDirSelectionWidget->tempPath() ) ) {
+ if( KMessageBox::warningContinueCancel( this,
+ i18n("Do you want to overwrite %1?").arg(m_tempDirSelectionWidget->tempPath()),
+ i18n("File Exists"), i18n("Overwrite") )
+ != KMessageBox::Continue )
+ return;
+ }
+ }
+
+ K3bProjectBurnDialog::slotStartClicked();
+}
+
+
+void K3bMovixDvdBurnDialog::toggleAll()
+{
+ K3bProjectBurnDialog::toggleAll();
+
+ if( m_checkSimulate->isChecked() || m_checkOnlyCreateImage->isChecked() ) {
+ m_checkVerify->setChecked(false);
+ m_checkVerify->setEnabled(false);
+ }
+ else
+ m_checkVerify->setEnabled(true);
+}
+
+#include "k3bmovixdvdburndialog.moc"
diff --git a/src/projects/k3bmovixdvdburndialog.h b/src/projects/k3bmovixdvdburndialog.h
new file mode 100644
index 0000000..df7b456
--- /dev/null
+++ b/src/projects/k3bmovixdvdburndialog.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * $Id: k3bmovixdvdburndialog.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_MOVIX_DVD_BURN_DIALOG_H_
+#define _K3B_MOVIX_DVD_BURN_DIALOG_H_
+
+#include "k3bprojectburndialog.h"
+
+class K3bMovixDvdDoc;
+class K3bMovixOptionsWidget;
+class K3bDataImageSettingsWidget;
+class QCheckBox;
+
+
+class K3bMovixDvdBurnDialog : public K3bProjectBurnDialog
+{
+ Q_OBJECT
+
+ public:
+ K3bMovixDvdBurnDialog( K3bMovixDvdDoc* doc, QWidget* parent = 0, const char* name = 0, bool modal = true );
+ ~K3bMovixDvdBurnDialog();
+
+ protected slots:
+ void slotStartClicked();
+
+ protected:
+ void saveSettings();
+ void readSettings();
+ void loadK3bDefaults();
+ void loadUserDefaults( KConfigBase* );
+ void saveUserDefaults( KConfigBase* );
+ void toggleAll();
+
+ private:
+ K3bMovixDvdDoc* m_doc;
+ K3bMovixOptionsWidget* m_movixOptionsWidget;
+ K3bDataImageSettingsWidget* m_imageSettingsWidget;
+
+ QCheckBox* m_checkVerify;
+};
+
+#endif
+
diff --git a/src/projects/k3bmovixdvdview.cpp b/src/projects/k3bmovixdvdview.cpp
new file mode 100644
index 0000000..8173199
--- /dev/null
+++ b/src/projects/k3bmovixdvdview.cpp
@@ -0,0 +1,48 @@
+/*
+ *
+ * $Id: k3bmovixdvdview.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 "k3bmovixdvdview.h"
+#include "k3bmovixdvddoc.h"
+#include "k3bmovixdvdburndialog.h"
+#include <k3bmovixlistview.h>
+#include <k3bfillstatusdisplay.h>
+
+#include <klocale.h>
+
+
+K3bMovixDvdView::K3bMovixDvdView( K3bMovixDvdDoc* doc, QWidget *parent, const char *name )
+ : K3bMovixView( doc, parent, name )
+{
+ m_doc = doc;
+
+ fillStatusDisplay()->showDvdSizes(true);
+
+ m_listView->setNoItemText( i18n("Use drag'n'drop to add files to the project.") +"\n"
+ + i18n("To remove or rename files use the context menu.") + "\n"
+ + i18n("After that press the burn button to write the DVD.") );
+}
+
+
+K3bMovixDvdView::~K3bMovixDvdView()
+{
+}
+
+
+K3bProjectBurnDialog* K3bMovixDvdView::newBurnDialog( QWidget* parent, const char* name )
+{
+ return new K3bMovixDvdBurnDialog( m_doc, parent, name, true );
+}
+
+#include "k3bmovixdvdview.moc"
diff --git a/src/projects/k3bmovixdvdview.h b/src/projects/k3bmovixdvdview.h
new file mode 100644
index 0000000..643b259
--- /dev/null
+++ b/src/projects/k3bmovixdvdview.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * $Id: k3bmovixdvdview.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_MOVIX_DVD_VIEW_H_
+#define _K3B_MOVIX_DVD_VIEW_H_
+
+#include <k3bmovixview.h>
+
+class K3bMovixDvdDoc;
+
+
+class K3bMovixDvdView : public K3bMovixView
+{
+ Q_OBJECT
+
+ public:
+ K3bMovixDvdView( K3bMovixDvdDoc* doc, QWidget *parent = 0, const char *name = 0 );
+ ~K3bMovixDvdView();
+
+ protected:
+ K3bProjectBurnDialog* newBurnDialog( QWidget* parent = 0, const char* name = 0 );
+
+ private:
+ K3bMovixDvdDoc* m_doc;
+};
+
+#endif
diff --git a/src/projects/k3bmovixlistview.cpp b/src/projects/k3bmovixlistview.cpp
new file mode 100644
index 0000000..9b943d3
--- /dev/null
+++ b/src/projects/k3bmovixlistview.cpp
@@ -0,0 +1,327 @@
+/*
+ *
+ * $Id: k3bmovixlistview.cpp 628165 2007-01-29 11:01:22Z 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 "k3bmovixlistview.h"
+#include "k3bmovixdoc.h"
+#include "k3bmovixfileitem.h"
+#include <k3bdiritem.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kio/global.h>
+#include <kurldrag.h>
+
+#include <qdragobject.h>
+#include <qptrlist.h>
+#include <qevent.h>
+#include <qheader.h>
+
+
+K3bMovixListViewItem::K3bMovixListViewItem( K3bMovixDoc* doc,
+ K3bMovixFileItem* item,
+ QListView* parent,
+ QListViewItem* after )
+ : K3bListViewItem( parent, after ),
+ m_doc(doc),
+ m_fileItem(item)
+{
+}
+
+
+K3bMovixListViewItem::K3bMovixListViewItem( K3bMovixDoc* doc,
+ K3bMovixFileItem* item,
+ QListViewItem* parent )
+ : K3bListViewItem( parent ),
+ m_doc(doc),
+ m_fileItem(item)
+{
+}
+
+
+K3bMovixListViewItem::~K3bMovixListViewItem()
+{
+}
+
+
+K3bMovixFileViewItem::K3bMovixFileViewItem( K3bMovixDoc* doc,
+ K3bMovixFileItem* item,
+ QListView* parent,
+ QListViewItem* after )
+ : K3bMovixListViewItem( doc, item, parent, after ),
+ KFileItem( 0, 0, KURL::fromPathOrURL(item->localPath()) )
+{
+ setPixmap( 1, KFileItem::pixmap( 16, KIcon::DefaultState ) );
+ setEditor( 1, LINE );
+}
+
+
+QString K3bMovixFileViewItem::text( int col ) const
+{
+ //
+ // We add two spaces after all strings (except the once renamable)
+ // to increase readability
+ //
+
+ switch( col ) {
+ case 0:
+ // allowing 999 files to be added.
+ return QString::number( doc()->indexOf( fileItem() ) ).rightJustify( 3, ' ' );
+ case 1:
+ return fileItem()->k3bName();
+ case 2:
+ {
+ if( fileItem()->isSymLink() )
+ return i18n("Link to %1").arg(const_cast<K3bMovixFileViewItem*>(this)->mimeComment()) + " ";
+ else
+ return const_cast<K3bMovixFileViewItem*>(this)->mimeComment() + " ";
+ }
+ case 3:
+ return KIO::convertSize( fileItem()->size() ) + " ";
+ case 4:
+ return fileItem()->localPath() + " ";
+ case 5:
+ return ( fileItem()->isValid() ? fileItem()->linkDest() : fileItem()->linkDest() + i18n(" (broken)") );
+ default:
+ return "";
+ }
+}
+
+
+void K3bMovixFileViewItem::setText( int col, const QString& text )
+{
+ if( col == 1 )
+ fileItem()->setK3bName( text );
+
+ K3bMovixListViewItem::setText( col, text );
+}
+
+
+QString K3bMovixFileViewItem::key( int, bool ) const
+{
+ return QString::number( doc()->indexOf( fileItem() ) ).rightJustify( 10, '0' );
+}
+
+
+
+
+K3bMovixSubTitleViewItem::K3bMovixSubTitleViewItem( K3bMovixDoc* doc,
+ K3bMovixFileItem* item,
+ K3bMovixListViewItem* parent )
+ : K3bMovixListViewItem( doc, item, parent ),
+ KFileItem( 0, 0, KURL::fromPathOrURL(item->subTitleItem()->localPath()) )
+{
+}
+
+
+K3bMovixSubTitleViewItem::~K3bMovixSubTitleViewItem()
+{
+}
+
+
+QString K3bMovixSubTitleViewItem::text( int c ) const
+{
+ switch( c ) {
+ case 1:
+ return fileItem()->subTitleItem()->k3bName();
+ case 2:
+ {
+ if( fileItem()->subTitleItem()->isSymLink() )
+ return i18n("Link to %1").arg(const_cast<K3bMovixSubTitleViewItem*>(this)->mimeComment());
+ else
+ return const_cast<K3bMovixSubTitleViewItem*>(this)->mimeComment();
+ }
+ case 3:
+ return KIO::convertSize( fileItem()->subTitleItem()->size() );
+ case 4:
+ return fileItem()->subTitleItem()->localPath();
+ case 5:
+ return ( fileItem()->subTitleItem()->isValid() ?
+ fileItem()->subTitleItem()->linkDest() :
+ fileItem()->subTitleItem()->linkDest() + i18n(" (broken)") );
+ default:
+ return "";
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+K3bMovixListView::K3bMovixListView( K3bMovixDoc* doc, QWidget* parent, const char* name )
+ : K3bListView( parent, name ),
+ m_doc(doc)
+{
+ addColumn( i18n("No.") );
+ addColumn( i18n("Name") );
+ addColumn( i18n("Type") );
+ addColumn( i18n("Size") );
+ addColumn( i18n("Local Path") );
+ addColumn( i18n("Link") );
+
+ setAcceptDrops( true );
+ setDropVisualizer( true );
+ setAllColumnsShowFocus( true );
+ setDragEnabled( true );
+ setItemsMovable( false );
+ setSelectionModeExt( KListView::Extended );
+ setSorting(0);
+
+ setNoItemText( i18n("Use drag'n'drop to add files to the project.") +"\n"
+ + i18n("To remove or rename files use the context menu.") + "\n"
+ + i18n("After that press the burn button to write the CD.") );
+
+ connect( m_doc, SIGNAL(changed()), this, SLOT(slotChanged()) );
+ connect( m_doc, SIGNAL(newMovixFileItems()), this, SLOT(slotNewFileItems()) );
+ connect( m_doc, SIGNAL(movixItemRemoved(K3bMovixFileItem*)), this, SLOT(slotFileItemRemoved(K3bMovixFileItem*)) );
+ connect( m_doc, SIGNAL(subTitleItemRemoved(K3bMovixFileItem*)), this, SLOT(slotSubTitleItemRemoved(K3bMovixFileItem*)) );
+ connect( this, SIGNAL(dropped(KListView*, QDropEvent*, QListViewItem*)),
+ this, SLOT(slotDropped(KListView*, QDropEvent*, QListViewItem*)) );
+
+ // let's see what the doc already has
+ slotNewFileItems();
+ slotChanged();
+}
+
+
+K3bMovixListView::~K3bMovixListView()
+{
+}
+
+
+bool K3bMovixListView::acceptDrag(QDropEvent* e) const
+{
+ // the first is for built-in item moving, the second for dropping urls
+ return ( K3bListView::acceptDrag(e) || KURLDrag::canDecode(e) );
+}
+
+
+void K3bMovixListView::slotNewFileItems()
+{
+ K3bMovixFileItem* lastItem = 0;
+ for( QPtrListIterator<K3bMovixFileItem> it( m_doc->movixFileItems() ); it.current(); ++it ) {
+ K3bMovixFileItem* item = it.current();
+ if( !m_itemMap.contains( item ) )
+ m_itemMap.insert( item, new K3bMovixFileViewItem( m_doc, item, this, lastItem ? m_itemMap[lastItem] : 0L ) );
+
+ if( item->subTitleItem() ) {
+ K3bMovixFileViewItem* vi = m_itemMap[item];
+ if( vi->childCount() <= 0 ) {
+ (void)new K3bMovixSubTitleViewItem( m_doc, item, vi );
+ vi->setOpen(true);
+ }
+ }
+
+ lastItem = item;
+ }
+
+ // arghhh
+ sort();
+}
+
+
+void K3bMovixListView::slotFileItemRemoved( K3bMovixFileItem* item )
+{
+ if( m_itemMap.contains( item ) ) {
+ K3bMovixFileViewItem* vi = m_itemMap[item];
+ m_itemMap.erase(item);
+ delete vi;
+ }
+}
+
+
+void K3bMovixListView::slotSubTitleItemRemoved( K3bMovixFileItem* item )
+{
+ if( m_itemMap.contains( item ) ) {
+ K3bMovixFileViewItem* vi = m_itemMap[item];
+ if( vi->childCount() >= 1 )
+ delete vi->firstChild();
+ }
+}
+
+
+void K3bMovixListView::slotDropped( KListView*, QDropEvent* e, QListViewItem* after )
+{
+ if( !e->isAccepted() )
+ return;
+
+ int pos;
+ if( after == 0L )
+ pos = 0;
+ else
+ pos = m_doc->indexOf( ((K3bMovixListViewItem*)after)->fileItem() );
+
+ if( e->source() == viewport() ) {
+ QPtrList<QListViewItem> sel = selectedItems();
+ QPtrListIterator<QListViewItem> it(sel);
+ K3bMovixFileItem* itemAfter = ( after ? ((K3bMovixListViewItem*)after)->fileItem() : 0 );
+ while( it.current() ) {
+ K3bMovixListViewItem* vi = (K3bMovixListViewItem*)it.current();
+ if( vi->isMovixFileItem() ) {
+ K3bMovixFileItem* item = vi->fileItem();
+ m_doc->moveMovixItem( item, itemAfter );
+ itemAfter = item;
+ }
+ else
+ kdDebug() << "(K3bMovixListView) I don't move subtitle items!" << endl;
+
+ ++it;
+ }
+
+ sort(); // This is so lame!
+ }
+ else {
+ KURL::List urls;
+ KURLDrag::decode( e, urls );
+
+ for( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it ) {
+ m_doc->addMovixFile( *it, pos++ );
+ }
+ }
+
+ // now grab that focus
+ setFocus();
+}
+
+
+QDragObject* K3bMovixListView::dragObject()
+{
+ QPtrList<QListViewItem> list = selectedItems();
+
+ if( list.isEmpty() )
+ return 0;
+
+ QPtrListIterator<QListViewItem> it(list);
+ KURL::List urls;
+
+ for( ; it.current(); ++it )
+ urls.append( KURL( ((K3bMovixListViewItem*)it.current())->fileItem()->localPath() ) );
+
+ return KURLDrag::newDrag( urls, viewport() );
+}
+
+
+void K3bMovixListView::slotChanged()
+{
+ header()->setShown( m_doc->root()->numFiles() > 0 );
+}
+
+#include "k3bmovixlistview.moc"
diff --git a/src/projects/k3bmovixlistview.h b/src/projects/k3bmovixlistview.h
new file mode 100644
index 0000000..7426ddb
--- /dev/null
+++ b/src/projects/k3bmovixlistview.h
@@ -0,0 +1,100 @@
+/*
+ *
+ * $Id: k3bmovixlistview.h 628165 2007-01-29 11:01:22Z 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_MOVIX_LISTVIEW_H_
+#define _K3B_MOVIX_LISTVIEW_H_
+
+#include <k3blistview.h>
+#include <kfileitem.h>
+
+#include <qmap.h>
+
+
+class K3bMovixDoc;
+class K3bMovixFileItem;
+class K3bFileItem;
+
+
+class K3bMovixListViewItem : public K3bListViewItem
+{
+ public:
+ K3bMovixListViewItem( K3bMovixDoc* doc, K3bMovixFileItem*, QListView* parent, QListViewItem* after );
+ K3bMovixListViewItem( K3bMovixDoc* doc, K3bMovixFileItem*, QListViewItem* parent );
+ ~K3bMovixListViewItem();
+
+ K3bMovixFileItem* fileItem() const { return m_fileItem; }
+ K3bMovixDoc* doc() const { return m_doc; }
+
+ virtual bool isMovixFileItem() const { return true; }
+
+ private:
+ K3bMovixDoc* m_doc;
+ K3bMovixFileItem* m_fileItem;
+};
+
+
+class K3bMovixFileViewItem : public K3bMovixListViewItem, public KFileItem
+{
+ public:
+ K3bMovixFileViewItem( K3bMovixDoc* doc, K3bMovixFileItem*, QListView* parent, QListViewItem* );
+
+ QString text( int ) const;
+ void setText(int col, const QString& text );
+
+ /** always sort according to the playlist order */
+ QString key( int, bool ) const;
+};
+
+class K3bMovixSubTitleViewItem : public K3bMovixListViewItem, public KFileItem
+{
+ public:
+ K3bMovixSubTitleViewItem( K3bMovixDoc*, K3bMovixFileItem* item, K3bMovixListViewItem* parent );
+ ~K3bMovixSubTitleViewItem();
+
+ QString text( int ) const;
+
+ bool isMovixFileItem() const { return false; }
+};
+
+
+class K3bMovixListView : public K3bListView
+{
+ Q_OBJECT
+
+ public:
+ K3bMovixListView( K3bMovixDoc* doc, QWidget* parent = 0, const char* name = 0 );
+ ~K3bMovixListView();
+
+ QDragObject* dragObject();
+
+ protected:
+ bool acceptDrag(QDropEvent* e) const;
+
+ private slots:
+ void slotNewFileItems();
+ void slotFileItemRemoved( K3bMovixFileItem* );
+ void slotSubTitleItemRemoved( K3bMovixFileItem* );
+ void slotDropped( KListView*, QDropEvent* e, QListViewItem* after );
+ void slotChanged();
+
+ private:
+ K3bMovixDoc* m_doc;
+
+ QMap<K3bFileItem*, K3bMovixFileViewItem*> m_itemMap;
+};
+
+#endif
diff --git a/src/projects/k3bmovixoptionswidget.cpp b/src/projects/k3bmovixoptionswidget.cpp
new file mode 100644
index 0000000..131af6b
--- /dev/null
+++ b/src/projects/k3bmovixoptionswidget.cpp
@@ -0,0 +1,243 @@
+/*
+ *
+ * $Id: k3bmovixoptionswidget.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 "k3bmovixoptionswidget.h"
+#include "k3bmovixdoc.h"
+#include "k3bmovixprogram.h"
+
+#include <kcombobox.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kdebug.h>
+
+#include <qcheckbox.h>
+#include <qspinbox.h>
+#include <qstringlist.h>
+#include <qmap.h>
+#include <qlabel.h>
+
+
+class K3bMovixOptionsWidget::LanguageSelectionHelper
+{
+public:
+ LanguageSelectionHelper( QComboBox* box )
+ : m_box(box) {
+ }
+
+ void insertLanguages( const QStringList& langs ) {
+ m_box->clear();
+ m_langMap.clear();
+
+ for( QStringList::const_iterator it = langs.begin(); it != langs.end(); ++it ) {
+ if( *it == i18n("default") )
+ m_box->insertItem( *it );
+ else {
+ QString lang = KGlobal::locale()->twoAlphaToLanguageName( *it );
+ if( lang.isEmpty() )
+ lang = *it;
+
+ m_langMap[m_box->count()] = *it;
+ m_indexMap[*it] = m_box->count();
+ m_box->insertItem( lang );
+ }
+ }
+ }
+
+ QString selectedLanguage() const {
+ if( m_box->currentItem() == 0 )
+ return i18n("default");
+ else
+ return m_langMap[m_box->currentItem()];
+ }
+
+ void setLanguage( const QString& l ) {
+ QMap<QString,int>::const_iterator it = m_indexMap.find(l);
+ if( it == m_indexMap.end() )
+ m_box->setCurrentItem( 0 );
+ else
+ m_box->setCurrentItem( it.data() );
+ }
+
+private:
+ QComboBox* m_box;
+ QMap<int,QString> m_langMap;
+ QMap<QString,int> m_indexMap;
+};
+
+
+K3bMovixOptionsWidget::K3bMovixOptionsWidget( QWidget* parent, const char* name )
+ : base_K3bMovixOptionsWidget( parent, name )
+{
+ m_keyboardLangHelper = new LanguageSelectionHelper( m_comboKeyboardLayout );
+ m_helpLangHelper = new LanguageSelectionHelper( m_comboBootMessageLanguage );
+}
+
+
+K3bMovixOptionsWidget::~K3bMovixOptionsWidget()
+{
+ delete m_keyboardLangHelper;
+ delete m_helpLangHelper;
+}
+
+
+void K3bMovixOptionsWidget::init( const K3bMovixBin* bin )
+{
+ m_labelAudioBackground->setShown( bin->hasFeature( "newfiles" ) );
+ m_comboAudioBackground->setShown( bin->hasFeature( "newfiles" ) );
+ m_labelKeyboardLayout->setShown( bin->hasFeature( "newfiles" ) );
+ m_comboKeyboardLayout->setShown( bin->hasFeature( "newfiles" ) );
+
+ m_comboSubtitleFontset->insertStringList( bin->supportedSubtitleFonts() );
+ m_helpLangHelper->insertLanguages( bin->supportedLanguages() );
+ m_comboDefaultBootLabel->insertStringList( bin->supportedBootLabels() );
+ m_keyboardLangHelper->insertLanguages( bin->supportedKbdLayouts() );
+ m_comboAudioBackground->insertStringList( bin->supportedBackgrounds() );
+}
+
+
+void K3bMovixOptionsWidget::readSettings( K3bMovixDoc* doc )
+{
+ m_comboSubtitleFontset->setCurrentItem( doc->subtitleFontset(), false );
+ m_spinLoop->setValue( doc->loopPlaylist() );
+ m_editAdditionalMplayerOptions->setText( doc->additionalMPlayerOptions() );
+ m_editUnwantedMplayerOptions->setText( doc->unwantedMPlayerOptions() );
+ m_helpLangHelper->setLanguage( doc->bootMessageLanguage() );
+ m_comboDefaultBootLabel->setCurrentItem( doc->defaultBootLabel(), false );
+ m_comboAudioBackground->setCurrentItem( doc->audioBackground(), false );
+ m_keyboardLangHelper->setLanguage( doc->keyboardLayout() );
+ m_checkShutdown->setChecked( doc->shutdown() );
+ m_checkReboot->setChecked( doc->reboot() );
+ m_checkEject->setChecked( doc->ejectDisk() );
+ m_checkRandomPlay->setChecked( doc->randomPlay() );
+ m_checkNoDma->setChecked( doc->noDma() );
+}
+
+
+void K3bMovixOptionsWidget::saveSettings( K3bMovixDoc* doc )
+{
+ doc->setShutdown( m_checkShutdown->isChecked() );
+ doc->setReboot( m_checkReboot->isChecked() );
+ doc->setEjectDisk( m_checkEject->isChecked() );
+ doc->setSubtitleFontset( m_comboSubtitleFontset->currentText() );
+ doc->setBootMessageLanguage( m_helpLangHelper->selectedLanguage() );
+ doc->setDefaultBootLabel( m_comboDefaultBootLabel->currentText() );
+ doc->setKeyboardLayout( m_keyboardLangHelper->selectedLanguage() );
+ doc->setAudioBackground( m_comboAudioBackground->currentText() );
+ doc->setAdditionalMPlayerOptions( m_editAdditionalMplayerOptions->text() );
+ doc->setUnwantedMPlayerOptions( m_editUnwantedMplayerOptions->text() );
+ doc->setLoopPlaylist( m_spinLoop->value() );
+ doc->setRandomPlay( m_checkRandomPlay->isChecked() );
+ doc->setNoDma( m_checkNoDma->isChecked() );
+}
+
+
+void K3bMovixOptionsWidget::loadDefaults()
+{
+ m_comboSubtitleFontset->setCurrentItem( 0 ); // default
+ m_comboAudioBackground->setCurrentItem( 0 ); // default
+ m_comboKeyboardLayout->setCurrentItem( 0 ); // default
+ m_spinLoop->setValue( 1 );
+ m_editAdditionalMplayerOptions->setText( QString::null );
+ m_editUnwantedMplayerOptions->setText( QString::null );
+ m_comboBootMessageLanguage->setCurrentItem( 0 ); // default
+ m_comboDefaultBootLabel->setCurrentItem( 0 ); // default
+ m_checkShutdown->setChecked( false );
+ m_checkReboot->setChecked( false );
+ m_checkEject->setChecked( false );
+ m_checkRandomPlay->setChecked( false );
+ m_checkNoDma->setChecked( false );
+}
+
+
+void K3bMovixOptionsWidget::loadConfig( KConfigBase* c )
+{
+ QString s = c->readEntry("subtitle_fontset");
+ if( !s.isEmpty() && s != "none" && m_comboSubtitleFontset->contains(s) )
+ m_comboSubtitleFontset->setCurrentItem( s, false );
+ else
+ m_comboSubtitleFontset->setCurrentItem( 0 ); // none
+
+ m_spinLoop->setValue( c->readNumEntry("loop", 1 ) );
+ m_editAdditionalMplayerOptions->setText( c->readEntry( "additional_mplayer_options" ) );
+ m_editUnwantedMplayerOptions->setText( c->readEntry( "unwanted_mplayer_options" ) );
+
+ s = c->readEntry("boot_message_language");
+ m_helpLangHelper->setLanguage( s == "default" ? QString::null : s );
+
+ s = c->readEntry( "default_boot_label" );
+ if( !s.isEmpty() && s != "default" && m_comboDefaultBootLabel->contains(s) )
+ m_comboDefaultBootLabel->setCurrentItem( s, false );
+ else
+ m_comboDefaultBootLabel->setCurrentItem( 0 ); // default
+
+ s = c->readEntry("audio_background");
+ if( !s.isEmpty() && s != "default" && m_comboAudioBackground->contains(s) )
+ m_comboAudioBackground->setCurrentItem( s, false );
+ else
+ m_comboAudioBackground->setCurrentItem( 0 ); // default
+
+ s = c->readEntry("keyboard_layout");
+ m_keyboardLangHelper->setLanguage( s == "default" ? QString::null : s );
+
+ m_checkShutdown->setChecked( c->readBoolEntry( "shutdown", false) );
+ m_checkReboot->setChecked( c->readBoolEntry( "reboot", false ) );
+ m_checkEject->setChecked( c->readBoolEntry( "eject", false ) );
+ m_checkRandomPlay->setChecked( c->readBoolEntry( "random_play", false ) );
+ m_checkNoDma->setChecked( c->readBoolEntry( "no_dma", false ) );
+}
+
+
+void K3bMovixOptionsWidget::saveConfig( KConfigBase* c )
+{
+ if( m_comboSubtitleFontset->currentItem() == 0 )
+ c->writeEntry( "subtitle_fontset", "none" );
+ else
+ c->writeEntry( "subtitle_fontset", m_comboSubtitleFontset->currentText() );
+
+ c->writeEntry( "loop", m_spinLoop->value() );
+ c->writeEntry( "additional_mplayer_options", m_editAdditionalMplayerOptions->text() );
+ c->writeEntry( "unwanted_mplayer_options", m_editUnwantedMplayerOptions->text() );