summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--redhat/applications/compizconfig-backend-kconfig/trinity-compizconfig-backend-kconfig-3.5.12.spec90
-rw-r--r--redhat/applications/kradio/kradio-3.5.13.1-updated_preset.patch26417
-rw-r--r--redhat/applications/kradio/trinity-kradio-3.5.13.1.spec8
-rw-r--r--redhat/components-3.5.13.txt1
-rw-r--r--redhat/extras/kasablanca/trinity-kasablanca-3.5.13.1.spec1
-rw-r--r--redhat/extras/kdebluetooth/trinity-kdebluetooth.spec6
-rw-r--r--redhat/extras/theme-baghira/baghira-0.8.tar.bz2bin0 -> 916658 bytes
-rw-r--r--redhat/extras/theme-baghira/baghira-3.5.13.1-fix_ftbfs.patch140
-rw-r--r--redhat/extras/theme-baghira/theme-baghira.tar.gz0
-rw-r--r--redhat/extras/theme-baghira/trinity-theme-baghira.spec204
-rw-r--r--redhat/kdebase/kdebase-3.5.13.1-fix_startkde_path.patch107
-rw-r--r--redhat/kdebase/kdebase-3.5.13.1-fix_tdm_pid_file.patch11
-rw-r--r--redhat/kdebase/pamd.kcheckpass-trinity.pclos20125
-rw-r--r--redhat/kdebase/pamd.kdm-trinity-np.pclos20127
-rw-r--r--redhat/kdebase/pamd.kdm-trinity.pclos20128
-rw-r--r--redhat/kdebase/pamd.kscreensaver-trinity.pclos20125
-rw-r--r--redhat/kdebase/suse-displaymanagers-tdm21
-rw-r--r--redhat/kdebase/trinity-kdebase-3.5.13.1.spec24
-rw-r--r--redhat/kdelibs/kdelibs-3.5.13.1-disable_invalid_certificate_always_prompt.patch15
-rwxr-xr-xredhat/kdelibs/trinity-kdelibs-3.5.13.1.spec18
-rw-r--r--redhat/kdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch39683
-rw-r--r--redhat/kdesdk/kdesdk-3.5.13.1-fix_various_cmake_issues.patch159
22 files changed, 66922 insertions, 8 deletions
diff --git a/redhat/applications/compizconfig-backend-kconfig/trinity-compizconfig-backend-kconfig-3.5.12.spec b/redhat/applications/compizconfig-backend-kconfig/trinity-compizconfig-backend-kconfig-3.5.12.spec
new file mode 100644
index 000000000..c21e3fa98
--- /dev/null
+++ b/redhat/applications/compizconfig-backend-kconfig/trinity-compizconfig-backend-kconfig-3.5.12.spec
@@ -0,0 +1,90 @@
+# Default version for this component
+%if "%{?version}" == ""
+%define kdecomp compizconfig-backend-kconfig
+%define version 3.5.12
+%endif
+%define release 1
+
+# If TDE is built in a specific prefix (e.g. /opt/trinity), the release will be suffixed with ".opt".
+%if "%{?_prefix}" != "/usr"
+%define _variant .opt
+%define _docdir %{tde_prefix}/share/doc
+%endif
+
+# TDE 3.5.12 specific building variables
+BuildRequires: autoconf automake libtool m4
+%define tde_docdir %{_docdir}
+%define tde_libdir %{tde_libdir}/kde3
+
+
+Name: trinity-%{?kdecomp}
+Version: %{?version}
+Release: %{?release}%{?dist}%{?_variant}
+Vendor: Trinity Project
+Packager: Francois Andriot <francois.andriot@free.fr>
+Summary: kconfig backend for compizconfig
+
+Group: System Environment/Libraries
+License: GPLv2+
+URL: http://www.opencompositing.org
+
+Prefix: %{tde_prefix}
+
+Source0: %{kdecomp}-%{version}.tar.gz
+
+BuildRequires: tqtinterface-devel
+BuildRequires: trinity-tdelibs-devel
+BuildRequires: trinity-tdebase-devel
+BuildRequires: desktop-file-utils
+
+BuildRequires: libcompizconfig-devel intltool
+Requires: compiz
+
+
+%description
+The Compiz Fusion Project brings 3D desktop visual effects that improve
+usability of the X Window System and provide increased productivity
+through plugins and themes contributed by the community giving a
+rich desktop experience.
+
+This package contains the kconfig backend for libcompizconfig
+
+%prep
+%setup -q -n applications/%{kdecomp}
+
+%__cp "/usr/share/aclocal/libtool.m4" "admin/libtool.m4.in"
+%__cp "/usr/share/libtool/config/ltmain.sh" "admin/ltmain.sh"
+%__make -f admin/Makefile.common
+
+
+%build
+unset QTDIR || : ; . /etc/profile.d/qt.sh
+export PATH="%{tde_bindir}:${PATH}"
+export LDFLAGS="-L%{tde_libdir} -I%{tde_includedir}"
+
+%configure \
+ --with-extra-includes=%{tde_includedir}/tqt
+
+%__make %{?_smp_mflags}
+
+
+%install
+export PATH="%{tde_bindir}:${PATH}"
+%__rm -rf %{?buildroot}
+%make_install
+
+
+%clean
+%__rm -rf %{?buildroot}
+
+
+%files
+%defattr(-,root,root,-)
+%doc COPYING.GPL COPYING.LGPL
+%{_usr}/%{_lib}/compizconfig/backends/*.so
+%exclude %{_usr}/%{_lib}/compizconfig/backends/*.la
+
+%changelog
+* Tue Sep 06 2011 Francois Andriot <francois.andriot@free.fr> - 3.5.12-1
+- Initial package
+- Import to GIT
diff --git a/redhat/applications/kradio/kradio-3.5.13.1-updated_preset.patch b/redhat/applications/kradio/kradio-3.5.13.1-updated_preset.patch
new file mode 100644
index 000000000..fa36c7341
--- /dev/null
+++ b/redhat/applications/kradio/kradio-3.5.13.1-updated_preset.patch
@@ -0,0 +1,26417 @@
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/australia/Makefile.am kradio-3.5.13.1/kradio3/presets/australia/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/australia/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/australia/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -1,18 +1,19 @@
+ SUBDIRS =
+-EXTRA_DIST = "brisbane-antenna-2.krp" "brisbane-antenna.krp" "brisbane.krp" "sydney2.krp" "sydney.krp"
++EXTRA_DIST = "brisbane-antenna-2.krp" "brisbane-antenna.krp" "brisbane.krp" "melbourne-antenna.krp" "sydney2.krp" "sydney.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/"
++ $(INSTALL_DATA) "$(srcdir)/brisbane-antenna-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/brisbane-antenna-2.krp"
+ $(INSTALL_DATA) "$(srcdir)/brisbane-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/brisbane-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/brisbane.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/brisbane.krp"
+- $(INSTALL_DATA) "$(srcdir)/brisbane-antenna-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/brisbane-antenna-2.krp"
+- $(INSTALL_DATA) "$(srcdir)/sydney.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/sydney.krp"
++ $(INSTALL_DATA) "$(srcdir)/melbourne-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/melbourne-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/sydney2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/sydney2.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/sydney.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/sydney.krp"
+
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/brisbane-antenna-2.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/brisbane-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/brisbane.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/brisbane-antenna-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/sydney.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/melbourne-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/sydney2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/australia/sydney.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/australia/melbourne-antenna.krp kradio-3.5.13.1/kradio3/presets/australia/melbourne-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/australia/melbourne-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/australia/melbourne-antenna.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,161 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Peter D.
++&lt;p13@g-node.com.au&gt;</maintainer>
++ <changed>2007-12-12T17:01:51</changed>
++ <country>Australia</country>
++ <city>Melbourne</city>
++ <media>Antenna</media>
++ <comments>Radio Stations for Melbourne, Australia
++ Contains merged Data</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>11974366782D0E540F17C02C9C4E20988BCD2C0C7100B2FC5ED1319E83350C0E4C0563EF35</stationID>
++ <name>3LIGHT FM community</name>
++ <shortname>light</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>89.9252</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1197436698FF15BCA070FB6227B18EBB68B9715621C393D7AF82C80F67F6E80CAB666759EC</stationID>
++ <name>3SYN FM comminity</name>
++ <shortname>syn</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>90.7002</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1197436719C0EC401C5D0333A6E5B547782E8121B1901809FFD98F727201ADE6DB74303AE2</stationID>
++ <name>3VEGA FM</name>
++ <shortname>vega</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>91.5253</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1197436737017BC3859256567C06F74FC6AD3F7B1915F042A77FF112BED373F401AC4028B4</stationID>
++ <name>3ZZZ FM comminity</name>
++ <shortname>zzz</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>92.3003</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1197436756249596085B3207542A09E11A9C8C74ACB46070D13973A137F67B4136EE86C962</stationID>
++ <name>3SBS FM</name>
++ <shortname>sbs</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>93.1254</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1197436810A51A6903E91CFB581EF498645A805CD95387B9E149D05F4F5C0E57C69CFE6AB5</stationID>
++ <name>3GOLDEN DAY FM community</name>
++ <shortname>G&apos; Day</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>95.6755</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119743691153837110B029B161953DDE804D73EA2E5861F76E507D7DA97C4FAFF5BEC1C2ED</stationID>
++ <name>3NOVA FM</name>
++ <shortname>nova</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>100.326</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11974369293DC812D3A5A7BF790997A673EDAAEFEDD1A50135D09CEC74C0F2841593C9BBC8</stationID>
++ <name>3MIX FM</name>
++ <shortname>mix</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>101.101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1197436948238C94F5ED52E042F96B82ED364BFECD1DE876F7DB212F590ADDA1BEBC6D7FE3</stationID>
++ <name>3FOX FM</name>
++ <shortname>fox</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>101.926</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1197437931AB81E5CE2324D406F215FA19A0B8C1927CD558960CFD9313FBE47E47A749C011</stationID>
++ <name>3RRR FM</name>
++ <shortname>rrr</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>102.751</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11974379481316966853D5FF30386493899394FFC3B3A8FAE73B28F93DD5E7DBB61F8CAC3E</stationID>
++ <name>3MBS FM classical</name>
++ <shortname>mbs</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>103.476</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1197437004F27F07648029E5F0A761C4BBBF1408C189B69DCA872F9FDB68E6BCE1B3F8952A</stationID>
++ <name>3GOLD FM</name>
++ <shortname>gold</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>104.301</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11974370239B06749375C9E77BB6AC1CADEAC4566B123E8E0C903EE4B9DB0C00A192400277</stationID>
++ <name>3MMM FM</name>
++ <shortname>mmm</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>105.151</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11974370423878D22E02EDF44D97ACEC2419689134C4700903D136AF45C56CE08F7D3E1CFE</stationID>
++ <name>ABC FM classical</name>
++ <shortname>abc classic</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>105.926</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119743706068B59CCAFF4E0462729EE829A55E3311AD32AEFFEF1067064919CCBD6AD1C465</stationID>
++ <name>3PBS FM community</name>
++ <shortname>pbs</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>106.701</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11974380497211583134DCDBC719C69479C5454C567A662FA3CC75A2EC69DECB6C4D440E7E</stationID>
++ <name>3JJJ FM</name>
++ <shortname>jjj</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>107.526</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/belarus/brest.krp kradio-3.5.13.1/kradio3/presets/belarus/brest.krp
+--- kradio-3.5.13.1/kradio3/presets.old/belarus/brest.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/belarus/brest.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,258 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.1-rc1</creator>
++ <maintainer>Blaze</maintainer>
++ <changed>2010-08-08T09:00:13</changed>
++ <country>Belarus</country>
++ <city>Brest</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1207729347B95CF236E42587F6871F53D00304A13643B98948622764D589238FDFE6F550A1</stationID>
++ <name>Першы нацыянальны</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>70.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>120772620854C001667C47982987BFB58FF2B485A2C828F99A875C28AD6C2A5FC61D587D2B</stationID>
++ <name>Культура</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>71.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207726041C55D9585D3A616D7E90CDB8AB1B343638DA19EFFB7DC7557602C2D76F312A07F</stationID>
++ <name>радыё Сталiца</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>72.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207725781B1CE695E03A103A33EA30C2AEE33B4FDB5757DAF907F0964F5A1EA23C553A8AD</stationID>
++ <name>radio 1 Polska</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1195418551882952DFC8A3913F8D3C68504C0E93BF72377B5CD67E045D20F27280F00F25E1</stationID>
++ <name>Культура</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11954185650FE254953641925E551685E06E70EAD8660CF8C010FF4B5446BAFB8FB597D918</stationID>
++ <name>radio 3 Polska</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1194713996F0E7E992470C24D4CE8060E398D7B24CF79C675808B56A957BA315E32BA9D3A2</stationID>
++ <name>RMF FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1194713863838DF5C3D87638EA1BC0C2F69C8A18EBEC793462C87EB1097DDDB0DC02663030</stationID>
++ <name>Новое радио</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.8004</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1194713867D9F544C68EE0C5E183652BAB20149AB9DD906EE04173894C48A482E29C744AB5</stationID>
++ <name>radio Belarus</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12077294984C448D1D756B4422108C36E16C7249BF7B2ABEFA33119A5CB5BAEE6C417DAB58</stationID>
++ <name>радыё Рацыя</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207687158AC1EFA6C9DD0FFFCEB20D5C4A1422DB3DB9EAA460E874326A65D4A9D1CC34C3E</stationID>
++ <name>Першы нацыянальны</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.9998</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128051385121F1B431D096F125FCAF235ECCA45C414ABE8DC64C8F2E3D0A41A4C9A843</stationID>
++ <name>радио Минск</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1227190558E55550FD0D68E6DDC089D3DFF7FB85A40F0D37900E0680BF1A78667166E99C21</stationID>
++ <name>Альфа радио</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1202244062D3B1BD6E67E93C3D3186F73B8AE89D4FCCD9E3ECDD51E328F65036A365381747</stationID>
++ <name>радио Рокс</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.201</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207729844804970DB985A067502CCD04CDB8CF67CDE973A3AC5C311998F80CA6212141C2D</stationID>
++ <name>radio Podlaśia</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1202244168B63FB1467284BF12B788C73B54412EA827276731841EA311E5DB412E3D67CA73</stationID>
++ <name>Unistar</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12171720541E9003C323E0451C23BA71BA9F04DA8800CD68AFCD2F7ECCD5D5D1DA9609C3D2</stationID>
++ <name>radio 2 Polska</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1202245059AE9EBED37F3B7BA219E0733F6FEA9A2D2E4CE4A9D006BFC4723557997AF0D836</stationID>
++ <name>Pilot fm</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1202292997527C0FCFE4DA7276A2330178ECA3662FAF3EA3011796C416CABF38144D1033D2</stationID>
++ <name>Radio dla ćiebię</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>120224528899157BF6DA7064D0D1325986522D67E3DB3D58B772CA8BF58F0EA566FE32BD74</stationID>
++ <name>Радиус fm</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1217172241D354DFEB01909925C0A8B485DBB22A3CC748619A388FF492F225D71D178C9C51</stationID>
++ <name>radio 3 Polska</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12171722879ACB44A1C2A18FFC543900D4F9C57067C662618247DD7BB7EE8FBC35FFAB0BB9</stationID>
++ <name>radio Maria</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1202245826D98B15CBF4743EBD4AC7C3244B952B551AB6CBBE876309603D97FFED2F1D5F05</stationID>
++ <name>радио Брест</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1194714022A97BEC079991179A7F6AB786705AB0DF6B834ED0C23B271D19E19CD7D702EF35</stationID>
++ <name>radio Zet</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1194714205A5F11E788B848B143CFA9E2350F74BD56902514359C51CD39AC07D1FC0FD786A</stationID>
++ <name>радио &quot;ba&quot;</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1281248050E5DD39785E5EFE11D82C9436E6AA3A48E0F6D1B19CF029CF43EAA6922846</stationID>
++ <name>радио Мир</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>121717241561F47D14C239BC8C669D47D567F9F82EF98251001C54207E8DD9AB2177D5D58E</stationID>
++ <name>radio Maria</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.7</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/belarus/Makefile.am kradio-3.5.13.1/kradio3/presets/belarus/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/belarus/Makefile.am 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/belarus/Makefile.am 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,9 @@
++SUBDIRS =
++EXTRA_DIST = "brest.krp"
++
++install-data-local:
++ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/belarus/"
++ $(INSTALL_DATA) "$(srcdir)/brest.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/belarus/brest.krp"
++
++uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/belarus/brest.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/belgium/antwerpen-antenna.krp kradio-3.5.13.1/kradio3/presets/belgium/antwerpen-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/belgium/antwerpen-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/belgium/antwerpen-antenna.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,133 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer></maintainer>
++ <changed>2008-05-01T21:00:03</changed>
++ <country>Belgium</country>
++ <city>Antwerpen</city>
++ <media>Antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1209668864D2A04359F84AB8D3733E1CCF1279310F0493587FB93BF7F74A854DC9EE0557BC</stationID>
++ <name>VRT Radio 1</name>
++ <shortname>Radio 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12096688808089E6109077979C4D5922F72F137891BE7D38EDB299D525C158F7327D572466</stationID>
++ <name>VRT Radio 2</name>
++ <shortname>Radio 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120966879513F8100817BD88AA03A7C918008327682640E59AD2246DBBED22C6DB52078977</stationID>
++ <name>VRT Radio Klara</name>
++ <shortname>Klara</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120966874819E4357D2D5E93338F402C2507FFEBCA071AB41A30CC5F896C6952354A73E2B3</stationID>
++ <name>VRT Radio Donna</name>
++ <shortname>Donna</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1209668807766DF511EEBD78100CFC98FEEEBA67E6406CDCC92F0A81653F9A0C095C98C7FB</stationID>
++ <name>VRT Studio Brussel</name>
++ <shortname>StuBru</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120966871597D85D822EE8C9D809E676A272FC62AC0E3F341DB79144F45C256253BA386310</stationID>
++ <name>Q-Music</name>
++ <shortname>Q-Music</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12096693197B8AC6F5BEF2CADB6CE975EA1905FC7A036C26B395D8F124021E86496E3E5C31</stationID>
++ <name>4FM</name>
++ <shortname>4FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120966910628654CADD557C4BD8BD8F1562939C077433F6221B369C63BE717942C856647D7</stationID>
++ <name>Radio Minerva</name>
++ <shortname>Minerva</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120966920982AE695B3C21D74EDB282A0D8BF32564BFFDD15F67D640AF26D2AD24DD74329B</stationID>
++ <name>Radio Nostalgie</name>
++ <shortname>Nostalgie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1209669397A89F41C973ECA289106883F6D088775F413EC43F9682C7AA854800F994C25DEA</stationID>
++ <name>Crooze FM</name>
++ <shortname>Crooze FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1209669501A71E45127C44908BA58078E5F433C86E1A50E77981BDB0E7961CFCAF66B6BEFC</stationID>
++ <name>Be One</name>
++ <shortname>Be One</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12096695556FC4775E17AE0D976314928CB5B8097E33C695491B12A46CBD634F996C11376F</stationID>
++ <name>Cool FM Antwerpen</name>
++ <shortname>Cool FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120966965615DC568C10D8100275FBAB0E32892335B8627A158E0EFEBBBF6CDFE608D03FB3</stationID>
++ <name>Radio Echo (TOPRadio)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.3</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/belgium/bilzen.krp kradio-3.5.13.1/kradio3/presets/belgium/bilzen.krp
+--- kradio-3.5.13.1/kradio3/presets.old/belgium/bilzen.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/belgium/bilzen.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,205 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Roeland Moors</maintainer>
++ <changed>2008-07-05T14:57:10</changed>
++ <country>Belgie</country>
++ <city>Bilzen</city>
++ <media></media>
++ <comments> Contains merged Data</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1082619533D0EF312578B2C12F4D76EE3E45054110BED5B081ABF144AEAE7E0E23E51FCEB6</stationID>
++ <name>Radio1 (VRT)</name>
++ <shortname>Radio1 (VRT)</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>94.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>121526266366A4F91967AAFD7340DFA2354AB1E0B0953070B481BD60DE45EB158429D9CE11</stationID>
++ <name>Radio2 (VRT)</name>
++ <shortname>Radio2 (VRT)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1215262732B6CFFDFD9EE3DDA03BC69D81B3607BEE359C5782A6C5CF2600670A3476067C19</stationID>
++ <name>Donna (VRT)</name>
++ <shortname>Donna (VRT)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1215262778F380B95C0963A856E4BCA4758D380E971B58C807E61054FED586B5697679FC06</stationID>
++ <name>Studio Brussel (VRT)</name>
++ <shortname>Stubru (VRT)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152628270707ED8F73E3365F315BF3F0197030E52CAE0AA84042712972E9FA0CC9C77D0A</stationID>
++ <name>Radio Vlaanderen Internationaal (VRT)</name>
++ <shortname>RVI (VRT)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1215262923ED9EC63654C6B06E16F90402F226CF58E3DCD28F8955F98C8379907DA2BD3547</stationID>
++ <name>Klara (VRT)</name>
++ <shortname>Klara (VRT)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>121526295602E09EEAB3D203004C4EFF337334F8F2CD1F5EB215BD3B9CE0C2D15CB1380E0A</stationID>
++ <name>Radio1 (NL)</name>
++ <shortname>Radio1 (NL)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152630627C3408C0B9033C392BDBCDDCF6DDD41503B56474238AD1B7888BF535D0D327F0</stationID>
++ <name>Radio2 (NL)</name>
++ <shortname>Radio2 (NL)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152635620BF54DC6411AD7AC204ECF8D99A6C6539146C49BFDF75E9363996EC938AB9302</stationID>
++ <name>Radio3 (NL)</name>
++ <shortname>Radio3 (NL)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1215263237792D55D9D3007EC6934A83E8A91906B3A011C9E11CD71882074A1F2CBF4F07EE</stationID>
++ <name>Radio4 (NL)</name>
++ <shortname>Radio4 (NL)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152633215918E45416B70B36915C5447EF08FC2D698B1ADBB26FFDBE0E8B8C4BA60617C9</stationID>
++ <name>4FM</name>
++ <shortname>4FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152633665237A15C2EDF4B82DCAD1414FB185F88EE629C94CB4201F4482B25DC9E55F893</stationID>
++ <name>Q-music</name>
++ <shortname>Q-music</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1215263397F320B0728B535D76E996EE0D6F5C0F9540BEBF2B8FAED6E9CF66AEDF356E1CD8</stationID>
++ <name>BBC World</name>
++ <shortname>BBC World</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1215263435410BB4AA6ABE12E2C3C9DB5D0DB850F7D3C415A3289A2D2B29509C1B6491A181</stationID>
++ <name>BBC 2</name>
++ <shortname>BBC 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152634678854A21F1A0C01FFA3A5E6E235B37C0C306FAF5617F305D5F924E739B15D430C</stationID>
++ <name>BBC3</name>
++ <shortname>BBC3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152632098F327814F8708422B8670F872234946D641AAFFA5A67C46947398C3CA7910071</stationID>
++ <name>Classic 21 (RTBF)</name>
++ <shortname>Classic 21 (RTBF)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152638141A9295AB35F2F119D0F5CB6EC63BA523A8256BB0A1E41432016D03B4BFB61BD7</stationID>
++ <name>Musique 3 (RTBF)</name>
++ <shortname>Musique 3 (RTBF)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152638542B98B42A3DD4AF0FB042498092849D753A1A6A9C28E098C5A4A498AD7AB94A46</stationID>
++ <name>Viva Cite (RTBF)
++</name>
++ <shortname>Viva Cite (RTBF)
++</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1215263895E17E4FC1BB559557C961B24DD5F77A1BA5CDB57891797D2B0D5E27E91C36ABC3</stationID>
++ <name>Viva Cite</name>
++ <shortname>Viva Cite</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12152640255FAE61BC958F1D9B0B77400462FB6309D5AC1BE3DB309A956FD09B034B9DA6E6</stationID>
++ <name>BRF
++</name>
++ <shortname>BRF
++</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1215264045475CC0A5EB09DBC99EFF53CE27532E793FF6A9EFF69CB86BCBC4A99A5BC6E78F</stationID>
++ <name>Deutsche Welle
++</name>
++ <shortname>Deutsche Welle
++</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>121526350496BB70933EDA4409C2127EB51B05C994C2D679D5A87C0B0DB93066F0B8ECFA2A</stationID>
++ <name>La premiere (RTBF)</name>
++ <shortname>La premiere (RTBF)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>121526407469366F46B22C57462B698052BE78CB8947776AEBA38AA7CB78857EEC834466B3</stationID>
++ <name>Sporza</name>
++ <shortname>Sporza</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.3</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/belgium/Makefile.am kradio-3.5.13.1/kradio3/presets/belgium/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/belgium/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/belgium/Makefile.am 2012-11-25 00:48:00.000000000 +0100
+@@ -1,14 +1,17 @@
+ SUBDIRS =
+-EXTRA_DIST = "buellingen-antenna.krp" "ieper-cable.krp" "limburg-cable.krp"
++EXTRA_DIST = "antwerpen-antenna.krp" "bilzen.krp" "buellingen-antenna.krp" "ieper-cable.krp" "limburg-cable.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/"
++ $(INSTALL_DATA) "$(srcdir)/antwerpen-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/antwerpen-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/bilzen.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/bilzen.krp"
++ $(INSTALL_DATA) "$(srcdir)/buellingen-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/buellingen-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/ieper-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/ieper-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/limburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/limburg-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/buellingen-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/buellingen-antenna.krp"
+-
+
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/antwerpen-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/bilzen.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/buellingen-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/ieper-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/limburg-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/belgium/buellingen-antenna.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/brazil/campinas-sp.krp kradio-3.5.13.1/kradio3/presets/brazil/campinas-sp.krp
+--- kradio-3.5.13.1/kradio3/presets.old/brazil/campinas-sp.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/brazil/campinas-sp.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,159 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0-rc2</creator>
++ <maintainer>Hélio Polessi &lt;hcpcamp@gmail.com&gt;</maintainer>
++ <changed>2010-02-14T23:00:00</changed>
++ <country>Brazil</country>
++ <city>Campinas-SP</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>126618494637241F4F8061AEF9182D981F7B7468052284DFB1E6618F268A85B9341A9E</stationID>
++ <name>Notícia FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126618501643BEDF9B833C1844F4BF68530E3D71D64610CEDCE25933824EF0941AA8B0</stationID>
++ <name>Vox FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12372390231F7155089C8FC8A96366D96D657AA4EAF8023A2F46C14594141F50B5C9E6</stationID>
++ <name>Educadora</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123723906031FBA978DAFC484F7EAEB3333FDD4CFFB2DDC7C832F26D2E60EB8510D26D</stationID>
++ <name>Cidade</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1237239087A51A3D3B08532CFEDEE91EFCA74C037C11F14827452DB492C680B081C40C</stationID>
++ <name>Laser</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12661850370C13437F6FF803AFE53C2E06EE0DA14DE34FAA8CFE0AD0EA744556CC3B92</stationID>
++ <name>Oi FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12661850830E51099D751D008F7F1AAFBBF4D5066EE30E30A7A174895460903AFDFBC5</stationID>
++ <name>Mundial FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123723911232AFC94ED9C86FE77C42754DEFF95019FF96C018B6F9E266ADF4CC311141</stationID>
++ <name>CBN</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12661851107493B0A58FD97F214400B5FCF30959E762E4FEB5A55FEC934F7EE1D78389</stationID>
++ <name>Educativa</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1237239133465FE65E06B9C09990FF2CF85417CDB3FD0442A38B6C0D761828F7F35AE0</stationID>
++ <name>Nova FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1237239162D54181C9DF565AEB384BEE8AB15519B0A0F537442B7B4FF6FC829DEAFDAB</stationID>
++ <name>Dumon FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1237239193D67830A2911A6C35CA0949D66AFA4DBDF491A365682C4614B789A1C6D9C3</stationID>
++ <name>105 FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12372392300091B35163BBF9C7C389AE885EA8131E1D519647A0A17E1FD0C580E4FA3B</stationID>
++ <name>Onda Livre</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12661851466F2B4913E272B35C34ADF28EB2287050FF7A47A68A31CD45C82BCA63629D</stationID>
++ <name>Band News FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12372392551C50902A4785BC42C95B2C4903991FFDBC61D0D328E517864920C8DF3003</stationID>
++ <name>Antena 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1237239273DF9EC3314BAA3D7EF50884AB0B3BC0F7D929B9DCA4BD3A750A9663650B21</stationID>
++ <name>Kiss FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/brazil/Makefile.am kradio-3.5.13.1/kradio3/presets/brazil/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/brazil/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/brazil/Makefile.am 2012-11-25 00:48:00.000000000 +0100
+@@ -1,14 +1,20 @@
+ SUBDIRS =
+-EXTRA_DIST = "brasilia.krp" "rio-de-janeiro.krp" "sao-paulo.krp"
++EXTRA_DIST = "brasilia.krp" "campinas-sp.krp" "rio-de-janeiro2.krp" "rio-de-janeiro.krp" "sao-paulo2.krp" "sao-paulo.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/"
++ $(INSTALL_DATA) "$(srcdir)/brasilia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/brasilia.krp"
++ $(INSTALL_DATA) "$(srcdir)/campinas-sp.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/campinas-sp.krp"
++ $(INSTALL_DATA) "$(srcdir)/rio-de-janeiro2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/rio-de-janeiro2.krp"
+ $(INSTALL_DATA) "$(srcdir)/rio-de-janeiro.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/rio-de-janeiro.krp"
++ $(INSTALL_DATA) "$(srcdir)/sao-paulo2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/sao-paulo2.krp"
+ $(INSTALL_DATA) "$(srcdir)/sao-paulo.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/sao-paulo.krp"
+- $(INSTALL_DATA) "$(srcdir)/brasilia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/brasilia.krp"
+-
+
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/brasilia.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/campinas-sp.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/rio-de-janeiro2.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/rio-de-janeiro.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/sao-paulo2.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/sao-paulo.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/brazil/brasilia.krp"
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/brazil/rio-de-janeiro2.krp kradio-3.5.13.1/kradio3/presets/brazil/rio-de-janeiro2.krp
+--- kradio-3.5.13.1/kradio3/presets.old/brazil/rio-de-janeiro2.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/brazil/rio-de-janeiro2.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,529 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.5</creator>
++ <maintainer>Paulo Roma</maintainer>
++ <changed>2012-04-26T07:20:16</changed>
++ <country>Brasil</country>
++ <city>Rio de Janeiro</city>
++ <media>FM</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>110852260463B1FF53E1CD96CF530D5073BBDC2E5E6D4E3CAB9B34065943518B4BAD5410A9</stationID>
++ <name>Rede TV</name>
++ <shortname>Rede TV</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1108522606CF0E16071B00E33871043B85546C70AA2AF543A71B4C24B9B04E1817131E5CCC</stationID>
++ <name>Rádio Globo</name>
++ <shortname>Globo</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11085226079713E38261AB9287D23763C4D825CBFAB4756409F233A41E405EDAAFF360E6CA</stationID>
++ <name>MPB</name>
++ <shortname>MPB</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1108522610E1E698C5DE74602CACD88D4BD92DB5A333FF31F77FACA15E10ACA36575E5B882</stationID>
++ <name>CBN</name>
++ <shortname>CBN</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>110852261107A4883E351F621F0ADEBADCF0BD45E7877F69B1DB48282598F8F6D0556C88BA</stationID>
++ <name>93 FM</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1143339804A5D28DF1EE170111D80B121BD62FEB305F0930127C1CC62B221F686E2ACF14A7</stationID>
++ <name>Roquette Pinto</name>
++ <shortname>Roquete</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>94.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11085226135301AB1B95E41ACE07478D6F2C86942A06944D1BDD11C73CED9D3A56D0850081</stationID>
++ <name>Band News FM</name>
++ <shortname>BandNews</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1108522621C91B5E7DFEC5C77575BF0B195FD21551C5BBB8A413C1CF0A129C7004CC7D7163</stationID>
++ <name>Paradiso</name>
++ <shortname>Paradiso</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>95.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1108522615798A0B2E248B18387E6433FD51190E66587E9A13EEA19E005588B98DAFEFC51F</stationID>
++ <name>Tupi</name>
++ <shortname>Tupi</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>96.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11433383473BEC1138AFC3903343768372D4EB8FA0B5AB2718054CDE6B0F901A2DFE8CEA8C</stationID>
++ <name>Beat98</name>
++ <shortname>Beat 98</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>98.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>110852261861A65E9E025217236634A2FED71D33BA90B39E7DBB47F575E638DDD14D6AA426</stationID>
++ <name>Rádio MEC</name>
++ <shortname>MEC</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>98.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1108522619C23DF4E4945D4514733F38BD25957B583A8AE4F1BB703CFCE6E675892585D4FB</stationID>
++ <name>JB FM</name>
++ <shortname>JB</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>99.7008</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11433391060DF3E724233493F9D3C1C37F9136C26F8E9C32956A1CD4AA89929794DD7E2E28</stationID>
++ <name>FM O Dia</name>
++ <shortname>O Dia</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1143339296D7F1D09A3AFAB2EBE6D36E9EFD26D78FE78FF7C9BBA969AAA9661E754898F806</stationID>
++ <name>Transamérica Pop</name>
++ <shortname>Transamérica</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11085226228543DC58DACD263E20C489701FB95A1815555AB77BDA2BEF2D8F524D2CDC0680</stationID>
++ <name>Mix</name>
++ <shortname>Mix</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1108522623AA9FD006C835CEB5488A4806543277E5A79D0C98EB07A1A0C4D39E223B5636D0</stationID>
++ <name>Jovem Pan</name>
++ <shortname>JP</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1108522624E2D9B6ED883B4EAB1CE5CF9F97016D7D3AD176F6E2998D9765721D682E0937C2</stationID>
++ <name>Nativa</name>
++ <shortname>Nativa</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1108522625CCA35BA2EE3A557BCCB3286C12658116BBC858D6673C1D88CA89B156851EE570</stationID>
++ <name>RádioCom</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>104.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1108522628F19FBF0FD0B62A4A7781AF7D8603BEB1215F1819E5028AA008748BBABFC34D39</stationID>
++ <name>Catedral</name>
++ <shortname>Católica</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11085226298BC8211EE7A66460385578D487B6729DA83550DF85F2517F514D9C019A93FF34</stationID>
++ <name>Gospel</name>
++ <shortname>Evangélica</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1335605678EE85AF1020B8DF8362741004FE16087079630F7DB4CB0CFB62DD2CD05FE0</stationID>
++ <name>_______________________________</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>0</frequency>
++ </FrequencyRadioStation>
++ <InternetRadioStation>
++ <stationID>132964209102A9E373176AC345769BF95FCDDAED10FB54E88137B307776909426B6C56</stationID>
++ <name>Rádio MEC AM 800</name>
++ <shortname></shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://radioslivres.radiobras.gov.br:8080/mecam.mp3</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1336644686598A6CE56A5C9830626FA81717D9A01E731EC60FA3B6AF59CD4AB5B3A732</stationID>
++ <name>Tamoio AM 900</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://187.110.226.22:8038/</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13284779563ADDF256BA86B8FC0F07902C774D4E69BF5C55175E5516936186668A1E0A</stationID>
++ <name>Rádio Nacional AM 1130</name>
++ <shortname>Nacional</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://radioslivres.radiobras.gov.br:8080/nacionalrio.mp3</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1238681020F4AA90589682D934172A4DB15EC4A4C4A424EDA082486D4B12937E556280</stationID>
++ <name>Globo AM 1220</name>
++ <shortname></shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>stereo</stereomode>
++ <url>mms://wm-sgr-live.globo.com/sgr_off_globoamrj_live.wma</url>
++ <decoderclass>asf</decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13356057218399B5BC913429CADDBA31F3BFA6BAC21E8937216AB392FE91E9809A7809</stationID>
++ <name>_______________________________</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>0</frequency>
++ </FrequencyRadioStation>
++ <InternetRadioStation>
++ <stationID>1241912811385B06FDB95068194C12F870D6E306E21E52A93991673FD9A33EFD54FE66</stationID>
++ <name>MPB FM 90.3</name>
++ <shortname>MPB</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>stereo</stereomode>
++ <url>http://69.31.54.133:3690/MPBFM903AAC</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13374327174E01A225AE834F813CF5FDB60EEEB0412AE69F60A691A52776326CD37649</stationID>
++ <name>Bradesco Esportes FM</name>
++ <shortname>Bradesco</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://208.80.54.47:3690/94_1FMAAC</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>133522364599C458AA2A85B35A918926F023F98BE5BB28B91CF0D8694A0555EC9F538B</stationID>
++ <name>93 FM</name>
++ <shortname>93</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://208.80.52.116:3690/FM93AAC</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1335405280FCCDE167E4908818F689FA3D41031FA10768F902A5ABCC2876A5EED361AA</stationID>
++ <name>CBN 92.5</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>mms://wm-sgr-live.globo.com/sgr_off_cbnfmrj_live.wma</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1241911980183645EA2E4C247D327AD84BF532AF96F33271106F18B8882403861A32E4</stationID>
++ <name>Roquette Pinto 94.1</name>
++ <shortname></shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>mms://roquette.94fm.rj.gov.br:8000/</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13353557754B5172FDD46B8EB4D8BA35E9154441E9EC339FA9CD0A197374035E482AAE</stationID>
++ <name>Band News FM 94.9</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://69.31.54.135:3690/NEWSRIOAAC</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>124191172671DC04E508F9A1D3362A912E1F854FA07FDB3ADA063131E4DD0AB040D5BB</stationID>
++ <name>Paradiso FM 95.7</name>
++ <shortname>Paradiso</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <url>mms://p.mm.uol.com.br/paradisofm</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>132964185813145D4AD44B972E36DB138819AAE5DBF3CE5BB3473D7344BEB83F1A0ED8</stationID>
++ <name>Rádio Nacional FM 96.1</name>
++ <shortname>Nacional</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <url>http://radioslivres.radiobras.gov.br:8080/nacionalfm.mp3</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13355333701F162639AD78EE2E18697712D5F192ADF258987197C411D5AE1A34B9292E</stationID>
++ <name>Super Rádio Tupi AM 1280 + FM 96.5</name>
++ <shortname>Tupi</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://174.122.109.90:8888/;stream.nsv</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13355348680B1FB972724DB59A39863C1C5D9B21EF95FF4EA1C3C90D39AC2E0D2842DE</stationID>
++ <name>Melodia 97.5</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>mms://streaming3.joinhost.com.br:80/radio_melodia</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13352238428A36568CBE8FE46E0C6B2CBD31197D3F5E6BDB12916A4A49F98165C43283</stationID>
++ <name>Beat98 FM 98.1</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>mms://wm-sgr-live.globo.com/sgr_off_98fmrj_live.wma</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1244201041C189FB35391781907985642BA71B78711FC0CAE3A34D1F0D608D045257B3</stationID>
++ <name>Rádio MEC FM 98.9</name>
++ <shortname>MEC</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <url>http://radioslivres.radiobras.gov.br:8080/mecfm.mp3</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>123868105729D7E1299035CBCBA570A5A24F356BE7D9D223BCA0C3BDDD6ECCCA2AE11B</stationID>
++ <name>JB FM 99.7</name>
++ <shortname>JB</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>stereo</stereomode>
++ <url>http://5923.live.streamtheworld.com:80/JBFMAAC1</url>
++ <decoderclass>acc</decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1335529955E1A22D934A874936D0D88353FBDFA33AF011B13156DD75C64F4C5483BCD5</stationID>
++ <name>FM O Dia 100.5</name>
++ <shortname>O DIa</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://208.80.54.128/FMODIAAAC</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13352190307C9B15684F734B7E4B18D36C631B14DF9E09A38B8727354C2584CF33712E</stationID>
++ <name>Mix FM 102.1</name>
++ <shortname>Mix</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>mms://p.mm.uol.com.br/mixriofm</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1335353779649713E5D0A6BB8A85BC827406176719BCCB1B51AC83755B450738B932AA</stationID>
++ <name>Nativa FM 103.7</name>
++ <shortname>Nativa</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://174.122.109.82:8886/</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13355282288C45165B0BBDECB759392355069E5BE468AD7A55C30A1F1514358A762CB6</stationID>
++ <name>RádioCom 104.5 FM</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://67.23.248.77:8000/aovivo.m3u</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1335699232EAD8EF7FB5319FA0106BBDE01E023AFCA7617548C0BED9720F656C7038FA</stationID>
++ <name>Aleluia 105.1 FM</name>
++ <shortname>Aleluia</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://servidor5.crossdigital.com.br:8016/;stream.nsv</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1335698861C025BAFB1EF74C6A2C8DA652B1C34CDB5B75B799E3B2F86AA23B42A00FCA</stationID>
++ <name>Catedral FM 106.7</name>
++ <shortname>Catedral</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://67.205.76.171:8092</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13356959814BA482B505F6D897EC382C8B7815ABE593C6D2F0CF52E8A1934E32DE2212</stationID>
++ <name>Gospel 107.9 FM</name>
++ <shortname>Gospel</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://173.192.184.70:8358/live</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <FrequencyRadioStation>
++ <stationID>133560574414161FAD76ADBCF1007E27A277E0AD8217CC4ED0A0E9F0171F236180826C</stationID>
++ <name>_______________________________</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>0</frequency>
++ </FrequencyRadioStation>
++ <InternetRadioStation>
++ <stationID>126182762802DF5F4526D4D07BB0BC6E56A040A7C4C9C7EC8CB2701522EB06BEA69A8F</stationID>
++ <name>Antena 1</name>
++ <shortname>Antena 1</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://a1rj.streams.com.br:7801/stream</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1238680874AB4FA8C5EA96C4654CBFE110206A226CFCB5B48C6941FE5D9453ECE7B65C</stationID>
++ <name>Globo FM</name>
++ <shortname></shortname>
++ <volumepreset>0.3</volumepreset>
++ <stereomode>stereo</stereomode>
++ <url>mms://wm-sgr-live.globo.com/sgr_off_globofmrj_live.wma</url>
++ <decoderclass>asf</decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13352802088D62569EA16EC2CD29B6F997067230DEC4294CFA2274B1253F297B47948D</stationID>
++ <name>Oi FM</name>
++ <shortname>Oi</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://173.236.58.98:9470/;stream.mp3</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>1238681086AABDFCAFFEDB4F0B52BCC889E6BDD5AC00AADB1DB9FF67CCA23685633656</stationID>
++ <name>Transamérica</name>
++ <shortname></shortname>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>stereo</stereomode>
++ <url>mms://wmedia.telium.com.br/transrjpop</url>
++ <decoderclass>asf</decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13284445512FDABAA1CA058AEAAD0E7A618DAAF8A3694549C7B185EB9291D3F1D3A55B</stationID>
++ <name>Tupi FM</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>mms://servidor10.crossdigital.com.br:8000/tupifm</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ <InternetRadioStation>
++ <stationID>13283722598C2F9B55731F7F7A4313A4F3A75BC13B5B983DFFFCA7B153803582085B0E</stationID>
++ <name>WestDeutscher Rundfunk</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://www.wdr.de/wdrlive/media/wdr5.m3u</url>
++ <decoderclass></decoderclass>
++ <playlistclass>auto</playlistclass>
++ <metadata_encoding>auto</metadata_encoding>
++ </InternetRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/brazil/sao-paulo2.krp kradio-3.5.13.1/kradio3/presets/brazil/sao-paulo2.krp
+--- kradio-3.5.13.1/kradio3/presets.old/brazil/sao-paulo2.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/brazil/sao-paulo2.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,375 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.2</creator>
++ <maintainer>Igor Isaias Banlian &lt;igorisaiasbanlian@gmail.com&gt;</maintainer>
++ <changed>2011-06-21T16:25:53</changed>
++ <country>Brazil</country>
++ <city>São Paulo</city>
++ <media></media>
++ <comments>Fonte das informações: http://pt.wikipedia.org/wiki/Anexo:Lista_de_rádios_do_Brasil#S.C3.A3o_Paulo</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1068544851063A4998A78195FDC4F511AD5E39A77EDF4A99545FEFEE1BA09A5159FB2DFC85</stationID>
++ <name>Gazeta (Popular)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851FA44B51067379B772E91D69C3F36BFD1BE373BFAAB02FB267BB9E79745D094DD</stationID>
++ <name>Fast 89 FM (Antiga Rádio Rock) (Pop, Black, Dance)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106854485192E7A1C2D349D37CBD77495D3ADB558CD7D921C3160003AE475BF39F3F0CA024</stationID>
++ <name>Nova Brasil FM (MPB)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851D8831804C6159634263FC359AE57CB8B96FF009B4FB4CB79FF39DB2CBF31EEBF</stationID>
++ <name>Gospel FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448518D7B45F6186E596C2A56A3F91C4FC1B773F7133E30BC2AA6FE1898DB34D5F4BA</stationID>
++ <name>CBN (Jornalismo)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448519B29A95C1A4F8B221A919B011D9296D15B5227225A5A7E27C9DA6703B1E3469A</stationID>
++ <name>Rádio Bandeirantes (Jornalismo, Esportes)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448517DD84085761847C094F78696B91D9B023BA80862F534827883165058CD06133E</stationID>
++ <name>Rádio Disney Brasil (Jovem, Pop, Rock, Dance)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851707ADA489310244DA5D4FAB004D99CD01601FA9FF7F5424A4660A53D88D5ECBE</stationID>
++ <name>Rádio SulAmérica Trânsito (Trânsito de SP)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851C9201AFEE47247B9A616E705AEAB7E3DAE707A43BD1824390AE427C12EB9B9FB</stationID>
++ <name>Mitsubishi FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851C5394861FBDFCE6794363776BC90E7F84124E8816818200879AD3CA2859D9632</stationID>
++ <name>Estadão ESPN (Antiga Eldorado) (Jornalismo, Adulto)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851D0289AC2B0AEFDED22C4D9341F534BF08DF140FE238FEA37C8A72639352C846D</stationID>
++ <name>USP FM (MPB, Alternativas, Informação)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851F9AFD5FC0F3384511069DC8DCF2220A0F7A12D5501388F4D66F8A72180CF7873</stationID>
++ <name>Oi FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448518696F96431246C0E8811A76A86CE07D3ADEF74C0D19B888A8B826160DBFD203C</stationID>
++ <name>Rede Antena 1 (Flashback, Pop Romântico)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851A8F04BB0725196CA919E38D5B9EF9A0DF5F0FF0C920636BFE7466E5C6FAF623E</stationID>
++ <name>Nativa FM (Popular, Sertanejo)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448512EF7D6A7AF70B101A36763BE25A3FB5C486C40C0B9BC29B17EBF2EA27536562E</stationID>
++ <name>Mundial (Esotérica)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448518BB559FF1125C773021E9DE13BA19BED84E488D4B73448D879DE9ECFF21C5DE7</stationID>
++ <name>Band FM (Popular, Black, Pop, Dance)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106854485184EF62D3E00617144EDB7EF0E3160F9A94464D4E529D28B4E160C5A0B44A45D8</stationID>
++ <name>Rádio Vida FM (Gospel)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448515838BB6F8E6831C577DB6BEF8B55E18F5A2179AE031EC4C4A76B809918137072</stationID>
++ <name>BandNews FM (Jornalismo)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851337DE5C347B8E19FF0E880A2B9E38392C48EE37BEF918272CCCCF4E084AFE46F</stationID>
++ <name>Energia 97 (Dance, House, Black, D&amp;B, Techno)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448513711C1C26ADA91953A177554A9796A2B4BF879C198A82715BAB4D241F0BB73E6</stationID>
++ <name>IMPD 98.1 FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448516A0B12A86C5DAD2C72F95B4991D5A9B5D1A490DFF605544AD7972C0A484A0A5A</stationID>
++ <name>Metropolitana (Pop, Black, Dance)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851AF15E6AD95800F485702F159914B0A93E46E5CD68DDB11EB583B3C37F08F02F4</stationID>
++ <name>Rádio Terra FM (Sertanejo)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685448519842A5E231775F250B013D3604832F184655D2BCEA1CFD1DCA1B572B9F26A4B3</stationID>
++ <name>Rede Aleluia (Evangélica)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106854485168590AD0DB7DB99C33772D5B362AB8C2575DB634C5F44FE18158E50FDD895B3B</stationID>
++ <name>Transamérica (Pop, Black, Dance)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851BDAF9DFE698BB91435D5C87510098BC54A6B834354B76112E5DB9F191BA03DAC</stationID>
++ <name>Jovem Pan 2 FM (Pop, Dance, Black)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851218C33FE44396A6CDD072A46BFE3A2F19DF815140048DD499C8AF8CEFE4A2A70</stationID>
++ <name>Alpha FM (Flashback, Pop Romântico, MPB)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068544851D6B3C38519AC4F100AFBFF40437A2A057346EDF60B8807F52960204DD1CE389D</stationID>
++ <name>Kiss FM (Classic Rock)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13086474014771276F6D1BA9B00AFB695144042EDED6BB404D402F81B027F40384964F</stationID>
++ <name>Imprensa (Forró, Música Regional)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130864745047ED7EFBBF90962261A79A431A64CB0ECD2EAAABF66F8E5311C226B6A5A1</stationID>
++ <name>Scalla FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1308647468484F8C0F98D8735571D9B96214477C9DAB79D700CF25B9881D22115226FC</stationID>
++ <name>Cultura (Clássico, Jazz)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130864748710A1608AF577C02453814307DFD3655C0E861E79F78791ACD6CE495C96BB</stationID>
++ <name>Tupi FM (Sertanejo)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1308647494E822E4E85F316E1C17F8EC537A030FC331E04BAAF0CBBA6810992A66AE7B</stationID>
++ <name>Dumont FM (Pop, Rock, Dance, Black)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1308647510BDB203D6312D5A3BCC630E7BB8B0A4BC78BFEF1379F8F6199D24A09278A3</stationID>
++ <name>Transcontinental (Pagode, Black)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1308647524F17E6261EFB800C8F3C8ADF362AFA88B11F34592467EEC7664D775156F51</stationID>
++ <name>105 FM (Samba, Pagode, Black, Soul, Rap)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130864754047125139D3E46F3A0C763A2BE51930358CEB355F4519F848AF19119760FE</stationID>
++ <name>Musical (Gospel)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130864756116CA5CC9C506A3261D2D4A41BB16A6AACC553A25126997731A6D0FE37FBE</stationID>
++ <name>Mix FM (Pop, Black, Dance)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130864756972F0365E169147F735A06E5B9725A745726FB42524895A11269E28536CF6</stationID>
++ <name>RBR (Rede Brasil de Radiodifusão) (Popular)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1308647624EE4ABB9AA1AA1DEDFBFAA05A523E62E6CEE3DBB91670F11484C7C906FCC9</stationID>
++ <name>Nossa Rádio FM (Evangélica)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1308647642AA11EFF0E0E71AB18CFCAB5956BD81E12BF480CDDB6410C67926DA129328</stationID>
++ <name>Rádio Eldorado (Antiga Brasil 2000) (Pop, Rock)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13086476879578B3D1BB9352761178E199CF7CE9A3070997936A161A0B366E2F30DBFE</stationID>
++ <name>Tropical (Popular)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/bulgaria/Makefile.am kradio-3.5.13.1/kradio3/presets/bulgaria/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/bulgaria/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/bulgaria/Makefile.am 2012-11-25 00:48:00.000000000 +0100
+@@ -1,12 +1,16 @@
+ SUBDIRS =
+-EXTRA_DIST = "sofia.krp" "stara-zagora.krp"
++EXTRA_DIST = "plovdiv-antenna.krp" "sofia.krp" "stara-zagora.krp" "varna.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/"
+- $(INSTALL_DATA) "$(srcdir)/stara-zagora.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/stara-zagora.krp"
++ $(INSTALL_DATA) "$(srcdir)/plovdiv-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/plovdiv-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/sofia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/sofia.krp"
+-
+-
++ $(INSTALL_DATA) "$(srcdir)/stara-zagora.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/stara-zagora.krp"
++ $(INSTALL_DATA) "$(srcdir)/varna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/varna.krp"
++
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/stara-zagora.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/plovdiv-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/sofia.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/stara-zagora.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/bulgaria/stara-zagora.krp"
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/bulgaria/plovdiv-antenna.krp kradio-3.5.13.1/kradio3/presets/bulgaria/plovdiv-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/bulgaria/plovdiv-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/bulgaria/plovdiv-antenna.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,222 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Peter Georgiev</maintainer>
++ <changed>2008-08-16T00:00:37</changed>
++ <country>Bulgaria</country>
++ <city>Plovdiv</city>
++ <media>FM Radio Stations</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1218755983103051C38B8B249D2344A212E4BBAC4C8252F16C03DBB01C2DBBB225CB1D23B4</stationID>
++ <name>BNR Horizont</name>
++ <shortname>Horizont</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>88.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121875619304FD8AEAF0436E6E3F68691C3A88479AFE09B9BD072600BCFCC2B541E1E28911</stationID>
++ <name>FM+</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756211F3F3933BDE80E7AA3C470335E9E28ABF237083FA40CF476A6A4DF1A68EA0488C</stationID>
++ <name>Focus</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121875622134469FC01380505EAB32A823EC8AC6A57A03CF7C46293BC75F9A63522650C86E</stationID>
++ <name>NRJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756506728FE149E449E172DA3CB5CEB06BB61319A661E1A678DB8F15BC5247159F639B</stationID>
++ <name>City</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12187562445C4F4905B8D44257C83BE277C97E6C2CEB00D605E60FE1B34B677A38145BF53F</stationID>
++ <name>BNR Hristo Botev</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756259D8B0B6FD38E46BA38AB996A5CC11308B08ED929A778D35EEB1A2727DA55EFB79</stationID>
++ <name>Veronnica</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12187562782B98DD0067A9F9BD9B433FA0A26DAD119D6B6720083F7382883AA06DA294A07C</stationID>
++ <name>BNR Plovdiv</name>
++ <shortname>Plovdiv</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12187562909F31EB8EA5C45271C58C673B169FD86C76D84B4C5CD8A6C5FEB302CE57A564A3</stationID>
++ <name>BG Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756302BF3B89A8D4F7A36486490CCD7CA317A83507E5FEAA8B25795E9D48A45768FAA6</stationID>
++ <name>Radio 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12187563157326C5907EFECE6A9812E710B63BAAEEE132ABE1B71A7F3F71E985AE56E7F0BE</stationID>
++ <name>Vitosha</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756328DBB067CCDA069586C783D62CA7C81D48EEE4A006509008FB7086CFD553314FA2</stationID>
++ <name>Atlantic</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756337F1AC64F857AC04B4F13C7DAC79FF75C2013396341C1C2010DCDF11AFA47C95FF</stationID>
++ <name>Focus</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12187563503316E105C2302EDA39CC05C368D8ADD46203A5F7256547BB31695448E6E45F1E</stationID>
++ <name>Katra FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121875636546F1F7FED4FE10744198F3AB02D08D11B45112BD598346417ECD0B60C6294277</stationID>
++ <name>BNR Horizont</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756375FC8B5BAA8FAA6D96CA42868CFF96EC5717CBB4B06F0E316E1423CF84F5410A7B</stationID>
++ <name>N-JOY</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756390D22E5095442D86638C8C0B2271F17C138E8FCA2BA92A3CEA1B324646BA3428EB</stationID>
++ <name>Star FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756400104A27C8E187BC595602C7F4C7A99006883D31C6B41FAD0424275806C4DE7F50</stationID>
++ <name>Fresh!</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756409BB2AD6C9ED6AFB914064F854E57C2A96E8ACBEF1CFC62114A3D5E76F7C670822</stationID>
++ <name>Z-Rock</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12187564528FE4024BA8FF5D3A386E31BF6B3020DD542D510B1BBB8D15E65E8DDA41DE3E12</stationID>
++ <name>Radio 1 Rock</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12187564747011B06D9E28650DD839FA3B76A1FA6A021AF3D0083AFDB9AF63D5526242B601</stationID>
++ <name>Darik</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1218756491255B3BDC321998858D18DF9504D6B6F81431FACFE60073CB6754903B6B26030B</stationID>
++ <name>The Voice</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12377236317EDEEEAEEA0ACF5224257DB772ECB06DEDD8763D3E15F8393C685BC0819D072B</stationID>
++ <name>Vesselina</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.5</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/bulgaria/varna.krp kradio-3.5.13.1/kradio3/presets/bulgaria/varna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/bulgaria/varna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/bulgaria/varna.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,198 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Velislav Kolev</maintainer>
++ <changed>2006-10-31T20:30:38</changed>
++ <country>Bulgaria</country>
++ <city>Varna</city>
++ <media></media>
++ <comments> Contains merged Data</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1162318601827F4BDBFB0362A1D195E998F26869054B35EB2A4133F2B068DE1E87351E98CB</stationID>
++ <name>�����</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5002</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116231862165D42300AC75574DAD46E7381F9C93EB1FD9F04C49732B1B31BD89E352AA96DA</stationID>
++ <name>N-JOY</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116231898247C9A0A9FA6F41FA374BF8D9FADA75EB293AE78E20F5044AE5989F6AB16B638C</stationID>
++ <name>NRJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11623190256F1A743C47333B5DBAC8EC95970F73319C494DFBE0D90199F853F6CC77959659</stationID>
++ <name>����</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162319025C18D07591DBE40AE364CC03F7559CCE3EB0DBF667E767D0AB8D4A0B572D3086F</stationID>
++ <name>������</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116231902528FD115D22B4CAB0F75E43F2C449518602931232AEFC4E9F643DA5B723D70152</stationID>
++ <name>����� 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162319020974CF47AAC09D713E9BDE91F99518F10803F0CA237492B4D045A00B63D341151</stationID>
++ <name>F�+</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116231852111FB56C8F8E8D463ADE5DA5176AEED10ECBCA3EC2F6EB9B73D6E4785BE1D33D1</stationID>
++ <name>Z Rock</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9005</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162319026415C16452006790E85B0DB4FF2B600523F6F47D47235EEF7081EF3B29C18E700</stationID>
++ <name>Bravo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162319149B07AE40DE4E3B3C221C45C92834103E19B2EAE290F54417383AA9A6CB8C185C2</stationID>
++ <name>����</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116231852883AA85312F5A295E668B26009730955AB1B1A006FAAB7FC788B061F504CDAB40</stationID>
++ <name>�� �����</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.8257</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162319151D21DAE9E87577C193EE4B1212F61FE7A1C8C169D13FBEFDEE1E17D678D6A2CDB</stationID>
++ <name>�ity</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162319151367F929877E122D879FEF5A43C27ADACCE22CD433A2A898F7F2B73D662E67DF7</stationID>
++ <name>�����</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162318536AE9D3E77D17C2E559FD9B91C654BB0F5380041C8FE423F92F76050D7A55EEDC9</stationID>
++ <name>Fresh!</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.351</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162319152F38CD5CCDABC8831D587FEE4D112D376BFFF6826DA0B7FF13B1725470CE93D92</stationID>
++ <name>�������� ���</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11623186397EA1E3928F80CB55F77E8896255E9F314E389BA20FB7236EFE21484D7B0387E7</stationID>
++ <name>Retro</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.501</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116231854791205EADF3CF6B3AB1B99504DFB800EB833FA840E32C324838B9CC809CA8E6D0</stationID>
++ <name>����� ���</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.426</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162318554BADC777E26831193C2AE2EFD0DC856441F623AF5C44A753914372AD84FDF486A</stationID>
++ <name>����</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162319336A868FA0C3FF819F5F337E69A1A8CC90031DB64DFA4E828ACC791FBAEC19D8194</stationID>
++ <name>�������</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162319337ACD11AA2581E8EDCD9F7C4E20B2FF6639118CDEFBA59900D1503B896CBE6D72F</stationID>
++ <name>�����</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Alberta_am.krp kradio-3.5.13.1/kradio3/presets/canada/Alberta_am.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Alberta_am.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Alberta_am.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,30 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>Alberta</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>10633853787DD40C1BEEE3947B3134F34252210E517164CC5FDE203EAA19C29972D39B139B</stationID>
++ <name>News/Talk @ CHQR-AM</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <frequency>0.77</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385378FE7442F39084CB89C3B5E38960A058F0B9D6B0AFC789AB4AF3EF8EC5470FE06F</stationID>
++ <name>Country @ CKGY-AM</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <frequency>1.17</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Alberta_fm.krp kradio-3.5.13.1/kradio3/presets/canada/Alberta_fm.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Alberta_fm.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Alberta_fm.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,126 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>Alberta</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>10633853778674CD580E00787E07AC1528B7CE8861157AB80B1ACBE1285D16CF68661D1EB9</stationID>
++ <name>Country @ CFWE-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>89.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853774ABE9752541CE4B9628567B81024E05450628AB02E5E25E6942B9046C41F9ACF</stationID>
++ <name>Rhythmic Oldies @ CJSW-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>90.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338537733E08552CF2DFD0C7925003F6EC2B02D2801E37F0C694335DB228F2E39CF35EE</stationID>
++ <name>Rock @ CJAY-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>92.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853776C25F86C70CCD31CEA23564BB708A57EF5F9085A7688B43DC6FD872014910FFB</stationID>
++ <name>Alternative @ CKNG-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>92.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853772A8F9E92C1CB29A7A59350909BED4BBFDF7F39660C352B878D9113D14013712D</stationID>
++ <name>Classic Hits @ CHHK-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>93.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853773611391247EE7FA954C7D9B66FF417A1608BCDB991260EC536CF043E5908BF78</stationID>
++ <name>Country @ CHLB-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>95.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385377096D0B37514F6B02B594995C4461722DF8DEB8C60824F18245CA27A729986A3C</stationID>
++ <name>CHR @ CHFM-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>95.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853775B02D76F9E43FA4A53B9795FF14D1A1D22A970EDA59D3D43C9F507E715EE112E</stationID>
++ <name>CHR @ CJTS-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>97.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853770337181A7624FFA5AC1B478A0805106E22AB7FBAFB49A68C7D7AEE9534A97007</stationID>
++ <name>Classic Rock @ CIRK-FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>97.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385377A83A6C70A32728E42BE200437F2605AAFF3BFB342F0A7596AA60C88442F49700</stationID>
++ <name>Hot AC @ CFGP-FM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>97.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338537734C34BAC629451F47196D3C1E703AC8E6513CDD2740FBBFFA54CD6995FC0B642</stationID>
++ <name>Classic Rock @ CFBR-FM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>100.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853770976EAE07E91233E016FB68C6D0EC2ECAEEB6662F974C444D3CA59F2958C9118</stationID>
++ <name>New Country @ CISN-FM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>103.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853773DEE94D38AB8333A773EDFB9ADE76F0F8161D381D1A7AA36906EAD1DC10D39EF</stationID>
++ <name>AC @ CFMG-FM</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <frequency>104.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853776C4C04904D4EBF1B4B6CF03AD5B98DF21541D8AF56F763E7D6935D45D34CDC64</stationID>
++ <name>Rock @ CKIK-FM</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <frequency>107.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Alberta.krp kradio-3.5.13.1/kradio3/presets/canada/Alberta.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Alberta.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Alberta.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,142 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>Alberta</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>10633853780FAE1C6C25061440A80A603674BE0548BE72CF9FA55F35ED9EE4D5BD8C0363A0</stationID>
++ <name>Country @ CFWE-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>89.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385378C0AADE85A43442C43CE31F22BFA5F05EAB2CEBE52AC7A0CA28965C42A8061F66</stationID>
++ <name>Rhythmic Oldies @ CJSW-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>90.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853783A71CA9D83193792249CEE100AB8927715CAEA722FA7240A6744558DCB6C319F</stationID>
++ <name>Rock @ CJAY-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>92.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385378AD37014EE4E733A5ACA31247FE51168ACD129E2B22CE7FC884C06561EF1B22D2</stationID>
++ <name>Alternative @ CKNG-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>92.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853785F2EB74C8B58F3AA9BCD474B30D7C13A78DB847009E914B1E0EB3F3D8C1A175A</stationID>
++ <name>Classic Hits @ CHHK-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>93.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385378F6E51ED3C76252FA6524D27E5109BFA743791D5C56A86B11AE5E14E4E9A254A6</stationID>
++ <name>Country @ CHLB-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>95.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853787B2AA8D76B6F7627D521207BE1E1727C415C3CBCAC18CA22E29B5A83E60E973E</stationID>
++ <name>CHR @ CHFM-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>95.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385378CDF63872C81ED21D08337FC844CD89E7C95F5FB5AF367A8BE45F277B8A473423</stationID>
++ <name>CHR @ CJTS-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>97.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853784B3D9C8D49E1503081AFEAF9F4E1AA3F4D00062F4711C58FDBED37A190BD7B53</stationID>
++ <name>Classic Rock @ CIRK-FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>97.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853780D4C3A7F642534552322E8E2D5BE2F913D8E94568FCE9B9A93B5A586740F4ABF</stationID>
++ <name>Hot AC @ CFGP-FM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>97.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385378A60ECF6358DA10AD893E14FF5F6EA521FEBC59BD8F4BD26CE0E041DBFF56C4F7</stationID>
++ <name>Classic Rock @ CFBR-FM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>100.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385378312FBB264D4A90BBA83EF41FF6D5FB60F1933C759111D733CCC46D8010F38D48</stationID>
++ <name>New Country @ CISN-FM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>103.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338537844B72671AA9A88CA5D5934C4C15852741904DE3B6F7B93BDE3A49E88F270EC49</stationID>
++ <name>AC @ CFMG-FM</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <frequency>104.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385378FE4CE6C37EB5F1811CD58132512AE292849E04893DB76F057732703C8D64F89E</stationID>
++ <name>Rock @ CKIK-FM</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <frequency>107.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385378E0379B23681449EB8C901A44454F0E59D23ED3B51D872513A1C89CD13F68E3EB</stationID>
++ <name>News/Talk @ CHQR-AM</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <frequency>0.77</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853783FC783D1673373FF08C16C68DD4930E57F3DE24D1289E2E31D08EC123E749EAD</stationID>
++ <name>Country @ CKGY-AM</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <frequency>1.17</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/British Columbia_am.krp kradio-3.5.13.1/kradio3/presets/canada/British Columbia_am.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/British Columbia_am.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/British Columbia_am.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,118 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>British Columbia</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385359E5A2DBA3F6BFD77DD674D149FC604C4F7A0936A253710318B042B49A09995ABF</stationID>
++ <name>CHR @ CKPG-AM</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <frequency>0.55</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359DEECE66A5C95CE02E6FA5674424B3AFD9E4814AB5DC04DC6EDDDAFADF5429A72</stationID>
++ <name>Country @ CJCI-AM</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <frequency>0.62</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359427537B107932F2983F3D1D0D44CA2506DCC66A5F53C1B83DE6045B010B40B97</stationID>
++ <name>Oldies @ CISL-AM</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <frequency>0.65</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359F44A29C1C5F4DA4F3D073EF63EF6A55861CB5EA72D75EFAD5FF2881F33636C35</stationID>
++ <name>Country @ CKQR-AM</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <frequency>0.76</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535922F1BC67CE0B8A3E32521C82ACFDEB520AE5E4218C6632F10B598F407879ADD1</stationID>
++ <name>CHR @ CKKC-AM</name>
++ <shortname>27</shortname>
++ <icon></icon>
++ <frequency>0.88</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853599EFD17AD0095E71E572E37BB8B56588EBF6CAC82FA4065A5A2D29E663E9CD565</stationID>
++ <name>News/Talk @ CJVI-AM</name>
++ <shortname>28</shortname>
++ <icon></icon>
++ <frequency>0.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853596D496E7338CACD5A2A0D5823FEBC25DF8D3037DB3D5DF4D6CAC3C441322C98F4</stationID>
++ <name>News/Talk @ CKNW-AM</name>
++ <shortname>29</shortname>
++ <icon></icon>
++ <frequency>0.98</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853592EE5091A6A34B19E2C4A6EF25D0E241096F3F31DDF66F588E5033BF9D208F0D4</stationID>
++ <name>Classic Hits @ CKST-AM</name>
++ <shortname>30</shortname>
++ <icon></icon>
++ <frequency>1.04</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359AC95EB6E19BCCA350D209B8BE4B23F27B5776EC48ADBC1E9396A50D6CF916DF5</stationID>
++ <name>News/Talk @ CFAX-AM</name>
++ <shortname>31</shortname>
++ <icon></icon>
++ <frequency>1.07</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359C31F7F7ED4DE20DAB0166BA881C584F64C6E6E4330F234B5252BB1CFFED8F348</stationID>
++ <name>News/Talk @ CKWX-AM</name>
++ <shortname>32</shortname>
++ <icon></icon>
++ <frequency>1.13</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359658EB256EC4AD36DD8F6A61BD1DE02EBA0814619463FC7B6D744D4D480E63268</stationID>
++ <name>AC @ CJAV-AM</name>
++ <shortname>33</shortname>
++ <icon></icon>
++ <frequency>1.24</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359228FDE7DCE8C430CCF137F5F5AB3D1EB7AA95E1092A8EEE04F9264DB2F335185</stationID>
++ <name>News/Talk @ CHMB-AM</name>
++ <shortname>34</shortname>
++ <icon></icon>
++ <frequency>1.32</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853593F73FB4F279E229596A57660ABB5C7392D69FF785C19F2B362EAB67C1CD5F4D5</stationID>
++ <name>Country @ CKGF-AM</name>
++ <shortname>35</shortname>
++ <icon></icon>
++ <frequency>1.34</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/British Columbia_fm.krp kradio-3.5.13.1/kradio3/presets/canada/British Columbia_fm.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/British Columbia_fm.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/British Columbia_fm.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,190 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>British Columbia</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>10633853590D470913EFF51B2E353F3ADE718349C4AF7C0AFD4222586C8074F52E97281DAE</stationID>
++ <name>AC @ CJSU-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>89.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853598DEB5D6CCB6220FB51C87F8542D06F962F8F46FCEA7369CC6C62C7A1C1542EA7</stationID>
++ <name>Country @ CJJR-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>93.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359EC9F32C83C8CD51CA92EE014B64585F70B4795EF42F6F9BAE724190A2D382FD4</stationID>
++ <name>Various @ CJSF-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>93.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359407D77C53DC9D578813E568E34073FA92102C995570DC6FF13C7D015986B18F1</stationID>
++ <name>Rock @ CIRX-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>94.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535932CD0CFF6C389736FA7CD3248111742DFC335DFF2D743DD5F272B85BEC177541</stationID>
++ <name>CHR @ CKZZ-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>95.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853593166C89AD687C9854C5F92E569B032E78677E0E3BA1562B1913FC8ADA5541CE1</stationID>
++ <name>CHR @ CJAT-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>95.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359F067608C6F11E5DA3F31447A8AF5783D28BFB5C46A6FBB5A94B913FF77E399FC</stationID>
++ <name>AC @ CKKS-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>96.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853591D4B72FC5F5F6A0287A2933BAFD58E30CAAB997576EEE3665370CDB53101163B</stationID>
++ <name>Hot AC @ CJMG-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>97.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359D582AA50D1BC56FC1064A087A25684950DDED72ECC3B54ED2A112A9925001C01</stationID>
++ <name>AC @ CIOC-FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>98.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853592D38CA7610711D5D51231A8AE8DE0EF88AAB7C9A24955420EB51A122C060EC32</stationID>
++ <name>Rock @ CFOX-FM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>99.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359B22CAF40A16FFC20B1BA2BB6F7D61336072726150F9DEE61FEF2241CD82C7D94</stationID>
++ <name>CHR @ CHSU-FM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>99.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535902A7FCBBE58AAFD8D958D2E9661731AFA87E565A7F9CA40D72FF247BCCC79CF2</stationID>
++ <name>Rock @ CKKQ-FM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>100.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853598C23C12C9F97E562E09D3EAF8173F6E28B6C129B84FBD940BB519FA1241D56DD</stationID>
++ <name>Classic Rock @ CFMI-FM</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <frequency>101.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535998E0E628C51AB2DCBFD1061E392851023B8EB9B207D8D781F04CBFE0653606C9</stationID>
++ <name>Hot AC @ CKKN-FM</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <frequency>101.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359680649EC02D1E110145649B23CCB744C33FA008846AD78598CD46CDABE40BA50</stationID>
++ <name>Nostalgia @ CFUV-FM</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <frequency>101.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359DBCEAA7F0DC6E8C73261E912CAC0BFE60FC66692BC44BCBC8225B365CA17CFE2</stationID>
++ <name>CHR @ CISW-FM</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <frequency>102.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359B368E35C2BBD3F01B51027029FCBDF631CE9B019CA9D58B55499ADA58E812C9E</stationID>
++ <name>Ethnic @ CKMO-FM</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <frequency>103.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853599BD2AE95C3F9AB2B89997A030A18FFD39CCB35072A4945807960B8BEC5E06E51</stationID>
++ <name>AC @ CHQM-FM</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <frequency>103.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359B54D9766475D0D613D1C5604ADDE7D0F49E91F7B56C22E524D94F156373CFCD9</stationID>
++ <name>AC @ CKSR-FM</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <frequency>104.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535905B485F99B1F3D8448C8EF1D69BE9473F472F7D58D47160F90E1668A570D7D1A</stationID>
++ <name>Classical @ CBU-FM</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <frequency>105.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359123885D3FDDD740756AD138F88B2676EB0D6324453529C5BB1F5C826090A2018</stationID>
++ <name>AC @ CISQ-FM</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <frequency>107.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853595E73E741DA155239CA2CD23C6BDEA442B856714F6CF309C70E573B062CD88A1C</stationID>
++ <name>AC @ CKIS-FM</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <frequency>107.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/British Columbia.krp kradio-3.5.13.1/kradio3/presets/canada/British Columbia.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/British Columbia.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/British Columbia.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,294 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>British Columbia</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385359D5F2CDD6F12A5F08FF862B6F04EA76E90E0991B9C7D7458CF70C393634632D94</stationID>
++ <name>AC @ CJSU-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>89.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359F6AC17F18E655860B8E7A65E0ACEA3DCEAF1CFBC707956A527D23FEF188F82E1</stationID>
++ <name>Country @ CJJR-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>93.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359F097F1B15886BD01849C57468F86A3DF45DB5CB8C9C99029C95731643002E89D</stationID>
++ <name>Various @ CJSF-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>93.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535915DBA56B6EDE5B843C04601D2FE4268B3268753DCF93F5163A854CCF922AC458</stationID>
++ <name>Rock @ CIRX-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>94.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853593BCA4073FFDA7F36A62A318B05925FA115E4ACFBC36E577C9B117D7EA141D92D</stationID>
++ <name>CHR @ CKZZ-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>95.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359A7EAAC3B45AA6CE4523502CD83FEC0F72BE631F30D8E4678C3BF3378233805B0</stationID>
++ <name>CHR @ CJAT-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>95.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853592A292C842356FD1D291AEFD315BD4D7783C877CA847D3E3653A6388A4C9D1238</stationID>
++ <name>AC @ CKKS-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>96.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535948C956430AA3776A8778C16544612BB332ED8200CA7E8AC3E75D1390F39F4E67</stationID>
++ <name>Hot AC @ CJMG-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>97.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853598906ADEE03A37745D1E98FD6E7381F0EF6AB1263856188CD3DC3A69275AA5148</stationID>
++ <name>AC @ CIOC-FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>98.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359BC752064BB4DCA331A9A0069107485A8F1D01BFDC7F65A9EDF34F798421C8CB6</stationID>
++ <name>Rock @ CFOX-FM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>99.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359560FB9E2053F54D71A04853510FD008F006060176BFE043D77BE11F5CD486A44</stationID>
++ <name>CHR @ CHSU-FM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>99.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853594FDBC3B886FDCDBFF49FEE354B2BC4821D5689BEA38809EE8273D58BE6A3DB8B</stationID>
++ <name>Rock @ CKKQ-FM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>100.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535969D7D59575FFD8F0EC4CBF739E4639BDA43AE5C2EBAC6EAD9BC7D623D157DF4F</stationID>
++ <name>Classic Rock @ CFMI-FM</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <frequency>101.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535995DF4F9F6E889895A10D733C97DFBBF922DF50AD582DF00330002ED3CED541AF</stationID>
++ <name>Hot AC @ CKKN-FM</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <frequency>101.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359CD92F5B64E70F31826D15141911D3765A9E610892208309C26C6C60294BD2BCD</stationID>
++ <name>Nostalgia @ CFUV-FM</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <frequency>101.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359A3CF06A48F737C1199BBDDF557FE48C66ECE84796B92EA76A29BA5B84B89BE19</stationID>
++ <name>CHR @ CISW-FM</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <frequency>102.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535959DDAA60D9DE068BC3EBD8D39F2D64376F3CD34B7E4DB871D99E4E90E7326900</stationID>
++ <name>Ethnic @ CKMO-FM</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <frequency>103.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359E9D75073B921265DB610B1AC0E4EC4984B42A155EEECDFC4CE2F021F83984BE1</stationID>
++ <name>AC @ CHQM-FM</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <frequency>103.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359A86C3AEDCD0A5B0F28BBEF316913D1B5DC58E60348B09D8A18E1F35B00498736</stationID>
++ <name>AC @ CKSR-FM</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <frequency>104.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359D542249A6C677F5F03CE3A40DD5A2EE487CA792B44BEC9CFD7D3D2C73CF38FBF</stationID>
++ <name>Classical @ CBU-FM</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <frequency>105.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853599FF38288DD86E0286B6161E6F3479C02B06D69B4286D4B7E95B6B0AF3EEB5DF0</stationID>
++ <name>AC @ CISQ-FM</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <frequency>107.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853597B45BBF753EF6A529D838E94FBFED83E44AA192B4ABC6B9653AFA84BCC6702D2</stationID>
++ <name>AC @ CKIS-FM</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <frequency>107.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359C551EE7983FBE6F50676A1589616E8776CD1440F3A9CC531C77EA7D83E1B46C4</stationID>
++ <name>CHR @ CKPG-AM</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <frequency>0.55</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535928ECE0C3208B4C9F52EE381CAFEEC6DB8F5AF2C3167DD9D50932DCEA0BB8FCD9</stationID>
++ <name>Country @ CJCI-AM</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <frequency>0.62</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359CE6FEA4D0940467DCAC059101954593CFF0BD234C58D8857B9527E9E4F3A03EC</stationID>
++ <name>Oldies @ CISL-AM</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <frequency>0.65</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359701D86995E780498A6FC3FD0772E8F5599BBC17FA8FF9EB7C202DE12D4ECFCF0</stationID>
++ <name>Country @ CKQR-AM</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <frequency>0.76</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359740D66F68A08A73502B36460F77D6168494179F8C928CE9DA4104AAD5423E8A2</stationID>
++ <name>CHR @ CKKC-AM</name>
++ <shortname>27</shortname>
++ <icon></icon>
++ <frequency>0.88</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535962BD3E066AE7DBD6DDE0011ED9F372CB301FEAE8D57C38B065A5AA56081D69D7</stationID>
++ <name>News/Talk @ CJVI-AM</name>
++ <shortname>28</shortname>
++ <icon></icon>
++ <frequency>0.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359EBEFAE79981DC478EDB0BAD7EF80A1206C7638F975AAFCDCE0627C6F724952DE</stationID>
++ <name>News/Talk @ CKNW-AM</name>
++ <shortname>29</shortname>
++ <icon></icon>
++ <frequency>0.98</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359349E399273A6FE830A43975752CDD50BC23546EDBE9075D597F25119DD274E4B</stationID>
++ <name>Classic Hits @ CKST-AM</name>
++ <shortname>30</shortname>
++ <icon></icon>
++ <frequency>1.04</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359B2E704463BC0D4C38CF3F3EAC9EB6E370FC9F6EB41BBC238539318D425E9F117</stationID>
++ <name>News/Talk @ CFAX-AM</name>
++ <shortname>31</shortname>
++ <icon></icon>
++ <frequency>1.07</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359899124E77D5F886672AB575E45B1155B6F318E584D613582DF9CB2A2C0F52476</stationID>
++ <name>News/Talk @ CKWX-AM</name>
++ <shortname>32</shortname>
++ <icon></icon>
++ <frequency>1.13</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535953AE20D883ED79AB9F258DCAEF6D01D97445E45412C6397C06F7A2AA8F5B079A</stationID>
++ <name>AC @ CJAV-AM</name>
++ <shortname>33</shortname>
++ <icon></icon>
++ <frequency>1.24</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359A28D4D85FFC1AC307A2CA461DC1244D6C80D781E090AC6B6EED2D427563048AC</stationID>
++ <name>News/Talk @ CHMB-AM</name>
++ <shortname>34</shortname>
++ <icon></icon>
++ <frequency>1.32</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385359278A3675076B786C676F1819843CFD9EC039C049A15DE1EE2CC3EF87FD3AAC97</stationID>
++ <name>Country @ CKGF-AM</name>
++ <shortname>35</shortname>
++ <icon></icon>
++ <frequency>1.34</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Makefile.am kradio-3.5.13.1/kradio3/presets/canada/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/canada/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -1,10 +1,64 @@
+ SUBDIRS =
+-EXTRA_DIST = "montreal-antenna.krp"
++EXTRA_DIST = "Alberta_am.krp" "Alberta_fm.krp" Alberta.krp" "British Columbia_am.krp" "British Columbia_fm.krp" "British Columbia.krp" "Manitoba_am.krp" "Manitoba_fm.krp" "Manitoba.krp" "montreal-antenna.krp" "New Brunswick_am.krp" "New Brunswick_fm.krp" "New Brunswick.krp" "Newfoundland_am.krp" "Newfoundland_fm.krp" "Newfoundland.krp" "Nova Scotia_am.krp" "Nova Scotia_fm.krp" "Nova Scotia.krp" "Ontario_am.krp" "Ontario_fm.krp" "Ontario.krp" "Quebec_am.krp" "Quebec_fm.krp" "Quebec.krp" "Saskatchewan_am.krp" "Saskatchewan_fm.krp" "Saskatchewan.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/"
++ $(INSTALL_DATA) "$(srcdir)/Alberta_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Alberta_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alberta_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Alberta_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alberta.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Alberta.krp"
++ $(INSTALL_DATA) "$(srcdir)/British Columbia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/British Columbia_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/British Columbia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/British Columbia_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/British Columbia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/British Columbia.krp"
++ $(INSTALL_DATA) "$(srcdir)/Manitoba_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Manitoba_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Manitoba_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Manitoba_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Manitoba.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Manitoba.krp"
+ $(INSTALL_DATA) "$(srcdir)/montreal-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/montreal-antenna.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/New Brunswick_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/New Brunswick_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Brunswick_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/New Brunswick_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Brunswick.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/New Brunswick.krp"
++ $(INSTALL_DATA) "$(srcdir)/Newfoundland_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Newfoundland_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Newfoundland_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Newfoundland_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Newfoundland.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Newfoundland.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nova Scotia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Nova Scotia_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nova Scotia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Nova Scotia_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nova Scotia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Nova Scotia.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ontario_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Ontario_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ontario_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Ontario_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ontario.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Ontario.krp"
++ $(INSTALL_DATA) "$(srcdir)/Quebec_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Quebec_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Quebec_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Quebec_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Quebec.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Quebec.krp"
++ $(INSTALL_DATA) "$(srcdir)/Saskatchewan_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Saskatchewan_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Saskatchewan_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Saskatchewan_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Saskatchewan.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Saskatchewan.krp"
+
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Alberta_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Alberta_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Alberta.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/British Columbia_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/British Columbia_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/British Columbia.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Manitoba_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Manitoba_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Manitoba.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/montreal-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/New Brunswick_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/New Brunswick_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/New Brunswick.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Newfoundland_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Newfoundland_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Newfoundland.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Nova Scotia_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Nova Scotia_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Nova Scotia.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Ontario_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Ontario_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Ontario.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Quebec_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Quebec_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Quebec.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Saskatchewan_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Saskatchewan_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/canada/Saskatchewan.krp"
++
+\ Pas de fin de ligne à la fin du fichier
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Manitoba_am.krp kradio-3.5.13.1/kradio3/presets/canada/Manitoba_am.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Manitoba_am.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Manitoba_am.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,54 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>Manitoba</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385372567FAEECC546FCB8B698C0DED0B9B7FC373F54964E7269E6F2097D2F6321EC32</stationID>
++ <name>Rock @ CFAR-AM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>0.59</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372679E852386AF719E9EC2C0601E13253D76516464D916D13E2E2218A53E35BA4D</stationID>
++ <name>News/Talk @ CJOB-AM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>0.68</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372202F08C60092B519D009A5E700CAF1C11B3C09E77CE91F77E76455ADDB9DADBF</stationID>
++ <name>Country @ CKDM-AM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>0.73</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372B5DA577EE59D667B19180D54335E981108E68BC90E0919C8CBA341B41CBC7893</stationID>
++ <name>Ethnic @ CKJS-AM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>0.81</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372AD587F819284AD479EEB5F9DC22F6E9943725A1B1D4947CC648E60D33D351EC9</stationID>
++ <name>News/Talk @ CIFX-AM</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <frequency>1.29</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Manitoba_fm.krp kradio-3.5.13.1/kradio3/presets/canada/Manitoba_fm.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Manitoba_fm.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Manitoba_fm.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,78 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>Manitoba</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>106338537233399A62D25D77EA4D8FCC8451783B38A249F29DAF3B7B03FAD172B65B4414FC</stationID>
++ <name>Rock @ CITI-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>92.0</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372DFE8BDBA148E3963997DEF32EB5D5E93B957D65BB9ECFAF940EA366559D2CCE1</stationID>
++ <name>Hot AC @ CHIQ-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>94.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372D0B0F1A1389C0B2AB983EBD8A2C2CCAC76562832487F17212C24E460130E789F</stationID>
++ <name>Modern AC @ CKLF-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>94.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372F0903CAA44A0BE6DEC41C707F448B54EC32CC456A7EF3BD8181D9F99FEFA2C46</stationID>
++ <name>Rock @ CJKR-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>97.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853725B4397003ED0D58C0716AA707AFC1514FBD02743786B8046E096CE1EAB1F79AE</stationID>
++ <name>Classic Hits @ CFWM-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>99.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372DA36B4034B53FC9324D0610397E9822DE88345715E3F76F05540630E30D84965</stationID>
++ <name>CHR @ CKXA-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>101.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372396A871B304FBF1790A2A9C8BDE4E0115996BB60EFB0A30F342E1AF1092E8F27</stationID>
++ <name>CHR @ CKMM-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>103.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853725038DB07B1019C3E2BC42E00FD6F0B6ACCE0E4B964D44D13B9167B31185B0DDF</stationID>
++ <name>Country @ CFQX-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>104.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Manitoba.krp kradio-3.5.13.1/kradio3/presets/canada/Manitoba.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Manitoba.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Manitoba.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,118 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>Manitoba</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>106338537235DE40FE931DDE7AB4ACE93C959304E7BFA062E7E5B078E9E2A01CF696F2C8A7</stationID>
++ <name>Rock @ CITI-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>92.0</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372BE099D03BC51FBEBDE20CBC70FC10423AD5E613054C0DDF72E787FF8CF0E4F0B</stationID>
++ <name>Hot AC @ CHIQ-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>94.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338537209A1EFF7611EAFD085F8936930DA9BBA09B829C7A6E6FD9BBE8C74694407A208</stationID>
++ <name>Modern AC @ CKLF-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>94.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853728D66D9EE218394C91355E5D110E08F362D8B68BBD1F281EAD0F96C16A0BDED62</stationID>
++ <name>Rock @ CJKR-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>97.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372C40013266B5DD98E82519FBE4A396847FA9B64C7A303AE48FCA527F959CD69FD</stationID>
++ <name>Classic Hits @ CFWM-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>99.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372D6F63A9BFC233D2F9662065C4724A4C512492F510295A78A5629A0292F4B4C02</stationID>
++ <name>CHR @ CKXA-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>101.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338537265D6BD981E58BCA3B70DD320903417E3E9FF7641AC4171E60AD659F904793636</stationID>
++ <name>CHR @ CKMM-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>103.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338537215E89F1BD490A98711E71261CFB0CF5DE9A9FF96DD0C3449E30AEC487EA1C7C0</stationID>
++ <name>Country @ CFQX-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>104.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853723C92632B65EAA085F8ADA5C1A7E22F1B6B92B68D36C334D43C2356640AC20A59</stationID>
++ <name>Rock @ CFAR-AM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>0.59</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372D6D1E62FC77378744328333B87F77C3F55ED107D2104BFE45F4E2413407747A4</stationID>
++ <name>News/Talk @ CJOB-AM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>0.68</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853729BE68A608EB4852F2FB94CFE385841CC1A8CCF6C0A2FD4821CFBABB967998978</stationID>
++ <name>Country @ CKDM-AM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>0.73</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372B082179F3FC50164F20D1A2EFB2BB65907F17A40B9D05FEE0D6EAACFBFC11252</stationID>
++ <name>Ethnic @ CKJS-AM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>0.81</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385372ADE418EAF6819DDE4859A0610BCC0D3EE140129A23EBA859986E76B7EBF718AA</stationID>
++ <name>News/Talk @ CIFX-AM</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <frequency>1.29</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/New Brunswick_am.krp kradio-3.5.13.1/kradio3/presets/canada/New Brunswick_am.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/New Brunswick_am.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/New Brunswick_am.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,22 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>New Brunswick</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385355CF17CC34E34861B4F07366466A551EFDCD3C87604508C1C731313F6A1D69874C</stationID>
++ <name>Country @ CKCW-AM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>1.22</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/New Brunswick_fm.krp kradio-3.5.13.1/kradio3/presets/canada/New Brunswick_fm.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/New Brunswick_fm.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/New Brunswick_fm.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,54 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>New Brunswick</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>106338537563FF343F7028276A4D0BFF553004AAF1257E6C11F66596198596FDFE45456169</stationID>
++ <name>Pop/Alt @ CKUM-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>93.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385375B1927CA7E6D2FD84C8C6FDD9B726EF1EF99751E38B86269C516642CE4B375A34</stationID>
++ <name>CHR @ CHSR-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>97.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853752D3E8314F46B5E97EA4E77C8FF16C17EDDDBF8D32F0D52DBE7B354746497682D</stationID>
++ <name>Rock @ CJMO-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>103.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385375B19B7BE82B799670C8A81C520BBFA43073BE523360FEDCD3C77EFB1A3E5DEAA3</stationID>
++ <name>Country @ CFQM-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>103.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853757DD605858EE796661C1F97538865E8065BF849CA2F8440D084118B0B434F3A1E</stationID>
++ <name>Alternative @ CHMA-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>106.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/New Brunswick.krp kradio-3.5.13.1/kradio3/presets/canada/New Brunswick.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/New Brunswick.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/New Brunswick.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,62 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>New Brunswick</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385376727BBC1B83D1C2F21F016FA3C6FE07FF94C5943890D6204C290509F65F6F0106</stationID>
++ <name>Pop/Alt @ CKUM-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>93.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385376925157412BAB49F3429F192B5B21AB1143E5E47CEF2AB3AD13FA2060D36B0816</stationID>
++ <name>CHR @ CHSR-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>97.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338537685E1131CEC97874856FC0B0C909388AD46A2E1BCB6A030DAB5B599F000DA370A</stationID>
++ <name>Rock @ CJMO-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>103.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385376F66B38C11B08AD05960B95CA93F34DBF9F296F090FB64E493B961D9F7870E86D</stationID>
++ <name>Country @ CFQM-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>103.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385376BD5CE49E5E3B5B55B5BACD887351669D2E469BC93AA63A6C900638D0E40D69A8</stationID>
++ <name>Alternative @ CHMA-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>106.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338537661A9F1D1C79A49DA630E16FBB7B98E764266736BEE7B3E8EA404537E60E6C747</stationID>
++ <name>Country @ CKCW-AM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>1.22</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Newfoundland_am.krp kradio-3.5.13.1/kradio3/presets/canada/Newfoundland_am.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Newfoundland_am.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Newfoundland_am.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,14 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>Newfoundland</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Newfoundland_fm.krp kradio-3.5.13.1/kradio3/presets/canada/Newfoundland_fm.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Newfoundland_fm.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Newfoundland_fm.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,22 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>Newfoundland</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>106338537789B29E90B35F99179A0AA91933650FC46E824CA5B6BF68F576B3182B55DD9056</stationID>
++ <name>Rock @ CHOZ-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>94.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Newfoundland.krp kradio-3.5.13.1/kradio3/presets/canada/Newfoundland.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Newfoundland.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Newfoundland.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,22 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:53 2003</changed>
++ <country>USA</country>
++ <city>Newfoundland</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385377D11D9B16595E641E697405179F8C6D5B562D2D0A7D84F70287AD185594E0FA2B</stationID>
++ <name>Rock @ CHOZ-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>94.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Nova Scotia_am.krp kradio-3.5.13.1/kradio3/presets/canada/Nova Scotia_am.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Nova Scotia_am.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Nova Scotia_am.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,22 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Nova Scotia</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>10633853835DC9A764A70C2E9080B031E63EAFD6F705632BEC8F8F43860CFB55EA53C20AE5</stationID>
++ <name>News/Talk @ CJCH-AM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>0.92</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Nova Scotia_fm.krp kradio-3.5.13.1/kradio3/presets/canada/Nova Scotia_fm.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Nova Scotia_fm.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Nova Scotia_fm.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,30 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Nova Scotia</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>10633853833F7B08CF4B773E874FD58D80B7FA0043373DB324A256C12C866E5244AD386EB0</stationID>
++ <name>Various @ CJLS-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>96.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853833C8F899020527563BD1F5DA705ED43D2A3FA9B43391135053FBBB273A7C0B3D0</stationID>
++ <name>CHR @ CFRQ-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>104.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Nova Scotia.krp kradio-3.5.13.1/kradio3/presets/canada/Nova Scotia.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Nova Scotia.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Nova Scotia.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,38 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Nova Scotia</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385383878D2D92A7691A444275FCF3189047A309CB29737D425D132E3C8976E9C05A4B</stationID>
++ <name>Various @ CJLS-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>96.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853839ECF21389639F415BDA39F7E8FBEFD0C6F5579F10594475BA801BD9CB1EED5C5</stationID>
++ <name>CHR @ CFRQ-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>104.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538376D203B4C09F3B3B261D56F2F0617A7D339FD7432DD788E6D85A850461D0E6F0</stationID>
++ <name>News/Talk @ CJCH-AM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>0.92</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Ontario_am.krp kradio-3.5.13.1/kradio3/presets/canada/Ontario_am.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Ontario_am.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Ontario_am.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,222 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Ontario</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385387734E601B33CF7FEF66FC8FCC05F0446D3C26E705D641C4085E63983229A98AB7</stationID>
++ <name>Oldies @ CFOS-AM</name>
++ <shortname>51</shortname>
++ <icon></icon>
++ <frequency>0.56</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538710E0424C6B045B2192E52A41633294FBC4D6D0DCE9718E7767AD3CBBB64FF418</stationID>
++ <name>CHR @ CKGL-AM</name>
++ <shortname>52</shortname>
++ <icon></icon>
++ <frequency>0.57</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387CA3C1F727A8B13541CEAB051C5D5336D7F23E176EA7D27B3836170FC8C5B9BE0</stationID>
++ <name>News/Talk @ CKPR-AM</name>
++ <shortname>53</shortname>
++ <icon></icon>
++ <frequency>0.58</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387020E218DD974FB8F1AB6C6CB4D8B197FF37F614974BAFF0FF04D1DF9C9FAFBDA</stationID>
++ <name>Sports @ CJCL-AM</name>
++ <shortname>54</shortname>
++ <icon></icon>
++ <frequency>0.59</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538700312BA43D080B58538D302DB860E404750984DD0074A916B39EC545CF1379CD</stationID>
++ <name>Oldies @ CFCO-AM</name>
++ <shortname>55</shortname>
++ <icon></icon>
++ <frequency>0.63</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387F68BD20A5BE999DE81DDEDDAA11FFC6752A43D51514986B902D70B410ACB4955</stationID>
++ <name>News/Talk @ CHOG-AM</name>
++ <shortname>56</shortname>
++ <icon></icon>
++ <frequency>0.64</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387E1DE75E2BE0F5CE4D3D2ACB40AABFDFAE5C25084D6BF6FFB203FB792C27F3F14</stationID>
++ <name>News @ CFTR-AM</name>
++ <shortname>57</shortname>
++ <icon></icon>
++ <frequency>0.68</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853879B10E0A091EF756AFFECD007746EE2EEB4C3D64E3375308E0FCC45453FB047F9</stationID>
++ <name>Country @ CJBQ-AM</name>
++ <shortname>58</shortname>
++ <icon></icon>
++ <frequency>0.8</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853874C8509AF11B4F856F570DA531316397FBE7B222BE943BCDD051780EEC0124963</stationID>
++ <name>Country @ CHAM-AM</name>
++ <shortname>59</shortname>
++ <icon></icon>
++ <frequency>0.82</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387E71997B442DCB3952D89AB290835AD5670783C9DA03A6AFCB50B2EACA5A981BB</stationID>
++ <name>Oldies @ CHML-AM</name>
++ <shortname>60</shortname>
++ <icon></icon>
++ <frequency>0.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853873FD423C2E1562B89C4E345BD4A1B1B73C677BE771291E8DB38A9F17173B4846E</stationID>
++ <name>AC @ CFPL-AM</name>
++ <shortname>61</shortname>
++ <icon></icon>
++ <frequency>0.98</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387D001E4C61E6DE920B1575B190BD9B5B37B020977E04F38576F64BA3004AD06CC</stationID>
++ <name>News/Talk @ CFRB-AM</name>
++ <shortname>62</shortname>
++ <icon></icon>
++ <frequency>1.01</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387424294ACA2638A9FA5C88E253B77DD51925A1E90878FF04CC63E7C07F8487A69</stationID>
++ <name>Oldies @ CHUM-AM</name>
++ <shortname>63</shortname>
++ <icon></icon>
++ <frequency>1.05</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853875A66270416082CB4C06DCA096DB2B946C67D50326720D285714C28771A8CF959</stationID>
++ <name>News/Talk @ CHOK-AM</name>
++ <shortname>64</shortname>
++ <icon></icon>
++ <frequency>1.07</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853877193518E7AC5D4F38FF398E79985586E2C3760CCAFC0890073424B1D3D33CC9E</stationID>
++ <name>Oldies @ CKKW-AM</name>
++ <shortname>65</shortname>
++ <icon></icon>
++ <frequency>1.09</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853872A8B3612D1E39C534F5656C13D01AAF4CDCBEA0F2D4CAAB2A4F411A8B9296CEB</stationID>
++ <name>Oldies @ CKOC-AM</name>
++ <shortname>66</shortname>
++ <icon></icon>
++ <frequency>1.15</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387876C5EB7785C42C34B17B6D5CDCD10459D37CEF452A533816684EA26C0AC8F07</stationID>
++ <name>CHR @ CJTT-AM</name>
++ <shortname>67</shortname>
++ <icon></icon>
++ <frequency>1.23</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853872BA99262573FDC126085ABAC358017391E5D5BF908BC54367785928491852922</stationID>
++ <name>Oldies @ CJCS-AM</name>
++ <shortname>68</shortname>
++ <icon></icon>
++ <frequency>1.24</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538751515E14FC1C0CAD503EA9C3A53AEE3A11A50A1D0D603C1B326586F08BD3526F</stationID>
++ <name>AC @ CJTN-AM</name>
++ <shortname>69</shortname>
++ <icon></icon>
++ <frequency>1.27</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538758A816DDFEA98055904B262B12A86C5EDD86C30B93890A4AD0CF90B69C56549B</stationID>
++ <name>News/Talk @ CJBK-AM</name>
++ <shortname>70</shortname>
++ <icon></icon>
++ <frequency>1.29</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538721ACEEACE356B2E0820D2EC3DF821EB31EBAB6CFFEFDEF2572DA4945DC923155</stationID>
++ <name>Classic Hits @ CKPC-AM</name>
++ <shortname>71</shortname>
++ <icon></icon>
++ <frequency>1.38</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853875B79C7F4383E6C762706370AEACF739D47C5712E7B832D36B04B47FC073F0186</stationID>
++ <name>Oldies @ CKSL-AM</name>
++ <shortname>72</shortname>
++ <icon></icon>
++ <frequency>1.41</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538752429D53A9F687C70E8E352F36219AD716D879F1AD41DC8FF5EE9C82EEE7734D</stationID>
++ <name>AC @ CKPT-AM</name>
++ <shortname>73</shortname>
++ <icon></icon>
++ <frequency>1.42</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538724737608C2A2A616DE49B424135B50A4F242108E8F619DD35474EAA9AF6D517B</stationID>
++ <name>Oldies @ CJOY-AM</name>
++ <shortname>74</shortname>
++ <icon></icon>
++ <frequency>1.46</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853875C1CE8727F5626C388394BF70085CE39E7B36CF507C902058A6CAD31C0FC32D5</stationID>
++ <name>Oldies @ CFPS-AM</name>
++ <shortname>75</shortname>
++ <icon></icon>
++ <frequency>1.49</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387A9A9AEDC27F800BD96818465CFBB3423E08FD4C3C27B99B27644D01A0B56DC85</stationID>
++ <name>Ethnic @ CHIN-AM</name>
++ <shortname>76</shortname>
++ <icon></icon>
++ <frequency>1.54</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Ontario_fm.krp kradio-3.5.13.1/kradio3/presets/canada/Ontario_fm.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Ontario_fm.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Ontario_fm.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,414 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Ontario</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385386BBD3399B483508CE617495612BC49B9EB8EEDDEC91D03918C1A7D9B78D05879F</stationID>
++ <name>Urban AC @ CKLN-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>88.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386402F58A2FC9ACB1732F00E4AD6953A0ACAD6002D06D280C1448BBF25C2C7CBED</stationID>
++ <name>Alternative @ CKDX-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>88.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386A6B5C6A56C654D1EF53FED84ECF71E7495689028C4209B738B97EDB64E6809C5</stationID>
++ <name>CHR @ CIUT-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>89.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853862AC1C308E19A22CE8EDCFEA3A4694B6E75D0061BE24E5184D717EE80F1F5D648</stationID>
++ <name>Classical @ CJRT-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>91.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853869940994CE36F56CC91E3755811501083CF75F3FA147B35C59EF501C6A9232BA5</stationID>
++ <name>CHR @ CKPC-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>92.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386C0B06FEBDC29742E738362C21488B6DC53E9C5467BEFF1FA1918066F33397CFF</stationID>
++ <name>CHR @ CISS-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>92.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386767DEDBC4C618CE65EB00E1860D9CD677EB6D635AA871AAC88C2E2C15C69F453</stationID>
++ <name>Rock @ CJRQ-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>92.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386DB863E27395DD2F381433DE2A61E5D129CECCE4E0054420979979EA1839E2ABE</stationID>
++ <name>Community @ CKCU-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>93.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386FAADF7AD44886F1E35744A0E93A4E52D8D4D8A28A788AC5BAE47478660A3F456</stationID>
++ <name>AC @ CFRU-FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>93.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538636200C8C40FE3BD9B35EDDD7376635BDB460DC2E212299F8F2F1382765D7F890</stationID>
++ <name>Urban @ CFXL-FM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>93.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386D7CE8D51E849BDB4DE57B733127F04B060F9C4B673440FFA7C6BDBD913028F56</stationID>
++ <name>CHR @ CKKL-FM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>93.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853864100CBE1F6361692B6F3281A8439F7DE20DCE4DA62A2BCD12A08CCEEA8C5121C</stationID>
++ <name>Rock @ CJSD-FM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>94.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853866C8E41CC7F246EEFE0FC7B12D48CB32DED00F264AC4C5B0E5A41CE94A022E503</stationID>
++ <name>Nostalgia @ CHRW-FM</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <frequency>94.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386168B69AB7EE5A725F393872C2E8D9D4A4CA1DA4B5AC15A9A0EE48A1425242D82</stationID>
++ <name>Hot AC @ CKGE-FM</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <frequency>94.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386982D84F66D2D1D415FE025064382691931D36666BAD901546E8DD9C3AA5E1266</stationID>
++ <name>AC @ CKSY-FM</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <frequency>95.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853864E34CBBC7BB3CBFBEF03686C4DD8BFEB0F1BD15F978DBF3E604AC42458E23AF5</stationID>
++ <name>Classic Rock @ CJXY-FM</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <frequency>95.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538619435BCB06CD70B3E72F9FC66A82CF7174E4715995B1119B18A415B4CA86E010</stationID>
++ <name>Rock @ CFJB-FM</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <frequency>95.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386F02EE0FE6FC1F7CC06BD0C51E16448BF0589256C1599B36B0AB1E6D559ABD829</stationID>
++ <name>Rock @ CFPL-FM</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <frequency>95.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386D8F3258DB9CAD4B877B6436F47C1A8CDFE0A1D98357CFDB87B12ACE9569390B0</stationID>
++ <name>Country @ CHVR-FM</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <frequency>96.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386FDA3B5B00A3CC38D48CBD83E67390B5739A60D9D4BF59648F5F1F39E7B629783</stationID>
++ <name>AC @ CJEZ-FM</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <frequency>97.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386DCE128C871AE0B3E88AD8914186744CEC297E7FA2695A2576E624132CFEA57F8</stationID>
++ <name>AC @ CIQM-FM</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <frequency>97.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386C478FABC579AC6F910B9F2145AFA3BE45A40C7780894B9A7D4C90B8C4C26BE35</stationID>
++ <name>CHR @ CHFI-FM</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <frequency>98.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538624D94F399AE7ACBF41F43E81FDA05AB1882D1059DA7BCFAEA87482B5DA5D376B</stationID>
++ <name>AC @ CFLY-FM</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <frequency>98.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386B4E7858A1C16F77774B6D60317734B9435A111C79867EAF33F5EEA019B2ED14A</stationID>
++ <name>Country @ CYSS-FM</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <frequency>99.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538654DEA9EA7D68F0D485BB980FF9E387487FE9278A486C32D34FD052CF4732A621</stationID>
++ <name>AC @ CKMX-FM</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <frequency>99.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386447C292FF745659014EF1F8DBF6B58414ACA6047FF9678E6DA5E5F2C7DA5A9FF</stationID>
++ <name>Ethnic @ CHIN-FM</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <frequency>100.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538625ACB8C48033773DC6DAD8B8DB3A65944A10B7624E11D6C25D091B078217ACC8</stationID>
++ <name>Alternative @ CFMO-FM</name>
++ <shortname>27</shortname>
++ <icon></icon>
++ <frequency>101.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386A164237B20FB1A881985DA52D64EFCC9D2057843BB88E3BA50B4E307BA4A86B1</stationID>
++ <name>Rock @ CKWF-FM</name>
++ <shortname>28</shortname>
++ <icon></icon>
++ <frequency>101.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538614A744DB3C84630BD3EA779761735CA6DF75FFB6E9FC2DCACCA1C25B531EA392</stationID>
++ <name>AC @ CFRC-FM</name>
++ <shortname>29</shortname>
++ <icon></icon>
++ <frequency>101.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853868D109D1121D6084BA5617FAFBF61511320C88427C243BCC345849F3E392133F1</stationID>
++ <name>Alternative @ CFNY-FM</name>
++ <shortname>30</shortname>
++ <icon></icon>
++ <frequency>102.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538690FB3CF0893E18C64F51903A11D73A99F4793CDBD16628E3CB2E39345FAA9B2D</stationID>
++ <name>Hot AC @ CHST-FM</name>
++ <shortname>31</shortname>
++ <icon></icon>
++ <frequency>102.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853863DD41F785B586BD29B07CC961DBE78A8F850040EFA43E443195FEBFC9FA3F151</stationID>
++ <name>CHR @ CFHK-FM</name>
++ <shortname>32</shortname>
++ <icon></icon>
++ <frequency>103.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386047F08B748ABA7CD3880814BF9F66C32342F7C80BFDC82DB99170F1B246BDC66</stationID>
++ <name>AC @ CKLP-FM</name>
++ <shortname>33</shortname>
++ <icon></icon>
++ <frequency>103.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386637F85CB8ACF831AA1DF14A40AA9131182F2D8C4FFB4F3B15D88E9CD3B8F6614</stationID>
++ <name>CHR @ CIDC-FM</name>
++ <shortname>34</shortname>
++ <icon></icon>
++ <frequency>103.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386907E950B4E21779DE4B34E4DEF7304C4519D2BB982DC9D366E14E741132BD337</stationID>
++ <name>Rock @ CHXL-FM</name>
++ <shortname>35</shortname>
++ <icon></icon>
++ <frequency>103.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386787853E1D7749B900FC8BC37FBABF2E367DEF584D4CB213DF45252F9E3D8E16E</stationID>
++ <name>Nostalgia @ CKDK-FM</name>
++ <shortname>36</shortname>
++ <icon></icon>
++ <frequency>103.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386F831810F48B27ED2DC2C77C3416D074C11EA8BFBC21B2433C8B03A916AA544ED</stationID>
++ <name>Country @ CICZ-FM</name>
++ <shortname>37</shortname>
++ <icon></icon>
++ <frequency>104.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853861CB5A9AEF68F8CAB403B2EB4ED350D89C35A007EF3C5046B1B334B55C430BB7D</stationID>
++ <name>Country @ CJQM-FM</name>
++ <shortname>38</shortname>
++ <icon></icon>
++ <frequency>104.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386CAA5542509AEBBCE1AB227BA3C8ED4AE99D4DEB801FF6A015F37190B0431E607</stationID>
++ <name>AC @ CHUM-FM</name>
++ <shortname>39</shortname>
++ <icon></icon>
++ <frequency>104.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386965E058688936CD2A8F1AF38046DE6DA764D5B7F21F64BB0E2F0E80CFAF6A946</stationID>
++ <name>Country @ CKQM-FM</name>
++ <shortname>40</shortname>
++ <icon></icon>
++ <frequency>105.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386A7CD1C9CF70CC34FF19A8EE55023FDE89ED1B6F4B2111C66D34EC3495BDABEFA</stationID>
++ <name>Classic Rock @ CFCA-FM</name>
++ <shortname>41</shortname>
++ <icon></icon>
++ <frequency>105.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538693A78B680171A292CA2F2BAE4415910E9495EF3A4F345AAADA1C0AA914000FCC</stationID>
++ <name>NPR @ CHRY-FM</name>
++ <shortname>42</shortname>
++ <icon></icon>
++ <frequency>105.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386F04D219347EF9006074AB70D3A4405A0F119E046A838F334B5FC99D3C5F9C376</stationID>
++ <name>AC @ CHRE-FM</name>
++ <shortname>43</shortname>
++ <icon></icon>
++ <frequency>105.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386EE619BE656B906FA217A860731E54AECC2F3058CF53FCF6F7C447C7618F1E553</stationID>
++ <name>Nostalgia @ CIMJ-FM</name>
++ <shortname>44</shortname>
++ <icon></icon>
++ <frequency>106.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386BE62C1CE01ED24B2F557DF4EE9EC54C4DC91909802DBAA0671CFFF6AB02CE793</stationID>
++ <name>Rock @ CHKS-FM</name>
++ <shortname>45</shortname>
++ <icon></icon>
++ <frequency>106.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538608B1EE52D64B3DF96C6B8FA637F4990A904E03ADC15038EB887EB7A2E32C1FF8</stationID>
++ <name>AC @ CIXK-FM</name>
++ <shortname>46</shortname>
++ <icon></icon>
++ <frequency>106.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853862F38341D678AFB178E35BC9E2EC81177E6ECF02F346AC8BE73F202C17B5506A8</stationID>
++ <name>AC @ CHCD-FM</name>
++ <shortname>47</shortname>
++ <icon></icon>
++ <frequency>106.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853863B768122EE5ABF32DF9AA18A8D489F5F232AC368ACB3FC301098A40DCACDB7F1</stationID>
++ <name>Rock @ CKQB-FM</name>
++ <shortname>48</shortname>
++ <icon></icon>
++ <frequency>106.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386ACDF712DD3826C57ECA305F40BCBFAAF5D8F34ADE81651E53F140E4A995E4D90</stationID>
++ <name>Classic Rock @ CILQ-FM</name>
++ <shortname>49</shortname>
++ <icon></icon>
++ <frequency>107.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385386F20F122F17C34424B4B3101B3FDEC0388E96395E48711F1ED50F3141B6ECFCC4</stationID>
++ <name>CHR @ CING-FM</name>
++ <shortname>50</shortname>
++ <icon></icon>
++ <frequency>107.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Ontario.krp kradio-3.5.13.1/kradio3/presets/canada/Ontario.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Ontario.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Ontario.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,622 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Ontario</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>10633853876E98DEFC969A09D6C13E4CD7C19F81DF1E95174BB71FA595BFA91E7BE4AFEF30</stationID>
++ <name>Urban AC @ CKLN-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>88.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853878C9BF92E01972A10CE22FB12F7BAC5F40CBDE7A7F6855ADBC109FF4E662EE8A7</stationID>
++ <name>Alternative @ CKDX-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>88.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387612ACBF8CCC9F553967792F51C7544AB3DB850030A05917786D7A4A07A42AF97</stationID>
++ <name>CHR @ CIUT-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>89.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853875CABE542CBF6AA88AEF61FCA1863EE48E8FCB8B2B0993E9277BC8FF154F51E4A</stationID>
++ <name>Classical @ CJRT-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>91.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387E8B15BCDD0565BC5F357AD4FC826051D3DC2CD93853F25A9CAE1A95C329C46AF</stationID>
++ <name>CHR @ CKPC-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>92.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853874CB71B000668424DB4C117AD087DBD06DCCA25DD31AE334B14F9098269CFE919</stationID>
++ <name>CHR @ CISS-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>92.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853873A28020387BE95260D4016A3858A071421107AE6F60AF9BCE6EEED8E9DD3166A</stationID>
++ <name>Rock @ CJRQ-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>92.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387B6A7C22A5CC4619A2BCF91F1D813F4F60AFCB9D4BDDEED5A500103BF8D5E9815</stationID>
++ <name>Community @ CKCU-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>93.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387E79B7801EF38DD6A0FE7758A9DCFE13F96E5A1573CC12699F6DD63A0C57E7167</stationID>
++ <name>AC @ CFRU-FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>93.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853875189655E80CC025AB1797DF35A9969AC6BF51D1B656AE48319719662E0655A14</stationID>
++ <name>Urban @ CFXL-FM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>93.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387DB5EAEE982BDB34BBBDA7D40DC39B1DE7E927B7ED50AC8F08AC15B44D5C7B366</stationID>
++ <name>CHR @ CKKL-FM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>93.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387B7D3B73330648DDC480DD5D4BB40045EBE59EF06C36D95E926059096DEE7130A</stationID>
++ <name>Rock @ CJSD-FM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>94.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853878E460B2401661EA007EC2CCA2BAD6EAFED60BEB86503C6FAAF0CDA52D09D0FCC</stationID>
++ <name>Nostalgia @ CHRW-FM</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <frequency>94.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387763E811BE7BF239EB35E6580D3D9936E7CDEEA4B28B13B8B6F59BDAED1CC0D1E</stationID>
++ <name>Hot AC @ CKGE-FM</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <frequency>94.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387A486E26543E4F633D83587B4162E2347FF26FE1AFB99C26DF5FAACC62C14A096</stationID>
++ <name>AC @ CKSY-FM</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <frequency>95.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387F7F7BC8A4760F68353D6B1B6039F80C7AF4FBA3B68565C9FB4C825B03374167C</stationID>
++ <name>Classic Rock @ CJXY-FM</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <frequency>95.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387B6E1CDC4D0369144EFD50DD7ECCB059291B9C5A5349973E76EAFB8660D28054F</stationID>
++ <name>Rock @ CFJB-FM</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <frequency>95.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853877F705CD0E90EB7C924C230EA29DA271ECF194E6E8AF366AE10A6B8DC2F913BF5</stationID>
++ <name>Rock @ CFPL-FM</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <frequency>95.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538723656F97FF16DE7B18CD714B91CD7EB15A511821CF22B155893157BFAFEDF679</stationID>
++ <name>Country @ CHVR-FM</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <frequency>96.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387AF261A8D40335B9B4BFAA43FDA39D7A7F5A53E976E6AA80CE1E85C5A4C04EC8F</stationID>
++ <name>AC @ CJEZ-FM</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <frequency>97.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853876D561577E3DC788C19571674B29C5AD5AF5D520ECFF670E7C75BE09250012207</stationID>
++ <name>AC @ CIQM-FM</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <frequency>97.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538774FFC8229642E61F322532AF4FC6DC63ECBB4AD33DDD4D658C22E4F9CC0F0A8D</stationID>
++ <name>CHR @ CHFI-FM</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <frequency>98.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853872A10FB5967CD90064B72DE60A7A25A13FE2F8ABC3466C4E40784578BF82F4E49</stationID>
++ <name>AC @ CFLY-FM</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <frequency>98.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853879EE628DA1882AC0D30A792250251A7A742AE1DDBBA5811A59B0246388426B65B</stationID>
++ <name>Country @ CYSS-FM</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <frequency>99.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387BE5A36CABF9B65A0B70E478CA2CF20F8F546636BD882184D0FDF54B74B7094C4</stationID>
++ <name>AC @ CKMX-FM</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <frequency>99.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387F32B6EF72C8B152DAF03FED92D12EB2FFC3D12CDE01AA4FB7CF118C736D6700A</stationID>
++ <name>Ethnic @ CHIN-FM</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <frequency>100.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387C4397050BB9E7BBAA1E26DCEB254B67F43984158D5F2575C1441005633392C6A</stationID>
++ <name>Alternative @ CFMO-FM</name>
++ <shortname>27</shortname>
++ <icon></icon>
++ <frequency>101.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538706412BAD92E6149D2AA9DD54571AFD4E1B42384A2BAED7979FFF6C45E0BB752D</stationID>
++ <name>Rock @ CKWF-FM</name>
++ <shortname>28</shortname>
++ <icon></icon>
++ <frequency>101.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387DD4F3EBC5658F6F0A62CDD8F3C26F303F4E14AB1A19328DC4FB0D90682D998C1</stationID>
++ <name>AC @ CFRC-FM</name>
++ <shortname>29</shortname>
++ <icon></icon>
++ <frequency>101.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853873BDA2F6A481DDDC9D578BE1587FEFF50428EBC9F88C650404F2B89ACEA75AE8B</stationID>
++ <name>Alternative @ CFNY-FM</name>
++ <shortname>30</shortname>
++ <icon></icon>
++ <frequency>102.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538716473ED7B07ED3D3427F033B89DA601941B27D9750CF6AB19DAE2877839827EB</stationID>
++ <name>Hot AC @ CHST-FM</name>
++ <shortname>31</shortname>
++ <icon></icon>
++ <frequency>102.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387EDCCD75C62578153A960662DC007092A1AEFC29D9263CB1A0802B257D1F4DCE0</stationID>
++ <name>CHR @ CFHK-FM</name>
++ <shortname>32</shortname>
++ <icon></icon>
++ <frequency>103.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387FCC1575AC7B63E73F65A4FF62360D7EF02D4E7A9108CCEEF414501862763ACA0</stationID>
++ <name>AC @ CKLP-FM</name>
++ <shortname>33</shortname>
++ <icon></icon>
++ <frequency>103.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387D9A3E774AF8667AA1BFC1BA5907836D84DE0C4C002604B8E9E5F8C3766526AF4</stationID>
++ <name>CHR @ CIDC-FM</name>
++ <shortname>34</shortname>
++ <icon></icon>
++ <frequency>103.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387256BC2D33EE81620BB8BE2BC2D01FCE6DED69B151C37604A399C817D01D97C57</stationID>
++ <name>Rock @ CHXL-FM</name>
++ <shortname>35</shortname>
++ <icon></icon>
++ <frequency>103.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853877BA40CEA39347B184BFD4CCC74D19EA2E61950BBED79671F3ED4970E7290FB50</stationID>
++ <name>Nostalgia @ CKDK-FM</name>
++ <shortname>36</shortname>
++ <icon></icon>
++ <frequency>103.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853877817B483F401A31D7828E8206898387283FCA1540CC07958302B35D487BFDAE6</stationID>
++ <name>Country @ CICZ-FM</name>
++ <shortname>37</shortname>
++ <icon></icon>
++ <frequency>104.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853870538B7B1497ED02C3E1919285BCFC3E00AE8219008687ABA87CF50519DD9EC99</stationID>
++ <name>Country @ CJQM-FM</name>
++ <shortname>38</shortname>
++ <icon></icon>
++ <frequency>104.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387B642EE3194250F31ECDDC410157AF67B1CEE6692429B92F4C8C5FD87EFAF34F6</stationID>
++ <name>AC @ CHUM-FM</name>
++ <shortname>39</shortname>
++ <icon></icon>
++ <frequency>104.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853878F35BF4F80A7C66A66CB3E5D240042CF41DFD7F476614CDC8058D585A091559A</stationID>
++ <name>Country @ CKQM-FM</name>
++ <shortname>40</shortname>
++ <icon></icon>
++ <frequency>105.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387A7CDF81610B0B74DFA711AD53B1401F5BCBF2808E4EC1F541290037D908E03C7</stationID>
++ <name>Classic Rock @ CFCA-FM</name>
++ <shortname>41</shortname>
++ <icon></icon>
++ <frequency>105.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538735B590EA8B14262A3D7E5C26F381BD2B3F672388C6A3CB8189E27540CC3197C9</stationID>
++ <name>NPR @ CHRY-FM</name>
++ <shortname>42</shortname>
++ <icon></icon>
++ <frequency>105.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853876A79F38B234FEA9275F17E25A009CCCC3799FC24DA620AB235D9402C68241EA9</stationID>
++ <name>AC @ CHRE-FM</name>
++ <shortname>43</shortname>
++ <icon></icon>
++ <frequency>105.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387225BDA02BA932246643D745C36BC2939BEA4210C339B412E994B663E6235A7AB</stationID>
++ <name>Nostalgia @ CIMJ-FM</name>
++ <shortname>44</shortname>
++ <icon></icon>
++ <frequency>106.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387F38D87244563679468C2B4BEBE2A54E7E4FB21AC53179493CD6CBBEA483D165F</stationID>
++ <name>Rock @ CHKS-FM</name>
++ <shortname>45</shortname>
++ <icon></icon>
++ <frequency>106.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853876B6A06BA95EF9D75A3471C9D7B5CD6F3F7A9DC29F948B3109B928E7A763508B6</stationID>
++ <name>AC @ CIXK-FM</name>
++ <shortname>46</shortname>
++ <icon></icon>
++ <frequency>106.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853875D7E4E4EB1D04567335789330CDCBBDCB57C9450282F5F7D9AE8DBB02EB2AD15</stationID>
++ <name>AC @ CHCD-FM</name>
++ <shortname>47</shortname>
++ <icon></icon>
++ <frequency>106.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387F8B40F9449181478EB112D7094B5084E3F568BDCBE08A688413E354F96766BCD</stationID>
++ <name>Rock @ CKQB-FM</name>
++ <shortname>48</shortname>
++ <icon></icon>
++ <frequency>106.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387C094B26D0BDE6C803C37923CC5FB32CD1EDF8DF52A3D6CB2122284A2A6C3016B</stationID>
++ <name>Classic Rock @ CILQ-FM</name>
++ <shortname>49</shortname>
++ <icon></icon>
++ <frequency>107.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538755F98172903403007BAC06168BDCD9F06B491E6C6BA44988736EC1A94A7575A4</stationID>
++ <name>CHR @ CING-FM</name>
++ <shortname>50</shortname>
++ <icon></icon>
++ <frequency>107.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538726EEE0485C0FBBD70981AE736AE24CC1474499C447208C5082513B20660644B8</stationID>
++ <name>Oldies @ CFOS-AM</name>
++ <shortname>51</shortname>
++ <icon></icon>
++ <frequency>0.56</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387C07E21EECF0A25E16F6A656EE640F2FAC4E53BA47D8AE32EC9E57F78D30E12F8</stationID>
++ <name>CHR @ CKGL-AM</name>
++ <shortname>52</shortname>
++ <icon></icon>
++ <frequency>0.57</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853878E6A34F02069592943599C06BAEFC372F3FB968695248C35544F8F65EECA9771</stationID>
++ <name>News/Talk @ CKPR-AM</name>
++ <shortname>53</shortname>
++ <icon></icon>
++ <frequency>0.58</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387D0E33C0BCF07B05815CB61EB9FC244BB4C73BCBF2B736C92284EE8D2F4D19B55</stationID>
++ <name>Sports @ CJCL-AM</name>
++ <shortname>54</shortname>
++ <icon></icon>
++ <frequency>0.59</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387EE790E6B43D12C980ECF8C55D5E947CBE9CD297B731275B2230DB86F56043C28</stationID>
++ <name>Oldies @ CFCO-AM</name>
++ <shortname>55</shortname>
++ <icon></icon>
++ <frequency>0.63</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853877E9CA0E6E7161E815266E8E12837CD9D97AD81ED5EBB768D0EF51FCF5F394DCD</stationID>
++ <name>News/Talk @ CHOG-AM</name>
++ <shortname>56</shortname>
++ <icon></icon>
++ <frequency>0.64</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853879538D6491E52FAA18DB3BC50F9241867A79B00DA53907C76D9BFCF19D50145E5</stationID>
++ <name>News @ CFTR-AM</name>
++ <shortname>57</shortname>
++ <icon></icon>
++ <frequency>0.68</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387E8D4CB03138624F10498976E0EEFE9B6E8A1414BC9CF9334848C3BEB7D7CEBB4</stationID>
++ <name>Country @ CJBQ-AM</name>
++ <shortname>58</shortname>
++ <icon></icon>
++ <frequency>0.8</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853873B47018A34F2913969C1379711467738CC1447C6D8A96A10BC816E3D08D2DF36</stationID>
++ <name>Country @ CHAM-AM</name>
++ <shortname>59</shortname>
++ <icon></icon>
++ <frequency>0.82</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387A17C05D5E7313B59164DB319C9CB5CBBE6D3648A73118ED9F1EC9B3EEFDC03E1</stationID>
++ <name>Oldies @ CHML-AM</name>
++ <shortname>60</shortname>
++ <icon></icon>
++ <frequency>0.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538764CE1690FF419201C02E1732BA9391BF94CFFBD00B8C9C1FBEA494D3171FA0F0</stationID>
++ <name>AC @ CFPL-AM</name>
++ <shortname>61</shortname>
++ <icon></icon>
++ <frequency>0.98</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387FAA32280A36E1881D28192C0585393D38DB29182FBFF509BE97BC71318317802</stationID>
++ <name>News/Talk @ CFRB-AM</name>
++ <shortname>62</shortname>
++ <icon></icon>
++ <frequency>1.01</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853876E80525B1EE7E7496987C5644DF0920681FA7843AD4EDA1D8397D8337DFCD145</stationID>
++ <name>Oldies @ CHUM-AM</name>
++ <shortname>63</shortname>
++ <icon></icon>
++ <frequency>1.05</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387E28F26BA719DEC29D74AD9414D1227E22215DB299264C5424D3DBE465BD5C3A1</stationID>
++ <name>News/Talk @ CHOK-AM</name>
++ <shortname>64</shortname>
++ <icon></icon>
++ <frequency>1.07</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853872D7635F61027AEB8847B27D16C08909EFEC3ABA42FF0F3F54C3FDE4F71B0F0D5</stationID>
++ <name>Oldies @ CKKW-AM</name>
++ <shortname>65</shortname>
++ <icon></icon>
++ <frequency>1.09</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853876C9E8B06257C7A1924CFDC270AB4C4D2C10372854AA18B8DAC4A51BD5141D0BF</stationID>
++ <name>Oldies @ CKOC-AM</name>
++ <shortname>66</shortname>
++ <icon></icon>
++ <frequency>1.15</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387E05F4659A976BDD0877DBE5DF0B38C58FAE13E0BF65A5506A0F63E4586FB0923</stationID>
++ <name>CHR @ CJTT-AM</name>
++ <shortname>67</shortname>
++ <icon></icon>
++ <frequency>1.23</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853877217F9D5FF93CE68A7A42842A02D56A35ABD3745D9379126BBA635F8CA6AEA11</stationID>
++ <name>Oldies @ CJCS-AM</name>
++ <shortname>68</shortname>
++ <icon></icon>
++ <frequency>1.24</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853876111C32C65B2382E4D8D19B92D3D315BC2F78BCF3E02A1D2811153DCA52AB765</stationID>
++ <name>AC @ CJTN-AM</name>
++ <shortname>69</shortname>
++ <icon></icon>
++ <frequency>1.27</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387F790B9D10F6151C81BB1E55667CFB7375A8065F19F3A0B7585763823F73BE172</stationID>
++ <name>News/Talk @ CJBK-AM</name>
++ <shortname>70</shortname>
++ <icon></icon>
++ <frequency>1.29</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387067AB80B3AAF92C801A95FF4F71399F279E8B452D4AA089F8D75C2D061A0B09D</stationID>
++ <name>Classic Hits @ CKPC-AM</name>
++ <shortname>71</shortname>
++ <icon></icon>
++ <frequency>1.38</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387193CFE62DC76D42AD202E169C6834AC313DDE061924E1411330D09CBDDB7270D</stationID>
++ <name>Oldies @ CKSL-AM</name>
++ <shortname>72</shortname>
++ <icon></icon>
++ <frequency>1.41</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387E63DEDF4DD5851C889E843FDDFB37136B4F9650F2F4DB3F54B18B8C827FCE779</stationID>
++ <name>AC @ CKPT-AM</name>
++ <shortname>73</shortname>
++ <icon></icon>
++ <frequency>1.42</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538776DA0BA89CCAAC57A9D6082AA848EA0CE7A2D20CEC2AE4DC02880F2ADD40671B</stationID>
++ <name>Oldies @ CJOY-AM</name>
++ <shortname>74</shortname>
++ <icon></icon>
++ <frequency>1.46</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853870C27702D5C4578D660CC1600408AFE1127C1DE8958808BD7B55B66BD0D8C7F4B</stationID>
++ <name>Oldies @ CFPS-AM</name>
++ <shortname>75</shortname>
++ <icon></icon>
++ <frequency>1.49</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385387DFD4D0AA3FED72182CA5555E2FC4A576570722C696FFABFD40BED9B946F28915</stationID>
++ <name>Ethnic @ CHIN-AM</name>
++ <shortname>76</shortname>
++ <icon></icon>
++ <frequency>1.54</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Quebec_am.krp kradio-3.5.13.1/kradio3/presets/canada/Quebec_am.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Quebec_am.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Quebec_am.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,30 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Quebec</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385389651181978E67E42215B4D30FD0060862B14D472B7E30917A978E36DC88F0313B</stationID>
++ <name>Talk @ CIQC-AM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>0.6</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385389E338FDF6FABED3D9A576513AECF04FD40E5001DC5B003893B4671B73BDDA9150</stationID>
++ <name>Talk @ CHRC-AM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>0.8</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Quebec_fm.krp kradio-3.5.13.1/kradio3/presets/canada/Quebec_fm.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Quebec_fm.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Quebec_fm.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,94 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Quebec</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385356CD9DD1A93794AB3675AB047B8E4E884FAA312F187A73AA6CB6919076C39CEB7B</stationID>
++ <name>Alternative @ CFAK-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>88.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853563B41E95179A54ECB4A00D6E0A80861B7BD22AA334A618FB85F0555F265EE2EE1</stationID>
++ <name>Ethnic @ CHCR-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>89.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853568287524B70496005D97E3E9487853AB5A9DAF272E9A5F099D853C2D940097BD8</stationID>
++ <name>AC @ CFQR-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>92.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853569402DBD98AB56C5A1D2A3705D4D023215C970130602DCCF105A42753CFDAFFE8</stationID>
++ <name>Alternative @ CFLX-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>95.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853566FDEC9652755850D746766CFF88B7B4420EA0D990C5CD2A17A7C52E2E572C1DC</stationID>
++ <name>Hot AC @ CJFM-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>95.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338535667B9AB049DC36A573F0B8AC3C73B78082A6CE5B36B640F94B9785CA51D5E536C</stationID>
++ <name>CHR @ CHOM-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>97.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385356A8AF6535A854DF52826B4E93CC763A9FC1610BC78163BFB0C30969DCDA6A02EA</stationID>
++ <name>Alternative @ CHOI-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>98.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853561CA6E44132CAFF8CDD7F6911708046B4EB1540F7156FE27DC8EE2F833EFAAECD</stationID>
++ <name>Oldies @ CFOM-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>102.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385356C718716056A273CAC1E4EABF02B9692085AA575B90A02139B050E05B4AAB0535</stationID>
++ <name>CHR @ CFJO-FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>103.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385356B14958EA8D57D93486064ADB374F0E1E3E6F15DE22BFA26C3D01B26708F902C9</stationID>
++ <name>Urban AC @ CITF-FM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>107.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Quebec.krp kradio-3.5.13.1/kradio3/presets/canada/Quebec.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Quebec.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Quebec.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,110 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Quebec</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>106338538917B618E7F0EEC470EB266AF65B527C0FC38A8E8BBBAC09E65D149B9ACC737FD4</stationID>
++ <name>Alternative @ CFAK-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>88.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385389DFF8E8EFF4060F58A180BC540D88960C7D3BAF568F774DA3DBB94AC70C1AFE1F</stationID>
++ <name>Ethnic @ CHCR-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>89.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538963B8F0086E9B6B22C97B41C51136DC2D2DB620421A9368BF07C32F1FBED1F98F</stationID>
++ <name>AC @ CFQR-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>92.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853895625E419BD1CDDBAE521E96DC15523CA7EA87DE945BC22354195F46E4E7FAB5C</stationID>
++ <name>Alternative @ CFLX-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>95.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385389D50371EF969ECC882716053C947FE4AA98147B1C354409E4FDCAA99C7765B9D0</stationID>
++ <name>Hot AC @ CJFM-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>95.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385389ABF38CC786A66D9E071AC6D4BA04CC8EE646205D74BC4CE9784A39BD07382AF3</stationID>
++ <name>CHR @ CHOM-FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>97.7</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853893C7A2C1B5B37A7D3DFF22237A0876D496FBFD44757541ABBD3FDBF572AF1630C</stationID>
++ <name>Alternative @ CHOI-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>98.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385389468260BA2B79BAAA971EFECA5B2C8AAC389782E3B85C726356AF8AB4A431B8FC</stationID>
++ <name>Oldies @ CFOM-FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>102.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538903A7AB9379C1918F3F321B18682958D071C70B0BE42F443DAD8E2B79550E32DE</stationID>
++ <name>CHR @ CFJO-FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>103.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385389D76EFB944D1D56D794BAFC219FA7911878F0EDCAC12BDD561549C32F1F334EB8</stationID>
++ <name>Urban AC @ CITF-FM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>107.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338538925183644B8075C87D6A37CC43D6B9136D5FC77CE7F72D51CEDA492CDE6D56582</stationID>
++ <name>Talk @ CIQC-AM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>0.6</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385389174B649D33F7845E1E4B9435DAEFFCF97ECABAABE3E4D191B018DEFA410D187E</stationID>
++ <name>Talk @ CHRC-AM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>0.8</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Saskatchewan_am.krp kradio-3.5.13.1/kradio3/presets/canada/Saskatchewan_am.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Saskatchewan_am.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Saskatchewan_am.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,70 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Saskatchewan</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>10633853922CBE03E5BF8155703EC10D3E0C3FAE6A256CB4FD8AB3CE2D3832C8F3E1951C2A</stationID>
++ <name>Country @ CJWW-AM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>0.6</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385392C81C9FB8F948767E9597ED261EA84C3C81BB082E9D5132C5CF46707342AD1930</stationID>
++ <name>Oldies @ CKCK-AM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>0.62</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853928B14DAA96CD8E42A0B7BA74D75F99D64FFD6DF1E7B04DBA5D1C39C723B01164E</stationID>
++ <name>Country @ CJVR-AM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>0.75</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853923BCD4914F1F6A90B213F161DC962B060AE5C9819AE5586728D7A879F69A5A8CB</stationID>
++ <name>New Country @ CKBI-AM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>0.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338539297B6A4F7667AE83208F641C1019592CCC7D78CEFB54B6B192061CD27F954DCFD</stationID>
++ <name>Country @ CKRM-AM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>0.98</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338539203382F7D0844AAC2ED0844A0D0A75B2783B6FA435382D0E81B1B41E06D605034</stationID>
++ <name>Hot AC @ CFYM-AM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>1.21</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338539243EDB5DB93FBF91FE7E44DF60204953F4C2C29742D7541272FA4919CC9DBBEE3</stationID>
++ <name>Hot AC @ CJYM-AM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>1.33</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Saskatchewan_fm.krp kradio-3.5.13.1/kradio3/presets/canada/Saskatchewan_fm.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Saskatchewan_fm.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Saskatchewan_fm.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,54 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Saskatchewan</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>106338539149CCF4BDBBBE1DD4D4D882464CECF011290172C50BB99EA9E69086A9B6EA4764</stationID>
++ <name>CHR @ CHMX-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>92.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385391CEEAF5E63A4936D1346D7EB79F9E7A6D4729E3E96C3B91153E69312BFB219596</stationID>
++ <name>Country @ CFQC-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>92.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853912B0A5E29B34ECDF206DADE105BF251C8F1941E50C2206F9987AE54446F9503CB</stationID>
++ <name>CHR @ CFMC-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>95.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853918828B2B765310949888688E194181918A9F8AF854094462A385790FA81FA6E73</stationID>
++ <name>CHR @ CFMM-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>99.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338539163B0B17992A2632030645ED944EFD4395A96939F2340A9E77F5937735BFAD899</stationID>
++ <name>Rock @ CFWF-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>104.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/canada/Saskatchewan.krp kradio-3.5.13.1/kradio3/presets/canada/Saskatchewan.krp
+--- kradio-3.5.13.1/kradio3/presets.old/canada/Saskatchewan.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/canada/Saskatchewan.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,110 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>G. Richard Raab, rraab@plusten.com</maintainer>
++ <changed>Sat Jan 18 14:31:54 2003</changed>
++ <country>USA</country>
++ <city>Saskatchewan</city>
++ <media>antenna</media>
++ <comments>Generated from http://links.radio-online.com/stations.htm</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385392F117413BFADF22E4E72F4745D7323B099F1F28A2CAD22EFC5D33B66661E24D2D</stationID>
++ <name>CHR @ CHMX-FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <frequency>92.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338539234488E7C829A5C45B21E9214262665CEEED21A70823942A69FD442B2B97368D3</stationID>
++ <name>Country @ CFQC-FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <frequency>92.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385392F46C1FA4EBE0AB793FE0C6672232B68810CD9149C8C68F32E553421A62FF6098</stationID>
++ <name>CHR @ CFMC-FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <frequency>95.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853926160480419127C9EAA00305CF902A6E1781A04134A1D2A264E8E727AD473448A</stationID>
++ <name>CHR @ CFMM-FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <frequency>99.1</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853922E23923749C3468C56ACA0DE9C402916DDBEBE083BAC6E34763BC5F2A1CB6725</stationID>
++ <name>Rock @ CFWF-FM</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <frequency>104.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385392ACA62862EA04E38850B9CCCF44BAD3AC95E05FD6938B4D23E561108F68EEB6AF</stationID>
++ <name>Country @ CJWW-AM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <frequency>0.6</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853921246AA0CC5D6569CAAD7B9122EBC9BA3BF74F4A56486DEF9E37B77AB4C7A900C</stationID>
++ <name>Oldies @ CKCK-AM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <frequency>0.62</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385392BAA64D7CDCCD7C1CF46A513FFE2815B12F602FE0BA67F5C1A699B302A66E26C9</stationID>
++ <name>Country @ CJVR-AM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <frequency>0.75</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385392454E721BD87FB3F8D707CB0E681E8D981EDF4092A809A109AB55708657D82DF0</stationID>
++ <name>New Country @ CKBI-AM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <frequency>0.9</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338539242BD87899BB87FF733DB4E48EEB3CA70C5F65526232C1CC039A3395C4EDC90DA</stationID>
++ <name>Country @ CKRM-AM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <frequency>0.98</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106338539225BCE8632827B870192D3E43907F7CE2A240C38B527EA85F0D9EEF6B32C9D4B9</stationID>
++ <name>Hot AC @ CFYM-AM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <frequency>1.21</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385392A4B7EBA582A1129D21179B617FFF95C3CDA93BC906C357943486E5516E0EB716</stationID>
++ <name>Hot AC @ CJYM-AM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <frequency>1.33</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/colombia/bogota.krp kradio-3.5.13.1/kradio3/presets/colombia/bogota.krp
+--- kradio-3.5.13.1/kradio3/presets.old/colombia/bogota.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/colombia/bogota.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,330 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0</creator>
++ <maintainer>Camilo Guevara Isidro &lt;mylosoft@gmail.com&gt;</maintainer>
++ <changed>2010-02-07T17:07:49</changed>
++ <country>Colombia</country>
++ <city>Bogotá</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1265586572E5657722177EBEA73DA4FF0518811C3484A717A9C12CC4C4BFB3B0340A8B</stationID>
++ <name>88,9 - Radio Uno</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126558534656E8020B1D8585EC1EE27CA7DB8365FCF5703EC1AE1EFBE7CFB12ABBA2CA</stationID>
++ <name>89,9 - 40 Principales</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265585398C027C4454EE87E3CF0BF2626DE27ECF258CBAD3A77F9F1651FA97A221841</stationID>
++ <name>90,4 - EMISORA HJUD LAUD (Universidad Distrital)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126558544558FC2009395BF1D9EF06D190DF6C4DC5B57BF0DC09F842010FEAAA002E3D</stationID>
++ <name>90,9 - La Mega</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265585512B2A5E1E6BCF0D7755E8809B02B4E2EFFAD5E7EB5CC1539019249A85D88E4</stationID>
++ <name>91,3 - Vilmar Stereo (Faca)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12655855391167AC86413F107081FE6AC284347816867044B554DF12CBAF74502AD604</stationID>
++ <name>91,9 - Javeriana Estereo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265585568699A8595F69B73223A07CA49137AE95C4DF49FB268AC8BEAA7FB6E1EA027</stationID>
++ <name>92,4 - Radio Policía Nacional</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126558560029169A35872F465CB876832E32CBBAC8FA092BCACDB8321092BB2BD99E34</stationID>
++ <name>92,9 - La Z</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265585620BB32D339B7D584101BDB753F8543163ACF118BA83B2130D1AA6639098061</stationID>
++ <name>93,3 - Unilatina Stereo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12655856443DAAFEE2E8E0208C6DFFE33E3FCAE978CD0DA7A86C2EAE9466AC299E13C3</stationID>
++ <name>93,4 - Colombia Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265585687761E6CB5384A4183D5B3CAEADF288BB781333F3C148B36E58C949C05378A</stationID>
++ <name>93,9 - Amor Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265585715EA2BE0C18E090093A7DD6EC6EF328ED54FF6AC5B26C7685D2F591156BC94</stationID>
++ <name>94,4 - Despecho stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265585747C397779EDAECA1EBBE137D71D7FDE6D7A1FD9368B4317A4788B183C5DB0C</stationID>
++ <name>94,9 - La F.M.</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265585765AE4E456336743FADC6F062B0A5EC912CE7449E771EE244C1AA69ADAF553D</stationID>
++ <name>95,4 - Quinta Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126558588417E1F181DA2BFEDF54050C1B5A634AC21D3F20B07AFAFBD83AB5B83A29EC</stationID>
++ <name>95,9 - Radio Nacional de Colombia</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126558592626C3EA5E78B816C4F441F8125FE77A2DD2F2E08684DA94FB8EC9C799C500</stationID>
++ <name>96,3 - Alternativa Stéreo / RCN Radio Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126558595451674B61A73EDD66BEE83371394479C90D318B2616CF3EBAE27DF8A020A5</stationID>
++ <name>96,9 - Melodía FM Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265585990BF6F27CAB43016860538C68D61C6D28D09664C3DB7ABB76124585B13A85F</stationID>
++ <name>97,4 - La Vallenata</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126558605213FD122E47EFCE1529547FCFA5E5A62F78B752F91DA2AD6FF29292AB0D8B</stationID>
++ <name>97,9 - RadioActiva</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586077C1C779B863DF0AEFD7A40C691FF5CB0B316400AF784A5A2B4280C098C078</stationID>
++ <name>98,5 - UN Radio - Emisora Universidad Nacional</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586107CBDDE91DE818CF1DC7C165DBEE97FC6EA7D00310919651673631A9A21498</stationID>
++ <name>99,1 - Radionica</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586123ECADAEB507405B7C51062AA1EF04E1DCDBE4852B39D1463C904FC044A969</stationID>
++ <name>99,9 - W Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586139D948BCFA0F57A6F8459CCE29055C6E59B51D21799318B84A18BA5FF97426</stationID>
++ <name>100,4 - Oxígeno</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12655861609F8D34C018D14435BD84EAE180213E1DAC209A38B5CFEAEF16822B791A64</stationID>
++ <name>100,9 - Caracol Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586188B331F176F32CFDF203ED323F3DF5DD9739B102B58F881754E128E80AB301</stationID>
++ <name>101,3 - Mauro Stereo - Funza</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586210C72E262B4123BE023000CF7B19BAAC35096F216B6FDB89829E279DF14B3B</stationID>
++ <name>101,9 - Candela Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586239A3A27E61661E60A972C3FAFE8AAE4EBEC0215906927FD023370BC7D03B51</stationID>
++ <name>102,9 - Tropicana Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586271BD4564DEB5AFA57B5D623461D8F41378348E7E7787065469DE8EAA9FD30B</stationID>
++ <name>103,9 - La X</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12655862903E11B0402AC81471A11C5DE3D5D3A6B3878A58676B737A9F90371D0EA834</stationID>
++ <name>104,4 - RCN Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586314D4AEB10D8887486F301C61C4D7CED780A7AF5F53B9AEB1C05D122B6BA293</stationID>
++ <name>104,9 - Vibra Bogotá</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12655863376F22B915AA76D4DC6A6343E990918ADEB5D27FAB7066CC7EBDF303997C68</stationID>
++ <name>105,4 - Rumba Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1265586361EA6092AAB1DC59589F99C73013CD37B554E7F95D8E5F652F26AB7D206BEB</stationID>
++ <name>105,9 - Olímpica Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12655863869246EB11A58366B4091C5A068AE0FA22C8759324D2527E1AB7EE1ED5D0B9</stationID>
++ <name>106,9 - Universidad Jorge Tadeo Lozano</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126558641326CC0554E127440B8CCF9533F9BA88BFB6CE48DDBF1932B0E5F006DB5400</stationID>
++ <name>107,4 - Radio Rumbo Stéreo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126558644096CF476B3D0758B75660C491437181EE5702DC2CB4C54A7A46CCFCCF817D</stationID>
++ <name>107,9 - Minuto de Dios</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/colombia/Makefile.am kradio-3.5.13.1/kradio3/presets/colombia/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/colombia/Makefile.am 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/colombia/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,9 @@
++SUBDIRS =
++EXTRA_DIST = "bogota.krp"
++
++install-data-local:
++ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/colombia/"
++ $(INSTALL_DATA) "$(srcdir)/bogota.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/colombia/bogota.krp"
++
++uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/colombia/bogota.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/croatia/Makefile.am kradio-3.5.13.1/kradio3/presets/croatia/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/croatia/Makefile.am 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/croatia/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,9 @@
++SUBDIRS =
++EXTRA_DIST = "split-cable.krp"
++
++install-data-local:
++ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/croatia/"
++ $(INSTALL_DATA) "$(srcdir)/split-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/croatia/split-cable.krp"
++
++uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/croatia/split-cable.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/croatia/split-cable.krp kradio-3.5.13.1/kradio3/presets/croatia/split-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/croatia/split-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/croatia/split-cable.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,231 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0-rc1</creator>
++ <maintainer>Ivica Božulić &lt;ibozulic@gmail.com&gt;</maintainer>
++ <changed>2008-04-05T16:59:08</changed>
++ <country>Croatia</country>
++ <city>Split</city>
++ <media>Cable</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>120740751328238D2159D5831AD30B26BA2A5A66CD1984B82075078737563C2FD2EA5E1557</stationID>
++ <name>RADIO SPLIT</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.4006</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407508E3A4EBB3E570DD94433A956AB7448DB5968860538E1D6A359FD70C0938F32171</stationID>
++ <name>OTVORENI</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.8505</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>120740751775D937D8C6A07B0E5A3FF7A690E85481ED81940F462705AD3A45FACE5161BFB5</stationID>
++ <name>DALMACIJA</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.0257</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407510D1E25B12ACC9660E602B300E6CF8E54E477F3C115442852B575AB2CDF5F27679</stationID>
++ <name>KL EURODOM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.6256</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407504EB158B4F1CF4176B28BF214BD88BA8A96C7FB26B6B17EA660FEFEC8092D303DF</stationID>
++ <name>RIVA</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.6504</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407500E9B6C096D64A894A068FABE75A019716C3B748D916EA2E354D69D7BAB862E5C4</stationID>
++ <name>RADIO SALONA</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.7253</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>122097750466D2BAFC3BC580FF5394F5F374F90D3DBB4AAC5A5155453A54F2E57A163BBE5E</stationID>
++ <name>DIN-DON</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1220977448C1DF1B92704B74A403BBFA80772DC0AAE78099963484B94A4FCAD98D69E3EC2F</stationID>
++ <name>RADIO TROGIR</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407498389C4F99C767482BD69BF12E465DB9E0E5909D7655D16EB4A11E06DB9696C81C</stationID>
++ <name>RADIO KAŠTELA</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407516A0B01C6CA2CB9A40C6EC11394D665983073B0D42444011652721645FEA061C30</stationID>
++ <name>HR 1</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.6507</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12074075150544492C037A467AC5F2A3B7FBC286954BF27034A44EEC379C1FC5CB1FDE64EC</stationID>
++ <name>HR 2</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.2007</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1220977646E1B29A182D5572F2B7CBCF7F2814D50923CB1CA312E83C75CE29E5E6D638678B</stationID>
++ <name>HR 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407511DBF4FAC44CA53796F2D74A357697A1E212F00C53838EFFD7AA648B2E147EC50E</stationID>
++ <name>NARODNI</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.0506</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12074075011E1E049ACABAB05DB23C164C4FD4102C4CD48A1C66CE8F9C12A6427A8B0EDBF2</stationID>
++ <name>RADIO BRAČ</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.3504</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>120740749651539469F93B7B572ACF9BA16639803013B692A1925A4CA5336FB9BCA7708A47</stationID>
++ <name>MEGA MIX HVAR</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.5252</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>120740750359F725F0F47690F7ED5EB1771CAE0D65DD4A7B6A1C8D51B26E69F0802E5A3A60</stationID>
++ <name>NAUTIC</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.9254</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407507B8D6C9AE7C806221B94CB81132248F208BE1546980C50BAC1B99DD42A3056760</stationID>
++ <name>KATOLIČKI RADIO</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.4255</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12074075240C0FA4E55B55464681E3185E457C820E0E3791E4AEA8E3C7A26A1698DBB83A65</stationID>
++ <name>1 LIVE (ẆDR)</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.626</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>120740752872ED80D1CA5FAB754D53BFE3FB2AC696485DF2D97C7D2A95C2F001196206CF9E</stationID>
++ <name>SUNSHINE RADIO (Pro Sieben)</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.251</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12074075337B5A5DCC896803FEF4ED2896F3E9C95A7A4C1644C0CF9D421AB1C63855FE5BCE</stationID>
++ <name>KLASIK RADIO (Vox)</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.126</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407535BDE94774C396714FA26A50F5CFCA6513E8CCAFF38F1C27A21D4050165345ED78</stationID>
++ <name>RTL RADIO(Vox)</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.951</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12074075381C8E6295357ED296DADEF6A7D2E294F8C14A621F0326E02C50F5B8EBD46809CC</stationID>
++ <name>ROCK ANTENNE (Kabel 1)</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207407539569A37859951819D18B33C11C57D6FFB95D75DA69461023B1157880CB90BDEAB</stationID>
++ <name>ANTENNE BAYERN (Kabel 1)</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.651</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12209778051F47033DD3C846295AFC5E1DE6F5AEB5C075DBB37FFE4ECE772BBC8EC12E4F16</stationID>
++ <name>JAM FM (RTL2)</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.4</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/czechia/ceske-budejovice-antenna.krp kradio-3.5.13.1/kradio3/presets/czechia/ceske-budejovice-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/czechia/ceske-budejovice-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/czechia/ceske-budejovice-antenna.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,143 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Petr Urban &lt;urbanp1@seznam.cz&gt;</maintainer>
++ <changed>2008-04-08T17:03:40</changed>
++ <country>Czech republic</country>
++ <city>Ceske Budejovice</city>
++ <media>Air</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1207666974509EE882BDBA2D87DC38D38A0BCEF0D51C991F4DBB617CD0208EDA11DAD9CAA9</stationID>
++ <name>ČRo1 - Radiožurnál</name>
++ <shortname>ČRo1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>120766698430190D64A0BA139E954D1E43B89612D5502C1F86C80C1642E1DD430B845549A5</stationID>
++ <name>ČRo2 - Praha</name>
++ <shortname>ČRo2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207667006DBB1303ED14BC81ADF7DF384A388B2943FB58EC931A293F9112CBB4D761B0871</stationID>
++ <name>ČRo3 - Vltava</name>
++ <shortname>ČRo3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207667008A26C97E5F7612C0820EE87362AB88E2EA0DBC8B74339996B5D14DFA56E79E3C3</stationID>
++ <name>ČRo5 - České Budějovice</name>
++ <shortname>ČRo5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>120766702720B7E904410567F2DFB9CBEBEBD8BE64101515C6C1F9D6187482402554A9D1D7</stationID>
++ <name>Kiss Jižní Čechy</name>
++ <shortname>Kiss</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207667739D293C26B631ACC80488CCCFE98D8A3CC0A7C56AFA7B7981B91AEB345E6E07054</stationID>
++ <name>Rádio Blaník JČ</name>
++ <shortname>Blaník</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207668015852339FEC6B77D79165DE45D45965DAA1E179ECC574D4A3CA3B2F10077FB99B8</stationID>
++ <name>Frekvence 1</name>
++ <shortname>F1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207668044C717459C7325BF313BF5FC6BE2ECA70D06BDDFEEB4E66AEA7AB5B8460F85DB99</stationID>
++ <name>Radio Impuls</name>
++ <shortname>Impuls</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12076680971544CB58DA52B02BDB7A3E8D1D02AFEF2F7B2E31DDBC891EE5FE6F5E814081DB</stationID>
++ <name>Hitrádio Faktor</name>
++ <shortname>Faktor</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12076681867F98C7B592723F35E8EF67EC33A823C164F88A740681041EDE7FBFEDA1DC6AD4</stationID>
++ <name>Evropa 2</name>
++ <shortname>Evropa 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>120766823348F4850F00D515F62DA7FBFF0A75C47701649A96D6F2EBC8F7FC6F2A0333FC4E</stationID>
++ <name>Radio Proglas</name>
++ <shortname>Proglas</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207668324BA0EAC424584D6FA18AEE86392411AEB1B1625B2B8019CBC58FF6A01BC9E9C35</stationID>
++ <name>Radio Faktor Gold</name>
++ <shortname>Gold</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12076670307AE2B3DF6C6D8F3223287781D174FA9B1C92B75F4239837EBCD5DA4C40C9FCDC</stationID>
++ <name>Rádio Beat</name>
++ <shortname>Beat</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1207668385CFDDA6ED02FA809768C7939C1A2CCBFD9C6D688BE6C2A654A58024802A9A4C26</stationID>
++ <name>BBC/ČRo - Rádio Česko</name>
++ <shortname>BBC</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12076705683C91C317574ADC848753E468585597BF46A7348C65F6F01083B97486AA04908B</stationID>
++ <name>Radio Šumava</name>
++ <shortname>Šumava</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12076727277A7919C9F95D6C9B86F7D8EAB2CC76B3D139085C6125F0CBA4561344CBE73AD1</stationID>
++ <name>Life Radio Ober Oesterreich</name>
++ <shortname>Life</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/czechia/Makefile.am kradio-3.5.13.1/kradio3/presets/czechia/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/czechia/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/czechia/Makefile.am 2012-11-25 00:48:00.000000000 +0100
+@@ -1,16 +1,18 @@
+ SUBDIRS =
+-EXTRA_DIST = "ostrava-antena.krp" "plzen-antenna.krp" "plzen-cable.krp" "prague-antenna.krp"
++EXTRA_DIST = "ceske-budejovice-antenna.krp" "ostrava-antena.krp" "plzen-antenna.krp" "plzen-cable.krp" "prague-antenna.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/"
++ $(INSTALL_DATA) "$(srcdir)/ceske-budejovice-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/ceske-budejovice-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/ostrava-antena.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/ostrava-antena.krp"
+ $(INSTALL_DATA) "$(srcdir)/plzen-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/plzen-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/prague-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/prague-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/plzen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/plzen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/ostrava-antena.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/ostrava-antena.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/prague-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/prague-antenna.krp"
+
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/ceske-budejovice-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/ostrava-antena.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/plzen-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/prague-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/plzen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/ostrava-antena.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/czechia/prague-antenna.krp"
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/england/Makefile.am kradio-3.5.13.1/kradio3/presets/england/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/england/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/england/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -1,18 +1,20 @@
+ SUBDIRS = buckinghamshire
+-EXTRA_DIST = "exeter-antenna.krp" "leeds-antenna.krp" "london.krp" "newcastle-upon-tyne.krp" "sheffield.krp"
++EXTRA_DIST = "exeter-antenna.krp" "leeds-antenna.krp" "london.krp" "milton-keynes-antenna.krp" "newcastle-upon-tyne.krp" "sheffield.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/england/"
++ $(INSTALL_DATA) "$(srcdir)/exeter-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/england/exeter-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/leeds-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/england/leeds-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/london.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/england/london.krp"
++ $(INSTALL_DATA) "$(srcdir)/milton-keynes-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/england/milton-keynes-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/newcastle-upon-tyne.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/england/newcastle-upon-tyne.krp"
+- $(INSTALL_DATA) "$(srcdir)/exeter-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/england/exeter-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/sheffield.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/england/sheffield.krp"
+- $(INSTALL_DATA) "$(srcdir)/leeds-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/england/leeds-antenna.krp"
+-
+
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/england/exeter-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/england/leeds-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/england/london.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/england/milton-keynes-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/england/newcastle-upon-tyne.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/england/exeter-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/england/sheffield.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/england/leeds-antenna.krp"
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/england/milton-keynes-antenna.krp kradio-3.5.13.1/kradio3/presets/england/milton-keynes-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/england/milton-keynes-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/england/milton-keynes-antenna.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,72 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Ian Hay, &lt;ian@rotodyne.co.uk&gt;</maintainer>
++ <changed>2003-01-25T22:35:18</changed>
++ <country>England</country>
++ <city>Milton Keynes, BUCKS</city>
++ <media>Antenna</media>
++ <comments>A poorly served and weak area for reception</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1063385353C6B88DA43D60485F93CE285F49666657543D54E610AB347EB1D73FDA2FC7C510</stationID>
++ <name>BBC Radio 2</name>
++ <shortname>BBC Radio 2</shortname>
++ <icon></icon>
++ <volumepreset>0.8</volumepreset>
++ <frequency>88.6097</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853532D933FCEF3A7613BDDD56EBF088F9B6362B69E0FCABB21DFFC26D9AC81DC28BD</stationID>
++ <name>BBC Radio 3</name>
++ <shortname>BBC Radio 3</shortname>
++ <icon></icon>
++ <volumepreset>1</volumepreset>
++ <frequency>90.8185</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385353C8BE87758A09C21FC727E3B7C8DE412595703F2E19438F5B7FBCD509531751D5</stationID>
++ <name>BBC Radio 3</name>
++ <shortname>BBC Radio 3</shortname>
++ <icon></icon>
++ <volumepreset>1</volumepreset>
++ <frequency>90.8634</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853533F24308814CEC86F7F2D451AF6CE0ADAA1EBBDED5507D7E1ED04AF7BB93C5E2C</stationID>
++ <name>BBC Radio 4</name>
++ <shortname>BBC Radio 4</shortname>
++ <icon></icon>
++ <volumepreset>1</volumepreset>
++ <frequency>93.0197</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385353606298F24CB48B4D31470EF41B4AF40F4BF19AF4CA0019E972419C5E5FDF2A7B</stationID>
++ <name>Classic FM</name>
++ <shortname>Classic FM</shortname>
++ <icon></icon>
++ <volumepreset>0.8</volumepreset>
++ <frequency>100.446</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1063385353E2F2EB1467A831526FB14696A5FE35FAD1623929349D8A8C9DC7F9A3EFB87F93</stationID>
++ <name>Horizon FM</name>
++ <shortname>Horizon FM</shortname>
++ <icon></icon>
++ <volumepreset>0.8</volumepreset>
++ <frequency>103.324</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10633853535F8DF276212D9521388835FE08AFEA463B8A2AE6BDFBD3B6AC34D330F9EE2613</stationID>
++ <name>BBC 3 Counties Radio</name>
++ <shortname>BBC 3 Counties Radio</shortname>
++ <icon></icon>
++ <volumepreset>0.8</volumepreset>
++ <frequency>104.518</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/abbeville.krp kradio-3.5.13.1/kradio3/presets/france/abbeville.krp
+--- kradio-3.5.13.1/kradio3/presets.old/france/abbeville.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/france/abbeville.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,127 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-unknown</creator>
++ <maintainer>Ren Riassetto &lt;rene.riassetto@fcvnet.net&gt;</maintainer>
++ <changed>2010-07-22T20:37:19</changed>
++ <country>France</country>
++ <city>abbeville</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1284670092CBB4B2223036021E901E948C5C89F0B128B7A4FE4844AA89DB5E2B9A9608A5A3</stationID>
++ <name>Europe 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092648660A98566A70CACE41486F03F4399DB65FB3ABACD5C055203FB39AE440499</stationID>
++ <name>Fun Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092B3619B5DE060324713328B8FAA5A7693FE9DA955C0889589E7E77119581F401C</stationID>
++ <name>France Musique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700922805BF9C1B19351F89DEA4E887493DF8F908A77B809BF5264FF30920CED7D361</stationID>
++ <name>Radio Soleil</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092CCD737EC9A595C0FA42A693AE4B9BD9BDEE561D29B035D9A3E934FBB538861E0</stationID>
++ <name>Contact</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092AF1640DAE80035EBA6DFDB4900619CA63A09B5BE7E696D9E588444209E814B74</stationID>
++ <name>RTL</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700923B52A20FAE2A9AD685AED4BCFDFA22D434AAD14CE9FE60EA08EE5144532BA8C8</stationID>
++ <name>Skyrock</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092AE5A89FF1501F8389594E2F77D608534EBA38EF82983388C01851326D10A90F2</stationID>
++ <name>France Inter</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700924E2152476AFE9B26576E130FE4A3537120E816F60944D84557FB4D04058A18DF</stationID>
++ <name>France Bleu - Picardie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009240334916A605A6359ABA11A3201B2DBF572D26EA1A453835C7718FD16E810DF1</stationID>
++ <name>Chérie FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700925022C005489EB6C1C182D5E3A7DE856419EFF889EC7E79F4C928A913871F465D</stationID>
++ <name>NRJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092160F1146D4E5A9B6FFA578AF3EF1E9E4B9B6DEB84ED95244934E3AEADF7CACFA</stationID>
++ <name>France Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092E69028D981D566C9E356F1C57F4D731C82424DDD41F57280CF409001BBC12F1A</stationID>
++ <name>Europe 2 - Fréquence Picardie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092A04C60A71A8CED83F526DAFC306DBF70B846B68D5D86BAC9223AAD392C852AF7</stationID>
++ <name>France Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/amiens.krp kradio-3.5.13.1/kradio3/presets/france/amiens.krp
+--- kradio-3.5.13.1/kradio3/presets.old/france/amiens.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/france/amiens.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,187 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Erjon Seferi, &lt;erseferi@wanadoo.fr&gt;</maintainer>
++ <changed>2008-07-12T14:58:40</changed>
++ <country>France</country>
++ <city>Amiens</city>
++ <media>?</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>12158657143024D1EC38E41C3981C2A3DED5B2457328B7E3D46BE37F8131554A8535B6E3B6</stationID>
++ <name>France Musique</name>
++ <shortname>Musique</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1215865745F6AE866FAC40BCC63AED628D4F1970C5D65A7925430C2CC4AB71D97B7C900A6E</stationID>
++ <name>Rire et Chansons</name>
++ <shortname>Rire</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12158657683AED59C29FA1CE49EB3BC433950CBFA0209C58F56D95E554EF3ECEE97DB80CFB</stationID>
++ <name>Fun Radio</name>
++ <shortname>Fun</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121586578595DEB7BF34B66CE3552438EAE9718FD81AF0CE86C74D203E1D8DF2361F680733</stationID>
++ <name>France Inter</name>
++ <shortname>France Inter</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1215865804D363782D3576B0FBBCECFE63C84407FBC46B81B8A0C73B13B9F64C9EA83A2A1D</stationID>
++ <name>Nostalgie</name>
++ <shortname>Nostalgie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12158658460F51E43754E99E634F4E0359806CBEE1A23027BDE386DAAB9250F2C907D1F3EF</stationID>
++ <name>Contact</name>
++ <shortname>Contact</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121586582586BD714C746F57B98DED30C59AC90EB9EDD276AC5786D5A95EA49D76F91E2BEE</stationID>
++ <name>Europe 2</name>
++ <shortname>Europe 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121586586532CE40330DA5033BDD651073E6B76B1C208FD9E394903E0885B3C9CD82F041D7</stationID>
++ <name>Fugue</name>
++ <shortname>Fugue</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1215865961A716CB4A7953401BF3FC007B882977487203F6039F220DF078DD72876831E2E0</stationID>
++ <name>France Culture</name>
++ <shortname>France Culture</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1215865987C3DCAF25A4F999955F0B225AED2A4B6D6CA4406D744DE1DEB9B382CFD2659B8E</stationID>
++ <name>Skyrock</name>
++ <shortname>Skyrock</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1215866650FA0E943EBD524C07EEA5B189A237D52A2759A90ED57AA894437438E9F58BB0D6</stationID>
++ <name>NRJ</name>
++ <shortname>NRJ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12158666739C0B0FBE2B6AD890ED1C3A71C6899295BE980AE361D0A334C96D489D43104C26</stationID>
++ <name>France Bleu Picardie</name>
++ <shortname>France Bleu Picardie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1215866771F115C902CA9CFB8363685C34DD934FC4AAD3FDCABF254F2A62FE92F8720C91DA</stationID>
++ <name>Cherie FM</name>
++ <shortname>Cherie FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12158667960E6580CE771ED7D39736049B44DF55D2D66B88010293973D68D84ACCED55DB48</stationID>
++ <name>Radio Classique</name>
++ <shortname>Radio Classique</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121586683984614CDE9D8A4B0F5FD6C2C23D2E881550DB9B20C0C0C2A97D92C29DAB51342A</stationID>
++ <name>RTL 2</name>
++ <shortname>RTL 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1215866858C0950D166660B91CC2A693AAD69008C04E7BD7BA817901090031BF0EA672243D</stationID>
++ <name>RTL</name>
++ <shortname>RTL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12158668803D46BEEDD6D924EEABF943B4CC79573350C106691AF039E2035B55DF86476D1B</stationID>
++ <name>Europe 1</name>
++ <shortname>Europe 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1215866898947135C6305A6B43ED1E14548DF7D15C1DF509C26D3A9842587D39E2ED300109</stationID>
++ <name>France Info</name>
++ <shortname>France Info</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1215865886EF1E5CA01719EEF06AF6F67D90FC7787ED543F376CF4BD66CF3C08990455B83F</stationID>
++ <name>Radio Soleil</name>
++ <shortname>Radio Soleile</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.1</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/bar-le-duc.krp kradio-3.5.13.1/kradio3/presets/france/bar-le-duc.krp
+--- kradio-3.5.13.1/kradio3/presets.old/france/bar-le-duc.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/france/bar-le-duc.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,111 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-unknown</creator>
++ <maintainer>Ren Riassetto &lt;rene.riassetto@fcvnet.net&gt;</maintainer>
++ <changed>2010-07-22T20:37:19</changed>
++ <country>France</country>
++ <city>bar le duc</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>128467009288848970E8B69F47F999D2B14FFD01D05E874529B3BAA15BE6B3BE4B7100D226</stationID>
++ <name>Europe 2 - Pyramide FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092F31430AEFF6F705EB72DC9E0DAD72038B1DC637A1033572C0EFDDD78E086EA06</stationID>
++ <name>RFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700922503FFDDF37D311B2AB5B08CE2EB6F8A36D83AD15C69C99AE30A047A5596F35B</stationID>
++ <name>NRJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092B0E43A29C4478F7948793BF32BD9139B06AD9C05F46479187E1758FF6F8414B4</stationID>
++ <name>France Musique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092DF6970930CFED3954B7E0A0F8C0763B41149F05801B9DCAA8628F820F8ADA225</stationID>
++ <name>Europe 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700927823C30BED79D2D6DC0DF09D0F8922B83B76DA0E3F2B1B1F051240594DDE88AB</stationID>
++ <name>France Inter</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092AE58ECECFDDA4D3B2ED21AD8D4BA98A75D7D5433B2DE5324F9C777897FA83419</stationID>
++ <name>Skyrock</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700929D83CE99148380CB4CFDBD9F465ABC4C217D158DF80AB0EAC512AF0DACCF4B9D</stationID>
++ <name>RTL</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092CB3DEAA6BBF2183C3A12D96C6951FF1D81056BE35A32568FAF1EEA4C4AE2B9A7</stationID>
++ <name>France Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092630FC18571A977D3BFDC29DE4F8F57EF8A7F3987FF9DCC957B9F7408B613E91B</stationID>
++ <name>Fun Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092044892468F7073A7F9A858036B0B8645166B405C34963D602D3D0B416B4B788E</stationID>
++ <name>Meuse FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092BEE4497AC8C30E3DE1154FA2EDDFF410EBDD0CC645BAE422D2A31C7EE1380B23</stationID>
++ <name>France Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.5</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/forbach.krp kradio-3.5.13.1/kradio3/presets/france/forbach.krp
+--- kradio-3.5.13.1/kradio3/presets.old/france/forbach.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/france/forbach.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,87 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-unknown</creator>
++ <maintainer>Ren Riassetto &lt;rene.riassetto@fcvnet.net&gt;</maintainer>
++ <changed>2010-07-22T20:37:19</changed>
++ <country>France</country>
++ <city>forbach</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1284670092F6AED1720BC4C25CC80DF8508E978A4C880F08C85AB37E648BA42865BC9172A5</stationID>
++ <name>France Musique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092ED7DF6074EA2290C8D25113C4A6C6430D19F356D0FE9D36943D3D95853CA6A48</stationID>
++ <name>FIP</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009246F3514DE657AF735CC78E204020871D0E51B79A67AC20E125976A57C2F8019B</stationID>
++ <name>France Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009227EE0EA3F0AC5FD8060857AC31F5DA1A87AA5E0D17B717ABAC47D09945E7FC20</stationID>
++ <name>Europe 2 - Rockin'Chair</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009277F842697A2C414EA61BB59D140D42C729CAA955E82F9B61E4B8D962C0EF2D3C</stationID>
++ <name>France Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700927706F0C7EF1D2345D8EF050CB3BB6E2DD967BE4125561BCC7360C5C7A14A9B2B</stationID>
++ <name>RTL2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009277DF30BEB0273483BDF86A77D935CAB6055D923829B5DABC4F8EA519325FF5C9</stationID>
++ <name>France Inter</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700920A3536E83EE0521FD84D6BA42D1295870629514B2E789BAA18A6F7516D652CD5</stationID>
++ <name>Jerico</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092427AAC75D4854737F1B0AC010DE15B74539F00FBF85AEE5B695E69330C622DA0</stationID>
++ <name>Europe 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.5</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/Makefile.am kradio-3.5.13.1/kradio3/presets/france/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/france/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/france/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -1,18 +1,35 @@
+ SUBDIRS =
+-EXTRA_DIST = "angers.krp" "lille-antenna.krp" "paris-antenna.2.krp" "paris-antenna.krp" "rennes.krp"
++EXTRA_DIST = "abbeville.krp" "amiens.krp" "angers.krp" "bar-le-duc.krp" "forbach.krp" "lille-antenna.krp" "metz.krp" "nancy.krp" "paris-antenna.2.krp" "paris-antenna.krp" "rennes.krp" "strasbourg.krp" "thionville.krp" "verdun.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/france/"
+- $(INSTALL_DATA) "$(srcdir)/paris-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/paris-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/lille-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/lille-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/abbeville.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/abbeville.krp"
++ $(INSTALL_DATA) "$(srcdir)/amiens.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/amiens.krp"
+ $(INSTALL_DATA) "$(srcdir)/angers.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/angers.krp"
+- $(INSTALL_DATA) "$(srcdir)/rennes.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/rennes.krp"
++ $(INSTALL_DATA) "$(srcdir)/bar-le-duc.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/bar-le-duc.krp"
++ $(INSTALL_DATA) "$(srcdir)/forbach.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/forbach.krp"
++ $(INSTALL_DATA) "$(srcdir)/lille-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/lille-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/metz.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/metz.krp"
++ $(INSTALL_DATA) "$(srcdir)/nancy.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/nancy.krp"
+ $(INSTALL_DATA) "$(srcdir)/paris-antenna.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/paris-antenna.2.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/paris-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/paris-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/rennes.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/rennes.krp"
++ $(INSTALL_DATA) "$(srcdir)/strasbourg.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/strasbourg.krp"
++ $(INSTALL_DATA) "$(srcdir)/thionville.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/thionville.krp"
++ $(INSTALL_DATA) "$(srcdir)/verdun.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/france/verdun.krp"
+
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/paris-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/lille-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/abbeville.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/amiens.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/angers.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/rennes.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/bar-le-duc.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/forbach.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/lille-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/metz.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/nancy.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/paris-antenna.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/paris-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/rennes.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/strasbourg.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/thionville.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/france/verdun.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/metz.krp kradio-3.5.13.1/kradio3/presets/france/metz.krp
+--- kradio-3.5.13.1/kradio3/presets.old/france/metz.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/france/metz.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,135 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-unknown</creator>
++ <maintainer>Ren Riassetto &lt;rene.riassetto@fcvnet.net&gt;</maintainer>
++ <changed>2010-07-22T20:37:19</changed>
++ <country>France</country>
++ <city>metz</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1284670092466690E5BD84B440D3BFB7C132EBBC6C027EBF679FC8A0C78472CF9799EE2CDA</stationID>
++ <name>NRJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092132340B2BCAE77B6B4A18ECF3B7F896A259A4796D6BBF59B695E4DE09CFAED52</stationID>
++ <name>Jerico</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700929B027D8D8DD1B4CA30CF8B1E31EA6CF765064D930499CF85134F3C5310EA5F95</stationID>
++ <name>FIP</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092A55DB1F4E72BE260B77B1A2988A3F156231B8F99231287A5C2BD7D3372901F02</stationID>
++ <name>France Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700921EF8E854DEE3F789FB23B8A70F9D79B4C63D179CBBEC7E418E25DDE303C85D56</stationID>
++ <name>France Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092DF970F5DC03F51880A418A6EA0F1AAE8E7C7859763B3884B02C930A04C840A2A</stationID>
++ <name>RTL2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700923DE7FD365EF2845589D012B14E55A24CB5D48BED38BDBBF1DD16D5FD0116367F</stationID>
++ <name>Europe 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700922AC40738DF237B073ED19EE9580C08766B1E327226751B156B0596C8D77F3FC1</stationID>
++ <name>France Inter</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092F6E60CFF47589D64AEAD4D38A78D30F5BD1364441DD81ED7E131A153C7127DE9</stationID>
++ <name>Chérie FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092568C98D1C04445A19B98E9AABD38C3DD7E1C77A2877FF89584E6CFB7F133BB03</stationID>
++ <name>France Musique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092D2CDD7D4A88A032E5C2278B9C43936080BD71DCB4444A4B1C263803C973BBC85</stationID>
++ <name>Nostalgie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092131E3465106EAFE3D5E6DD2FC460A297972E8C8CCDD93449F95A65AA84C7541B</stationID>
++ <name>RFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009221D81E4678C70A8397098A47334FB521DC6CD66B87D681DBCB08F3FFEE53E22C</stationID>
++ <name>Europe 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092EB4D99794BDA559BBCB972C3D4FD37968CB1B682D48CE952B5848654E557C304</stationID>
++ <name>Radio Peltre Loisirs</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009236146D220BA2293EEE3E862EAFFD6EDAA5989D562C8D482D83FB62CF3505D9ED</stationID>
++ <name>RTL</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/nancy.krp kradio-3.5.13.1/kradio3/presets/france/nancy.krp
+--- kradio-3.5.13.1/kradio3/presets.old/france/nancy.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/france/nancy.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,199 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-unknown</creator>
++ <maintainer>Ren Riassetto &lt;rene.riassetto@fcvnet.net&gt;</maintainer>
++ <changed>2010-07-22T20:37:19</changed>
++ <country>France</country>
++ <city>nancy</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>12846700928C28BDB4C167CC28ABE2F241150B6BFBCD84D19B6A112F1CD6CA74E85031FED6</stationID>
++ <name>RTL</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092925044DE1D2F730CEA2C1A285B1431D3D6A1A62A01FFAE143F04650990DEDB6C</stationID>
++ <name>Fun Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092874B5F769CD83F20B7E29F9C9855201FC0ACDA9BE56C452B71F38D668E236C31</stationID>
++ <name>France Inter</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092589C2D6A0A64D385B1405DB122A475BE6D4E34D17ACFDDF31002311421A96982</stationID>
++ <name>NRJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700923CA73B2F862BA6838D7E2340C6411A0C705A5F7864F55781C3DF48B9D319C1DF</stationID>
++ <name>Chérie FM - RDS</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092486003F914B38CEAD941AE7AE3465C16B2E55208FE8C65177E59A044EDBB6D85</stationID>
++ <name>France Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092519CBAAD8B3B3F4F761B09C25EA30591D3DF4825A6E9E009A7F0E3D97530D116</stationID>
++ <name>Fajet</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009261139B2CAAD7FC4047642B8B9AC99362418DA14030B701C8FC44368B7C236D73</stationID>
++ <name>Graffiti</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092C0899A5EA8982054D3FE6153DC62053B513B9B249CDB0557DCB6BE0EC58C737D</stationID>
++ <name>France Bleu - Nancy-Lorraine</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700925FF6A09B43FCC5C952391AC09C782236A1991F521147DB6F6F998F908863A421</stationID>
++ <name>BFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092D7958B2205E340B1F556994057D6048A8505FD97444C0F3572CC522718934901</stationID>
++ <name>Europe 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092A1BBD823EBA8304505C54F27BA10A34B286BB7717DB662CCA3997DEBD7B5C103</stationID>
++ <name>Europe 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092C59EDEAFDDF5BD12421941363887E3FC1F9C02F7C42CB51C289B0D78686DC789</stationID>
++ <name>Caraïb Nancy</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092178423C7130AD6033A41F5B4E4A5358431D0C32D39C449F5F9643AC462B3AA42</stationID>
++ <name>RFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009286C289A67EC2856C8E11C575436249337356E1D03AE5D7D69869C72C304D32A2</stationID>
++ <name>Jerico</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009280EDAF82A0E4C8E0791A7771F0EBFAF85FBF47E1AF2D356DF5E0B96D09C0E41C</stationID>
++ <name>RTL2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092057A818064C625FFDF8FFDCEE8F7D5157C9593B328C71E8CB46BE8D94F8D32EE</stationID>
++ <name>Radio Classique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700923D4B26C666F75F4638E96D4255851CA819B612F0202473CDA1AAB81820959CB5</stationID>
++ <name>Radio Soleil</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700925253237B2FE53DB85D6E8D08261D3C72C556A4A87C11C99CFA324A4F9E013B54</stationID>
++ <name>France Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009291EACD5C3118FCB39650CF2F50282CB1C146292978DD88FC5D28F919CBC8BE23</stationID>
++ <name>Nostalgie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700926B71E5FD4D48F337AFF56F29B63844FA3AAAB9BD6E12F3A30205817D406BA13B</stationID>
++ <name>MFM - Lor'Music</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092C852D374AC6E276A0197ED5FD76639F419A4233DFE7D34E0927294F93473D56D</stationID>
++ <name>Skyrock</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092BC391D3495405E5BFC39A74705C00EBB8380C4D8A46634943831BE05186A64AD</stationID>
++ <name>France Musique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.7</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/strasbourg.krp kradio-3.5.13.1/kradio3/presets/france/strasbourg.krp
+--- kradio-3.5.13.1/kradio3/presets.old/france/strasbourg.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/france/strasbourg.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,159 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-unknown</creator>
++ <maintainer>Ren Riassetto &lt;rene.riassetto@fcvnet.net&gt;</maintainer>
++ <changed>2010-07-22T20:37:19</changed>
++ <country>France</country>
++ <city>strasbourg</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>12846700923E4B393E5A415A8821F0950DB7ADC911B451101CB8A83412BDB214AC10A45BDB</stationID>
++ <name>Europe 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092F28C30CF2C2D2F21B5B8EEC4272B5482D4B9AD3891B867090DC1E331C9371C89</stationID>
++ <name>RTL</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009295FB4D21C567A53288C5F50B80FFC6C8BF145F8CF3383E618B92336E1D80AA04</stationID>
++ <name>Top Music</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009240B254A71CC061CEFCE36E499A4F8FA23A8870EC6E62A2C9E35AD659F542319E</stationID>
++ <name>BFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700920E56FC721B1DD85B12528F3EFCE9324E65CB8D128293432024E0428D4F6177A2</stationID>
++ <name>Nostalgie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009206068A852BBB11271575C4A56F5B695A4FB59D705589CB5D879F47FA4A5567A7</stationID>
++ <name>France Musique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092C350A16918E618B81BF46CEBB4612AB0CC2E07EB4E51AA2A2667D12FE43213D4</stationID>
++ <name>France Bleu - Alsace</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700922CEAE73C2850068D80764A919CB121BFF1522809542BEA48AA524CB01AF72E7B</stationID>
++ <name>RFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092B329F2B0ECC0EC64A450996A322C488139AA62AB9F532F3559C36259F4667F35</stationID>
++ <name>Arc-en-ciel - Campus</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700926567B2DE55046AE0D42756D179C7BFB06F6CD4F7469218EE2D0EAF766EDB7F9C</stationID>
++ <name>France Inter</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700924E0A4633D0BA750F8D7AE08237AE8FB305705F3EA70FE80ED55AB2169AF7B689</stationID>
++ <name>France Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009238F063D7AF81EC70CD704A4AF075C8CC1D9A5BE138EB40820C837F9959C5E26D</stationID>
++ <name>FIP</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092AEF9E1B9AFEFDA210D407EC70E08F732821737BA5FF2335FBDBEEF8F1163F927</stationID>
++ <name>NRJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009297A9C9DB6F0E218ED83A72CAC3B14EBBCFB2698792B11E4678A3F78C0E1D141D</stationID>
++ <name>R.B.S. 91.9</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009246A97CDEE4F12958FCDC501FA941CDD2A95750EFDA463A3048A4E1BBD432B19D</stationID>
++ <name>Accent 4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700925FF9BA22396CB3511FC436859ECBF2A6EDEB6A7D9FD33BB42B87769B55A415E0</stationID>
++ <name>Europe 2 - Capital</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092A47372115FBCDFEC1344E4B52CABFDC219F5E8B64F58C601749B0169C18C6594</stationID>
++ <name>France Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700923FD02A9CC9511880575B654239FA8DB65BD22E4EAE13E47C9CCEF6826813824E</stationID>
++ <name>Judaïca</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/thionville.krp kradio-3.5.13.1/kradio3/presets/france/thionville.krp
+--- kradio-3.5.13.1/kradio3/presets.old/france/thionville.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/france/thionville.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,95 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-unknown</creator>
++ <maintainer>Ren Riassetto &lt;rene.riassetto@fcvnet.net&gt;</maintainer>
++ <changed>2010-07-22T20:37:19</changed>
++ <country>France</country>
++ <city>thionville</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1284670092B6F6DC3DB805642C794D30675BD3F7BBB2B568458B4E640F0F8DC278951BBCC8</stationID>
++ <name>France Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700924930B52A844DAF1F8B3D70B171143D4848AA2EB1E22BAC78016919ACCF1E34F5</stationID>
++ <name>France Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092B308F6A499A6CDE3B8A1DC841B12B211E2879945EA920FE31B21D90E755B39D0</stationID>
++ <name>France Inter</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092A66DC5CB34CFD20DE722EC83BD5D73B65EF98AFD5C4DE633BC07AFC2AF3B4BB4</stationID>
++ <name>RTL2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092B715B5EAEAEC0E37343B21D3D2FA59614E630A255D9589196CBC97282EBB0027</stationID>
++ <name>NRJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092AE16D76A22DB50E7D816F2CCA6A5FA30F830A55BAFD174FE70CFB8CCA290E7FB</stationID>
++ <name>Skyrock</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009234F204DB71A42CF68454454369DCDA9104674FBE22456DB4BB1678D0B566E77C</stationID>
++ <name>France Musique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700928D34A3FE9629FEC8AAB358615C846D492D094222270127FA1647632DF7588C9F</stationID>
++ <name>Europe 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700926944E469E73757903A6CBE0A72B9FB05CA95E18ED5C195176959D034DF93B889</stationID>
++ <name>Fun Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009244FEB99A0C2D7D723F3A7DF3751067708051BBA745E4331BC03FEC8B5D6A64ED</stationID>
++ <name>Jérico</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/france/verdun.krp kradio-3.5.13.1/kradio3/presets/france/verdun.krp
+--- kradio-3.5.13.1/kradio3/presets.old/france/verdun.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/france/verdun.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,87 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-unknown</creator>
++ <maintainer>Ren Riassetto &lt;rene.riassetto@fcvnet.net&gt;</maintainer>
++ <changed>2010-07-22T20:37:19</changed>
++ <country>France</country>
++ <city>verdun</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>128467009278010A2D5434A6F6F22E5A66CE7708D2CA6DBD3C316A474FE9854D82B9FD736F</stationID>
++ <name>Nostalgie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700922278AD8A45B5150E6E2D361484A17DBA8CAD7D3A22A60177D20BC4CE8F8C9863</stationID>
++ <name>Meuse FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.0</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009262F715217EDC9DE27775EC7EC16290810351190A7E478E603A4B7B29DDC5466D</stationID>
++ <name>France Musique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092D93351740E07CF987C5221762D5D2207BAD1BF579913FF192622F84C211D1D83</stationID>
++ <name>Fun Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009268CA66D4B2BA14EE0CED2D0C2C92D1F8EFAEBAF010136F72A52D21E43D165CAA</stationID>
++ <name>Europe 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128467009252BF0EE1D79A69F3B35D35D917B006FB1AEA51528D5B864BFA1FF39B98B252FD</stationID>
++ <name>France Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092BCCF1C1AF114AD7CC0A33CAED6391C0BB37556BDD28F5ABBE3E33384CA789323</stationID>
++ <name>France Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1284670092B5A21674EB0CB60DFAD1EE5289C13B2E5E4024EFFB9282A45D087EC9F3E539D4</stationID>
++ <name>France Inter</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12846700922BD31A6A4F8FE9EE920303802128940DDAA4F90C5B1884666F646153DE0A98CA</stationID>
++ <name>NRJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.0</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/amtzell-cable.krp kradio-3.5.13.1/kradio3/presets/germany/amtzell-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/amtzell-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/amtzell-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,225 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-10-29-3</creator>
++ <maintainer>Michael Wlotkowski</maintainer>
++ <changed>2006-11-04T08:00:33</changed>
++ <country>Germany</country>
++ <city>88279 Amtzell</city>
++ <media>Kabel Amtzell</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1162625143B8F60924DFBD4124E7C3A6EFCD28D74818B50E090DDCD4FFCD570CD1F0789530</stationID>
++ <name>Bayern 1</name>
++ <shortname>BR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11626252039C1FA9FA1F8752C1AA3B4848D497EF40289663E34FE856DCDF9C02D7B1642621</stationID>
++ <name>Bayern 2</name>
++ <shortname>BR2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625276BC3D5BA7B8BE66A16376C5112C2366C99749CBED7DA2DE68E1CAF767D51939A9</stationID>
++ <name>Bayern 3</name>
++ <shortname>BR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116262527893232B6703651D7A7EC14292A1A45DFACC78B0B2F1CD334BA5CF908D316109DB</stationID>
++ <name>Bayern 4</name>
++ <shortname>BR4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625278532D106A2CB47925F5CA62600A8925F6B53F988629962D4B960B0518370B6AA5</stationID>
++ <name>Bayern 5 Akt.</name>
++ <shortname>BR5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625278AC5E844387B48B03022F370F779B44D6F2C9BB14D6B49918D0244CCE918C791B</stationID>
++ <name>Antenne Bayern</name>
++ <shortname>AT_BY</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11626252791F9B2E4F29EB7725663A8C96FD2661AD0950A1FB8E579E43687C5101A2408DF3</stationID>
++ <name>Radio 7</name>
++ <shortname>RA7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625279001DB03F038C523AD3F613ACCA261072D65947D9580939351E46A7BD39EB2DFB</stationID>
++ <name>S�dwestfunk Stuttgart</name>
++ <shortname>S�d_Stut</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11626256245813E9094294405282DD336F1ECFBD9C00B1BADFAB396C5D6E92379FC881E3FB</stationID>
++ <name>S�dwestfunk 2</name>
++ <shortname>SWR2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625624B83C31DB6A49ED5BF1E5875A67F72F3E71DF8EA075ACAC5DE848F3AA9A270EC8</stationID>
++ <name>S�dwestfunk 3</name>
++ <shortname>SWR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116262562504B184DB45DE35AEB046DD049C34735A6594D782304DB0B6C94EDA261F262166</stationID>
++ <name>�sterreich 3</name>
++ <shortname>�3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625625D2EA7E951DBB437CAE61C7B164AC10AE4E6873A812589AA9C2B1AB7E47767D8F</stationID>
++ <name>�sterreich Vorarlberg</name>
++ <shortname>�Vor</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625625A4662613704BFBCC8D54F84E970F74768580146F5223E2C0BE7594D4E44B53B6</stationID>
++ <name>DRS 1</name>
++ <shortname>DRS1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625879F0D63A6C3DCEC52C12E4B355759BB782F2399FFEAE5FD07DA923C5819BF953DB</stationID>
++ <name>DRS 3</name>
++ <shortname>DRS3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11626258797A1228AD9BB871940E56976EE2279071ACF759F4C7AF61F227BE3C03A1F6AA3B</stationID>
++ <name>S�dwestfunk 1</name>
++ <shortname>SWR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625880695B4EA1E6A17A598FC40A29BDD8951E13C57266565A7010FCED0BB0B23C430D</stationID>
++ <name>Radio Lindau</name>
++ <shortname>RaLi</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11626258808F8679ED6AAFE17B9A7BD6571386E3A7BDC71C16F571F19028B7A5F92E546C4D</stationID>
++ <name>BDR-FM 4</name>
++ <shortname>BDR4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11626258806B01BF5B8FE3F46A1D5DE3A11AC59525AF4804E7ED213C808095FFC27C0BC519</stationID>
++ <name>RTL Oldies</name>
++ <shortname>RTLO</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116262588182BBFD4700519E8ACFACA2FAE19E10B64F80814B8F767932C7298178FC003A83</stationID>
++ <name>MDR-Sputnik</name>
++ <shortname>MDRS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116262588190642A6E97E8F2335C9D2A217C89C49A4C53A012A6D060D31345E1ECA1D28B22</stationID>
++ <name>WDR / 1-Life</name>
++ <shortname>WDR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625881E85B022A640DBC7504130C464F72E9DB1D4766676E0AEA1B39D02E5D0675D406</stationID>
++ <name>Klassik Radio</name>
++ <shortname>KlRa</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1162625881BD9FFF78EE575F4DB03FDE70923DCA044D332AD6338DE4CFFD5F5C84DCC0C57B</stationID>
++ <name>Seefunk FN</name>
++ <shortname>SEFN</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11626258827BB56022653275D2B3D2D71D01FE7460C903744F9BA18C9BBB8CB69D3548D5CB</stationID>
++ <name>Schweiz 2</name>
++ <shortname>SW2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>108</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/bayreuth.krp kradio-3.5.13.1/kradio3/presets/germany/bayreuth.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/bayreuth.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/bayreuth.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,227 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-1.0beta3b</creator>
++ <maintainer>Ralf Großerhode
++&lt;ralf.grosserhode@t-online.de&gt;</maintainer>
++ <changed>2006-09-25T11:25:28</changed>
++ <country>Germany</country>
++ <city>Bayreuth</city>
++ <media>cable</media>
++ <comments>Angaben stützen sich auf
++kabeldeutschland.de. Alle Angaben ohne Gewähr</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1159176370F91BDD0EEE856DEAD20664F469A498EE506C3656D1C93C2E54C2ACD9F0945EDC</stationID>
++ <name>NDR 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115917641582A8F885CA1B60018EF4FAD96CD127D49F8716D87774563060A742D4FE57FB05</stationID>
++ <name>Radio Plassenburg</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159176449A125C3340338A9019B847ABAB591E2BDA1AF0D472BE6E72A00397D75BD2298FF</stationID>
++ <name>Radio Melodie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115917647341F42319F3A75DC00E9BE5123BBB9CD08E65C94CC7F3C44AACB292842D1B27A1</stationID>
++ <name>Klassik Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159176506B42E1656C242954B4CE5F86F64E27F65D80D0457C46E0EF5A780FB31CCE2B5F5</stationID>
++ <name>ERF Evangeliums-Rundfunk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159176552292C30B53790A995DC66F2503C83DA6B3308D8C98D168D6190F5C756A5639488</stationID>
++ <name>RTL Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159176584EECCEDD8A70AA99D90F48D3735FCDB8138614666FB801EEFA7EDBDFD1246CBCB</stationID>
++ <name>sunshine live</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591766482EAFE02B575BDDA5B1167B3999CF8F3B36AA9A1959DBF0B467FFB8523B14160F</stationID>
++ <name>JAM-FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159176674300CF3DCE4ADDB188E4C7E67B7DC1948C06026FF3F2A92B05ED2957F7F2D38F2</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>dlf</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159176717DA67BDB605A5176C4B583B9CBE4EB7893615243D77B7AA31664A8ADD580146C6</stationID>
++ <name>Antenne Thüringen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591767428362F9949DF6118DB0CE2C4B7FF40F530700FCB20D480431F63765C17BA9D342</stationID>
++ <name>Landeswelle Thüringen Suhl</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591767674E301B719648F56C922A9933FDD4E2DB6E4D2C0409CE62224C8A687CF05879AB</stationID>
++ <name>JUMP</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591768140C2188DDC2ECD8A7BB27822638F84F84359A378ECF3B5AB4004B27A881CF021C</stationID>
++ <name>mdr1 Radio Thüringen</name>
++ <shortname>mdr1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159176895232978E557EF2CF353C2F816B6B193FB01B3490C802A6C3D5709D148601A4525</stationID>
++ <name>mdr Figaro</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159176932A0E4BF414E39CD3EB016EF9F1B4EC8A54151B435C47AB97968FFD702A168C50F</stationID>
++ <name>DeutschlandRadio Kultur</name>
++ <shortname>dradio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159177049F8673E03B331FB756142AAFC347BFA37B2770D94F1A8230DE9B4CBFAF650FB7E</stationID>
++ <name>Bayern3</name>
++ <shortname>BR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115917709191D3D432F33F531306770B400ACC263BF3CC8F8A42D5E419143A24DF79C17310</stationID>
++ <name>B5 aktuell</name>
++ <shortname>BR5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115917712194A3CA5B3209D4226A467F2556EEC51C3A4AFCEE6F031FA5F446AB5632F766D9</stationID>
++ <name>BR2 Oberfranken</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159177150435518411DDFFDAE21AD099566B3C331266E1AA5F083962544043DD6C1158792</stationID>
++ <name>BR1 Oberfranken</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159177190AED3B92961E90467002B8D036062364F82B2CBFE8256B1D5070B6B57D3F16622</stationID>
++ <name>Bayern 4 Klassik</name>
++ <shortname>BR4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159177233793063353EAC9E8F1F8C2D65BA5A87B40718AB9308B687AD55411E5B1B56E754</stationID>
++ <name>Radio Galaxy</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159177364D6FF08C3DA4F93B14F8DFDB5C57FACBC86F4B832ACA66CB636EABE05DD5BD670</stationID>
++ <name>Radio Mainwelle</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159177393A85981F6062ADAF5C8B6364C5F6761469184E847AAA93EE4DF6E49052E6C8993</stationID>
++ <name>Antenne Bayern</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.65</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/berlin-cable.3.krp kradio-3.5.13.1/kradio3/presets/germany/berlin-cable.3.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/berlin-cable.3.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/berlin-cable.3.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,333 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>juergen kauer&lt;jkauer@arcor.de&gt;</maintainer>
++ <changed>2007-03-20T22:46:38</changed>
++ <country>Germany</country>
++ <city>Berlin</city>
++ <media>Cable</media>
++ <comments>Kabelnetz von Kabel Deutschland in Berlin-Lankwitz</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1072791566EE4FC1594E6E6DC394DB75EEA2E9938CA67BA6682313127E3DC8CFD562686A13</stationID>
++ <name>BBC Worldservice</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>87.495</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915677F9936FA0BAB670FB58F07C35C232BF6C8F65DB1C7A491480937848532CBB384</stationID>
++ <name>RTL RADIO</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>0.82</volumepreset>
++ <frequency>88.055</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791567CC15FD02795828846ABF82393E35836D35535ACE3BE8DE23A3D666764EC92EEE</stationID>
++ <name>Klassik Radio</name>
++ <shortname>RTL</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>88.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915686667AAF2ABA643A8427136F1FF23B13680686E00AC029D20C746F82110E15883</stationID>
++ <name>100,6 Motor FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>89</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279157082D00D133FC0C7F0A736DF9DA658240AE74C45890AE0A3E2E074448807441213</stationID>
++ <name>Fritz</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915708CED28FBC443431F076E8E377DDFECDC96801422442D7A89DBD4567F05E915A8</stationID>
++ <name>Radio Energy</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>90.455</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915716F7ED9C758E6C5CC9F58FBFA5957EA22BFF20B19CCBE47E9741A6A6C0E5ADF57</stationID>
++ <name>Radio Melodie</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.805</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915727A649C66B9C75FF3ED4CB90B686BF3ADE3F27A658F1446CA1DB599E759B2719B</stationID>
++ <name>JAM FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>96.68</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791573F82AE782CEEEBD775EB38501C64B71B14C8DFEC95D001474317959E6581A1F8E</stationID>
++ <name>infoRADIO</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279157430C736B8ED87C5571B6FDEB10504E28CCD9486F62DF082CFD590A699C3E0248E</stationID>
++ <name>Offener Kanal Berlin</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279157482B2FA653974785D4655257398C16A26A4B8EFFB21FADE3262D2159C55F235AE</stationID>
++ <name>94,8 Metropol FM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791575013759401591C315632A40F3F6734FC75048A4345ACBB02D99067C5CF553DBC3</stationID>
++ <name>DEFJAY</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279157688C1348A5C55ACED6747F7B0FDBD4863B36F11EFA5C80443FFE52355AE8C7EDC</stationID>
++ <name>Star FM </name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>94.551</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791577C45B6C9771EA973DF94328D91A5FDFF87B11790B23AD6001B218FC777E6CE2F1</stationID>
++ <name>radio BERLIN 88,8</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9255</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279157865A27D18F805B7F2DF9873794B299DEF581B7AB615949944EB0A232683FCAD38</stationID>
++ <name>KulturRadio</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279157937EE7B714C71289579A1C99C508664996231F58F92529F7FE46E2B38FBF06657</stationID>
++ <name>BB Radio </name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.996</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791579332D9366F17BD87251985FC7C429E2952A69E06EFDD85D254BB4DDF8816A4408</stationID>
++ <name>Radio Paradiso</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.546</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915801AC51F36D9DB58534B0CC40DF6055C0717ADE6B59776D1C04AF4C5E0E33D7718</stationID>
++ <name>RADIOmultikulti</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.851</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791581F1329D24372E9ED5171891011B1D34792BB423B640A0DD0248E6D82A403FA220</stationID>
++ <name>DeutschlandRadio Berlin</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.496</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279158182E86933E311515E8355B8D72F1AE2E65F5887BF78E9F5B84BE1155BCABDCC8D</stationID>
++ <name>98,8 KISS 99 FM</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.901</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915836948510D2C8FE10382E670931472C2D1CFFF6D2F80A617CDA8483EB678FA4321</stationID>
++ <name>Berliner Rundfunk</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.251</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915848BC80E6D186BC53D388A41307E314B3C977185BB7BB24B0D86F329BEB29D1003</stationID>
++ <name>RADIO EINS</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9508</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279158571AE18245596E9390E46457F573BBC152F4A7DCD02C52641CE192E727E60CD69</stationID>
++ <name>mdr SPUTNIK</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.301</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279158593519FA971426F180D2376830F7095EA51761ED137E43058D7B80A638CF58620</stationID>
++ <name>94 3 r.s.2</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.746</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791587EA7AA8881EF9FFE900E6B0BED14F01B38BA22CBC16526397AEDD3FB7D38C2758</stationID>
++ <name>Antenne Brandenburg</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.646</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915873FF901E6FC22915B56137882D60DEE023706BDB5FCF368209061582D2614758B</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.001</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791588378E9D932C33F1231837B9A2014E604CDE9DF44EAB8EB5FB2B55B5A6E9E3A1DB</stationID>
++ <name>Jazz Radio</name>
++ <shortname>27</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.446</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791589A310930786205964A1A672504FEFCFE0C3FC34AE2A43CCEC4345556C6167B580</stationID>
++ <name>Spreeradio</name>
++ <shortname>28</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.001</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11744269309D360EE4BFE2B2A775AEC8F16A1CBF4D46AF5BB75B1CB610639E346802A431B9</stationID>
++ <name>JAM FM</name>
++ <shortname>34</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.746</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>107279159044714ABF2F837EFA328827AD05695552023C89D6B4DC728EB175EE1BAC4A4D8C</stationID>
++ <name>104,6 RTL Berlin</name>
++ <shortname>29</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.076</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10727915928FF2DFF1847AC9ACEF507F3353229A2B67EFF320AB9712C200E002F37A28895F</stationID>
++ <name>SWR3</name>
++ <shortname>30</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.951</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791593C28480C8972B00751352BBA74BC446B3A7338BF5E581C0C38BBA95C063B479BA</stationID>
++ <name>sunshine live</name>
++ <shortname>31</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.846</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791593A55AE94E136B46AC1EF61FF2A8AA2DA703EA17189BA6C7B18BD9506CB4EB6DC5</stationID>
++ <name>Radio France Internationale</name>
++ <shortname>32</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.201</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791594E4FCB64702D7F3190369EE339FF4229396A4791AA1A1446012FA58BE91F25A95</stationID>
++ <name>WDR 2</name>
++ <shortname>33</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.946</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1072791596546338507FEBC23B2130D3E3BC0F909B6C7047EEDA64CF7EB6BD2938F03DA3A0</stationID>
++ <name>SWR2 - Baden-Wuerttemberg</name>
++ <shortname>34</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.876</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/bonn-cable.krp kradio-3.5.13.1/kradio3/presets/germany/bonn-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/bonn-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/bonn-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,285 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.4</creator>
++ <maintainer>Gereon Schueller email@gereon.de</maintainer>
++ <changed>2012-07-30T23:43:39</changed>
++ <country>Germany</country>
++ <city>Bonn</city>
++ <media>Unitymedia Cable Network</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>10919654322C2EF9495C225621B9F02F38D65CFC19F781211D908E273732E406391CD83D79</stationID>
++ <name>EINS LIVE</name>
++ <shortname>32</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432DBB1C47689A796F5A1C31D13160E84E4B0B2B2BCF238ADFCD56D5291ECBE7D34</stationID>
++ <name>WDR 2</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432E620D2DEA57DE8D3425869D9B61FAE8A909EBC1722C46E9FBF9B76D67ED16064</stationID>
++ <name>WDR 3</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>109196543276474D50DC0126736B1119DD90EC0AB7BE3055817859732721E8D84396EAD0F4</stationID>
++ <name>WDR 4</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432C0D8D51BEC7FF0F3D80EE649446D9DBD6C644D5B40BBF847B78C06DEAE0528A5</stationID>
++ <name>WDR Radio 5</name>
++ <shortname>35</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>109196543202597F652196A8D0009727B698654FF01A73E446650AB4B0F7D78128268F10BF</stationID>
++ <name>WDR Radio 5 Funkhaus Europa</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10919654327FC5DE92D726B62F116DC19AB42A5B9E50F4C2B6D9EE8CEB885CF5CD95743CD0</stationID>
++ <name>HR 1</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432EB0D627AD9EA1893AB97AF05E283F9818B9C5BC03A96828A824CAB2794F2422C</stationID>
++ <name>HR 2</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432AC1714188FE3DED94E17643578A3E62ACFD719E0B45742C3E2382DB18AEDEEB2</stationID>
++ <name>HR 3</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>109196543242548D5CC887023C30BAAD21DEC259799CD610808DB84512ED0F5E0110243B96</stationID>
++ <name>SWR 1 Rheinland Pfalz</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10919654322B538342EF91D6B54D33F4DA945A72439271B8204D1BEEB61270FC81F43ACB36</stationID>
++ <name>SWR 2 Rheinland-Pfalz</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432F2368F7A2CD6FA43903E86319637E767C98EE31AA5AE1432E44AF7F9E45BA023</stationID>
++ <name>SWR 3</name>
++ <shortname>28</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432E125008DF90996BFD0997C7D3DE02B0A794DD3F6ADED22025500878964ED059D</stationID>
++ <name>SWR 4 Rheinland</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>109196543207D0720F7D31DA8771BA01EBAFF4F6B36550DB8DAA86DAA1A032F0EDCE5B0BAE</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>109196543266466AC67416B83BD8FD516241243783C74023FD75DFAEAB17F8325BD1BCCDE5</stationID>
++ <name>DeutschlandRadio Kultur</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432BEBF709E0B4332DDBCB8F94C34EE848CF5BEE1A4F28AC37966378C7017DA1BE2</stationID>
++ <name>Radio Bonn/Rhein-Sieg</name>
++ <shortname>33</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432C2CF129CEA931E111DA60CFC9D36C588FD72ACA92ABD44763DED1F050E820FE5</stationID>
++ <name>Radio Köln</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432CCE146C86E2248511CF3373E685BDA8F54A8D8CC97C5C9CD56039CB4F5943CC9</stationID>
++ <name>sunshine live</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432520C12ECD249D970FE383731DCF2C796233E6A13D8EAFF413FE07A6C4FEDB6EB</stationID>
++ <name>DomRadio</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432DAA66E312D952479B2ECB430EE509F8625E0F64C3866C454AE02F2E272DE8A60</stationID>
++ <name>Jam-FM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10919654324719F08B7D922C9956CBC1794CF886037C6FE8210D0D44107D04DA2F323329AB</stationID>
++ <name>RTL Radio</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1343691592BA7AA01237F6E3E7E9F6FA677EDA32DC604054ED37608748B137AFD320E4</stationID>
++ <name>Radio Paloma</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10919654329D3E62F7898B303285904EB4D7400A8051766199D279E9B4970DCE53AA35FFE4</stationID>
++ <name>Radio RPR Eins Rheinland</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10919654320ADB8A8DA2451E866A10421A346F0CECD55A0B9F270AB263D9DABCD1D62946A0</stationID>
++ <name>Klassik Radio</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432A0454782B1B958D30B59CD7FC2C02811E9EB63432F55469EEE5121577C35A39B</stationID>
++ <name>Belgischer Rundfunk (deutsch)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>134369151654628D560CDE8CB1DF82669C0CAA2EA2C46F94C0C7171605343B76E2A301</stationID>
++ <name>bigFM - Hot Music Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1343691539C50D1F861456D49146F6FED5AA9704E68D632C68536BDEE9E306F9A27ED9</stationID>
++ <name>ERF (Evangeliums-Rundfunk)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>134369175436874EEA444FE168D7CD968569EC60A1BD656ECA93B8493B82804E8A1056</stationID>
++ <name>AFN - Frankfurt</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1091965432D540169A28BE38B5BC636CC5958B619A5EBF736B6534AC1DE7BD3021AC5FDEB1</stationID>
++ <name>BFBS</name>
++ <shortname>27</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13436915630ECC4585C73D9671B8255ADF510E275F8F2C688684315D9AA259D8707517</stationID>
++ <name>FM 3 (niederl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.9</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/bremerhaven-cable.krp kradio-3.5.13.1/kradio3/presets/germany/bremerhaven-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/bremerhaven-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/bremerhaven-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,261 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-10-29-3</creator>
++ <maintainer>Tim Gollnik, &lt;Tim.Gollnik@t-online.de&gt;</maintainer>
++ <changed>2004-06-09T11:18:14</changed>
++ <country>Germany</country>
++ <city>Bremerhaven</city>
++ <media>cable</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1091290560F19DCAC9442D72D89504676F5CED64569520089652BE8A8A468E3AE29FBDFA1E</stationID>
++ <name>NDR 2</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560DCC0EEE1C09CE8C77AF9C4363AB86860E2B729254B6CBB23609E01FB38AB2C11</stationID>
++ <name>NDR 1 Niedersachsen</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905603BB0C169D59130A7E4CDB50299B30B4CBAE3140C2E30208DB3BA1D7CA865DDC3</stationID>
++ <name>NDR 4 / Parlament</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905609C9242B6154C7E571A4C9E1836EBA6E697BFC7228FDBAC875A7C485BAA697684</stationID>
++ <name>NDR 90,3</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905607D32CC781625CA4804D255AE88896A46524D21EDD358490CD2985F9A7F94BCD6</stationID>
++ <name>NDR Kultur</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560A2E30DF5AF74EC8699A380BEFF08A942ACF65417DD305FECEA447369716BDB90</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>109129056092E86276D7410E5C7CC3D2B9F4463DD63CEE5C9363D732181E089F37D0EB7D7A</stationID>
++ <name>Radio Bremen 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>109129056009982D289707EE2CCBABFBD81A2074A64E056DFF11E2E9BBD05CDE64A851D141</stationID>
++ <name>Nordwest Radio</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560D51AC5807AB56AEC3A4BF76F14C190DA9E6569068F1CF7AF25E3144075EA9E41</stationID>
++ <name>Funkhaus Europa</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560B66E310EC16F9DE501DA13CFCC5040FF0B31D62247C7CEFE5628C4A3F36A85C6</stationID>
++ <name>Radio Bremen 4</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905602AC2A9C53F9B6E6EFE9E1674878400E7FF5C7F124684CC7F57C9C216A0E01366</stationID>
++ <name>Energy Bremen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560E610CC27C3CF08B84731FA4FF3C98EC6CB82AD5443E30049E539A2F3443F4202</stationID>
++ <name>Radio HH</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905600334C7216171F1A43051A8A499453CB86833E4DD3268FC448073E63423DD667C</stationID>
++ <name>Radio ffn</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905603085269311505B713B67522CA258791BE5E96E28D39638B55DC412A103BFC178</stationID>
++ <name>OFFENER KANAL</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905606EC5591E60AB4673DCEB558470C77BCB246DA9FB755D7283719019CC0E270E4E</stationID>
++ <name>AFN Power Network</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560D30C88E8D43940B11373590F658CC96DDD2658EB06EC3F1581B777F852321E5D</stationID>
++ <name>Delta Radio</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560BA5ECFEDAEB193F5B8630C1C38A93A85304BBAB9AAC1D47661E3ED92077A6B02</stationID>
++ <name>Radio RSH</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560252B8C5FD95DDBE48DAEF86135F2BF2FA4398FD7C7B37FF425BCCFF321514FD6</stationID>
++ <name>HitRadio Antenne Niedersachsen</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905602ECB0B3F03E29CEFD2E07F844BF99621F08CE8B99DBDC6519D813891CE76C734</stationID>
++ <name>BFBS Radio 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560F205062F8746603F2F1CF3C697878D9E82833AA5871AD5F89740068468DC299F</stationID>
++ <name>DeutschlandRadio Kultur</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560645B2E7C0C5F1DD65A0426497CA4618735145E5928DDFA824957C964EE27DCC2</stationID>
++ <name>106!8 rock&apos;n pop</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560F63220989D5D33B98DFA024203D01D1D4BC59C3226C715A5C44A28159791C189</stationID>
++ <name>sunshine live</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>109129056099FECBDC47A1044EBE759AB969D64FBF1B2590C8AEBA9179E76649818E61AE4C</stationID>
++ <name>RTL Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560D5DCC73CD877D51CDFB6975B7A4074A9A26D257267DE6527CBF8C3FBFE793DE4</stationID>
++ <name>n-joy radio</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560E53E10FEF4C1654C3F4D497D8F8EAA4BEAACB473F1C7500D277349F4D7514844</stationID>
++ <name>Klassik Radio</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905608D35FCB469CB01369E584315BBADAABD9D7B9C8B9D1C1837372BD88FBAC7AB6B</stationID>
++ <name>JAM-FM</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560C494E867489FA592C07DE70CF3C1216B4F5E6D1C0C42987E3FC457B4B9E8B5FC</stationID>
++ <name>Radio Melodie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/coswig.krp kradio-3.5.13.1/kradio3/presets/germany/coswig.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/coswig.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/coswig.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,294 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Hagen Edlich</maintainer>
++ <changed>2007-04-11T01:39:29</changed>
++ <country>Germany</country>
++ <city>06869 Coswig (Anhalt)</city>
++ <media>Kabelnetz</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1176247707A0C82B606E65CC7F2FBEA0866020438DF24632426678DC361F7C193C7B8845BE</stationID>
++ <name>Sunshine Live</name>
++ <shortname>Sunshine Live</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>117624703266B62F9E009559DBD9A294B32B2F73EAF63A8B28AF83431F80E5593786641AC1</stationID>
++ <name>NDR 1 Niedersachsen</name>
++ <shortname>NDR 1 Niedersachsen</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>117624708971E9A8A2BDD50B839C80F17E99FC2615603B9AF02F3B9705EB71FBEF5CD7DDFB</stationID>
++ <name>NDR 2</name>
++ <shortname>NDR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176247163E70DCE726F2CFBE3BEDFE8B05EE6C384D5318795E41C4466A9D7D48A19F3D8E9</stationID>
++ <name>NDR Kultur</name>
++ <shortname>NDR Kultur</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176245349AF57021CB5F93E2F5A44202078E3D594898EF9872CAB0F55A5829328C7EAD2E8</stationID>
++ <name>Jump</name>
++ <shortname>Jump</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176247446EA0C211D139184145EA8064C5E02087F1E93344C014ECC142E373A46EE7E77AD</stationID>
++ <name>Fritz</name>
++ <shortname>Fritz</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11762474728BDF3F755C240D8D8EB9781F3A928DD4F22EAB34B36E9CCE9F6C24F4FB22831D</stationID>
++ <name>NRJ</name>
++ <shortname>NRJ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176245354F9792D14D7A4C02FED7644C6303C3E62B96E1E359B27F35F29846AA304932DE4</stationID>
++ <name>MDR Sputnik</name>
++ <shortname>MDR Sputnik</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176247621B215007AC7280D5AE46B6F93A29A9DFFE3294F7CA63684D265D00ED5D2D70365</stationID>
++ <name>Radio Leipzig</name>
++ <shortname>Radio Leipzig</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11762477071EAC736A707A9AD5509666EAB5FF92E6CF5A6C7EA071BFEC4DA56D97BF4BDD7E</stationID>
++ <name>Radio Brocken</name>
++ <shortname>Radio Brocken</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176247708D821B8DDC4E76242BCC0BB4BF906412069F6ED1FCAEAC1B8D03964B1CBE8678C</stationID>
++ <name>Radio SAW</name>
++ <shortname>Radio SAW</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176247708D5E33AC1D3235A3B271AC0E9B528BF08E3F7AA040E83CBD48DFEEE1DB9C8E3B8</stationID>
++ <name>MDR Figaro</name>
++ <shortname>MDR Figaro</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11762469094F443FA4C67B3C73A1E9E0BAA1E3B014646B4C654F4EE1C450FDA11CC6493A67</stationID>
++ <name>Antenne Bayern</name>
++ <shortname>Antenne Bayern</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11762453616DC96E98F9F2BB736BF0BED0642CDC2DE88F1991EA915DEF2D2962229D1B30FB</stationID>
++ <name>Rockland SA-AN</name>
++ <shortname>Rockland SA-AN</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11762453621223D1F049DF97DBE0F4A9A9E6B39671D21628044599F72342464C97D6F22081</stationID>
++ <name>Eins live</name>
++ <shortname>Eins live</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.0004</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176245363C836DBABFAB34DBBB91AC2D42AF7CE1454F2A0FF095FF31E9F70F40E2211AD56</stationID>
++ <name>Nordwestradio</name>
++ <shortname>Nordwestradio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11762453641AABE4D81D8EF0C27DB3C48B078D6C93E30FE3830E9053F195CD9D2108AA7481</stationID>
++ <name>Radio 1</name>
++ <shortname>Radio 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176245365D229F90373EB6CA1F4E2ADF2097BA1AA1A8363E83A2D5EF4557F7573070B87BB</stationID>
++ <name>MDR Info</name>
++ <shortname>MDR Info</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176245367AE96165F2EC516BBF2F71FB44077D98C704EFD0B7F99481BC98E91B6E8DE4400</stationID>
++ <name>Stadtradio 88,88</name>
++ <shortname>Stadtradio 88,88</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176245368B945284318577B0B720618D63FAB35CE85F9F45D77BBF0A87F71C0BA8FC19D42</stationID>
++ <name>DLF</name>
++ <shortname>DLF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176246864242513E9CE92BAF25CBB8433B11384AC93E9F35FA2E7F978FCDB5F903ECC5CAD</stationID>
++ <name>MDR 1 Radio SA-A</name>
++ <shortname>MDR 1 Radio SA-A</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>117624682132A6A74354D08337EB493D374072B03763DC26FE4F5F1386FA8CC1AAFC644F7F</stationID>
++ <name>MDR 1 Radio SA</name>
++ <shortname>MDR 1 Radio SA</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176245373B9B0F90767273A2D459B78EC67A5E9236696975DC9B3B77297618818D1CDCAFA</stationID>
++ <name>Radio Melodie</name>
++ <shortname>Radio Melodie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11762453744C9A303A5C5A7E3504F75EAB55DE2ED1D6615AFF845F83C7ACC1BB6AD3A36E04</stationID>
++ <name>n-joy</name>
++ <shortname>n-joy</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>117624537733B9E8D7B049EB078A4CE72545B28E4EEA9B24ECA20C3B72B9AE5175D3E83E4F</stationID>
++ <name>Deutschlandradio</name>
++ <shortname>Deutschlandradio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>117624537973BF9927DDB11CCCA2E1DC331145C184763291A36FB37FE6C83EA4A5B3F320FE</stationID>
++ <name>RTL Radio</name>
++ <shortname>RTL Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11762467554B0CD17FAECDE5837EE6588BB3C6369BCDE6991A787DF809A1CD7B3631CBF982</stationID>
++ <name>Hitradio Antenne SA</name>
++ <shortname>Hitradio Antenne SA</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176246795DD47990D17CF58ABB65DFEFCFE0438780A7ABB4861B01A39D4B30B4659B06C34</stationID>
++ <name>R.SA</name>
++ <shortname>R.SA</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176245383C0A242E951364EE884AAB9286100E06033AFB09A165DFCAD9CE6AC787472FC34</stationID>
++ <name>Das Ding</name>
++ <shortname>Das Ding</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11762453843AAEDF886054B17B1394DF7B17678D7E1F85FC029CDD541FF69E7C7882B9A316</stationID>
++ <name>Radio Kultur</name>
++ <shortname>Radio Kultur</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1176245389E77366541FAE828839AA3E4F8503FB21940E7A40E81E566E64B118AFC18F681C</stationID>
++ <name>FFH</name>
++ <shortname>FFH</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.15</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/erlensee.krp kradio-3.5.13.1/kradio3/presets/germany/erlensee.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/erlensee.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/erlensee.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,304 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-1.0beta3b</creator>
++ <maintainer>Werner Muehl &lt;info@ib-muehl.de&gt;</maintainer>
++ <changed>2006-10-03T17:36:01</changed>
++ <country>Germany</country>
++ <city>Erlensee</city>
++ <media>Cabel</media>
++ <comments>Stations/Frequencies for Hanau, Bruchkoebel, Maintal, Erlensee,
++Rodenbach, Neuberg, Langenselbold</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>106854525432A288014DF7C85A99EB501E082B06B4F96949EBAE12DD4A859C19C3636C7101</stationID>
++ <name>Antenne Bayern</name>
++ <shortname>Antenne Bayern</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254739FC26D6EA0AFF43BCC062A18F2B696DD53495A4DB3E0CE961695FDE6CF251C</stationID>
++ <name>AFN</name>
++ <shortname>AFN</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254A4F642897A3A7A2FDCF75CC91EC34AB83409A44E520926B65616CB71A888A632</stationID>
++ <name>Bayerischer Rundfunk 1 (Main / Franken)</name>
++ <shortname>BR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685452545BFB673861F03BE773365B16486F1312D0E67EE191A44D3E6E8A2EDE9CFF860B</stationID>
++ <name>Bayerischer Rundfunk 2 (Main / Franken)</name>
++ <shortname>BR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254A50C8E4F463384279978E9990FE99AD5E8D02892DC85239B19FF5D03D0B2D2E6</stationID>
++ <name>Bayerischer Rundfunk 3</name>
++ <shortname>BR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685452542B850A62AFBC32E86A8AEEAFB6ADDB4471C997F6EC31B99A4705C034891FF15F</stationID>
++ <name>Bayerischer Rundfunk 4 Klassik</name>
++ <shortname>BR 4 KLassik</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254AFA422E0A4F4D99F24FFC42C2EA3E5563D518014CAAD3D29F69BC15105EA2B8D</stationID>
++ <name>Bayerischer Rundfunk 5</name>
++ <shortname>BR 5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159888999C88F220598C7CA2D533194FF95E4EF0629E3EA1144151F13104F3D0A957F6975</stationID>
++ <name>BIG-FM</name>
++ <shortname>BIG-FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159889239AFCB7A4D3F499D83C998312C5314A3374819A63E5DD848F26D2A28724A188BF5</stationID>
++ <name>Deutschlandfunk Köln</name>
++ <shortname>DLF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685452544B20BEB753EDDA4B34C42E483252E211C5BCB770258F801EE1840268FD85CCA2</stationID>
++ <name>Deutschlandradio Kultur</name>
++ <shortname>DLR Kultur</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11598894980E90DF6E12053843D94648E3AC2B00607502F7B3338DBE6C237AAC528179BBE1</stationID>
++ <name>Harmony FM</name>
++ <shortname>Harmony FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254870A846605C88985C8D465AA421B30FF35FDBEBB55A43E57FCAFD16154206359</stationID>
++ <name>Hessischer Rundfunk 1</name>
++ <shortname>HR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106854525467DD7BA14D8A886573BE9AED9A64A86C9F8E5AF487245E4146D0307E1EBAFF45</stationID>
++ <name>Hessischer Rundfunk 2</name>
++ <shortname>HR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254702E9C08B12CD8B1420A2124B447183B0A668DFCB197EE89DF93E6ACF98E9812</stationID>
++ <name>Hessischer Rundfunk 3</name>
++ <shortname>HR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685452546CFB27CC9962BF5D8977046D34628F539AA5D68B836F03732D03EC4943541F6C</stationID>
++ <name>Hessischer Rundfunk 4 Rhein-Main</name>
++ <shortname>HR 4 Rhein-Main</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11367224732DD9647905D1A0E3003D6727D6C6A468489AE8E1B8349C8BDE108A1BE864F4DF</stationID>
++ <name>Hessischer Rundfunk - Info</name>
++ <shortname>HR - Info</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11598893448B33C4FDC7C5C5B9B501188282E8B21D0B19A89E026C9BC0E284F344F9DB8C3D</stationID>
++ <name>Hessischer Rundfunk - Info MW</name>
++ <shortname>HR-info MW</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685452549B0EB616A99AF727280D11B619234DFFABDAA8F588578B31D946064A1E4F0CE1</stationID>
++ <name>Hit-Radio FFH Rhein-Main</name>
++ <shortname>FFH</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1136724537075C78FBD2816E19C6B77CC4DAFDC888A9DC10DEBA65983A0B76537048067AE1</stationID>
++ <name>JAM-FM</name>
++ <shortname>JAM-FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106854525483F9405C61CE3EED8B1790B72AE42D9ECF45255D65635DCCA1A185EDB0876D34</stationID>
++ <name>Klassik Radio</name>
++ <shortname>Klassik</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11367244420E0433EBB9A7933AE1DFCAE9AC5968416B2B9C1718E31FED01DFD0676DC2505B</stationID>
++ <name>MAIN FM</name>
++ <shortname>MAIN FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254D0CE4F17DAD846DDC36D7DC42608C19C2F18B4885EC251CE790C84C41CB27447</stationID>
++ <name>Planet Radio</name>
++ <shortname>Planet</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254933EFC46CF2BFFE13CC182D4B05FF2D2461E6F6D7589DDAF3C87DA473962E186</stationID>
++ <name>Radio Fortuna</name>
++ <shortname>Fortuna</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254AC687063AB78F567A8746D9C8C6B2122EDD6595C51D4BE060F507045CE72F2C3</stationID>
++ <name>Radio Melodie</name>
++ <shortname>Melodie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159889106EC20DC8D1EA0580D1BC060B8B6D873182E34D8269303B75B03A36EC11810BDC9</stationID>
++ <name>Radio Primavera</name>
++ <shortname>Primavera</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1136724286E5985147114BB716FE9E15FA357C38BBB0CB331B5396CEB9EBDBCE94915F4A18</stationID>
++ <name>Radio RPR Eins</name>
++ <shortname>RPR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106854525437C470CE8A4CDE8335D5C2F7734E80C021240F03A3CAAEE3012CD289EDC275EC</stationID>
++ <name>RTL Radio</name>
++ <shortname>RTL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10685452541FF3CA5C607D5DE6797DC299B2145287B967056B74590104E2C042A49CDF62B6</stationID>
++ <name>Sunshine Live</name>
++ <shortname>Sunshine</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254C3EDE8BB17AC69C6BFAE1D0C57D3226A907A7420C6B2B792CF8EA9D2844D5BFC</stationID>
++ <name>SWR 1-Rheinland-Pfalz</name>
++ <shortname>SWR 1-Rh.Pfalz</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106854525444FF41C1C7E711CF7C74D8AC38A735064E85E5376AC0F57D568D429B9E913BD5</stationID>
++ <name>SWR 2-Rheinland-Pfalz</name>
++ <shortname>SWR 2-Rh.Pfalz</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254CC505A9B2AEF4B7C6BDA243798B7AED04B2D39569524C28CC4BE3EC0CA46D765</stationID>
++ <name>SWR 3</name>
++ <shortname>SWR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1068545254355DB6BC4C4A688C5E1FEF7DBF78B7FB62C40545D488ADA1A4CCF51AF702F839</stationID>
++ <name>SWR 4 - Pfalz</name>
++ <shortname>SWR 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115988887190FF89418BFC2D560EB0F3E672896E7B59B292E3B85FA8AB6AC579E5FF5ECB05</stationID>
++ <name>Sky Radio</name>
++ <shortname>Sky Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1136724325091824FE3A7B2E74B15CCE068D71760C4BA8271CE5F3511F5BA9F69098A9C9C8</stationID>
++ <name>WDR 2 (Siegen)</name>
++ <shortname>WDR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>106854525406B343319F3EC21170A752D910A7C6C26670A13961C9F0CC9652DF5D53695E68</stationID>
++ <name>WDR 3</name>
++ <shortname>WDR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11367226162FF388CE9717148283756F57FE37EEE28DD6148247865CBD8BC64CF3C8EF3A01</stationID>
++ <name>YOU FM</name>
++ <shortname>Y</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/erwitte-cable.krp kradio-3.5.13.1/kradio3/presets/germany/erwitte-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/erwitte-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/erwitte-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,295 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Michael Skutek &lt;grf-chz@gmx.de&gt;</maintainer>
++ <changed>2007-12-18T15:31:54</changed>
++ <country>Germany</country>
++ <city>Erwitte/Lippstadt/Soest/Paderborn/Warstein</city>
++ <media>cable</media>
++ <comments>Stand November 2007</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422</stationID>
++ <name>hr1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1</stationID>
++ <name>hr2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0</stationID>
++ <name>hr3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608</stationID>
++ <name>hr4-Rhein-Main-Journal</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114</stationID>
++ <name>1LIVE (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49</stationID>
++ <name>Deutschlandradio Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08</stationID>
++ <name>WDR2 - Siegen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62</stationID>
++ <name>NDR1 Radio NDS - Südwest</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61</stationID>
++ <name>NDR2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3</stationID>
++ <name>WDR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F</stationID>
++ <name>NDR Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07</stationID>
++ <name>JUMP</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F</stationID>
++ <name>WDR4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF</stationID>
++ <name>Klassik Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9</stationID>
++ <name>BR1 - Main/Franken</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884</stationID>
++ <name>WDR Radio 5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D</stationID>
++ <name>domradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897</stationID>
++ <name>ERF (Evangeliums Rundfunk)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01</stationID>
++ <name>Funkhaus Europa (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419</stationID>
++ <name>SWR1 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C</stationID>
++ <name>SWR2 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B</stationID>
++ <name>SWR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A</stationID>
++ <name>BFBS (engl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB</stationID>
++ <name>DEFJAY</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54</stationID>
++ <name>radio ffn - Osnabrück</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF</stationID>
++ <name>JAM FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E</stationID>
++ <name>Radio Melodie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744</stationID>
++ <name>Radio 4 (niederl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83</stationID>
++ <name>RTL Radio - Die besten Hits aller Zeiten</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D</stationID>
++ <name>sunshine live</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5</stationID>
++ <name>WDR2 Bielefeld/HIT RADIO FFH</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7</stationID>
++ <name>2255LIVE Ihr Gewinnradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59</stationID>
++ <name>Radio Hochstift/AFN - Frankfurt</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265</stationID>
++ <name>Radio Siegen/Hellweg Radio/Radio Sauerland</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/frankfurth-am-main-cable.krp kradio-3.5.13.1/kradio3/presets/germany/frankfurth-am-main-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/frankfurth-am-main-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/frankfurth-am-main-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,355 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0-beta1-r664</creator>
++ <maintainer>Andreas Karl</maintainer>
++ <changed>2005-03-04T19:15:35</changed>
++ <country>Germany</country>
++ <city>Frankfurt / Hessen</city>
++ <media>Cabel</media>
++ <comments>Stations/Frequencies for Frankfurt Main</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1068545254870A846605C88985C8D465AA421B30FF35FDBEBB55A43E57FCAFD16154206359</stationID>
++ <name>HR1</name>
++ <shortname>HR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254933EFC46CF2BFFE13CC182D4B05FF2D2461E6F6D7589DDAF3C87DA473962E186</stationID>
++ <name>HR-KLASSIK</name>
++ <shortname>HR4 KL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525467DD7BA14D8A886573BE9AED9A64A86C9F8E5AF487245E4146D0307E1EBAFF45</stationID>
++ <name>HR-Info</name>
++ <shortname>HR-Info</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254702E9C08B12CD8B1420A2124B447183B0A668DFCB197EE89DF93E6ACF98E9812</stationID>
++ <name>HR3</name>
++ <shortname>HR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10685452546CFB27CC9962BF5D8977046D34628F539AA5D68B836F03732D03EC4943541F6C</stationID>
++ <name>HR4-RheinMain</name>
++ <shortname>HR4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10685452549B0EB616A99AF727280D11B619234DFFABDAA8F588578B31D946064A1E4F0CE1</stationID>
++ <name>YOU FM</name>
++ <shortname>YOU FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254ADEF6022D469FC3619A861A9696292F20C8DCBA6AD9F0B18313132367BD9CEE8</stationID>
++ <name>DeutschlandRadio-Berlin</name>
++ <shortname>DLR-B</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254C3EDE8BB17AC69C6BFAE1D0C57D3226A907A7420C6B2B792CF8EA9D2844D5BFC</stationID>
++ <name>Hitradio FFH</name>
++ <shortname>FFH</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525444FF41C1C7E711CF7C74D8AC38A735064E85E5376AC0F57D568D429B9E913BD5</stationID>
++ <name>BR1 (Mainz/Franken)</name>
++ <shortname>BR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254CC505A9B2AEF4B7C6BDA243798B7AED04B2D39569524C28CC4BE3EC0CA46D765</stationID>
++ <name>SWR4-Pfalz</name>
++ <shortname>SWR4</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10685452546D14E1356C2246B3F5D7185F12B04FCCA6FD2489D136AFD321BD33231C2C4DB4</stationID>
++ <name>BR3</name>
++ <shortname>BR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254355DB6BC4C4A688C5E1FEF7DBF78B7FB62C40545D488ADA1A4CCF51AF702F839</stationID>
++ <name>BR4 Klassik</name>
++ <shortname>BR4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525435295B421B71BB719FFC423427D88A13394AC09A41C7FADE4CFAF34CF20A967D</stationID>
++ <name>Antenne Bayern</name>
++ <shortname>ANT-BAY</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254A4F642897A3A7A2FDCF75CC91EC34AB83409A44E520926B65616CB71A888A632</stationID>
++ <name>SWR1-Rheinaland Pfalz</name>
++ <shortname>SWR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10685452545BFB673861F03BE773365B16486F1312D0E67EE191A44D3E6E8A2EDE9CFF860B</stationID>
++ <name>SWR2-Rheinaland Pfalz</name>
++ <shortname>SWR2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254A50C8E4F463384279978E9990FE99AD5E8D02892DC85239B19FF5D03D0B2D2E6</stationID>
++ <name>BR5</name>
++ <shortname>BR5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10685452542B850A62AFBC32E86A8AEEAFB6ADDB4471C997F6EC31B99A4705C034891FF15F</stationID>
++ <name>SWR3</name>
++ <shortname>SWR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254AFA422E0A4F4D99F24FFC42C2EA3E5563D518014CAAD3D29F69BC15105EA2B8D</stationID>
++ <name>Radio RPR Eins</name>
++ <shortname>RPR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525432A288014DF7C85A99EB501E082B06B4F96949EBAE12DD4A859C19C3636C7101</stationID>
++ <name>Sunshine LIVE</name>
++ <shortname>SUNSHINE</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254E6194286DD3604C97905284DBD5755FEA2D0D8243E97D5BC889C76C1B6E91888</stationID>
++ <name>Radio Melodie</name>
++ <shortname>MELODIE</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525480DD9CEA8D762EF40365B81DC415F98E8D8D49BB5077BACB848F33AB8FFC1154</stationID>
++ <name>RADIO BOB!(ex Sky Radio)</name>
++ <shortname>SKY</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10685452547C658BFD8AB9FE93566A1D66601EE06F430A26079E188A0E4E304860235DE200</stationID>
++ <name>HR2</name>
++ <shortname>HR2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254739FC26D6EA0AFF43BCC062A18F2B696DD53495A4DB3E0CE961695FDE6CF251C</stationID>
++ <name>radio-x</name>
++ <shortname>radio-x</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525431E0BF7A1159B68FE9747EC8803E96EDE40295B8DCDFC2ADE2D50090859A2AF3</stationID>
++ <name>BIG-FM</name>
++ <shortname>BIG-FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10685452544B20BEB753EDDA4B34C42E483252E211C5BCB770258F801EE1840268FD85CCA2</stationID>
++ <name>WDR2-Siegen</name>
++ <shortname>WDR2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254C2A9AD17F3E452CBB5EDA1FC41F3E91A2CE003910634BC8F3FC0472D24C5BE3B</stationID>
++ <name>WDR3</name>
++ <shortname>WDR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254886BEA32C5981E47D8085FAC639673F691BBEA7D08BEA9437C8168874C4FF3DA</stationID>
++ <name>Radio Fortuna</name>
++ <shortname>FORTUNA</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525483F9405C61CE3EED8B1790B72AE42D9ECF45255D65635DCCA1A185EDB0876D34</stationID>
++ <name>RTL RADIO</name>
++ <shortname>RTL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525490359933CE6E34491643A8F2D51D4B3CDF0644A3FC88A9122F9173A0422A77A4</stationID>
++ <name>planet radio</name>
++ <shortname>planet</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254D0CE4F17DAD846DDC36D7DC42608C19C2F18B4885EC251CE790C84C41CB27447</stationID>
++ <name>Deutschlandfunk (Koeln)</name>
++ <shortname>DLF-K</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1068545254AC687063AB78F567A8746D9C8C6B2122EDD6595C51D4BE060F507045CE72F2C3</stationID>
++ <name>AFN</name>
++ <shortname>AFN</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525437C470CE8A4CDE8335D5C2F7734E80C021240F03A3CAAEE3012CD289EDC275EC</stationID>
++ <name>MAIN FM</name>
++ <shortname>MAIN FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10685452541FF3CA5C607D5DE6797DC299B2145287B967056B74590104E2C042A49CDF62B6</stationID>
++ <name>KLassik Radio</name>
++ <shortname>KlassikR</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106854525406B343319F3EC21170A752D910A7C6C26670A13961C9F0CC9652DF5D53695E68</stationID>
++ <name>JAM-FM</name>
++ <shortname>JAM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/goettingen-cable.krp kradio-3.5.13.1/kradio3/presets/germany/goettingen-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/goettingen-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/goettingen-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,367 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Christian Haase</maintainer>
++ <changed>2008-01-23T15:04:13</changed>
++ <country>Germany</country>
++ <city>G�ttingen</city>
++ <media>Cable</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>120109774346C3B3C59CC62EE9B80B8D8E08A315081FF6DEECADDE797036DD35DD720313AB</stationID>
++ <name>NDR 1 Niedersachsen S�dost</name>
++ <shortname>NDR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010980262AC02EA7CEE4A9787E1BAB56662E863F8406F1DBD1121C163281EBEC130DF71C</stationID>
++ <name>NDR 2</name>
++ <shortname>NDR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120109780028FA4C97936D91B7AA300175D6246EA08F4B5CD9E4CCB628641F6227FDA707EA</stationID>
++ <name>NDR Kultur</name>
++ <shortname>NDR Kultur</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201097927EFEA249C8FC673EBD62E941ED93ED433BCF7E836D1CD7782CDD2CDB152189691</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>Deutschlandfunk</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010978510EA8D2B980E6C19488BA1E7535640C12518B88F734A91A50DB5ECAB1DCF3E4F5</stationID>
++ <name>NDR Info</name>
++ <shortname>NDR Info</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120109837495323238ABA5A082BC5CE9E13FB9BAC2319CB9E8C2FDC5D51E5F7F57CFC3B794</stationID>
++ <name>BFBS (engl.)</name>
++ <shortname>BFBS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201098447C7921DFDCE0A87585C877A4E4F14469E6E631197D8F61C3D9DB7992C0F6CF94E</stationID>
++ <name>N-Joy Radio</name>
++ <shortname>N-Joy</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010985118C339A3D9CF54A26F18143C58DDE078F0C4398FF419B22C8A1112EF54EC9AA72</stationID>
++ <name>HR 1</name>
++ <shortname>HR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201098547D3AB57CEE698B1055882DADE29CB3BFCB82BBBF20CBF6F2F2B1976EFF9044708</stationID>
++ <name>HR 2</name>
++ <shortname>HR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010985715E0FCC725AC4DF418CB8BE1BBF2401F969B75AAC93F3E12AFF6FE818B7BC4DAB</stationID>
++ <name>HR 3</name>
++ <shortname>HR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010986083B91D444A320FF64D572F4D06E5EBF7CF9F5E58BD9CEC18429D6B4C179BEDE9F</stationID>
++ <name>HR 4 Nordhessen-Journal</name>
++ <shortname>HR 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010986436FC6FB10889A59B3E26CF84319697556F79675891B01D19E087BE589A51BD835</stationID>
++ <name>WDR Radio 5</name>
++ <shortname>WDR 5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201098676DC4A41C8EBF28E3EA290014DDB3AE0BDB33EB4F05ED3FFE781348C803686134B</stationID>
++ <name>MDR 1 Radio Th�ringen Erfurt</name>
++ <shortname>MDR 1 Th�ringen</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201098849EE6F5544A5FDEF6F4E671794F7B0D49294B52D96146A015A91EDC48286D85AB9</stationID>
++ <name>WDR 2 Bielefeld</name>
++ <shortname>WDR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201097557C000942967970C43A83708468FF26103AC8B0581DEB400BA21BAA8A849874B32</stationID>
++ <name>Stadtradio G�ttingen</name>
++ <shortname>Stadt G�</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010989008BC7BC41095AC902061E5E57722FF5DC4E18AD136EBAC375EB9E5B74B67DB036</stationID>
++ <name>WDR 4</name>
++ <shortname>WDR 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010989234A3586E929CF194D5AE5061E2B51FDE4CB0DDA02C21811EB73A8CDD679CE3F89</stationID>
++ <name>BR 2 Main/Franken</name>
++ <shortname>BR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201098961DB6AA80EBEF605DB7726EDE700738740F99E762D3B9673046909F377F5BC81A9</stationID>
++ <name>BR 1 Main/Franken</name>
++ <shortname>BR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201098991D21FAC6C42CBCA1C30EDAB03AA24F35F6C0EDA5D9EBB6AB9D3575A055E1D1A59</stationID>
++ <name>Bayern 3</name>
++ <shortname>Bayern 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201099021BADD498B6AEC071B3D17C5FA9DC6491CF07DEE1ABDD5E0D193DC04D0D0C6AB83</stationID>
++ <name>Eins Live (WDR)</name>
++ <shortname>Eins Live</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201099060F137794C0CABE65412572A3A1E133778DB9A56F21E0051DF5AE004DB7EFF1588</stationID>
++ <name>Deutschlandradio Kultur</name>
++ <shortname>Dtl Kultur</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201099105DE85CE952993AC3FEE8B917C0FC45FF302BE4DE3514056800C802CED566AAD3D</stationID>
++ <name>WDR 3</name>
++ <shortname>WDR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120109912693D8EAD66B191CC7A8E74A66CD8F16439634F4E02C27A55B3C05C096A27FEC9A</stationID>
++ <name>Radio Hochstift</name>
++ <shortname>Hochstift</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120109915408E02695F27D249358DA6D4DF70ADE3FFF4F64426449434DA9C21C0B94012FE7</stationID>
++ <name>Antenne Th�ringen</name>
++ <shortname>Antenne Th�ringen</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010991983A71807FC0FF0365E5400DC2A509123262CEC6B18FCD5AE7D29293D198BCCFCC</stationID>
++ <name>89,0 RTL</name>
++ <shortname>89,0 RTL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120109923991F554555E1295EB09A9DE9D0B6208EC7E506B35BA3E55B57BEEC55DC439FEAF</stationID>
++ <name>MDR 1 Radio Sachsen-Anhalt Magdeburg</name>
++ <shortname>MDR 1 Sachsen-Anhalt</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120109931215CD26378E5951B3C42F185A66A67D3D1CF2232BB7A9671BADB30E47F94CE77D</stationID>
++ <name>Jump</name>
++ <shortname>Jump</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120109934107BECD3DDA9C499E7BF7CF85D856A2FE0303C63771B39618B8D865D1353BEBD6</stationID>
++ <name>Radio SAW</name>
++ <shortname>Radio SAW</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201099371D3D2A916EC4AE1ACDBAE8DB326FC93A0FBAB9D7CA67F0768F02633150F58C77D</stationID>
++ <name>MDR Figaro</name>
++ <shortname>MDR Figaro</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201099410375D010A6DC949089AC8548A8767B283E400580491A40EB9FC1F2844FDE748FA</stationID>
++ <name>Radio 21</name>
++ <shortname>Radio 21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010994505AA8B9A303C5365BD0377108CAC995D185AA06FE9DC280AB1F3764FD6062079A</stationID>
++ <name>Radio FFN G�ttingen</name>
++ <shortname>FFN</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010995145E068162D8B94A1DC01E3D59898ECCDFE5E2242602AD59D560BD33ED2A37919E</stationID>
++ <name>Hit-Radio Antenne Niedersachsen G�ttingen</name>
++ <shortname>Antenne Niedersachsen</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201099558D1923339D9D36028AB475C46AB4C84D6CCE86295FAECA640FA99B2D84D6D8BB3</stationID>
++ <name>sunshine live</name>
++ <shortname>sunshine live</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010995821652BB98253CA9A3F953BDD44D4BE6DA7BF855DBC6290EED9C915D488E716F41</stationID>
++ <name>Radio Melodie</name>
++ <shortname>Radio Melodie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12010996100276949EC86ACCDEB088DB01877A9A0E2B53AF2EC6BB8B042BDA14C6597EDC6C</stationID>
++ <name>Klassik Radio</name>
++ <shortname>Klassik Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120109963563936CEE1E7D6B93A945FD9607A1EAC60D2FE23A4D222A8571F306FDDB447BCC</stationID>
++ <name>Hit Radio FFH Nordhessen</name>
++ <shortname>FFH</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201099700A4AF799AEC5140A08E9CCC709595B2A508AAEF09DC1DAF710F0AC06432D93229</stationID>
++ <name>RTL Radio - Die besten Hits mit Gef�hl</name>
++ <shortname>RTL Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201099740E0E7E0DB340AF8DDE58C6981D09FE7C5B8E6A6278CC15AD387BC40BE7677B96B</stationID>
++ <name>DEFJAY</name>
++ <shortname>DEFJAY</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1201099768FDAA47CB55582A630F00D1A94BBA7593014DE7B012357FB155BDD4AF8555FF68</stationID>
++ <name>Jam FM</name>
++ <shortname>Jam FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>108</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/hilden.krp kradio-3.5.13.1/kradio3/presets/germany/hilden.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/hilden.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/hilden.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,353 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Uwe Kuhlmann, Uwe_Kuhlmann@web.de</maintainer>
++ <changed>2005-05-03T18:20:35</changed>
++ <country>Germany</country>
++ <city>Hilden</city>
++ <media>cable</media>
++ <comments>Gilt fr Hilden / Langenfeld / Leichlingen / Monheim / Leverkusen
++(any comment and thanx welcome!)
++ Enth�lt zusammengef�gte Eintr�ge</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>11135013660F9F721EC3DC80603B46C9B67D41EC8F353D462884758182C22E2077C5A6E497</stationID>
++ <name>SWR1-Rheinland-Pfalz</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11135013665F0A1111D6314DAAF3D15B0190CCD182F24D0C60991DEEB9B94F59C1677AD451</stationID>
++ <name>SWR4-Rheinland</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11135013665186333B9483BC89B57913499A9E70F6393DCCF34CC89877F80044FCE256AA7D</stationID>
++ <name>SWR3</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366138A802AD5A22ACBFB1DB303E0D67097FFB8B72914AFE4EADBB906627695F64C</stationID>
++ <name>WDR2-Wuppertal</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366E5A9DE63878AF799B9CAF38BCF370DAA0E5A7B43A8FE9C640FA8668F704EE60C</stationID>
++ <name>WDR Radio 5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11135013667E9887B5EEBE22B9DAFF23CFBA9E070109351EFC26A26286F63BDD19EE66E698</stationID>
++ <name>JAM-FM</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366CF2D50F282F0C22E452E6D7F3130773C446F5906C9305C2A45B53A8480F78890</stationID>
++ <name>WDR2-Rhein-Ruhr</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11135013662BDEA51AF1ABE96284621DF2E6EF55BB9C075ED63E16914AA95A561F4AB17C5A</stationID>
++ <name>WDR4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.1753</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>111350136699854D3B8C0FB6729070CB2AF25C72E672BE565F8B5742CCD6473CDCCB1CC863</stationID>
++ <name>Radio Neandertal</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366A7ADDEB8C9A8341BD6ED9BC754AE0E39DF172E9E4B20C7DE27A818F77196DDEA</stationID>
++ <name>DeutschlandRadio Berlin</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.4004</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>111350136671FD32971DB55D9712623AE318937011D1F42C6F61C9D5E3918403B643C311DB</stationID>
++ <name>Eins Live (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>111350136682160AC418966730CDA6BFA3264F27BFAA63D8D6481FA8EE12A0181C9C8B7CD7</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366D1D121522B0A5B8AE9527134DBFBE187C97A4DE7183C57F4D200C135F2C07957</stationID>
++ <name>RTL RADIO - DIE GR�SSTEN OLDIES</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366F8D933B2F83F720B5124C85435F071C19522579E89C89F7647F3ED2490EB223E</stationID>
++ <name>WDR Radio 5 Funkhaus Europa</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366DB8E4FA3F8534872CFF67494232ECA2E0B1AE6E6B4E1E349DC5761EA766453F5</stationID>
++ <name>Klassik Radio</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366073A8DC7CF7DDE6CFC1A5B4F62B6CD4EB6E2EB932C338787F847B8C5BCC9DC92</stationID>
++ <name>Radio Berg</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366C53472253704CB7F6B1FDE7D1EDF76DCB586336AD12FC2878F51F418B6516651</stationID>
++ <name>Radio 3 (niederl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.951</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366B41219F825DE19A759CF74E874FECBC14DB39ACECAEF16448257C009AAC7E55F</stationID>
++ <name>sunshine live</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.051</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366CFE017DFCC8A99D4656566A73CAFCFE2C40FB8B50D2A30A748AB4A6B327F5AE9</stationID>
++ <name>Radio Melodie - Heimatfunk mit Herz M�nchen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.551</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366165B0CA74BF612CDEFF38DC3262780DCFFBD76523396DA987B648B5554AC6794</stationID>
++ <name>SWR2-Rheinland-Pfalz</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366FEB7AB3FBC338FB78E0BBBF284D377EEF809EE6A6835E323805BFC665B251CC9</stationID>
++ <name>Radio RPR Eins-Rheinland</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.951</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366C7761F0E03F265D63062F2FAA29B6547D786974D33512630893942E754E4856A</stationID>
++ <name>Radio RSG</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11135013666976F9AF303FC869DE76FC858BC99A1EA59CE7A085D422455D726D8F95E95109</stationID>
++ <name>RPR Zwei</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11151372270EC2A4BF0F3036909FAE1CAEB62513B25CD6CC458264FA0EBC0AEC2459AB9DF1</stationID>
++ <name>Radio 2 (niederl.)</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.226</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1113501366A1FB1AB86226CDD00EFCB3EB6682621E1FD1F9F33EDCC22F0F4B532F7E70892F</stationID>
++ <name>Radio 4 (niederl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.501</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1115137175FDF5091456A1D516BAA383BCCB627DEEA81DD03FF84E9C717612D08113588191</stationID>
++ <name>WDR Radio 5</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.7752</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1115137180DFA1745F8A7300B22E767E411E1C589B2A4D6FD4EBF7999758BCA9B2636F21C8</stationID>
++ <name>WDR 3</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.3753</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1115137190DD24C928DD3EBFD3A52AC708916FF2D33FD9177C60BDD96C00FC13F655B0F5F0</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.5255</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1115137191E6E3192689593527258FBE309B99ABC975756DA62A654060E611722D93D5395E</stationID>
++ <name>Antenne D�sseldorf</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.0255</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1115137197FCFA500F48697544E1D615FE25960E193ED884DFCBD792D151D7B04AAB7FE414</stationID>
++ <name>WDR Radio 5 Funkhaus Europa</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.8256</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11151372038613F752A26302D72D4D81EC08D55D5EDA3399ADB0C44EDA4CC4F2771ACBD5B1</stationID>
++ <name>Radio Berg</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.8757</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1115137205517685CB9E5B1C8C3EC2A3CA5BEACEEDF709791AF99BE3ECCAD34E89FDF56BD7</stationID>
++ <name>hr3</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.5508</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1115137207FD6AA54223126EE02DA3C2A6D9BCC41D14AF2F509ABE8DC0368769410D153A79</stationID>
++ <name>BFBS (engl.)</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.026</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11151372129C623D6777686C2A80630E4E4D5A4418334033A86B30A1053C2FEA522F91D9B5</stationID>
++ <name>ERF (Evangeliums-Rundfunk)</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.651</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1115137221EB4CC9C6A22DC1204E6087A523333CA4E6B34ECC70DB3D955C03680DDFD70B21</stationID>
++ <name>Radio RSG</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.326</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11151372245CEB4DCA54C0376C7944BCB601E8C5489F66A2ABB6C147AC597D6AAD837F0CCC</stationID>
++ <name>bigFM</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.476</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>111513723052CCEE3605297250E16967BE66424CD40A53BF4B8C025EA93479D4A446CFE13C</stationID>
++ <name>Domradio</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.126</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/konstanz-cable.krp kradio-3.5.13.1/kradio3/presets/germany/konstanz-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/konstanz-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/konstanz-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,255 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-1.0beta3b</creator>
++ <maintainer>Daniel Str&auml;nger (dev at schmaller dot de)</maintainer>
++ <changed>2006-12-18T12:35:21</changed>
++ <country>Germany</country>
++ <city>Konstanz</city>
++ <media>Cable Analog</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>116644167238F1321A4B015F1A70F1842BBD28B7DBA8363006066739ECFA4F89940729E454</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441674E3AAF2D536A35F27D5E131E302E18E17917B9494E129F68D1C024DABAE330D0B</stationID>
++ <name>Radio Seefunk</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>116644167511341F9D7375A102777A285699E9B19B32086C3D07F2C680124431E6BA88D8A1</stationID>
++ <name>RSI 1</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441677044454339E85CB23E0FEA80C97395F0B5F082834621AFF71FA0F6ADCD0F2D3F6</stationID>
++ <name>DASDING</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>116644153867318DD8FA616CB002B7FEFF3F116DF68E827BCC769BB7A021010251DDE8ABA9</stationID>
++ <name>RTL Radio</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11664416801E589D311ADF455D4FCB833AEDC04FCC43FB47826334173FBEB9A321E5C0D517</stationID>
++ <name>SWR1</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441681D1C8EE34DA5B5FE2DEC676D3637C77289C1481479BB739B98EB1A72A6C8F095F</stationID>
++ <name>SWR2</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11664416828E205C849B191DF5451F0860CE93EA01C8E99D9FB0035582D32F18A738DFDFF6</stationID>
++ <name>SWR3</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>116644168351AFF8CAE8BC28FD39CE5D8AF01C87AE5FD7846FCD787A992E12A05389D80135</stationID>
++ <name>SWR4</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441686E6B7B6A6F9330000DE77BE3F17D29949832AADED45E4A255C8D3C616A185B1C3</stationID>
++ <name>Ö1</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441687E8198ED84131F832827B2A92B7C83EF390FC501C294FB8A402907055687F11AA</stationID>
++ <name>Ö2 (Radio Vorarlberg)</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441688C0209D108F8D6916416D33514FCE4E8DF3C40A3A9B12FC57B1DA0B18F0106562</stationID>
++ <name>Ö3</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441690A492F72FDB725DFEA7C727463535B570F301E39118BE6A85A5D6D0FFF73EDACE</stationID>
++ <name>FM4</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441691D64CE148BACD840CCFFE639FA2430DBF48793C6091BEB6DFC923237DE8311966</stationID>
++ <name>Klassik Radio</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11664416923BED343121C02899E757E85FC91F2D66A4FD30008839AA8FCB2B46A986831416</stationID>
++ <name>Antenne Bayern</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11664416935FA995580C00EB03AB99D6B8C3627B2F9AFD00555BABDBFBD8B6C847701951E5</stationID>
++ <name>BR2</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11664416954251D17FFAB1C19888B3BDAF309017191E8491A11CCA94CAC4AEAFDFC87D98E4</stationID>
++ <name>BR1</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441549E468A60BBEC88E3339CF1A6373AB4396A859CF4D6DD101AC9801A5D48F94A85B</stationID>
++ <name>BR3</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441698F67C9285970AC34FE783A1836A1A3E1803F76F49D7B12A09B29BA04B091FDF88</stationID>
++ <name>BR4</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441700D7B89D336BB7B1F99B077C67043F15466D919E17B16DF11A94AAEE341731B07D</stationID>
++ <name>BR5</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441702B157AA712BABF263606A5E443DC45F86D96F95FBB356893A52EAA109DBC29C57</stationID>
++ <name>ERF Radio</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11664417049F25A61DD6C16564B65E024BB73D521960DA92AC806C2CF0E7E721EA611EFC7C</stationID>
++ <name>radio horeb</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441554347C30787FB9E9EBDE1ACA28B860B5A9B93E591E1D50F99D9A967FE947F7ACC3</stationID>
++ <name>DRS1</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441707031EB9C9E8C4151B05CFEC6A968FBD13B23893F4D94D4222F72A9062D39EBDCF</stationID>
++ <name>DRS2</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11664417087A318E1452B0D1B3F54AA8485AD3F67F74F5D44AD758C104C0B4FDD61F758339</stationID>
++ <name>DRS3</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11664417100AB0C53D85FAADBF07AD5EB8C02384E12BA33BCFC23C5AF20800B674440827B6</stationID>
++ <name>Radio Melodie</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441711D189CA449A9546945255009207B5C9367287BF496B7001A7C938AC6A326901E3</stationID>
++ <name>Radio 7</name>
++ <shortname>27</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>116644171371F70255CFB196BCE5F932B0618CBE35F681F092278A13A69678CA61C6869C6E</stationID>
++ <name>JAM-FM</name>
++ <shortname>28</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11664417167F4F1DFCFB7C204E8AB95C8D042E295FFB2EC595E441055F60325A48559F7CF8</stationID>
++ <name>Deutschlandradio Kultur</name>
++ <shortname>29</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1166441717BE71C69ECAF383473836EFB426F77A6155FAA5D9496658C99C2F4E6401FC5E74</stationID>
++ <name>sunshine live</name>
++ <shortname>30</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.55</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/lippstadt-cable.krp kradio-3.5.13.1/kradio3/presets/germany/lippstadt-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/lippstadt-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/lippstadt-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,295 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Michael Skutek &lt;grf-chz@gmx.de&gt;</maintainer>
++ <changed>2007-12-18T15:31:54</changed>
++ <country>Germany</country>
++ <city>Erwitte/Lippstadt/Soest/Paderborn/Warstein</city>
++ <media>cable</media>
++ <comments>Stand November 2007</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422</stationID>
++ <name>hr1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1</stationID>
++ <name>hr2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0</stationID>
++ <name>hr3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608</stationID>
++ <name>hr4-Rhein-Main-Journal</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114</stationID>
++ <name>1LIVE (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49</stationID>
++ <name>Deutschlandradio Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08</stationID>
++ <name>WDR2 - Siegen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62</stationID>
++ <name>NDR1 Radio NDS - Südwest</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61</stationID>
++ <name>NDR2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3</stationID>
++ <name>WDR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F</stationID>
++ <name>NDR Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07</stationID>
++ <name>JUMP</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F</stationID>
++ <name>WDR4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF</stationID>
++ <name>Klassik Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9</stationID>
++ <name>BR1 - Main/Franken</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884</stationID>
++ <name>WDR Radio 5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D</stationID>
++ <name>domradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897</stationID>
++ <name>ERF (Evangeliums Rundfunk)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01</stationID>
++ <name>Funkhaus Europa (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419</stationID>
++ <name>SWR1 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C</stationID>
++ <name>SWR2 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B</stationID>
++ <name>SWR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A</stationID>
++ <name>BFBS (engl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB</stationID>
++ <name>DEFJAY</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54</stationID>
++ <name>radio ffn - Osnabrück</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF</stationID>
++ <name>JAM FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E</stationID>
++ <name>Radio Melodie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744</stationID>
++ <name>Radio 4 (niederl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83</stationID>
++ <name>RTL Radio - Die besten Hits aller Zeiten</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D</stationID>
++ <name>sunshine live</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5</stationID>
++ <name>WDR2 Bielefeld/HIT RADIO FFH</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7</stationID>
++ <name>2255LIVE Ihr Gewinnradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59</stationID>
++ <name>Radio Hochstift/AFN - Frankfurt</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265</stationID>
++ <name>Radio Siegen/Hellweg Radio/Radio Sauerland</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/magdeburg-mdcc-cable.krp kradio-3.5.13.1/kradio3/presets/germany/magdeburg-mdcc-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/magdeburg-mdcc-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/magdeburg-mdcc-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,402 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0</creator>
++ <maintainer>H.-J.v.Angern" &lt;h.j.v.angern@mdcc-fun.de&gt;</maintainer>
++ <changed>2010-01-17T18:05:53</changed>
++ <country>Germany</country>
++ <city>Magdeburg</city>
++ <media>Cable</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1263742682EFA8D7372495F12DC5035422BAD8D3846427919A16F52EF7FF445AFA377B</stationID>
++ <name>Hitradio Brocken</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12637427327527D1C44D176E9453D15642882AA0A707E44309221E46E7F2880685268B</stationID>
++ <name>Jump MDR</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742775EB08A061881C66DCB3F6458E4A460DA7AD2C5DCB1535E063FAE23F188826</stationID>
++ <name>MDR 1 Sachsen Anhalt</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742825D0BB7B10DA6EB23C2FAC12F3C684F04B4E90797356E2BCF667C133218BF6</stationID>
++ <name>Sky Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742827A3842FCF15F38EFD4AE035EBD778E446BE23071188606E1A4D6974361B7F</stationID>
++ <name>Deutschland Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374282814ADFADBE2EF1CE3D8D76C481B621D30EE27BBCFF14A52676918965C4945</stationID>
++ <name>MDR Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374282923CF6A6384B154BD196B26FAEC0F46E5D2F75992F1A4CB1E3922E945756F</stationID>
++ <name>SAW</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742830B389853BBD307C73B674DD3080C10A8D7CB8838BDD6057B175CA920FD3AA</stationID>
++ <name>Oldi Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742831CC06B9C80311B37D6466924D9AB2D3ADA554FF9DED60340AC9A039E9B3C8</stationID>
++ <name>Rock Antenne</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12637428322B4118EB5A3211F093974CCCC9927F9558491D774C8AA7E0A33F07700346</stationID>
++ <name>Eins Live</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742833D9A214651D3D206F59094AABE5E3353C48F4020AA8C27C76F836275592E0</stationID>
++ <name>NDR 1 Radio Niederschsen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374283318A69C075A277B3AE8BBC79F4E1E1CFF4D823EABB3E27F2EFC9AA217DDCC</stationID>
++ <name>NDR 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374283421160FBC90ECB09B18979625B7F274B18546F9C5C97A246495B9AAE1A5E9</stationID>
++ <name>FFH</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374283589E02D1E4A540935B08F8687AB04E172BB80B27849A0CDDFFF03174B4C17</stationID>
++ <name>NDR Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374283631ED9E0026122FD10F2825536EC8979B1F01BEB7AD59A182A60DA6AB6337</stationID>
++ <name>NDR Info</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742837C5F29068AF8F6315053367092213F5A91FECB77C79B25DC7123F0F97CE96</stationID>
++ <name>Deutsche Welle</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374283890A8F7FA29894A666714B8C172C8AC2B4AB800CFCE4CFAECCE5B89E97343</stationID>
++ <name>Klassik Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374283997A76504466255252E1563C2AB7F4C94AF7CB603B93CBF0F04A192200307</stationID>
++ <name>HR 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742840F23D0ECD733FDD8E3731B6056CEB2E209AB55CDF408DC3D77D63C4213280</stationID>
++ <name>WDR 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374284156512415BAD6D5DDC43C6D31836973C0907AB8D029DFF6B517E53C2FDDF6</stationID>
++ <name>Radio Multikulti</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742841551253EE75D6424548E0CC1889E159736C4D2ADD3549A113C07F1F061CE2</stationID>
++ <name>FFN</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374284252DC31E7051B8F2C4984B09241B8BB7819148D202E8E524B02774BD15A8A</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12637428435D4645161BCED1C50EF09BF6CE85BEA46C166A1E2D64B19B1822D6700EAD</stationID>
++ <name>Antenne Niedersachsen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374284413BE6B50358FE9B9ADF0A6EA2D9EDF035B91B1321D75EDF33D749E1CFA20</stationID>
++ <name>HR 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374284593B682D61F333A3D754C703C82F42B741DDE18D0C8A2CF8524399A3798F9</stationID>
++ <name>JAM-FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374284646159C57300999149BF9E29B870F326D53B7AD3585AA98358AE57FB57D76</stationID>
++ <name>Radio Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263742847858C45BB6735345C399F738AFF6F55013D910568D69A6A9A85C313021A5F</stationID>
++ <name>HR 4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12637428482EBB68304452FDD74383FB9A44ED38027A32F0806F305E13C5368B14F616</stationID>
++ <name>Bayern 4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263743544D78D9BED87ED0DF1E8519FB2AF5D2C111B20A29EFF9C93A1DFB9F96254C5</stationID>
++ <name>MDR Sputnik</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374354537444BA44CBE30C1D397DA0991B3F9BF542115EEF022AFBC5E5FF290C7A5</stationID>
++ <name>MDR Figaro</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374354645C945AE5A4783113FEEB24D935493E61DCD872EE2A134A465E863CD3876</stationID>
++ <name>Fritz !</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12637435473D9A588A8A12B43BF3596ED13EFB1180A2A05719E7A8FB40D30A250A0056</stationID>
++ <name>BFBS</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263743548B8232CCE6182B4CF3816782E0844B502DDF91E2C28351A0B5877367DE0D3</stationID>
++ <name>SR 1 Europawelle</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263743549B9F2A5257233788E6F04310A8F1DD491442CA56AD73B0E5798C729B99EDC</stationID>
++ <name>YOU FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263743550BFDFB8BCD636A097518718168B3D5D61ECD57E40BCC0F277542874A1BA7C</stationID>
++ <name>Bayern 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263743551B0AEC06DC0F6E54AEE4040B5C41574A6875E90B9911063287E2D6D26F294</stationID>
++ <name>RBB 88.8</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374355201213C9812FD21730D85E96DE0D3A52EF78B5E02A2715518232B56C8A7BD</stationID>
++ <name>Rockland Sachsen Anhalt</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12637435532085DA6DFCF8ACF5D9110E3D8906C6787F5C5959EA24F6556F8B352E32CC</stationID>
++ <name>Radio Eins</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12637435547572CEF30E8B572F74EFE1BD51A7857523DA4C6C72CE5231468DC024D09C</stationID>
++ <name>Sunshine Live</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263743941C06A86CC4F04B028AA968B5A1D0C649853283C5CC797B064E9291C30B25F</stationID>
++ <name>ORF 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1263743942BC75454A3292124CDCE7FCE62C833AA3C823D7B730489D91694921C82BBE</stationID>
++ <name>89.0 RTL</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374394362921148E9ECCE4D0A53BAA6752E8C954750B5716E2DA94072190FB92E46</stationID>
++ <name>Antenne Bayern</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>126374394436B325F6FA9AF7DA917B9D0F9651623DD1D358F20DDBFCAF846F16F20BDC</stationID>
++ <name>Antenne Brandenburg</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/Makefile.am kradio-3.5.13.1/kradio3/presets/germany/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/germany/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/germany/Makefile.am 2012-11-30 23:30:53.000000000 +0100
+@@ -1,244 +1,282 @@
+ SUBDIRS =
+-EXTRA_DIST = "aachen-antenna.krp" "aachen-cable-2.krp" "aachen-cable-3.krp" "aachen-cable.krp" "aichach-cable.krp" "aschaffenburg-cable.krp" "augsburg-cable.krp" "berlin-adlershof-antenna.krp" "berlin-antenna.2.krp" "berlin-antenna.krp" "berlin-cable.2.krp" "berlin-cable.krp" "bielefeld-cable.krp" "bochum-cable.krp" "bonn-antenna.krp" "bottenhorn-antenna.krp" "braunschweig2-cable.krp" "braunschweig-cable.krp" "bremen-cable.krp" "bremerhaven-antenna.krp" "bruchkoebel-cable.krp" "chemnitz-cable.krp" "cologne-cable-2.krp" "cologne-cable.krp" "cologne.krp" "dortmund-cable-2.krp" "dortmund-cable.krp" "dresden-cable.krp" "duesseldorf-cable.krp" "duesseldorf.krp" "emsdetten-cable.krp" "erfurt-cable.2.krp" "erfurt-cable.krp" "erlangen-cable.krp" "erlensee-cable.krp" "erwitte-lippstadt.krp" "essen-cable.krp" "fischbachau-cable.krp" "freiburg-cable.krp" "gelsenkirchen-cable.krp" "gerolsbach-cable.krp" "hamburg-antenna.krp" "hamburg-cable1.krp" "hamburg-cable-2.krp" "hamburg-cable2.krp" "hamburg-cable-3.krp" "hamburg-cable3.krp" "hamburg-cable4.krp" "hamburg-cable5.krp" "hamburg-cable.alternative.krp" "hamburg-cable.krp" "hanau-cable.krp" "hannover-antenna.krp" "hannover-cable.2.krp" "hannover-cable.krp" "heidelberg-cable.krp" "herzogenrath-cable.krp" "hilden-cable.krp" "ingolstadt-cable.krp" "juelich-cable.krp" "karlsruhe-cable.krp" "karlsruhe-noerdlicher-landkreis-cable.krp" "kiel-antenna.krp" "kirchzarten-cable.krp" "klingenthal-antenna.krp" "koeln-antenne.krp" "koeln-cable.2.krp" "koeln-cable.krp" "koeln-loevenich-cable.krp" "langenfeld-cable.krp" "langenselbold-cable.krp" "leer-ostfriesland-cable.krp" "leichlingen-cable.krp" "leipzig-cable.2.krp" "leipzig-cable.krp" "lennestadt-cable.krp" "leverkusen-cable.krp" "ludwigsburg-antenna.krp" "luedenscheid-cable.krp" "maintal-cable.krp" "mainz-cable.krp" "mannheim-cable.krp" "meerbusch-struemp-cable.krp" "moenchengladback-cable.krp" "monheim-cable.krp" "muenchen-2.krp" "muenchen-antenna.krp" "muenchen-cable-2.krp" "muenchen-cable.krp" "muenchen-forstenried-antenna.krp" "muenchen.krp" "muenster-cable.krp" "muenster.krp" "muensterland-antenna.krp" "neuberg-cable.krp" "neuoetting.krp" "nuernberg-cable-2.krp" "nuernberg-cable.krp" "oldenburg-cable.krp" "olpe-antenna.krp" "owen-cable.krp" "pfaffenhofen-ilm-cable.krp" "rheine-mesum-antenna.krp" "rodenbach-cable.krp" "saarbruecken-antenna.krp" "schifferstadt-cable.krp" "schwerte-cable.krp" "st.georgen-cable.krp" "stuttgart-cable-2.krp" "stuttgart-cable.krp" "tuebingen-cable.krp" "ulm-cable.2.krp" "ulm-cable.krp" "weilheim-iOB.krp" "weingarten-cable.krp" "weinstadt-beutelsbach-cable.krp" "wernigerode-antenna.krp" "worfelden-cable.krp"
++EXTRA_DIST = "aachen-antenna.krp" "aachen-cable-2.krp" "aachen-cable-3.krp" "aachen-cable.krp" "aichach-cable.krp" "amtzell-cable.krp" "aschaffenburg-cable.krp" "augsburg-cable.krp" "bayreuth.krp" "berlin-adlershof-antenna.krp" "berlin-antenna.2.krp" "berlin-antenna.krp" "berlin-cable.2.krp" "berlin-cable.3.krp" "berlin-cable.krp" "bielefeld-cable.krp" "bochum-cable.krp" "bonn-antenna.krp" "bonn-cable.krp" "bottenhorn-antenna.krp" "braunschweig2-cable.krp" "braunschweig-cable.krp" "bremen-cable.krp" "bremerhaven-antenna.krp" "bremerhaven-cable.krp" "bruchkoebel-cable.krp" "chemnitz-cable.krp" "cologne-cable-2.krp" "cologne-cable.krp" "cologne.krp" "coswig.krp" "dortmund-cable-2.krp" "dortmund-cable.krp" "dresden-cable.krp" "duesseldorf-cable.krp" "duesseldorf.krp" "emsdetten-cable.krp" "erfurt-cable.2.krp" "erfurt-cable.krp" "erlangen-cable.krp" "erlensee-cable.krp" "erlensee.krp" "erwitte-cable.krp" "erwitte-lippstadt.krp" "essen-cable.krp" "fischbachau-cable.krp" "frankfurth-am-main-cable.krp" "freiburg-cable.krp" "gelsenkirchen-cable.krp" "gerolsbach-cable.krp" "goettingen-cable.krp" "hamburg-antenna.krp" "hamburg-cable1.krp" "hamburg-cable-2.krp" "hamburg-cable2.krp" "hamburg-cable-3.krp" "hamburg-cable3.krp" "hamburg-cable4.krp" "hamburg-cable5.krp" "hamburg-cable.alternative.krp" "hamburg-cable.krp" "hanau-cable.krp" "hannover-antenna.krp" "hannover-cable.2.krp" "hannover-cable.krp" "heidelberg-cable.krp" "herzogenrath-cable.krp" "hilden-cable.krp" "hilden.krp" "ingolstadt-cable.krp" "juelich-cable.krp" "karlsruhe-cable.krp" "karlsruhe-noerdlicher-landkreis-cable.krp" "kiel-antenna.krp" "kirchzarten-cable.krp" "klingenthal-antenna.krp" "koeln-antenne.krp" "koeln-cable.2.krp" "koeln-cable.krp" "koeln-loevenich-cable.krp" "konstanz-cable.krp" "langenfeld-cable.krp" "langenselbold-cable.krp" "leer-ostfriesland-cable.krp" "leichlingen-cable.krp" "leipzig-cable.2.krp" "leipzig-cable.krp" "lennestadt-cable.krp" "leverkusen-cable.krp" "lippstadt-cable.krp" "ludwigsburg-antenna.krp" "luedenscheid-cable.krp" "magdeburg-mdcc-cable.krp" "maintal-cable.krp" "mainz-cable.krp" "mannheim-cable.krp" "meerbusch-struemp-cable.krp" "moenchengladback-cable.krp" "monheim-cable.krp" "muenchen-2.krp" "muenchen-antenna.krp" "muenchen-cable-2.krp" "muenchen-cable.krp" "muenchen-forstenried-antenna.krp" "muenchen.krp" "muenster-cable.krp" "muenster.krp" "muensterland-antenna.krp" "neuberg-cable.krp" "neuoetting.krp" "norderstedt-cable.krp" "nuernberg-cable-2.krp" "nuernberg-cable.krp" "oer-erkenschwick.krp" "oldenburg-cable.krp" "olpe-antenna.krp" "owen-cable.krp" "paderborn-cable.krp" "pfaffenhofen-ilm-cable.krp" "rheine-mesum-antenna.krp" "rodenbach-cable.krp" "saarbruecken-antenna.krp" "schifferstadt-cable.krp" "schwerte-cable.krp" "soest-cable.krp" "st.georgen-cable.krp" "stuttgart-cable-2.krp" "stuttgart-cable.krp" "tuebingen-cable.krp" "ulm-cable.2.krp" "ulm-cable.krp" "warstein-cable.krp" "weilheim-iOB.krp" "weingarten-cable.krp" "weinstadt-beutelsbach-cable.krp" "wernigerode-antenna.krp" "wilhelmshaven-cable.krp" "worfelden-cable.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/"
+- $(INSTALL_DATA) "$(srcdir)/weilheim-iOB.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weilheim-iOB.krp"
+- $(INSTALL_DATA) "$(srcdir)/moenchengladback-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/moenchengladback-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/bremerhaven-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremerhaven-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/muenchen-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-2.krp"
+- $(INSTALL_DATA) "$(srcdir)/weingarten-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weingarten-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/hamburg-cable3.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable3.krp"
++ $(INSTALL_DATA) "$(srcdir)/aachen-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/aachen-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable-2.krp"
++ $(INSTALL_DATA) "$(srcdir)/aachen-cable-3.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable-3.krp"
++ $(INSTALL_DATA) "$(srcdir)/aachen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/aichach-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aichach-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/ingolstadt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ingolstadt-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/karlsruhe-noerdlicher-landkreis-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/karlsruhe-noerdlicher-landkreis-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/muenchen.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen.krp"
++ $(INSTALL_DATA) "$(srcdir)/amtzell-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/amtzell-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/aschaffenburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aschaffenburg-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/augsburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/augsburg-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/bayreuth.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bayreuth.krp"
++ $(INSTALL_DATA) "$(srcdir)/berlin-adlershof-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-adlershof-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/berlin-antenna.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-antenna.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/berlin-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/berlin-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-cable.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/berlin-cable.3.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-cable.3.krp"
++ $(INSTALL_DATA) "$(srcdir)/berlin-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/bielefeld-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bielefeld-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/bochum-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bochum-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/bonn-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bonn-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/bonn-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bonn-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/bottenhorn-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bottenhorn-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/braunschweig2-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/braunschweig2-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/braunschweig-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/braunschweig-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/bremen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/bremerhaven-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremerhaven-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/bremerhaven-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremerhaven-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/bruchkoebel-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bruchkoebel-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/chemnitz-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/chemnitz-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/cologne-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne-cable-2.krp"
++ $(INSTALL_DATA) "$(srcdir)/cologne-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/cologne.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne.krp"
++ $(INSTALL_DATA) "$(srcdir)/coswig.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/coswig.krp"
++ $(INSTALL_DATA) "$(srcdir)/dortmund-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dortmund-cable-2.krp"
++ $(INSTALL_DATA) "$(srcdir)/dortmund-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dortmund-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/dresden-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dresden-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/duesseldorf-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/duesseldorf-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/duesseldorf.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/duesseldorf.krp"
+- $(INSTALL_DATA) "$(srcdir)/pfaffenhofen-ilm-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/pfaffenhofen-ilm-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/worfelden-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/worfelden-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/leer-ostfriesland-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leer-ostfriesland-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/leipzig-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leipzig-cable.2.krp"
+- $(INSTALL_DATA) "$(srcdir)/muenchen-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-cable-2.krp"
++ $(INSTALL_DATA) "$(srcdir)/emsdetten-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/emsdetten-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/erfurt-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erfurt-cable.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/erfurt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erfurt-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/erlangen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erlangen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/hanau-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hanau-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/hamburg-cable-3.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable-3.krp"
+- $(INSTALL_DATA) "$(srcdir)/saarbruecken-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/saarbruecken-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/koeln-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/bonn-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bonn-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/nuernberg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/nuernberg-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/langenfeld-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/langenfeld-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/augsburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/augsburg-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/herzogenrath-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/herzogenrath-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/cologne-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne-cable-2.krp"
+- $(INSTALL_DATA) "$(srcdir)/ulm-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ulm-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/muenster-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenster-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/meerbusch-struemp-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/meerbusch-struemp-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/erlensee-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erlensee-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/erlensee.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erlensee.krp"
++ $(INSTALL_DATA) "$(srcdir)/erwitte-lippstadt.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erwitte-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/erwitte-lippstadt.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erwitte-lippstadt.krp"
++ $(INSTALL_DATA) "$(srcdir)/essen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/essen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/fischbachau-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/fischbachau-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/frankfurth-am-main-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/frankfurth-am-main-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/freiburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/freiburg-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/gelsenkirchen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/gelsenkirchen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/gerolsbach-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/gerolsbach-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/goettingen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/goettingen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/hamburg-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/hamburg-cable1.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable1.krp"
+ $(INSTALL_DATA) "$(srcdir)/hamburg-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable-2.krp"
+- $(INSTALL_DATA) "$(srcdir)/schifferstadt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/schifferstadt-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/olpe-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/olpe-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/dresden-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dresden-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/hamburg-cable2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable2.krp"
++ $(INSTALL_DATA) "$(srcdir)/hamburg-cable-3.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable-3.krp"
++ $(INSTALL_DATA) "$(srcdir)/hamburg-cable3.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable3.krp"
++ $(INSTALL_DATA) "$(srcdir)/hamburg-cable4.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable4.krp"
+ $(INSTALL_DATA) "$(srcdir)/hamburg-cable5.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable5.krp"
+- $(INSTALL_DATA) "$(srcdir)/lennestadt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/lennestadt-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/monheim-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/monheim-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/kirchzarten-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/kirchzarten-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/hamburg-cable.alternative.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable.alternative.krp"
+ $(INSTALL_DATA) "$(srcdir)/hamburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/berlin-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-cable.2.krp"
+- $(INSTALL_DATA) "$(srcdir)/aschaffenburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aschaffenburg-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/dortmund-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dortmund-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/braunschweig-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/braunschweig-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/oldenburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/oldenburg-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/berlin-antenna.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-antenna.2.krp"
+- $(INSTALL_DATA) "$(srcdir)/hamburg-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/owen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/owen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/ulm-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ulm-cable.2.krp"
+- $(INSTALL_DATA) "$(srcdir)/luedenscheid-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/luedenscheid-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/duesseldorf-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/duesseldorf-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/hamburg-cable1.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable1.krp"
+- $(INSTALL_DATA) "$(srcdir)/bremen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/schwerte-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/schwerte-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/leipzig-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leipzig-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/st.georgen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/st.georgen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/tuebingen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/tuebingen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/hanau-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hanau-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/hannover-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hannover-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/hannover-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hannover-cable.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/hannover-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hannover-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/heidelberg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/heidelberg-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/herzogenrath-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/herzogenrath-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/hilden-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hilden-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/hilden.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hilden.krp"
++ $(INSTALL_DATA) "$(srcdir)/ingolstadt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ingolstadt-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/juelich-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/juelich-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/karlsruhe-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/karlsruhe-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/erfurt-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erfurt-cable.2.krp"
+- $(INSTALL_DATA) "$(srcdir)/aachen-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable-2.krp"
++ $(INSTALL_DATA) "$(srcdir)/karlsruhe-noerdlicher-landkreis-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/karlsruhe-noerdlicher-landkreis-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/kiel-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/kiel-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/kirchzarten-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/kirchzarten-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/klingenthal-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/klingenthal-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/koeln-antenne.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-antenne.krp"
++ $(INSTALL_DATA) "$(srcdir)/koeln-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-cable.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/koeln-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/koeln-loevenich-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-loevenich-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/konstanz-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/konstanz-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/langenfeld-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/langenfeld-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/langenselbold-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/langenselbold-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/leer-ostfriesland-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leer-ostfriesland-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/leichlingen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leichlingen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/leipzig-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leipzig-cable.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/leipzig-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leipzig-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/lennestadt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/lennestadt-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/leverkusen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leverkusen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/lippstadt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/lippstadt-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/ludwigsburg-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ludwigsburg-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/luedenscheid-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/luedenscheid-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/magdeburg-mdcc-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/magdeburg-mdcc-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/maintal-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/maintal-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/mainz-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/mainz-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/mannheim-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/mannheim-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/meerbusch-struemp-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/meerbusch-struemp-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/moenchengladback-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/moenchengladback-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/monheim-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/monheim-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/muenchen-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/muenchen-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-cable-2.krp"
+ $(INSTALL_DATA) "$(srcdir)/muenchen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/weinstadt-beutelsbach-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weinstadt-beutelsbach-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/berlin-adlershof-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-adlershof-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/wernigerode-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/wernigerode-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/neuoetting.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/neuoetting.krp"
+- $(INSTALL_DATA) "$(srcdir)/juelich-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/juelich-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/fischbachau-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/fischbachau-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/stuttgart-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/stuttgart-cable-2.krp"
+- $(INSTALL_DATA) "$(srcdir)/gelsenkirchen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/gelsenkirchen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/muensterland-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muensterland-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/leverkusen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leverkusen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/berlin-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/muenchen-forstenried-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-forstenried-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/muenchen.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen.krp"
+ $(INSTALL_DATA) "$(srcdir)/muenster.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenster.krp"
+- $(INSTALL_DATA) "$(srcdir)/erfurt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erfurt-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/mannheim-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/mannheim-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/erlensee-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erlensee-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/heidelberg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/heidelberg-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/bielefeld-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bielefeld-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/bottenhorn-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bottenhorn-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/erwitte-lippstadt.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erwitte-lippstadt.krp"
+- $(INSTALL_DATA) "$(srcdir)/cologne.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne.krp"
+- $(INSTALL_DATA) "$(srcdir)/koeln-antenne.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-antenne.krp"
+- $(INSTALL_DATA) "$(srcdir)/mainz-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/mainz-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/muenster-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenster-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/muensterland-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muensterland-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/neuberg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/neuberg-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/bochum-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bochum-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/dortmund-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dortmund-cable-2.krp"
++ $(INSTALL_DATA) "$(srcdir)/neuoetting.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/neuoetting.krp"
++ $(INSTALL_DATA) "$(srcdir)/norderstedt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/norderstedt-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/nuernberg-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/nuernberg-cable-2.krp"
+- $(INSTALL_DATA) "$(srcdir)/leichlingen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leichlingen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/ludwigsburg-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ludwigsburg-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/cologne-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/braunschweig2-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/braunschweig2-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/emsdetten-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/emsdetten-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/aachen-cable-3.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable-3.krp"
+- $(INSTALL_DATA) "$(srcdir)/freiburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/freiburg-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/maintal-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/maintal-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/hannover-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hannover-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/hannover-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hannover-cable.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/nuernberg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/nuernberg-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/oer-erkenschwick.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/oer-erkenschwick.krp"
++ $(INSTALL_DATA) "$(srcdir)/oldenburg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/oldenburg-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/olpe-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/olpe-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/owen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/owen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/paderborn-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/paderborn-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/pfaffenhofen-ilm-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/pfaffenhofen-ilm-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/rheine-mesum-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/rheine-mesum-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/rodenbach-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/rodenbach-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/gerolsbach-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/gerolsbach-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/hannover-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hannover-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/saarbruecken-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/saarbruecken-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/schifferstadt-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/schifferstadt-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/schwerte-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/schwerte-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/st.georgen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/st.georgen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/soest-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/soest-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/stuttgart-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/stuttgart-cable-2.krp"
+ $(INSTALL_DATA) "$(srcdir)/stuttgart-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/stuttgart-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/hamburg-cable.alternative.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable.alternative.krp"
+- $(INSTALL_DATA) "$(srcdir)/koeln-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-cable.2.krp"
+- $(INSTALL_DATA) "$(srcdir)/klingenthal-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/klingenthal-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/hamburg-cable2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable2.krp"
+- $(INSTALL_DATA) "$(srcdir)/aachen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/bruchkoebel-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bruchkoebel-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/hilden-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hilden-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/aachen-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/hamburg-cable4.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable4.krp"
+- $(INSTALL_DATA) "$(srcdir)/kiel-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/kiel-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/berlin-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/rheine-mesum-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/rheine-mesum-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/muenchen-forstenried-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-forstenried-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/essen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/essen-cable.krp"
+-
+-
++ $(INSTALL_DATA) "$(srcdir)/tuebingen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/tuebingen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/ulm-cable.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ulm-cable.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/ulm-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ulm-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/warstein-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/warstein-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/weilheim-iOB.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weilheim-iOB.krp"
++ $(INSTALL_DATA) "$(srcdir)/weingarten-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weingarten-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/weinstadt-beutelsbach-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weinstadt-beutelsbach-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/wernigerode-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/wernigerode-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/wilhelmshaven-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/wilhelmshaven-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/worfelden-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/worfelden-cable.krp"
++
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weilheim-iOB.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/moenchengladback-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremerhaven-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weingarten-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable3.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable-2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable-3.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aichach-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ingolstadt-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/karlsruhe-noerdlicher-landkreis-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/chemnitz-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/duesseldorf.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/pfaffenhofen-ilm-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/worfelden-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leer-ostfriesland-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leipzig-cable.2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-cable-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erlangen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hanau-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable-3.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/saarbruecken-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bonn-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/nuernberg-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/langenfeld-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/augsburg-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/herzogenrath-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne-cable-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ulm-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenster-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/meerbusch-struemp-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/schifferstadt-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/olpe-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dresden-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable5.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/lennestadt-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/monheim-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/kirchzarten-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-cable.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/amtzell-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aschaffenburg-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dortmund-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/braunschweig-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/oldenburg-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-antenna.2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/owen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ulm-cable.2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/luedenscheid-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/duesseldorf-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable1.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/schwerte-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leipzig-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/st.georgen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/tuebingen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/karlsruhe-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erfurt-cable.2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-loevenich-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/langenselbold-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weinstadt-beutelsbach-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/augsburg-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bayreuth.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-adlershof-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/wernigerode-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/neuoetting.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/juelich-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/fischbachau-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/stuttgart-cable-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/gelsenkirchen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muensterland-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leverkusen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-antenna.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-cable.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-cable.3.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenster.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erfurt-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/mannheim-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erlensee-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/heidelberg-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bielefeld-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bochum-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bonn-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bonn-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bottenhorn-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erwitte-lippstadt.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/braunschweig2-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/braunschweig-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremerhaven-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bremerhaven-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bruchkoebel-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/chemnitz-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne-cable-2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-antenne.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/mainz-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/neuberg-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bochum-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/coswig.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dortmund-cable-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/nuernberg-cable-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leichlingen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ludwigsburg-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/cologne-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/braunschweig2-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dortmund-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/dresden-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/duesseldorf-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/duesseldorf.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/emsdetten-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable-3.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erfurt-cable.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erfurt-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erlangen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erlensee-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erlensee.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erwitte-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/erwitte-lippstadt.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/essen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/fischbachau-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/frankfurth-am-main-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/freiburg-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/maintal-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/gelsenkirchen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/gerolsbach-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/goettingen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable1.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable-2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable-3.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable3.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable4.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable5.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable.alternative.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hanau-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hannover-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hannover-cable.2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/rodenbach-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/gerolsbach-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hannover-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/stuttgart-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable.alternative.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-cable.2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/klingenthal-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/bruchkoebel-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/heidelberg-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/herzogenrath-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hilden-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/aachen-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hamburg-cable4.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/hilden.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ingolstadt-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/juelich-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/karlsruhe-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/karlsruhe-noerdlicher-landkreis-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/kiel-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/berlin-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/rheine-mesum-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/kirchzarten-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/klingenthal-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-antenne.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-cable.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/koeln-loevenich-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/konstanz-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/langenfeld-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/langenselbold-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leer-ostfriesland-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leichlingen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leipzig-cable.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leipzig-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/lennestadt-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/leverkusen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/lippstadt-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ludwigsburg-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/luedenscheid-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/magdeburg-mdcc-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/maintal-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/mainz-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/mannheim-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/meerbusch-struemp-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/monheim-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/moenchengladback-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-cable-2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenster-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenchen-forstenried-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/essen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muenster.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/muensterland-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/neuberg-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/neuoetting.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/norderstedt-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/nuernberg-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/nuernberg-cable-2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/oer-erkenschwick.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/oldenburg-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/olpe-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/owen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/paderborn-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/pfaffenhofen-ilm-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/rheine-mesum-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/rodenbach-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/saarbruecken-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/schifferstadt-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/schwerte-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/soest-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/st.georgen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/stuttgart-cable-2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/stuttgart-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/tuebingen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ulm-cable.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/ulm-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/warstein-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weilheim-iOB.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weingarten-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/weinstadt-beutelsbach-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/wernigerode-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/wilhelmshaven-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/germany/worfelden-cable.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/norderstedt-cable.krp kradio-3.5.13.1/kradio3/presets/germany/norderstedt-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/norderstedt-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/norderstedt-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,450 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2009-02-14</creator>
++ <maintainer>Gerhard-Czech@web.de</maintainer>
++ <changed></changed>
++ <country>Germany</country>
++ <city>Norderstedt</city>
++ <media>cable</media>
++ <comments>wilhelm.tel Senderliste</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1063385350B84E83FC624D588B9BE2C16667AF463CE62AE705548F65C08E293A455B179381</stationID>
++ <name>Radio Hamburg</name>
++ <shortname>Radio HH</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535026BB6D13F62EB11F9202671BE547076886D906672B3BA433EEA32DEE1D5CFBBC</stationID>
++ <name>Deutschlandradio Kultur</name>
++ <shortname>Deutschlandradio Kultur</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853501AC822C1346D33E13696EEC91ACF26BA372F11213BD45B4EE82A96C15FA32287</stationID>
++ <name>WDR 3</name>
++ <shortname>WDR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350373BB2F1ABE25FE88366C4630D30676015E09340196CE2D9CA144A574BF9E312</stationID>
++ <name>NDR 1 Radio Niedersachsen</name>
++ <shortname>NDR 1 RN</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535060116062B40326BB376BFE3AFC499BED2E9977E2FD33EFC4C2EA9A8EC7536CA9</stationID>
++ <name>NDR 1 Welle Nord</name>
++ <shortname>NDR1 WN</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350EE3CB6DB0F51E1AA3983153965EA7FA09DCE13F03EF634CB5831F8DB746ADD02</stationID>
++ <name>NDR 4 Info Spezial</name>
++ <shortname>NDR 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535093FD8B50CD14B4DEDDCAB424AD4A236A3B5132F5A742DD5AE35A1523EA82761E</stationID>
++ <name>N-Joy Radio</name>
++ <shortname>N-Joy</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535044CA129A3069F2F21913EF30FA88A204A17C4F3B771FDB8D37D72B5897D516E6</stationID>
++ <name>1-Live</name>
++ <shortname>1-Live</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535054196C1A743CDE1D0B11CAA8DE8ACD3A7AFB00ABE2A2803F3E6FBA8EA828014B</stationID>
++ <name>hr 1</name>
++ <shortname>hr 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350DE5AD2FDA58E954D66478D9324226E127F9223095557A8D3DFFFEF16FB37C337</stationID>
++ <name>Radio Nora</name>
++ <shortname>Radio Nora</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853509EAAA7B362EC8BCFC1629FA3834FF7A76B91D6C4BFF4CDC3BB222C79D9568692</stationID>
++ <name>hr 2 kultur</name>
++ <shortname>hr 2 kultur</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853500A5320B468F00DDB554C8AFD8D8DB4366DDE401B68B8C10D4BF1100A550E3138</stationID>
++ <name>hr 3</name>
++ <shortname>hr 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350508688C1414B72DB224F647C9BBD7A21F19D3F86897B0A82ECB4DBEABAE2C92E</stationID>
++ <name>SWR 1</name>
++ <shortname>SWR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853506439B306C57FD4A5340C8F7E7364CBEFE1372C60178FEF29688E0627A218BC52</stationID>
++ <name>NDR 90,3</name>
++ <shortname>NDR 90,3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535021D5A21FDEDA49C85D63E57004F55638248728F0BFD40F7671CC9BBC5AEA95DB</stationID>
++ <name>SWR 2</name>
++ <shortname>SWR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350D34BD6644543C07C38FA2D661672A512583CC51AD16F6F0DE32CC4697AEB1118</stationID>
++ <name>NDR Info</name>
++ <shortname>NDR Info</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350FF40EDBD2E10FDAD51A29E107DCAF7077E29E1736E60CB0BDDFA49A551A6A1C2</stationID>
++ <name>NDR 2</name>
++ <shortname>NDR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853500D6CCAD018C68368688B649B1ACFEE285A557AB5C0FDA660E65718DB691499E1</stationID>
++ <name>MDR Sputnik</name>
++ <shortname>MDR Sputnik</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350EBE5C823BACEAE26C7FF138AE71E7711B738C34E75208D92DC51ED5FB9C2FB5E</stationID>
++ <name>Tide 96,0 + HH Lokalradio</name>
++ <shortname>Tide + HH Lokal</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535011B527125E5F38884C3CF693AB2004D3E1C810FD877D2B4213FEFD3836370889</stationID>
++ <name>NDR Kultur</name>
++ <shortname>NDR Kultur</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350AB3F8EE6BAC5C355404FD149F70CF608788C42CBCD172722787BFE29CFBAA8BA</stationID>
++ <name>Bayern 1</name>
++ <shortname>Bayern 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350601899CA33011371470A528C450992A0D64DD34A718C7BCE4AF47EF312D4B136</stationID>
++ <name>Bayern 2</name>
++ <shortname>Bayern 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535068C208A46296C2BE28873616D9C401F53E209937F709EDC3EB6EB7BE49EC4F02</stationID>
++ <name>106!8 rock&apos;n pop</name>
++ <shortname>106!8 rock&apos;n pop</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853502006935D7247875D8AA64C3B2AF8933D5B8D3650A1CAE77A4C6B677833772F0E</stationID>
++ <name>Oldy 95</name>
++ <shortname>Oldy 95</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350169E84364F4F9F4D3C3547FAC7365B9521BEFAB964624811D599177AA4E77E55</stationID>
++ <name>radio Paloma</name>
++ <shortname>radio Paloma</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853503D5AA8B2230615373C62861989B4AD0EB99F4EAED33ECF1EBF06B5967FCD831A</stationID>
++ <name>bremen 1</name>
++ <shortname>bremen 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853507248B4D0A7AD9E7DF13B1893C01E6FC349E736D790CD33B3D0696E9063E85E46</stationID>
++ <name>RTL Radio</name>
++ <shortname>RTL Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350F6080C0CB178074EB190CA8E77340D8267A33B6C3C3E58B87D1E3255DD0AF5D5</stationID>
++ <name>Klassik Radio</name>
++ <shortname>Klassik Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535094733F26C046A7795D27ED029389749370E31C7C1C78483134F220F8D8FAD4A7</stationID>
++ <name>Antenne Bayern</name>
++ <shortname>Antenne Bayern</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350FAD03C1D4B5A46C859A3A110D862C8523602E39385B8E5E402B94A751731F2EC</stationID>
++ <name>Radio ffn</name>
++ <shortname>Radio ffn</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853500526AA9671790C3BB2211D6DF78CC72D1ABB18733ED5803200B3B1B0ED13C46A</stationID>
++ <name>Energy 97,1 Hamburg</name>
++ <shortname>Energy</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853502CD554F9AD1EB9D0727B9D0621D03342D67D2F526DC6C43040F140D1D8412A88</stationID>
++ <name>NDR 1 MV</name>
++ <shortname>NDR 1 MV</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350FCC367BB28B3F06B05EE9436A580DD111C23C69BA950EFFF390F827E9539BB65</stationID>
++ <name>Bayern 4</name>
++ <shortname>Bayern 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535048C54A30155C428309B238A6B368938D90074D049CAC4719607EAB5CF7D1CBB3</stationID>
++ <name>Das Ding</name>
++ <shortname>Das Ding</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633853506D9D33CCAD3D2A21934D4332B28A106F4E7B556D2E85E73D1CA9694FE389A9BF</stationID>
++ <name>WDR 2</name>
++ <shortname>WDR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338535090C69B1F51500F2011BA197DBBF8655430B7EBCE140C874329F8C8C8B0CEA50A</stationID>
++ <name>you fm</name>
++ <shortname>you fm</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350B7953D6A790A5AB4818383A12C503EC062B044FCA52ABF433AA19E42A49283BF</stationID>
++ <name>sunshine live</name>
++ <shortname>sunshine live</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385350FC80A9732793334A7DAC69EA8F7B486EC7160FC3F7A6E592E08C280C7D06F449</stationID>
++ <name>Fritz!</name>
++ <shortname>Fritz!</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12340016715898BD9CD68481FA7E9268C59FDCF206A92F6C2FC4D81F4BF99B1CD14087279D</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>Deutschlandfunk</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1234001676F3C24D22C4CEFAAF59368B1C6175B9A112326DD02540159968DCE362531E47BF</stationID>
++ <name>Hit-Radio Antenne</name>
++ <shortname>Hit-Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1234004410D728141F410BBB7AE00435D01B95B781EAA667EFA34510D49D1F3B511BF1421B</stationID>
++ <name>SWR 3</name>
++ <shortname>SWR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1234004410592FCEB5589B5E7B2E730AB5CB789633232C5CAF6D6D19C59D09BBC989CB022F</stationID>
++ <name>Bayern 3</name>
++ <shortname>Bayern 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1234004411DFC8AC8BFB2B7B5065F7BE40919DA57485B510CAAA1DA6C66D5B15185BF1FBEF</stationID>
++ <name>delta radio</name>
++ <shortname>delta radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>123400445658D18DC5F7E316C14349DAA777FE6EC95255EC80D8E33B208D502CC98C97C9B5</stationID>
++ <name>R.SH Radio Schleswig-Holstein</name>
++ <shortname>R.SH</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>123400445766065E8E29FA0613993EAF2667A8B3E9D6AF0F4ADACEC66F591C43800662D112</stationID>
++ <name>Nordwest Radio</name>
++ <shortname>Nordwest Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12340044573D82674FCA85A381784833081DFDF233C9C032301D07C8CAB368BD735FAAA9CC</stationID>
++ <name>Freies Sender Kombinat (FSK)</name>
++ <shortname>Freies Sender Kombinat</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1234004409F068FBDBCEF941ACA3B7C82B7DBBCE43BF5287F6A4B96407FA5343837E171138</stationID>
++ <name>BFBS</name>
++ <shortname>BFBS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1234004458B512B7DC7D8646454A0094CF9F2930306C137063BF00680315D0802EDEDA67B4</stationID>
++ <name>Jam FM</name>
++ <shortname>Jam FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.3</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/oer-erkenschwick.krp kradio-3.5.13.1/kradio3/presets/germany/oer-erkenschwick.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/oer-erkenschwick.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/oer-erkenschwick.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,175 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-1.0beta3b</creator>
++ <maintainer>Uwe Thaler, &lt;Uwe.Thaler@t-online.de&gt;</maintainer>
++ <changed>2003-12-23T22:02:09</changed>
++ <country>Deutschland</country>
++ <city>Essen</city>
++ <media>Kabel</media>
++ <comments>Liste Radio Kabelcom Essen</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>111645544461FE8EC7D53496B0149CC2169AFF2BE5A321887F26EA65C4C52540225748C2DE</stationID>
++ <name>RTL Radio</name>
++ <shortname>RTL R</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444132EC8910552A076B2263EB4FB6DA83828A0EDE6BACD06C3147D3D1D432A0B84</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>DLF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444C33A968EE2BF1BB48608049D2CF4CF12067F88AD3A8399924505353DC2F8C1B1</stationID>
++ <name>WDR 4</name>
++ <shortname>WDR 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554441C32631CB6263AF15048C040D027B28AFFC9380A2B9027721DAC470EFF0F2B13</stationID>
++ <name>WDR Eins Live</name>
++ <shortname>Eins Live</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444EC9767FF57C695D2BC57D4E9960583C198339CBC10C280ADC8967430FA73362C</stationID>
++ <name>Deutschland Radio Berlin</name>
++ <shortname>DR</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554447E69E7F5DC8891C1EC85A6BABE9DA55BF3F972E92D42A27D94189964F338DAEF</stationID>
++ <name>WDR III</name>
++ <shortname>WDR III</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>111645544489F961FBA68B91A2590ED0348782FD901D630C4B10247EE161FF365EDA52A0A4</stationID>
++ <name>Funkhaus Europa - WDR 5</name>
++ <shortname>WDR 5 FHE</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554447D2214728E8C6A0FE7F397222627101A4A4186A81B2C51C0D9C9E66A4A91DE81</stationID>
++ <name>wdr II</name>
++ <shortname>wdr ii</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444DCD947F01824F0A55659C25B627F517E6ADDF5B00B3FB2A658F738A482055810</stationID>
++ <name>Klassik Radio</name>
++ <shortname>Klassik</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554446002034B38BC07A94EDA8819EF2177282B18B46232A19A5ECE0901DF6A0D4D85</stationID>
++ <name>NDR 2</name>
++ <shortname>NDR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444B6F7C6375D08F52073F4D132CEC84048966F773C1492E82A05585CCA2C11A891</stationID>
++ <name>HR 3</name>
++ <shortname>HR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>111645544479D905B9328F1AC358A01F714EE8C17400018AE87DBED4CE5C7F625F914B5FDB</stationID>
++ <name>domradio</name>
++ <shortname>dom</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>111645544480377316E6435D71F5EB8AA0402FB46031174B80C5AC418AE0C0CCDAEDA937A2</stationID>
++ <name>bigFM Rheinland-Pfalz</name>
++ <shortname>bigFM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554449784A88F4B6C63A7C41D755BE911D687B4C687070880F5B28605E85AECA30754</stationID>
++ <name>SWR 4 Rheinland</name>
++ <shortname>SWR 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444D5E482E6616E9D6E5D5BDFE5A04193005823CE44E87B48484DF749B8FF8D035B</stationID>
++ <name>SWR 3</name>
++ <shortname>SWR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554440A3113553BB364D4A20AE066334DE449CA5C17CCA426E8FA1D1EDCCB375D94B6</stationID>
++ <name>SWR 1 Rheinland-Pfalz</name>
++ <shortname>SWR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554447A369B21CFC99C0BF2B72914C742BE496DFDFCD025658A93E387411759BBFA9D</stationID>
++ <name>sunshine live</name>
++ <shortname>Sunshine</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444C55AFCD21C815FB71F984EABA23B215432E193FCC8D4F77B9722D39CCA020CF2</stationID>
++ <name>BFBS</name>
++ <shortname>BFBS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>111645544418C2B1594DAF8F9AD98E1A3D4EC894D3A74B163377373AA0D594B4690538B502</stationID>
++ <name>WDR 5</name>
++ <shortname>WDR 5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554446B06F6FC468822B3823EA87329E6F0A6F352A325BC2618FB8037056CC8A53191</stationID>
++ <name>Radio Melodie</name>
++ <shortname>Melodie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/paderborn-cable.krp kradio-3.5.13.1/kradio3/presets/germany/paderborn-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/paderborn-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/paderborn-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,295 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Michael Skutek &lt;grf-chz@gmx.de&gt;</maintainer>
++ <changed>2007-12-18T15:31:54</changed>
++ <country>Germany</country>
++ <city>Erwitte/Lippstadt/Soest/Paderborn/Warstein</city>
++ <media>cable</media>
++ <comments>Stand November 2007</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422</stationID>
++ <name>hr1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1</stationID>
++ <name>hr2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0</stationID>
++ <name>hr3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608</stationID>
++ <name>hr4-Rhein-Main-Journal</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114</stationID>
++ <name>1LIVE (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49</stationID>
++ <name>Deutschlandradio Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08</stationID>
++ <name>WDR2 - Siegen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62</stationID>
++ <name>NDR1 Radio NDS - Südwest</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61</stationID>
++ <name>NDR2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3</stationID>
++ <name>WDR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F</stationID>
++ <name>NDR Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07</stationID>
++ <name>JUMP</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F</stationID>
++ <name>WDR4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF</stationID>
++ <name>Klassik Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9</stationID>
++ <name>BR1 - Main/Franken</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884</stationID>
++ <name>WDR Radio 5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D</stationID>
++ <name>domradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897</stationID>
++ <name>ERF (Evangeliums Rundfunk)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01</stationID>
++ <name>Funkhaus Europa (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419</stationID>
++ <name>SWR1 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C</stationID>
++ <name>SWR2 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B</stationID>
++ <name>SWR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A</stationID>
++ <name>BFBS (engl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB</stationID>
++ <name>DEFJAY</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54</stationID>
++ <name>radio ffn - Osnabrück</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF</stationID>
++ <name>JAM FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E</stationID>
++ <name>Radio Melodie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744</stationID>
++ <name>Radio 4 (niederl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83</stationID>
++ <name>RTL Radio - Die besten Hits aller Zeiten</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D</stationID>
++ <name>sunshine live</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5</stationID>
++ <name>WDR2 Bielefeld/HIT RADIO FFH</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7</stationID>
++ <name>2255LIVE Ihr Gewinnradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59</stationID>
++ <name>Radio Hochstift/AFN - Frankfurt</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265</stationID>
++ <name>Radio Siegen/Hellweg Radio/Radio Sauerland</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/soest-cable.krp kradio-3.5.13.1/kradio3/presets/germany/soest-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/soest-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/soest-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,295 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Michael Skutek &lt;grf-chz@gmx.de&gt;</maintainer>
++ <changed>2007-12-18T15:31:54</changed>
++ <country>Germany</country>
++ <city>Erwitte/Lippstadt/Soest/Paderborn/Warstein</city>
++ <media>cable</media>
++ <comments>Stand November 2007</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422</stationID>
++ <name>hr1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1</stationID>
++ <name>hr2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0</stationID>
++ <name>hr3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608</stationID>
++ <name>hr4-Rhein-Main-Journal</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114</stationID>
++ <name>1LIVE (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49</stationID>
++ <name>Deutschlandradio Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08</stationID>
++ <name>WDR2 - Siegen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62</stationID>
++ <name>NDR1 Radio NDS - Südwest</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61</stationID>
++ <name>NDR2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3</stationID>
++ <name>WDR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F</stationID>
++ <name>NDR Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07</stationID>
++ <name>JUMP</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F</stationID>
++ <name>WDR4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF</stationID>
++ <name>Klassik Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9</stationID>
++ <name>BR1 - Main/Franken</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884</stationID>
++ <name>WDR Radio 5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D</stationID>
++ <name>domradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897</stationID>
++ <name>ERF (Evangeliums Rundfunk)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01</stationID>
++ <name>Funkhaus Europa (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419</stationID>
++ <name>SWR1 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C</stationID>
++ <name>SWR2 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B</stationID>
++ <name>SWR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A</stationID>
++ <name>BFBS (engl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB</stationID>
++ <name>DEFJAY</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54</stationID>
++ <name>radio ffn - Osnabrück</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF</stationID>
++ <name>JAM FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E</stationID>
++ <name>Radio Melodie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744</stationID>
++ <name>Radio 4 (niederl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83</stationID>
++ <name>RTL Radio - Die besten Hits aller Zeiten</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D</stationID>
++ <name>sunshine live</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5</stationID>
++ <name>WDR2 Bielefeld/HIT RADIO FFH</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7</stationID>
++ <name>2255LIVE Ihr Gewinnradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59</stationID>
++ <name>Radio Hochstift/AFN - Frankfurt</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265</stationID>
++ <name>Radio Siegen/Hellweg Radio/Radio Sauerland</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/warstein-cable.krp kradio-3.5.13.1/kradio3/presets/germany/warstein-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/warstein-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/warstein-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,295 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Michael Skutek &lt;grf-chz@gmx.de&gt;</maintainer>
++ <changed>2007-12-18T15:31:54</changed>
++ <country>Germany</country>
++ <city>Erwitte/Lippstadt/Soest/Paderborn/Warstein</city>
++ <media>cable</media>
++ <comments>Stand November 2007</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422</stationID>
++ <name>hr1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1</stationID>
++ <name>hr2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0</stationID>
++ <name>hr3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608</stationID>
++ <name>hr4-Rhein-Main-Journal</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114</stationID>
++ <name>1LIVE (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49</stationID>
++ <name>Deutschlandradio Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08</stationID>
++ <name>WDR2 - Siegen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62</stationID>
++ <name>NDR1 Radio NDS - Südwest</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61</stationID>
++ <name>NDR2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3</stationID>
++ <name>WDR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F</stationID>
++ <name>NDR Kultur</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07</stationID>
++ <name>JUMP</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F</stationID>
++ <name>WDR4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF</stationID>
++ <name>Klassik Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9</stationID>
++ <name>BR1 - Main/Franken</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884</stationID>
++ <name>WDR Radio 5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D</stationID>
++ <name>domradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897</stationID>
++ <name>ERF (Evangeliums Rundfunk)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01</stationID>
++ <name>Funkhaus Europa (WDR)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419</stationID>
++ <name>SWR1 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C</stationID>
++ <name>SWR2 -Rheinland Pfalz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B</stationID>
++ <name>SWR3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A</stationID>
++ <name>BFBS (engl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB</stationID>
++ <name>DEFJAY</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54</stationID>
++ <name>radio ffn - Osnabrück</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF</stationID>
++ <name>JAM FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E</stationID>
++ <name>Radio Melodie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744</stationID>
++ <name>Radio 4 (niederl.)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83</stationID>
++ <name>RTL Radio - Die besten Hits aller Zeiten</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D</stationID>
++ <name>sunshine live</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5</stationID>
++ <name>WDR2 Bielefeld/HIT RADIO FFH</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7</stationID>
++ <name>2255LIVE Ihr Gewinnradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59</stationID>
++ <name>Radio Hochstift/AFN - Frankfurt</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265</stationID>
++ <name>Radio Siegen/Hellweg Radio/Radio Sauerland</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/germany/wilhelmshaven-cable.krp kradio-3.5.13.1/kradio3/presets/germany/wilhelmshaven-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/germany/wilhelmshaven-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/germany/wilhelmshaven-cable.krp 2012-11-30 23:30:53.000000000 +0100
+@@ -0,0 +1,277 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Michael Herbers, &lt;michael.herbers@gmx.de&gt;</maintainer>
++ <changed>2007-12-11T23:23:26</changed>
++ <country>Germany</country>
++ <city>Wilhelmshaven</city>
++ <media>cable</media>
++ <comments>tux fan</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1091290560F19DCAC9442D72D89504676F5CED64569520089652BE8A8A468E3AE29FBDFA1E</stationID>
++ <name>NDR 1 Niedersachsen</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560DCC0EEE1C09CE8C77AF9C4363AB86860E2B729254B6CBB23609E01FB38AB2C11</stationID>
++ <name>NDR 2</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905603BB0C169D59130A7E4CDB50299B30B4CBAE3140C2E30208DB3BA1D7CA865DDC3</stationID>
++ <name>NDR Kultur</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905609C9242B6154C7E571A4C9E1836EBA6E697BFC7228FDBAC875A7C485BAA697684</stationID>
++ <name>NDR Info</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>109129056091591890E743FC62C0FE220A787BDAFD61AC8C983B8D81A36B97886C7BFCA512</stationID>
++ <name>Radio Jade</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905607D32CC781625CA4804D255AE88896A46524D21EDD358490CD2985F9A7F94BCD6</stationID>
++ <name>Radio Ostfriesland</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560A2E30DF5AF74EC8699A380BEFF08A942ACF65417DD305FECEA447369716BDB90</stationID>
++ <name>RTL Radio</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>109129056092E86276D7410E5C7CC3D2B9F4463DD63CEE5C9363D732181E089F37D0EB7D7A</stationID>
++ <name>FFN</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>109129056009982D289707EE2CCBABFBD81A2074A64E056DFF11E2E9BBD05CDE64A851D141</stationID>
++ <name>Hitradio Antenne</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560D51AC5807AB56AEC3A4BF76F14C190DA9E6569068F1CF7AF25E3144075EA9E41</stationID>
++ <name>N-Joy</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560B66E310EC16F9DE501DA13CFCC5040FF0B31D62247C7CEFE5628C4A3F36A85C6</stationID>
++ <name>Bremen 1</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905602AC2A9C53F9B6E6EFE9E1674878400E7FF5C7F124684CC7F57C9C216A0E01366</stationID>
++ <name>Energy Bremen</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560E610CC27C3CF08B84731FA4FF3C98EC6CB82AD5443E30049E539A2F3443F4202</stationID>
++ <name>Nordwest Radio</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905600334C7216171F1A43051A8A499453CB86833E4DD3268FC448073E63423DD667C</stationID>
++ <name>Bremen 4</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905603085269311505B713B67522CA258791BE5E96E28D39638B55DC412A103BFC178</stationID>
++ <name>Radio Sunshine</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905606EC5591E60AB4673DCEB558470C77BCB246DA9FB755D7283719019CC0E270E4E</stationID>
++ <name>Jam FN</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560D30C88E8D43940B11373590F658CC96DDD2658EB06EC3F1581B777F852321E5D</stationID>
++ <name>FH Europa</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560BA5ECFEDAEB193F5B8630C1C38A93A85304BBAB9AAC1D47661E3ED92077A6B02</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560252B8C5FD95DDBE48DAEF86135F2BF2FA4398FD7C7B37FF425BCCFF321514FD6</stationID>
++ <name>Deutschlandradio Berlin</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905602ECB0B3F03E29CEFD2E07F844BF99621F08CE8B99DBDC6519D813891CE76C734</stationID>
++ <name>Radio Klassik</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560F205062F8746603F2F1CF3C697878D9E82833AA5871AD5F89740068468DC299F</stationID>
++ <name>Radio Melodie</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560645B2E7C0C5F1DD65A0426497CA4618735145E5928DDFA824957C964EE27DCC2</stationID>
++ <name>Radio 1 NL</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560F63220989D5D33B98DFA024203D01D1D4BC59C3226C715A5C44A28159791C189</stationID>
++ <name>Radio 2 NL</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>109129056099FECBDC47A1044EBE759AB969D64FBF1B2590C8AEBA9179E76649818E61AE4C</stationID>
++ <name>Skyradio NL</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560D5DCC73CD877D51CDFB6975B7A4074A9A26D257267DE6527CBF8C3FBFE793DE4</stationID>
++ <name>Radio 4 NL</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560E53E10FEF4C1654C3F4D497D8F8EAA4BEAACB473F1C7500D277349F4D7514844</stationID>
++ <name>RESERVE</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10912905608D35FCB469CB01369E584315BBADAABD9D7B9C8B9D1C1837372BD88FBAC7AB6B</stationID>
++ <name>RESERVE</name>
++ <shortname>27</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1091290560C494E867489FA592C07DE70CF3C1216B4F5E6D1C0C42987E3FC457B4B9E8B5FC</stationID>
++ <name>RESERVE</name>
++ <shortname>28</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>109129056054E0EC549A20C823CC67874F7909A856ED54416CDD24B65DE1C12AD39B5B5EFE</stationID>
++ <name>RESERVE</name>
++ <shortname>29</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.45</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/greece/athens2-antenna.krp kradio-3.5.13.1/kradio3/presets/greece/athens2-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/greece/athens2-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/greece/athens2-antenna.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,639 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>George Alexandropoulos &lt;g.alexandropoulos@gmail.com&gt;</maintainer>
++ <changed>2008-12-26T18:43:34</changed>
++ <country>Greece</country>
++ <city>Athens</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1230309911B23A391B5B6404E3091E9D9ECF9BE8DE4A6FBC37628F936966CA145F15FEED0F</stationID>
++ <name>Κρήτη FM (RDS)</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230310041C53AF537096A464EA9D7393DB1ED3791370F5775E49BC8858BA82280458F5DAC</stationID>
++ <name>Εν Λευκό (RDS)</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303101575D33579382D14ECCC22E92B1414305016182FB7BA9EFE6CA50A604D850A57CBC</stationID>
++ <name>Oasis FM (RDS)</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230310220B5C206BC9810A35D1EFC93D70746E857B846B8E310CAA13D3602035490A9913E</stationID>
++ <name>V FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303102476E86C70BF2EA5C48D3F805B504267254CE29524B0C63D596BD22B6BCEF20E221</stationID>
++ <name>John Greek</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230310272DFE71B1E1BF4CB2EE6E6DA9E2F7AF5B19072431F604C8BE6B18D2EAF368FC67A</stationID>
++ <name>Angel (RDS)</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303103371BC455280287C472750952A9492A173E7279696BE7277A3DB9C66CD53149B85A</stationID>
++ <name>Arren-a Radio (RDS)</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303104015CF4557D8ACE18694D6EE8154D07ECA17672AF11C6F5FF0F723EA05D0145705D</stationID>
++ <name>ΡΣ Εκκλησίαςτης Ελλάδος (RDS)</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303104471B8BBD04DF9F47C0EDB773F06B4BACAE82699ACD1A45F0BB75F8D25B3882794E</stationID>
++ <name>Δρόμος FM (RDS)</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303104933673A9EFFDAB1E1AD16F03D4FFE37C1F5CED43B5C75620A80BC2E9C404F67699</stationID>
++ <name>902, Αριστερά στα FM</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303105374AE158E5AB0ED3A18C78292DD00315902384EA6109A0AA1172552C1C080BAE77</stationID>
++ <name>Κανάλι 1 Πειραία</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230310714AE2CA9D371FBCA12154CF555677EF21621890B461BA8FA41F9D9D764DCCDB484</stationID>
++ <name>Γλυφάδα FM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031075982EB93F0EF674D9AA441B245BD7FC8D1FEFAA870F9109E184E6DBE4596FDD410</stationID>
++ <name>Ράδιο Άστυ</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031080527F7E8134485FDE8926E30146332E82E336178DBF4ABD96487E9D52D5AE22C20</stationID>
++ <name>Ε.ΡΑ. Τρίτο</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303109063B0E3AD5E48ED3A8CF88FE8CC51A90CEF91CA05453F7B360BD86723BB051B413</stationID>
++ <name>Πειραεϊκή Εκκλησία (RDS)</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303109560CCDEF1DFE6DD06D30184BD88334C27D249404F7C06141D1E15DEED2769A26C3</stationID>
++ <name>Κρητική Ραδιοφωνία (RDS)</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031099637DA95EC174BC5C9C0C30E5793D31DEC5D1F80C23C56F9791CE86F6ADA4794A1</stationID>
++ <name>ΝΕΤ (RDS)</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303110246F1535C1B2CC59A3667E77E510E27CC6D0CE1BC195B16C8C1F2E07E98D5EF0C1</stationID>
++ <name>Galaxy 92 (RDS)</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230311024FC7B25A31EC1F8FB66C8575BBBC79BB71852C7FFFDBB4C9FD2640605C24E4A0F</stationID>
++ <name>Λάμψη FM (RDS)</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031116244E7BDC268D4A421650CBA260D84346E9DFCA6D2BA54B0DF53EE49CCBF29E034</stationID>
++ <name>Best Radio (RDS)</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303111928090247F007166010E5D852822A29E1FDAACEDB887EA1261923F19A599386CB3</stationID>
++ <name>Kiss Radio (RDS)</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230311213A944DC146D6BFAA016A9F26EAD33E758890572A9BCA0E1319327B250F2C5AFEE</stationID>
++ <name>Orange (RDS)</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230311245C89045C8E4A643D71D1924EEAD1B28C67AE522A65071531C2353C8FB57EF22A9</stationID>
++ <name>Energy Radio TEI FM</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303115166EC20D8697A6C3050C3AA563EFBE770A99C1B0798F2A7A606478B34E367B694E</stationID>
++ <name>Kosmos (RDS)</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230311550F6F0482ED41A99B83F9BB388EF16F0036BEC8D74B18472D3BC37DBB6D93AADD7</stationID>
++ <name>Ράδιο Μεσώγεια</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303115893C0F6BB62B993A0F13809EB983624554E39A1BA8ACA0A12ED49C38D39D9B3CD5</stationID>
++ <name>Επικοινωνία</name>
++ <shortname>26</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230311623B8101A41BD370C4EF460EC27324FF1F5B7DC74C2F24DEF1040131D54EC8FE6CB</stationID>
++ <name>Ξένιος (RDS)</name>
++ <shortname>27</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303116644824056613E423391508C9C281DEE90D20CE8ACA0314F50F466D75BF2AC16DF8</stationID>
++ <name>Nova Sport FM (RDS)</name>
++ <shortname>28</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230311710D727DBE7F8CA17F95D03CFA6D30792C80E0E040DA8420015272305DBD56EE553</stationID>
++ <name>Ρυθμός (RDS)</name>
++ <shortname>29</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303117775436213D83FC8FFC561FF16EC0237120E5A5F2BA7B9AB3B50A49C4787E75AC65</stationID>
++ <name>Athens Deejay (RDS)</name>
++ <shortname>30</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031182099429EF22F12F22F67E2687DE8E7E1135CF17C4A97338CA0D823A7CD06AF585F</stationID>
++ <name>Ε.ΡΑ. Τρίτο</name>
++ <shortname>31</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230311851996923E9C3FE3723FDF97B589375FC6407F26EA25208B8834A403B4711B8D9A7</stationID>
++ <name>Φλόγα FM</name>
++ <shortname>32</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031189004AE833A162F5018E0CE681665DEE99206E26CD3C7E9936D1591F7719F4C9658</stationID>
++ <name>Disco Radio</name>
++ <shortname>33</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303120414A9CD78220A67C5AD36C260CE2DF6116A7B81B7D178AF5A8EF31C992EEB232BB</stationID>
++ <name>Flash (RDS)</name>
++ <shortname>34</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303120671B21410896F7FDC86B9A94492DFBEA717FA148DBB2E42E2B8DD867B678E39528</stationID>
++ <name>Red FM (RDS)</name>
++ <shortname>35</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312096E38A0CACC50521610911604EB55EEC77B4A747F608831BF9083EE5512311D3A3</stationID>
++ <name>Hijack 96.6 (RDS)</name>
++ <shortname>36</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303121260761F5F5BAAB82465FB3A2C3ECBAEE61CAE3A792C46D9548DE5F649648A73270</stationID>
++ <name>Rock FM</name>
++ <shortname>37</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312166804069BA50E9D7111832D0EA4852161E89B5731255BF0CAE2CCE50550093AE9B</stationID>
++ <name>Ant1 (RDS)</name>
++ <shortname>38</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303121992EB1FA8C469E8BB788AB71BCC3AAB8F9742987112AFC1F6CE45F2166E9A91FA4</stationID>
++ <name>Love Radio (RDS)</name>
++ <shortname>39</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312232366483921B506A2979478D06B02158103F0EB385DBB7B2B856C52168FC595967</stationID>
++ <name>Real FM (RDS)</name>
++ <shortname>40</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312306F95ED4F74CEFDE73EF011BA8CF8778AFAA3467DB5FB30144450D3245A192515B</stationID>
++ <name>98 FM</name>
++ <shortname>41</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312327A2288437FE737C29476DC47CB0508582ADF7E9DBADDB8774C04577B33FBEBC19</stationID>
++ <name>Αθήνα 9.84 </name>
++ <shortname>42</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312364E2AA2C6881FEE40B2D884943C3E8B64481D60ACCBE9A2432EDE514FE51753308</stationID>
++ <name>Derti</name>
++ <shortname>43</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303124142D87A4C355F98DDE7CB724DAEE89545FF34A606A36F76ABD84B7B5E4E8CD40D6</stationID>
++ <name>Alpha Radio (RDS)</name>
++ <shortname>44</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031244511426477E7E610045A66A6D0648BD107284348B0468CDEE0BAAC91FA0DA08C5D</stationID>
++ <name>Μελωδία</name>
++ <shortname>45</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312493A31F04C250C1D43FD9C594F763BFC1B87A1010A03899E9291D1EA2E79698D695</stationID>
++ <name>City 99.5 (RDS)</name>
++ <shortname>46</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312525A4CAAE7137B93A8D20DFFAB81BEA4204385EA6C189A30DE176BB82CB3D4A148B</stationID>
++ <name>Σκαϊ 100.3 (RDS)</name>
++ <shortname>47</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312591B671B9655862ABA64375F40E746FA963F2A4505F0EDEA78AD33E03A339BBA3AF</stationID>
++ <name>Ε.ΡΑ. Σπορ (RDS)</name>
++ <shortname>48</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303126302C4C368C2349DAD777E3D6F4AD90894D48C29579859906DE59FF20C54BD187D7</stationID>
++ <name>Δίεση (RDS)</name>
++ <shortname>49</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312665CBE843B50F7F4895C9461709F956CEFD6ACC0AA75BD380E0D0241AB88670114A</stationID>
++ <name>FM1</name>
++ <shortname>50</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031268612ED29D140FC9FD11967DCF92C0DC33C82861B4F5089A394BA80AEF15D33ABF0</stationID>
++ <name>Ράδιο Κουρσάρος</name>
++ <shortname>51</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031274240D069495348EA1D28B8BD54A4A017B286E8444F2CBBEF72582F5438F6C4BEBD</stationID>
++ <name>Ε.ΡΑ Σπορ (RDS)</name>
++ <shortname>52</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303127692012CEFDB538BB251256AAFD024C4DB8BAC224CD6C9B7920211B6850C34A359F</stationID>
++ <name>Sfera (RDS)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312809CCCC7D548CEB4151F8190472A6E0459B728B5E74930805AB103319560297EAED</stationID>
++ <name>Nitro Radio (RDS)</name>
++ <shortname>54</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312850905EE182DBAD8E79EE4386C24413E2154A31CDCEAD3AA12B457A9E2568122523</stationID>
++ <name>Ε.ΡΑ Δεύτερο (RDS)</name>
++ <shortname>55</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230312886817169D7A15A93410BFE95957996DC91D991585BEC1E45DAF693E26D317804F5</stationID>
++ <name>Ράδιο Αναγέννηση (BlackMan) (RDS)</name>
++ <shortname>56</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303130012B5ABE270738A8EC062B1E27F5154F2BF3F3672E6352C5DB44C6DE6AE22C5017</stationID>
++ <name>Sentra FM (RDS)</name>
++ <shortname>57</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031309044B0C6B4FC9EC701C76FF0E7A6768D86DBD12AE00ED80896B645BFBF87461CFE</stationID>
++ <name>Dream FM</name>
++ <shortname>58</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303130998219B153DCF3C8F424A9AA19CEFFE7655171852B4C342C55E8F22078BB431339</stationID>
++ <name>Ε.ΡΑ. Δεύτερο (RDS)</name>
++ <shortname>59</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031320703190AF84743CFFA4197D7281A023936BFFAA8F9B2C483D77FBE0BF4B608F9DD</stationID>
++ <name>Παρέα FM (RDS)</name>
++ <shortname>60</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230313237B50AF8C2E59E8BBAB86DC11C0383988DF52F9CCC5925CE44E2A74C5EA3888D86</stationID>
++ <name>Athens International Radio</name>
++ <shortname>61</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230313281C3A6919D43EB36613751890BA2A52B1A6B2A8468F7A2B234F6BB9256E77EE2BE</stationID>
++ <name>Athens Shock Radio</name>
++ <shortname>62</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303133198504BD0FD62C0E5041BB115CC1500975A0CD88AC5FE350A8BE98382B21CA5148</stationID>
++ <name>Radio Paradise (RDS)</name>
++ <shortname>63</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031336668A73E93D3A4F9DA8E629E9683521DE0914CD7E344AFC223ECC2A40732CE7427</stationID>
++ <name>Στυλ FM (RDS)</name>
++ <shortname>64</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031341161834E2B7904C834F82709132303CB4A198EF37D476079A8CD32AC5B283056C2</stationID>
++ <name>Ε.ΡΑ Σπορ (RDS)</name>
++ <shortname>65</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230313446E73E13D8B03DAD2777B665D5BE7BA7D81E17FEC6F7E9003F27058BD6B1B59D32</stationID>
++ <name>Atlantis </name>
++ <shortname>66</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031358462B35AC7AE0E6C9192F6D5D3CAAF62F9239903610EFDAB3DC718B0A68168A021</stationID>
++ <name>Παλμός</name>
++ <shortname>67</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230313617CC4B3C32327F712A220D7221443447E80E5D99A3C71E80E5A7878C78B5EE04C6</stationID>
++ <name>Στο Κόκκινο (RDS)</name>
++ <shortname>68</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230313664E878568C085647D08491F498CBAA9369F76F2DCA407587E7C21BDA41BCF55738</stationID>
++ <name>ΝΕΤ (RDS)</name>
++ <shortname>69</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031368917BFC8A91497C0194CFE9D2D8CB058EE98222B86EF99944E17585F802C19373E</stationID>
++ <name>Mad Radio (RDS)</name>
++ <shortname>70</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303138141D53424848F1188AC3BC6E8F99E7A8437CD2316CCC05803F035198B3CE573573</stationID>
++ <name>Ράδιο Αργοσαρωνικός</name>
++ <shortname>71</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303138654AE79C55DE444E7393577333E613CBED20C0CA7699F84F99FBF3B36647789BA4</stationID>
++ <name>Digital FM</name>
++ <shortname>72</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031390634A5D157059B3EC7240BB2FC9E3CB2362A6276261AE13A6BCF96CC52B8B3F8DC</stationID>
++ <name>Kosmos (RDS)</name>
++ <shortname>73</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230313941D75FBD7052D139CDB27CC53A4284924C335A8604275D3E9F30BFE92CE32CEEF4</stationID>
++ <name>Blue Space</name>
++ <shortname>74</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303139928D015AE8A07354DD78F3E4696EE19A4C7A28355A6CFAB152F27A74F7B7E63205</stationID>
++ <name>Star Radio</name>
++ <shortname>75</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123031402535BB69B460FE9C4D04663F7E6B8979490B5C134369E42D10967DBA94DF832936</stationID>
++ <name>Ακτίνα</name>
++ <shortname>76</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1230314060D147B66919B197790141847E85744766CE02ABE25521EDBF9ADB038B1D549B5C</stationID>
++ <name>Super FM</name>
++ <shortname>77</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12303141163EA61198376BD854C55C07DB1AC4154AEF2F18FD38AD4D3A2882D45BA6BB4711</stationID>
++ <name>Ηχόραμα</name>
++ <shortname>78</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>108</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/greece/athens-antenna.krp kradio-3.5.13.1/kradio3/presets/greece/athens-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/greece/athens-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/greece/athens-antenna.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,665 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0</creator>
++ <maintainer>Michael Tr.&lt;michtri@otenet.gr&gt;</maintainer>
++ <changed>2009-07-02T14:16:43</changed>
++ <country>Greece</country>
++ <city>Athens</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1236303555F8C6D2B7D76AB919961DED8B465344600D480097DFA0B9D8FD21EE4407743965</stationID>
++ <name>ΚρΞ?τη FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355521C6A97AC143F04E4FFEF9B3296A8D76AAC854EA957FD9E73FE35DBCC613F56E</stationID>
++ <name>Εν Ξ›Ξ΅Ο…ΞΊΟŽ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555B5D8B70524B3E069215BBD5F346D540F080C118092F4A5C20C46BA4913E9D333</stationID>
++ <name>Oasis FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355592B516BDCAE2D5B5117E8380F5C41A7425C4D3602A9C50DCCDFADDA8772C5140</stationID>
++ <name>VFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035551849550D23A9C290AD1089418684403211056223761369428A5442BFB798845C</stationID>
++ <name>John Greek</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035552856D73C8625ABB8CE79549854C486E994731F59D4D4E2F682134AC8BF610CEB</stationID>
++ <name>Angel</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035559401473C68D712CFB05370CBACC513E3407AD70F06C4AE5EE66B0A6544DD8B87</stationID>
++ <name>Arren-a Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555DF524877EA983F64260140F197B075D3BD3D535FBB6C6F78F58AD498B70A3180</stationID>
++ <name>ΑΣ Εκκλησίας της Ελλάδος</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555B950E4E8944932CF5F899D284017823CA7EB448F5464BF512371E1407A515995</stationID>
++ <name>Ξ”ΟΟŒΞΌΞΏΟ‚ FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555FE988948927F6B487000FA9AA7A5633C44653BF74C5DBDA3CE6D27A088350511</stationID>
++ <name>902 ΑριστΡρά στα FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555BE3B63152696DFA54B3A92B66775A35264BB7281F2C2E2B342BFB3594D65F598</stationID>
++ <name>Κανάλι 1 ΠΡιραιά</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363384889A1A75FA05DEE86039BD59FD19D83DB15CA0C9367271F0EA3AD6379241B77D36</stationID>
++ <name>Radio Asty</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555D034E543C6CBD3A56BDD86E42C3B3786BB9DFB185CB7F2A73670A51769693FAF</stationID>
++ <name>Ξ•.ΑΑ. ΀ρίτο</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035557DC51B6683E28C647D0E16B52477B8BF2F7443F6D0F978F0D4123F89A2A53C22</stationID>
++ <name>ΠΡιραϊκΞ? Εκκλησία</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355579A9ED56F6354B0F53FEF9102BCB7342FC6A8CCD369AAFE206C1DF7E83A6494A</stationID>
++ <name>ΞšΟΞ·Ο„ΞΉΞΊΞ? Ααδιοφωνία</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123633865886ABEF0BD85FA264A328E2D52FC8C3E4893BF1FAADB1E04AE447B10495E4F403</stationID>
++ <name>NET</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555025BCA17F8EF9A0B5B48AF56C02D07CFF8EAE7BECD66DEAE04FA39CC018DA682</stationID>
++ <name>Galaxy 92</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355578828CC76A23BCDFCAAB11465BA737D79C719BB35FBE232B352442AD3C81563A</stationID>
++ <name>Ξ›Ξ¬ΞΌΟˆΞ· FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035557B2403325DD733982F42829F4CA43FE9626BF7A1A5A68FD482AA36EBC6E6BBDE</stationID>
++ <name>Best Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555E15EE72ABEC2D16F003455AC70685892F731AA36E818356AAFD6868297144CE3</stationID>
++ <name>Kiss FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>92.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035554FA4D7BE8217DCC400C11D50231BDCC560E8D4467F3CFF12F91964CEBDC23A35</stationID>
++ <name>Orange</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555CC91671E5F32D0EA8F6C7A47DE9DF968000FFEC1F096B74E65F35EDC31320775</stationID>
++ <name>Kosmos</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555EE0F168A293A39F6B7715EB7015BBC5AE1B84F98B6894B60375913F89F3E3837</stationID>
++ <name>Epikoinonia FM 94</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555D807F6B64385AFAFF35CA0C71E48D6402D8F6DD1317FD8985368202683E76F99</stationID>
++ <name>XFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355582F11794FA491D9AE942B99CCE9CFA385D60A76ADCA8272398798F66FF5023D0</stationID>
++ <name>Nova Sport FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555DE36BA648307E877F5C340E34F10E7ED563BE03BD991A7450B73ADFE87611457</stationID>
++ <name>Ξ‘Ο…ΞΈΞΌΟŒΟ‚</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555F619039E0DB51B3B3F55754A159449F4987CCC442060D32AE6E356090B8ACE70</stationID>
++ <name>Athens DeeJay</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123633888677CEFB92E1F3A3633D56C3179ACF1EEC1C060BC7F7B1355614ECDC8F6D817F72</stationID>
++ <name>Ξ•.ΑΑ. ΀ρίτο</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555F019432F2B2A97E6A9289B3FA6E172E58C306F31E7D14BFEE8B6651DF6FFE4AD</stationID>
++ <name>Floga</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>95.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555002B7464B001BD05C6D36F0DF95839816750FA47A4C4BB620522BE3313234FB6</stationID>
++ <name>Flash</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555CE211857EA50B8116A8C780BFB75B354F0F24471E8A250D465E95B476C4C32D0</stationID>
++ <name>Red FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035552BD28A667EDE6729B103EB0113819281D4FD8C9FB6ECCE791510744AEDE96470</stationID>
++ <name>Hijack 96.6</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555B6DE03DB507ED282725F38D2126C7E2B53C99A15CB9C1D9E5D2FAAAA71B2C54C</stationID>
++ <name>Rock FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035550F41ABC97DBFA000B3049E6BE2C8CC094565BA9CFA86419367AF83DA286A377E</stationID>
++ <name>Ant1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555228F598B5C8AEBB9E7DEB479DBB324EFC609073E2A505C1DA9C65F024AF0A273</stationID>
++ <name>Love Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555AF8701B92ED1DFAC5F94AA6D76D64ACC4045FFE126AE5B9D65890FB28F8001C0</stationID>
++ <name>Radio Veronica</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555BB78B6473DCA5D19CD162E660D97C3DCC20C1B168BAD04BAEB393743DD4DE192</stationID>
++ <name>Real FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>97.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355584EFCCA46C288369540AEA2E9177C6FEC32931B3A41BAAADC772302EC6B70C30</stationID>
++ <name>Free FM 98</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035556772D03B3375CA4CBB4C77526F4C68665A982472337D7E6FB57A70C6AD08CB7D</stationID>
++ <name>ΑθΞ?Ξ½Ξ± 9.84</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555D05113FEDCD174B864DFE6C363D64D8F0FEDDB93A0895D5951444A6FFC271DE0</stationID>
++ <name>Derti</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555E3B5FBA84598C50E5D5AA5DEC44020AEF46F05CEA27B5962AF71A36302EB05DA</stationID>
++ <name>Alpha Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>98.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355502E85E6E11163EC9CE92D641E96E23C2AB647D8F10E3C636572712FA388CFC59</stationID>
++ <name>ΞœΞ΅Ξ»Ο‰Ξ΄Ξ―Ξ±</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035556B4FBBE8D6D94307A23452C23B7F1EF17470DEC6A261B1945480300877040849</stationID>
++ <name>City 99.5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363391269EBCA96147929CD6EA80429E231A1F13C2AA9C45F1DDA930C0494BBF6F3ECC49</stationID>
++ <name>Ξ•.ΑΑ. ΔΡύτΡρο</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035556B5F9C8F7B4D768DCA637C204F25F1E298E6A404C7A97091261CDE9D4052451A</stationID>
++ <name>Σκάι</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035553183FA84CE18D387CB46EBF5CC16505D39F9FF616AFAB34D809FBA59005473F8</stationID>
++ <name>Αάδιο ΞˆΞ½Ο„Ξ±ΟƒΞ· (ΞšΞ±Ο„Ξ¬Ξ»Ξ·ΟˆΞ· ΝομικΞ?Ο‚)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363392215C1075EAAAAF5F8B68DC241DC64B73E74F8CA31C80B8CC5CDAA5A6FFA831CCE6</stationID>
++ <name>Ξ•.ΑΑ. Σπορ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355546A9DBD579719C3F103D9BCD58C4A4A93E7EE0081B3878770CA4FBAAC69104B8</stationID>
++ <name>ΔίΡση</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123633930939349E99E1583D905411E3A26A9F7A0F3B1854E36D8DD0ABD9D7ECF27C92A79C</stationID>
++ <name>FM1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035550FB3D1826ADA343C62F12E359EC478299C150CAF5EB77600601A693C9AFEEA7F</stationID>
++ <name>Ξ•.ΑΑ. Σπορ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035559F6943BECB480619307FB7846D0D6049CE6B63871E531C04D89126A9A0BCBEE9</stationID>
++ <name>Sfera</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035553E482A95AA9987C3A13DD33143C23B73E7FFB25AA030805EFA54EA35F608B45A</stationID>
++ <name>Nitro Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123633941752D1852572742677A43F7BBC58123BADEAC534375869AB801E5AEA35D3E27A54</stationID>
++ <name>Ξ•.ΑΑ. ΔΡύτΡρο</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555F437335446AED229C9B7173F51FE17C07E4E0BB2B9FFEAF9184B419391B80F27</stationID>
++ <name>Αάδιο Αναγέννηση (Blackman)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035551465037E37D37C8643099BA790C9517BF50876E67333AE6F6013D7748AEA8299</stationID>
++ <name>Sentra FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555BC9F9CFAF5E21430C6527BEAF2FB64E7C057ED24F1B6BAEFC4ECCD1FFBD55BF8</stationID>
++ <name>Ξ•.ΑΑ. ΔΡύτΡρο</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035555742A6CD0D32F6B7442B4F64A76D0F640673125BCC3D244B89C279B57C8020A3</stationID>
++ <name>Παρέα FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236339576168E8F86D1EFEB569EC1BE7E8B9076FFE2DBEA320C1E10E46035FECF489C55F4</stationID>
++ <name>Radio Laikos</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035552826561E0029161F6A503930BA1F6C47201A6E3C68D154371F54D64DC93204CD</stationID>
++ <name>Athens International Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355532218320A3836943AEE9715736B1A30E09E8D04FCFF0E41E3325B8E57681C32E</stationID>
++ <name>Shock Radio/Paradise Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236339857FD45FB7C8BF3CD34E2A81D8DDC0A4C533F9312A346A9E948CB848A1636C2AC2B</stationID>
++ <name>Styl FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555B3AC4C4846304D7D5CB88AD564C7B9291D4119031D5D5B8B085251AF8E3EE4A7</stationID>
++ <name>Atlantis</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355529017C5A217A450030806F0667B6AAE22A3D609C5A643A0E7AAAEC4CEC2C0938</stationID>
++ <name>Στο κόκκινο</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555C56B7569D58DAFEEEBC35636A57418EA19C6C6487DDEF05D6E7FE9AB48222330</stationID>
++ <name>NET</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355564CE6CC7B5934E7C847A55C2E13AE83F870C4DE984DAB56C100FE7D3F31C7D0E</stationID>
++ <name>Mad Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236303555EA609BC93A37A5207464F74D75118039B2D584CE6452D6698CEBA61AE028C294</stationID>
++ <name>Αάδιο Ξ‘ΟΞ³ΞΏΟƒΞ±ΟΟ‰Ξ½ΞΉΞΊΟŒΟ‚</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363404362D264AEDDC91C1E2A212597D78ECAE4C633315101C2D1C96789CD265CC45C9E9</stationID>
++ <name>Digital FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035553FC9D2C8AAF40C2FFDBE37510033B111AD1B323C66ADC3F0019DDB838EDCA999</stationID>
++ <name>Kosmos</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123634057618FA5E35E2D3FD8BD5242DC258A594E14B15F717CB25EA5F2890892747DE622F</stationID>
++ <name>Blue Space FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12363035556CEBBE420E1068460097F219C8A46A51A6ED734B28FA9644F3F85F64A1D8D923</stationID>
++ <name>Ακτίνα</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123630355527CE70F600EEEF1844A053FD3A3E2635FB28AA296D8D8B180AB413D3158329B7</stationID>
++ <name>Ξ—Ο‡ΟŒΟΞ±ΞΌΞ±</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>108</frequency>
++ </FrequencyRadioStation>
++ <InternetRadioStation>
++ <stationID>1246530641771960F6E09566E2D1FC981BA989DB7371D1C962E23D5B859B78ABB9E60A</stationID>
++ <name>NME</name>
++ <shortname>NME</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <url>http://shout.astream.com:80</url>
++ <decoderclass>mp3</decoderclass>
++ <playlistclass>auto</playlistclass>
++ </InternetRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/greece/kastoria-antenna.krp kradio-3.5.13.1/kradio3/presets/greece/kastoria-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/greece/kastoria-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/greece/kastoria-antenna.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,243 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Kotorkis Constantinos &lt;kkie68@gmail.com&gt;</maintainer>
++ <changed>2007-04-26T19:30:02</changed>
++ <country>Greece</country>
++ <city>Kastoria</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1063385407E05886942B080C70E9095C4F9EF8862C65C78A24F00C860909A8F2DF1D8E4276</stationID>
++ <name>NET</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854072B0E0DC480808BDB1B13DE7C9EAD8922118AA2308E8EAE5734F497B27D0E5CA4</stationID>
++ <name>Kastoria FM</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>89.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407BAC77165139F07C89AC054801FFCC28D35D934283F02B9BCED437CEE6AC0714E</stationID>
++ <name>Star FM</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338540734A200C587C92B80A77C200463AB2E267EC19752C4A9437DEB5F536717B94D20</stationID>
++ <name>Second Program</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338540752061A546AA001A586665BCB54004C1C1347298E7283572C82D64949DBE9C957</stationID>
++ <name>Radio 1</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>91.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854076453138F76391F38AB129A608316C5D09E32485167705CA7955F77678A2940A0</stationID>
++ <name>Kastoria FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407C1E6152C11A5C05EC1A9B26344BC96855CB5499B0FE9A34778570B790E42D350</stationID>
++ <name>Love Radio</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854074684F1C732220572385076AA324545DAA6F665760E56C87A810D7993A286798F</stationID>
++ <name>Radio Galatini</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>92.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407C2FDA891449DE0C03E5E7932F799722FAA4FF13B03CBE4C99A0917B6C7ADD6DB</stationID>
++ <name>Radio Kastoria</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>93</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854075A7010C56169D354DA3EF48A44A96CD0A0D0E37B3901BE8D3BB0A8C463EFC47B</stationID>
++ <name>ANT</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407DE46F8206EF76187D23429152202A1B933189E4B1058E32A2F9B4CA7633CAC14</stationID>
++ <name>Church FM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>94.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407B76A1FDD10FBFF5530744D064D6BAA8B830B25EF0A574F0392AA52CC9B12C6E8</stationID>
++ <name>ALPHA - Kastoria</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>94.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407B364D20C095E208175C40582AF362B2AFF3BA446358B43A75D885C7089181318</stationID>
++ <name>Radio Top</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407925B3F89E35DCA26D0FDD23B201FB3B5D913150A0B2ED13406D4550A8F225EE7</stationID>
++ <name>FM 95.7</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>95.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338540763F9B74ECB3A3738307E1F8CAC58922C79D914D1A19D9DE507FB9F0AF73D481F</stationID>
++ <name>ERA Florina</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>96.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407BBFCDA7EEB359F7449A9AB09788E3B61611A75A52A0132D62A97345D4AE5120E</stationID>
++ <name>Radio Argos</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>97.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407EC895CE1ED4BA554256C9675503A14AE0A16204C31C96D1EF8DA5F5EAE1CDCE4</stationID>
++ <name>98 - 0 FM</name>
++ <shortname>17</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854073984D438913EB6D843C930D9E3C759F66D5D6844F62CD0B9BC13DE9D088D0E06</stationID>
++ <name>ALPHA</name>
++ <shortname>18</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>98.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407B773C66DE987BF3F6C54397272705D41947595F1627E186C69EC4869070517B5</stationID>
++ <name>Astra</name>
++ <shortname>19</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1097440937C315B67747A306C466CCCF55B8F055176DFD6A2061AADC235FD95FE5259545E3</stationID>
++ <name>ERA Kozani</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>100.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338540776AB993148427CF32961DF65E082B3746EE579B7F51228015D2C0AFEE5FE3B18</stationID>
++ <name>Energy FM</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854072EF5E4D39CD2686DC398799C6BC06B33C6CF5AF8F49EF08AB2DDE87A1DF28CB5</stationID>
++ <name>Melodia</name>
++ <shortname>22</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>102.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854070216B895699C7066D736450D9AB7CE21915CEDEE4160943B05558B7DCA595F8B</stationID>
++ <name>Radio Contact</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1177228968EE49047C34766F31EBA3CBC70B260C51795FF804520F3673FA4D31D60C29C5E5</stationID>
++ <name>Siera FM</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1177228975E0F618803191F64E0F240EA42E64C2FE3CAF4220B5381EBF53F5C2DA7BF44774</stationID>
++ <name>xristianity.gr</name>
++ <shortname>25</shortname>
++ <icon></icon>
++ <volumepreset>0.7</volumepreset>
++ <frequency>107.3</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/greece/Makefile.am kradio-3.5.13.1/kradio3/presets/greece/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/greece/Makefile.am 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/greece/Makefile.am 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,13 @@
++SUBDIRS =
++EXTRA_DIST = "athens2-antenna.krp" "athens-antenna.krp" "kastoria-antenna.krp"
++
++install-data-local:
++ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/greece/"
++ $(INSTALL_DATA) "$(srcdir)/athens2-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/greece/athens2-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/athens-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/greece/athens-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/kastoria-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/greece/kastoria-antenna.krp"
++
++uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/greece/athens2-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/greece/athens-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/greece/kastoria-antenna.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/hungary/bodajk.krp kradio-3.5.13.1/kradio3/presets/hungary/bodajk.krp
+--- kradio-3.5.13.1/kradio3/presets.old/hungary/bodajk.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/hungary/bodajk.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,144 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Zoltán Kukk &lt;kukkzoli at freemail.hu&gt;</maintainer>
++ <changed>2007-01-03T21:00:00</changed>
++ <country>Hungary</country>
++ <city>Bodajk</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1167850373C82402EA2D65E2EF47C5AD84039FCA74B2C9606BDA3149E6D6BDF7FBE95D063E</stationID>
++ <name>Juventus rádió</name>
++ <shortname>Juventus</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1167850406B8127A80BD8BD2C586FD1631292311B0CED2324E69418EC01B0557B9968CACAC</stationID>
++ <name>Ezerjó rádió</name>
++ <shortname>Ezerjó</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1167850435CFAC2599DDD436BF567F4271775919A5B073D86F44E1F4060A7C28B8F0F6A2F2</stationID>
++ <name>Danubius rádió</name>
++ <shortname>Danubius</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1167850498CCFA6F317518BF91DF109749ECB2DFDB6E9EC8166C0A969B744DAEEF6ACF8242</stationID>
++ <name>Sláger rádió (Budapest)</name>
++ <shortname>Sláger</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1167850855354EC11F0524A66B56EBF339D03E94CFEACCF7CCD5321509F1FA04047EC4AA7D</stationID>
++ <name>Sláger rádió (Kabhegy)</name>
++ <shortname>Sláger</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11678510534FA202C2D87C91BABE55195F61FCF266513D3FDDD4FD825E1531ABA688DA9176</stationID>
++ <name>Kossuth rádió (Budapest)</name>
++ <shortname>Kossuth</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1167851116A73EED2A8825C4D7FDB0CF782E800B989D0AE371B5B0DCD7DE29C0B9A3E729ED</stationID>
++ <name>Kossuth rádió (Székesfehérvár)</name>
++ <shortname>kossuth</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116785116398AF0022838BE746A818A591D40E0724E64E12194140D15BBD54A164999C2128</stationID>
++ <name>Petőfi rádió (Budapest)</name>
++ <shortname>Petőfi</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11678512258B63DE67579D3C8A129EDBCC01F899B13BBBE330F0A9639354957A85A7EFA3E0</stationID>
++ <name>Petőfi rádió (Kabhegy)</name>
++ <shortname>Petőfi</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116785126176BD6278000E1B61D6456B665421F90C2399723E2FF720C6A422748F6B10086F</stationID>
++ <name>Bartók rádió (Budapest)</name>
++ <shortname>Bartók</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11678513005B487EEA72C73F5C6C68C219F140943028F878063E44F6DB114EFF24F51C60A0</stationID>
++ <name>Bartók rádió (Kabhegy)</name>
++ <shortname>Bartók</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1167851614C4E8169C6CBA010DE341C04C2945D0F372DBCE50FDF23A6EAFA8BFE50ED1AF72</stationID>
++ <name>Fehérvár rádió (Székesfehérvár)</name>
++ <shortname>Fehérvár</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11678516557A409DB4975E5AFCF59176FAF534BAEFC5AB5AE0828EA0F3EAB932A502D26F02</stationID>
++ <name>Vörösmarty rádió (Székesfehérvár)</name>
++ <shortname>Vörösmarty</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1167851693B85F04BD653789133040263C907C468621EA5E96E1546A763B543243B3BADA55</stationID>
++ <name>Rádió 1 (Székesfehérvár)</name>
++ <shortname>Rádió 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/hungary/Makefile.am kradio-3.5.13.1/kradio3/presets/hungary/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/hungary/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/hungary/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -1,14 +1,16 @@
+ SUBDIRS =
+-EXTRA_DIST = "budapest-antenna.2.krp" "budapest-antenna.krp" "budapest.krp"
++EXTRA_DIST = "bodajk.krp" "budapest-antenna.2.krp" "budapest-antenna.krp" "budapest.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/"
+- $(INSTALL_DATA) "$(srcdir)/budapest.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/budapest.krp"
++ $(INSTALL_DATA) "$(srcdir)/bodajk.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/bodajk.krp"
+ $(INSTALL_DATA) "$(srcdir)/budapest-antenna.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/budapest-antenna.2.krp"
+ $(INSTALL_DATA) "$(srcdir)/budapest-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/budapest-antenna.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/budapest.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/budapest.krp"
+
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/budapest.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/bodajk.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/budapest-antenna.2.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/budapest-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/hungary/budapest.krp"
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/iceland/akureyri-antenna.krp kradio-3.5.13.1/kradio3/presets/iceland/akureyri-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/iceland/akureyri-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/iceland/akureyri-antenna.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,66 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Sveinn í Felli,
++&lt;sveinki@nett.is&gt;</maintainer>
++ <changed>2007-09-19T16:06:04</changed>
++ <country>Iceland</country>
++ <city>Akureyri</city>
++ <media>Antenna</media>
++ <comments>Skýrustu stöðvarnar í Þorpinu, beint á móti
++Hallandssendunum og í sjónlínu við
++Vaðlaheiðarmöstrin.</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1116455444C0A53C88CF0B0CDA23B95FF522492EDC8D85A8A49E1FFDEC642F996299EBB966</stationID>
++ <name>12spor AEY</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>111645544483CB529B5F78FB43D62D676F8E160605DDB4EF2740153A1C170D9E77B153CEB7</stationID>
++ <name>Talstöðin AEY</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1116455444EF6B983A00E17071CFDECD828F1BDC0B8D79AAEA6B7070982F29B978DAAAA2E0</stationID>
++ <name>Gamla Gufan</name>
++ <shortname>RUV</shortname>
++ <icon>/home/sveinki/Documents/mnt/myndir/Skype
++Pictures/ruv0.jpg</icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190205101A69868A03E013E9129D67A1A2C905B0269D0F028844017DE11058713DB990936</stationID>
++ <name>Bylgjan AEY</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7504</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11902051081962E6F35CE1BCF2BC88F69F37181A8D9D354ACC18945492247F99F3C75D886B</stationID>
++ <name>Raus 2 AEY</name>
++ <shortname>R2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.5256</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/iceland/Makefile.am kradio-3.5.13.1/kradio3/presets/iceland/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/iceland/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/iceland/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -1,10 +1,11 @@
+ SUBDIRS =
+-EXTRA_DIST = "reykjavik-antenna.krp"
++EXTRA_DIST = "akureyri-antenna.krp" "reykjavik-antenna.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/iceland/"
++ $(INSTALL_DATA) "$(srcdir)/akureyri-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/iceland/akureyri-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/reykjavik-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/iceland/reykjavik-antenna.krp"
+
+-
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/iceland/akureyri-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/iceland/reykjavik-antenna.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/india/chennai-antenna.krp kradio-3.5.13.1/kradio3/presets/india/chennai-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/india/chennai-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/india/chennai-antenna.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,90 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_11_27</creator>
++ <maintainer>R Deepak</maintainer>
++ <changed>2007-03-31T18:43:18</changed>
++ <country>India</country>
++ <city>Chennai</city>
++ <media>FM Channels</media>
++ <comments>All the FM channels in Chennai.</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>11753445936E9E0E3CB2F8B796DA65739E538B78054D02FC4FF552D5AD5322BF9096662427</stationID>
++ <name>Suryan FM! 93.5</name>
++ <shortname>Suryan</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>117534478397469F0EE509B25EC447D0FB792BAD25C215AC5030FCE0A5526753581D51EE8A</stationID>
++ <name>AIR Chennai! 106.4</name>
++ <shortname>AIR</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11753448532F6C07DB566ADC38950FBEFE3BA1B7A17C67588FCFE42ECF91EBC93060C5484E</stationID>
++ <name>Radio Mirchi! 98.3</name>
++ <shortname>Mirchi!</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1175344609AEBF26E4585D6BB9451B35A6B79D28D60BB45191557CEABE2B70DE9B73286723</stationID>
++ <name>Hello FM! 106.4</name>
++ <shortname>Hello</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1175345266393FFD660E04396BD99D66EF2B285E20CFEE6F34EC7C1D76D6CE7CD5678A5A99</stationID>
++ <name>Radio City! 91.1</name>
++ <shortname>City!</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11753453722D6047CF4D052685FF27306A5E4EB1D199E8F73B96D8F6FF98D2ECD83377B214</stationID>
++ <name>Aha! 91.9</name>
++ <shortname>Aha!</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1175345415AB9DF01C90B137E3F59A6D461167A3DCA48358E634B8018ACB4302D67004B137</stationID>
++ <name>92.7</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1175345458D724DBB612353F3FEE62EF46FDF1262938FB884B7DB68746D40ADB11E4B44824</stationID>
++ <name>Radio One! 94.3</name>
++ <shortname>One!</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1175345587560034B04EDFB7D495329917971B0D575ABA42943DE907244C2712EAFDC58C7D</stationID>
++ <name>All India Radio 105</name>
++ <shortname>AIR 105</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/india/Makefile.am kradio-3.5.13.1/kradio3/presets/india/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/india/Makefile.am 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/india/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,9 @@
++SUBDIRS =
++EXTRA_DIST = "chennai-antenna.krp"
++
++install-data-local:
++ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/india/"
++ $(INSTALL_DATA) "$(srcdir)/chennai-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/india/chennai-antenna.krp"
++
++uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/india/chennai-antenna.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/italy/bologna.2.krp kradio-3.5.13.1/kradio3/presets/italy/bologna.2.krp
+--- kradio-3.5.13.1/kradio3/presets.old/italy/bologna.2.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/italy/bologna.2.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,239 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_11_27</creator>
++ <maintainer>Gabriele Armao - &lt;armao@cs.unibo.it&gt;</maintainer>
++ <changed>2006-10-04T19:27:15</changed>
++ <country>Italy</country>
++ <city>Bologna</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1159867796E4871EB13C28A4A30D192702AE16A05157116050944CD6793E90BF9431658294</stationID>
++ <name>Puntoradio</name>
++ <shortname>Puntoradio</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>88</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867800ACD74C759A92F0A0145B76486A9BA709640E3C8F5E09F4AA2349729389715EEB</stationID>
++ <name>Radio 1</name>
++ <shortname>Radio 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5252</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11598678056B10C8341D5C385A6E8083B51B686CF65A96E423BB96146AB0EBB15F12EBAEAA</stationID>
++ <name>Radio 2</name>
++ <shortname>Radio 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.6753</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867815F32674A7E6FCF9D777C56835DE55FD2EF382991E57FA34D17B6084D8AE6A96DA</stationID>
++ <name>Radio Gamma</name>
++ <shortname>Radio Gamma</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115986781556CB6407ED08D4399F2B64B0D712DF67904FE87E846290502F5E7D29F74273D7</stationID>
++ <name>Radio Company</name>
++ <shortname>Radio Company</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.3755</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115998100090243491D552054F89D8AE7CC4C1BBB8E5A75979E8623EDCE4B4FA88E66F5259</stationID>
++ <name>Radio Città del Capo</name>
++ <shortname>Radio Città del Capo</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867821D06CE1DEFACAE89FA611D6C23F51494EF2AA0E9644A204A103574E4246A500F4</stationID>
++ <name>Radio Nettuno</name>
++ <shortname>Radio Nettuno</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867823CDAAED89B09854AE271D642C9CA742EEAD75D17800B0139C21BA29E8C3A48F45</stationID>
++ <name>Radio International</name>
++ <shortname>Radio International</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.5756</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867824DFE7DA44AA821CEF20013FB9698274C644DA33DCFCDB594271F69B9B7B21782A</stationID>
++ <name>Paneburro</name>
++ <shortname>Paneburro</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11598678290325C9320F5DE2D693129FAD419939421E812A1C96B5A41EF5DCFC3951EC0B15</stationID>
++ <name>Playstudio</name>
++ <shortname>Playstudio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159981753D8BD52A46D7EAFD830788FE999D83B1A3CBF25070AED7694DA606FFFC5359D60</stationID>
++ <name>Radio Deejay</name>
++ <shortname>Radio Deejay</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159981844BCA202D2B3664A3DF04F9A5B0CC018D76C0BF6D378608CD6A7CD5198C44896DA</stationID>
++ <name>Radio Fashion</name>
++ <shortname>Radio Fashion</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867834C67A4C4EFF36BBBA44B89F4EEFA5A0FDA68318BE7C332940741BE05CC9FC4E02</stationID>
++ <name>Radio Maria</name>
++ <shortname>Radio Maria</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867835AA567DCB00F1CDA9CEC1D422F70EBDA6D4F7DA7013A2BCC645F4B8AEEEC9BFAE</stationID>
++ <name>Radio Monte Carlo 2</name>
++ <shortname>RMC2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115998202597FB17CD324D30D4365EBFAAB74C28DB868BB8D425D1D730113AB84587524351</stationID>
++ <name>RTL 102.5</name>
++ <shortname>RTL 102.5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159982065046E122F7603346855EF8A55392F69BAFD8A73FA43B2C1A7CD10325A2E7F75DF</stationID>
++ <name>Kiss Kiss</name>
++ <shortname>Kiss Kiss</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115986783739E74C73DCAE72789AB048FB7551DCB819C63A7F1870A746B08AB62F3BE80B2C</stationID>
++ <name>Radio Anni 60</name>
++ <shortname>Radio Anni 60</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.351</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115986783967AD82D48D91060A6D094CC266C7B84667EE0219D268835AD5B65A9E7B835DC0</stationID>
++ <name>Radio Bruno</name>
++ <shortname>Radio Bruno</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11599822368F30FEE3569AD480E8E9EDDC59E3ADB3F077542FD82BED3B147C62ACF47268AF</stationID>
++ <name>Radio Città Fujiko</name>
++ <shortname>Radio Città Fujiko</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867840EC49187AF76B4CC4862BD711948CF56DB9FBCDB0040409329E5918F1C4FB9E8C</stationID>
++ <name>Radio 103.3</name>
++ <shortname>Radio 103.3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.251</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11599823610B03AD0A2BA306E94007E0E548C1FDF3F7A2960FA9E2F745A08C80CF286FEF31</stationID>
++ <name>Radio105</name>
++ <shortname>Radio105</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867842CC2EB15567BD3B2BB8167B7D0A467877326888C087BE7FE78FE8826CDB70FBB7</stationID>
++ <name>Radio Sabbia</name>
++ <shortname>Radio Sabbia</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.976</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11598678446057BC4116C3FD33AF7BAF73951B6DAEE334DC8A35311D6952232AC131AB86D2</stationID>
++ <name>Radio DImensione Suono</name>
++ <shortname>RDS</shortname>
++ <icon></icon>
++ <volumepreset>0</volumepreset>
++ <frequency>104.501</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115986784537E07F9C327005C0DB00C6D1BB6749175482EB87FE5C7DEE67AEDEC6EAB06921</stationID>
++ <name>Lattemiele</name>
++ <shortname>Lattemiele</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.026</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11598678482059D4D5764000004CF5FD49E8796D8E1E1B5DA24CBAFB3670FCBC1F9D644FFF</stationID>
++ <name>Playradio</name>
++ <shortname>Playradio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.076</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867850B8776E8E5D779CC8EC9CD4FBEF53C3A6CBDBAB1049FBC64455B0BA3222B9B964</stationID>
++ <name>Radio 24</name>
++ <shortname>Radio 24</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.001</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867852D619DE2433296B2FD51950E7A1F34D750801F1D90BBEEC2750851A9166F65C0C</stationID>
++ <name>Lattemiele</name>
++ <shortname>Lattemiele</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.526</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1159867853CCFF791DEAD366D390AB80F332149BE5523826D5927A027319AABD4A118FFCF2</stationID>
++ <name>Radio 101</name>
++ <shortname>Radio 101</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.951</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/italy/Makefile.am kradio-3.5.13.1/kradio3/presets/italy/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/italy/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/italy/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -1,14 +1,17 @@
+ SUBDIRS =
+-EXTRA_DIST = "bologna.krp" "rovato.krp" "torino-antenna.krp"
++EXTRA_DIST = "bologna.2.krp" "bologna.krp" "rovato.krp" "torino-antenna.krp" "trento.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/"
++ $(INSTALL_DATA) "$(srcdir)/bologna.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/bologna.2.krp"
+ $(INSTALL_DATA) "$(srcdir)/bologna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/bologna.krp"
+ $(INSTALL_DATA) "$(srcdir)/rovato.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/rovato.krp"
+ $(INSTALL_DATA) "$(srcdir)/torino-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/torino-antenna.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/trento.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/trento.krp"
+
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/bologna.2.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/bologna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/rovato.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/torino-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/italy/trento.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/italy/trento.krp kradio-3.5.13.1/kradio3/presets/italy/trento.krp
+--- kradio-3.5.13.1/kradio3/presets.old/italy/trento.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/italy/trento.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,367 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>ClaudioFior</maintainer>
++ <changed>2008-02-23T12:21:33</changed>
++ <country>Italy</country>
++ <city>Trento</city>
++ <media>Generical commercial radio</media>
++ <comments>The first private radio for audience</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>12037788327C5000A1E1C3107F31D06EE254802E7FE64344B8508BD16B33321349F935F092</stationID>
++ <name>RTT</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12037784512E058DF3EB180F961037205703CFA3E43AD176232529B6F7A694C83C90133064</stationID>
++ <name>Radio 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12037783990F5404D815267E1CEFBEBD2AF561F18B4AA33DE9DBC766067B0BE8A04398B6EA</stationID>
++ <name>RTT</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203778152A526CCA7DA26245392806D9EEBC290A91EEC1D318C9D80F87BE2F00C41B8B27C</stationID>
++ <name>Radio 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203766148E30AA19F10875C0E4491222EF1665EFFC0D39FD585D8A7867309FD8AE02D2E13</stationID>
++ <name>Radio Italia</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203765566F4E2677160964DE0F02C40E19C974AF24CA370A5497DC8684CDA0971F1565234</stationID>
++ <name>Radio Italia Anni 60</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120376511549E6B71A3CE890F8B8676EEFD32C390819740918C2141BA47DD3150368D636E3</stationID>
++ <name>Latte e miele</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120376467696B11D09DBAE0D31FC25BC86C345975673125B1C3E0DE0962A9CDB822548D482</stationID>
++ <name>Radio Maria</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1195497782E78C6F58B61A33B081034F832CAF523A81F48BB5DD73D145CAE67C6D658F8E91</stationID>
++ <name>Radio1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1195498225CD235FD6E77F1BB29DF7303459C6ED8F08603A713F988646EBE11998E54D4122</stationID>
++ <name>Radio2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11981031163FC9FCF9F8557F554E7B70F10ABD1D8709C53C0AB9932DC9352467EEC8C00603</stationID>
++ <name>Radio3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119810398361E8DC092D02E9643CA66BDCCC5EB080057E8BB1BF8534EC6FFE3277DB186A7F</stationID>
++ <name>Radio Montecarlo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203150062CB034C1991734F1DC16A7F45C94824B25183111A6C807DE86FED49C10EB41DE9</stationID>
++ <name>Radio Margherita</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203150356B2B3BF5088BF9B9224B6E44A13843E8D5FCCC9C9E6CD722DFBDEF67DB7B3D571</stationID>
++ <name>Radio Cuore2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203150494711D017990E1A8C63D001A814F39BF5CD86E7FA27B31EA5B7832962E769FC1F2</stationID>
++ <name>Radio Studio pi�</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120315071062B241694CA1A60BAE348E8EF398A0E787A9DCC3C217A146CC5BB5D063EADD92</stationID>
++ <name>Radio Italia</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203153606B8A32AD018D71B5804D33FC84739B120ED1E04180E44E0234D5A200516DC3EE1</stationID>
++ <name>105 in alta quota</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120315396131FC29130C20B77297DF7D1F37C78079FC106952987C864AE6D5F492AC1D6E06</stationID>
++ <name>Radio cuore</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203154501D15FD503F381C2FEF7661D720D5F52963461D72CFA9FA21127CFA667CADF9A33</stationID>
++ <name>Radio cuore 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12031568517DD2548E0946F0065974D5A21507A3E08350C7AA97AE0957D887E276AD99C019</stationID>
++ <name>NBC</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203200613E74CEFC21DA7C4B61BC16A599C136A70D129B325476B181C2C1CAECF6556E90E</stationID>
++ <name>In blue</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12037568765ECB0C523B1E78437E39371DC85BC474862827FA874A2B15D66D1B352B10AB26</stationID>
++ <name>Radio Dimensione Suono</name>
++ <shortname>RDS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203757011E882BF401D989C42961F043F263E18467AECBB0A10E00652EDC1D82337D405D1</stationID>
++ <name>Vergin Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12037570988FB0B1EBE148AC82B42FB155E3429D704D950EE22ADDA71D55DB145A65CB1ABA</stationID>
++ <name>Radio Dimensione Suono</name>
++ <shortname>RDS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203757250F1C78881D6FF295D020E80C91C4AC8E56329C223B3F87837CE44E4C78D08CF0D</stationID>
++ <name>Radio Latte e Miele</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203757675DF3EB701C74C7CF82B8B9173CEC28CB21C70F61A87CC91025EA6C021E3898B5F</stationID>
++ <name>Radio Dolomiti</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120375786255B98C202F837DD293EEF55471EACA537B331E228B2EE835E494F4866C4E9A2F</stationID>
++ <name>Radio Genius</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12037583500BB86685BFC434BE7675EC38DD2E7604E0220C0DE8D1D65695A0E7B06378AD6A</stationID>
++ <name>Radio Dolomiti</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12037584063E07EC045C029EDBFE8499AC6E21E4342C33B8CF7C4824DD2DDA12A21C852D03</stationID>
++ <name>Radio Genius</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12037584836A28EE00AF9C12F3FAD88367F1DB27C939CE4DA444200AE57017191D0813614E</stationID>
++ <name>Radio Capital</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203758731A214755DC7D0A2FEC3927765269DCE92958E7D5C3D83B8C884D9212621CE9644</stationID>
++ <name>Radio Gamma</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203758996A5D1C5CF5289364B936E933C047EFA878B2663A679F56B0A8DE1DEEF029E5526</stationID>
++ <name>RTL 102.5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120375929353FA1323BD876CCF878483DDE94B4A6AC5CDB97FC16B4C4CFE460C901B60CCCD</stationID>
++ <name>Radio 24</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120375997547B7A1EDB73B248BB273EB8CD513AC1D2B3C0DC882208B4DCEDE1CFB244DACE3</stationID>
++ <name>Rete 101</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203761052A4C36EDEEE1E12F8452070F64678AD816B2E449E2C1B9D761A9644F7DB1FE18A</stationID>
++ <name>Radio Radicale</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203761721500B262A77C5F20170FCE50704F412CB4C55AA7B7CAF552F636CD4E307A3FF4A</stationID>
++ <name>Radio DJ1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.65</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203764354DE34015364D5C788E9EE6BB21CF1286AF4BBD7CCA54E4836D6536E5B8D68C3A3</stationID>
++ <name>Radio Maria</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203764542A23343C3040B36F14B8B65AE6D8298113863B25247836B094DDC21E962A0279A</stationID>
++ <name>Radio DJ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.25</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1203764641F20C7E2AC6EBD257052162471AE4DEFD3773757B400E480176B471F07CEE6612</stationID>
++ <name>Radio 105</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/lithuania/Makefile.am kradio-3.5.13.1/kradio3/presets/lithuania/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/lithuania/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/lithuania/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -1,12 +1,13 @@
+ SUBDIRS =
+-EXTRA_DIST = "kaunas-antenna.krp" "panevezys.krp"
++EXTRA_DIST = "kaunas-antenna.krp" "panevezys.krp" "vilnius.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/lithuania/"
+ $(INSTALL_DATA) "$(srcdir)/kaunas-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/lithuania/kaunas-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/panevezys.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/lithuania/panevezys.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/vilnius.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/lithuania/vilnius.krp"
+
+ uninstall-local:
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/lithuania/kaunas-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/lithuania/panevezys.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/lithuania/vilnius.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/lithuania/vilnius.krp kradio-3.5.13.1/kradio3/presets/lithuania/vilnius.krp
+--- kradio-3.5.13.1/kradio3/presets.old/lithuania/vilnius.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/lithuania/vilnius.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,88 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Andrzej Valchik</maintainer>
++ <changed>2008-08-27T23:00:25</changed>
++ <country>Lithuania</country>
++ <city>Vilnius</city>
++ <media></media>
++ <comments>Contains merged Data</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>12198672179D04D8F6F96417B40484863BE066FC65D89EB7336B216618B7319056873D6999</stationID>
++ <name>Zip FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1219867219728EC984D598E6FC962752395F584B659E6D7C2DCF837FCE3C20951C5DD66969</stationID>
++ <name>Russian Radio</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1219867220014EF13080BDD4E133C40C717013A6D0E184DED3CE7D49C820379D0F4ED69288</stationID>
++ <name>Radiocentras</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1219867222255675B2B22E8A9936E9BCE61691DD75DCE674AE5CD3A0D1B83C717CB64D7FCA</stationID>
++ <name>M1</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.801</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121986753461099673260F43AC1048500BA8CD6A48CE88E7C3655AC55029A0533699DEEE5C</stationID>
++ <name>Power Hit Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121986760885465B9D5A74B4022D81F51C0478BAA1BF2E57D4C4A983FFB26616F66E28491A</stationID>
++ <name>European Hit Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12198670760B330000E51F0F3617E1C73F67120DF45ACE16AB33D101129A0F65BEF43D2847</stationID>
++ <name>Opus 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12198677026740FED9FAD2BC544E5FFDF0F11F5B9FCF3C84AE76210C237B238794FE3E35B0</stationID>
++ <name>M1+</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/luxemburg/alzette.krp kradio-3.5.13.1/kradio3/presets/luxemburg/alzette.krp
+--- kradio-3.5.13.1/kradio3/presets.old/luxemburg/alzette.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/luxemburg/alzette.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,324 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_11_27</creator>
++ <maintainer>Loes Alex &gt;alex@linux.lu&gt;</maintainer>
++ <changed>2006-11-12T12:25:01</changed>
++ <country>Luxembourg</country>
++ <city>Esch/Alzette</city>
++ <media></media>
++ <comments>Contains merged Data</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1163326933EB744DBB9C1EDD1D8E16F31C269ADD45F914715B65BABABC04EDAD9B1333F0C0</stationID>
++ <name>S�dwestrundfunk 1</name>
++ <shortname>SWR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329364799814657B8D3E7D22528643D3E4BAB028C46DE92DC3F89F7C0F1B119B985359</stationID>
++ <name>S�dwestrundfunk 1</name>
++ <shortname>SWR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329214DB6B30879AB4302A94C98A2ACFB6B2149FC6510CB58E6AA1F7B4EF51843D2262</stationID>
++ <name>S�dwestrundfunk 2</name>
++ <shortname>SWR2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163328832D863DD1C695DA1403F48C349657FDF2677DF343F3F0882DF390BE7212716720E</stationID>
++ <name>S�dwestrundfunk 3</name>
++ <shortname>SWR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163325201376872BE5AB201ACBE6B7916BC9FEAE1F778FAE36EDF09D1D8576C2FABE8B808</stationID>
++ <name>S�dwestrundfunk 3</name>
++ <shortname>SWR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163330034075C9ECB9718957096823D12613AD16CB915A26D10BE65CF5407CCD56A43DF08</stationID>
++ <name>Classic21</name>
++ <shortname>Classic21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338540798C0D12726F1661419AB34C2642A94AC5C6E261E91C693826FE8AAB710612343</stationID>
++ <name>Premiere</name>
++ <shortname>Premiere</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633290654CF0230A48506DC3DD90CD2D762F486571C0F789F7EBB5AC0C21A9FA780427D7</stationID>
++ <name>Vivacit�</name>
++ <shortname>Vivacit�</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407AFBFB6A017C8C7A5F8F16BC30B85D0C0E87B84799C65FCE80394C9D2202CE4B6</stationID>
++ <name>RTL L�tzebuerg</name>
++ <shortname>RTL L�tzebuerg</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.9001</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633291411FAD229D1CAAADED0CE059FE98C637C0D4990AE9576CB360DB47DB434B1E7E42</stationID>
++ <name>RTL L�tzebuerg</name>
++ <shortname>RTL L�tzebuerg</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332520866D4C8867B32DE1801A83417CAD34D4D385052BA2C9A2CF6300AFD972A5FF38E</stationID>
++ <name>RTL Radio</name>
++ <shortname>RTL Oldie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407EA222E19244D3040A4F1B8AC8AF03F4EB304ED09F9D0C946A9B557590C5D2B71</stationID>
++ <name>RTL Radio</name>
++ <shortname>RTL Oldie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332892335934EA1B377096CBBCD683C87556466B34F9A3720458EE6BC15AECCF3F0D07F</stationID>
++ <name>BEL RTL</name>
++ <shortname>Bel RTL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332520577808CE062019CAEA5A0EA201C8F5FB635FCAD2B27184857ADA60F1546BCD77B</stationID>
++ <name>Musique </name>
++ <shortname>Musique</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854070D0624F5D0DE76E44CBFCA7425618F58AB75BEF835973FBF447FDA5B50117B85</stationID>
++ <name>Musique 3</name>
++ <shortname>Musique 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854076161020BD41D27F67E226E563E890312F73FB3301F832FD42F97F2C7FC6764C6</stationID>
++ <name>DNR</name>
++ <shortname>DNR</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633252222E92DD5C3EC58F99CD07722FDA5639008D903059DFFC75EDCFF658B4D6D89C36</stationID>
++ <name>DNR</name>
++ <shortname>DNR</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407C0E4A025D422F911694EA657E38FD8B85C87FD88DD984A01C9E0CB5F3DAC0561</stationID>
++ <name>100komma7</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.701</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854079297D695D8BC75127B779ACDACAB080F4F03335C9B916941C159377D64678AF0</stationID>
++ <name>Radioara</name>
++ <shortname>ARA</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407BB520D98D14CECDCD0AAD64B8FF750BA848C03845757BDFB9F0B955D39843639</stationID>
++ <name>Eldoradio</name>
++ <shortname>ELDO</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.002</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329418E8576AD40D75C543EE9A093DCE03B4051FAECBDF73D37CC48B96F40BEC79E22C</stationID>
++ <name>City FM Esch</name>
++ <shortname>City FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407917331FDBE436B09CF00637FC7F12D4E277AF861322A256EC884DD7E86CEF606</stationID>
++ <name>Inter</name>
++ <shortname>Inter</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633252192E0BA2ED6CD18FDFE748A79C5125781907807F97341E8822B1B404B5FACD486F</stationID>
++ <name>Radio Festival</name>
++ <shortname>Festival</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332522516BC3F1CF778CF47ABBFE182FD7AFA0865B7F87E9089E5FBC8A4D1BAA32DABA9</stationID>
++ <name>new station 9</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332954945F54F898EC8F2BB6AA85DDC110F72F64AB4D8E3451E55345F4E1FEDF5634E45</stationID>
++ <name>Radio Latina</name>
++ <shortname>Latina</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329706DED977EB4B2A58B696F64B718E96BC68CAD6DB1DA034BE75BDC5320FECEBF85A</stationID>
++ <name>Lokalradio Betebuerg</name>
++ <shortname>LRB</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633297674FEF7DD1C2FBF43ACA3CA7EB2C936F59620DD5374ACB0609F9B1CF4FABA7849D</stationID>
++ <name>Radio Contact 2</name>
++ <shortname>Contact 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329812F12CE288BAF733BD9199B53EDA01804DE48CC577A08FBBFAD6C4F7ACA1848C39</stationID>
++ <name>RGL</name>
++ <shortname>RGL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329847C0213ACA35041D97ADD05C5DB1B7C1CCD2F6E8C5BFED71C2E19FDDC24B93254E</stationID>
++ <name>Radio Belle Vallee</name>
++ <shortname>Belle vallee</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329897A1FDDD433DD21199DED68FF9F0E540F1E4CD6C55B33BBAF99241B902091C2AAF</stationID>
++ <name>Radio Contact</name>
++ <shortname>Contact</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329591D429F2459980ACBC417A2048FADD9D273F527EE86515629C14E91F417FE039FA</stationID>
++ <name>Radio Challenger</name>
++ <shortname>Challenger</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163330188CC0367F029D5A66062615F6BCE2FAF0728695533704EF79C712BF0B06BA56890</stationID>
++ <name>95,5 FM</name>
++ <shortname>95,5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163330246FF5200963B1566F233EE7AB74AE953AD9E77ABBBD4EE5251EC63DA2647CCCCF6</stationID>
++ <name>95,9 FM</name>
++ <shortname>95,9 FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633303204AFAE7D4A526CF4AE040C00CB72415289FB237237EF96227CBC73E1939F3B9E7</stationID>
++ <name>106,5 FM</name>
++ <shortname>106,5 FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.5</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/luxemburg/esch.krp kradio-3.5.13.1/kradio3/presets/luxemburg/esch.krp
+--- kradio-3.5.13.1/kradio3/presets.old/luxemburg/esch.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/luxemburg/esch.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,324 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_11_27</creator>
++ <maintainer>Loes Alex &gt;alex@linux.lu&gt;</maintainer>
++ <changed>2006-11-12T12:25:01</changed>
++ <country>Luxembourg</country>
++ <city>Esch/Alzette</city>
++ <media></media>
++ <comments>Contains merged Data</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1163326933EB744DBB9C1EDD1D8E16F31C269ADD45F914715B65BABABC04EDAD9B1333F0C0</stationID>
++ <name>S�dwestrundfunk 1</name>
++ <shortname>SWR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329364799814657B8D3E7D22528643D3E4BAB028C46DE92DC3F89F7C0F1B119B985359</stationID>
++ <name>S�dwestrundfunk 1</name>
++ <shortname>SWR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329214DB6B30879AB4302A94C98A2ACFB6B2149FC6510CB58E6AA1F7B4EF51843D2262</stationID>
++ <name>S�dwestrundfunk 2</name>
++ <shortname>SWR2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163328832D863DD1C695DA1403F48C349657FDF2677DF343F3F0882DF390BE7212716720E</stationID>
++ <name>S�dwestrundfunk 3</name>
++ <shortname>SWR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163325201376872BE5AB201ACBE6B7916BC9FEAE1F778FAE36EDF09D1D8576C2FABE8B808</stationID>
++ <name>S�dwestrundfunk 3</name>
++ <shortname>SWR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163330034075C9ECB9718957096823D12613AD16CB915A26D10BE65CF5407CCD56A43DF08</stationID>
++ <name>Classic21</name>
++ <shortname>Classic21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106338540798C0D12726F1661419AB34C2642A94AC5C6E261E91C693826FE8AAB710612343</stationID>
++ <name>Premiere</name>
++ <shortname>Premiere</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633290654CF0230A48506DC3DD90CD2D762F486571C0F789F7EBB5AC0C21A9FA780427D7</stationID>
++ <name>Vivacit�</name>
++ <shortname>Vivacit�</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407AFBFB6A017C8C7A5F8F16BC30B85D0C0E87B84799C65FCE80394C9D2202CE4B6</stationID>
++ <name>RTL L�tzebuerg</name>
++ <shortname>RTL L�tzebuerg</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.9001</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633291411FAD229D1CAAADED0CE059FE98C637C0D4990AE9576CB360DB47DB434B1E7E42</stationID>
++ <name>RTL L�tzebuerg</name>
++ <shortname>RTL L�tzebuerg</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332520866D4C8867B32DE1801A83417CAD34D4D385052BA2C9A2CF6300AFD972A5FF38E</stationID>
++ <name>RTL Radio</name>
++ <shortname>RTL Oldie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407EA222E19244D3040A4F1B8AC8AF03F4EB304ED09F9D0C946A9B557590C5D2B71</stationID>
++ <name>RTL Radio</name>
++ <shortname>RTL Oldie</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332892335934EA1B377096CBBCD683C87556466B34F9A3720458EE6BC15AECCF3F0D07F</stationID>
++ <name>BEL RTL</name>
++ <shortname>Bel RTL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332520577808CE062019CAEA5A0EA201C8F5FB635FCAD2B27184857ADA60F1546BCD77B</stationID>
++ <name>Musique </name>
++ <shortname>Musique</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854070D0624F5D0DE76E44CBFCA7425618F58AB75BEF835973FBF447FDA5B50117B85</stationID>
++ <name>Musique 3</name>
++ <shortname>Musique 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854076161020BD41D27F67E226E563E890312F73FB3301F832FD42F97F2C7FC6764C6</stationID>
++ <name>DNR</name>
++ <shortname>DNR</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633252222E92DD5C3EC58F99CD07722FDA5639008D903059DFFC75EDCFF658B4D6D89C36</stationID>
++ <name>DNR</name>
++ <shortname>DNR</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407C0E4A025D422F911694EA657E38FD8B85C87FD88DD984A01C9E0CB5F3DAC0561</stationID>
++ <name>100komma7</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.701</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10633854079297D695D8BC75127B779ACDACAB080F4F03335C9B916941C159377D64678AF0</stationID>
++ <name>Radioara</name>
++ <shortname>ARA</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407BB520D98D14CECDCD0AAD64B8FF750BA848C03845757BDFB9F0B955D39843639</stationID>
++ <name>Eldoradio</name>
++ <shortname>ELDO</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.002</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329418E8576AD40D75C543EE9A093DCE03B4051FAECBDF73D37CC48B96F40BEC79E22C</stationID>
++ <name>City FM Esch</name>
++ <shortname>City FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1063385407917331FDBE436B09CF00637FC7F12D4E277AF861322A256EC884DD7E86CEF606</stationID>
++ <name>Inter</name>
++ <shortname>Inter</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633252192E0BA2ED6CD18FDFE748A79C5125781907807F97341E8822B1B404B5FACD486F</stationID>
++ <name>Radio Festival</name>
++ <shortname>Festival</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332522516BC3F1CF778CF47ABBFE182FD7AFA0865B7F87E9089E5FBC8A4D1BAA32DABA9</stationID>
++ <name>new station 9</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116332954945F54F898EC8F2BB6AA85DDC110F72F64AB4D8E3451E55345F4E1FEDF5634E45</stationID>
++ <name>Radio Latina</name>
++ <shortname>Latina</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329706DED977EB4B2A58B696F64B718E96BC68CAD6DB1DA034BE75BDC5320FECEBF85A</stationID>
++ <name>Lokalradio Betebuerg</name>
++ <shortname>LRB</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633297674FEF7DD1C2FBF43ACA3CA7EB2C936F59620DD5374ACB0609F9B1CF4FABA7849D</stationID>
++ <name>Radio Contact 2</name>
++ <shortname>Contact 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329812F12CE288BAF733BD9199B53EDA01804DE48CC577A08FBBFAD6C4F7ACA1848C39</stationID>
++ <name>RGL</name>
++ <shortname>RGL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329847C0213ACA35041D97ADD05C5DB1B7C1CCD2F6E8C5BFED71C2E19FDDC24B93254E</stationID>
++ <name>Radio Belle Vallee</name>
++ <shortname>Belle vallee</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329897A1FDDD433DD21199DED68FF9F0E540F1E4CD6C55B33BBAF99241B902091C2AAF</stationID>
++ <name>Radio Contact</name>
++ <shortname>Contact</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163329591D429F2459980ACBC417A2048FADD9D273F527EE86515629C14E91F417FE039FA</stationID>
++ <name>Radio Challenger</name>
++ <shortname>Challenger</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163330188CC0367F029D5A66062615F6BCE2FAF0728695533704EF79C712BF0B06BA56890</stationID>
++ <name>95,5 FM</name>
++ <shortname>95,5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1163330246FF5200963B1566F233EE7AB74AE953AD9E77ABBBD4EE5251EC63DA2647CCCCF6</stationID>
++ <name>95,9 FM</name>
++ <shortname>95,9 FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11633303204AFAE7D4A526CF4AE040C00CB72415289FB237237EF96227CBC73E1939F3B9E7</stationID>
++ <name>106,5 FM</name>
++ <shortname>106,5 FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.5</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/luxemburg/Makefile.am kradio-3.5.13.1/kradio3/presets/luxemburg/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/luxemburg/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/luxemburg/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -1,10 +1,13 @@
+ SUBDIRS =
+-EXTRA_DIST = "walferdange.krp"
++EXTRA_DIST = "alzette.krp" "esch.krp" "walferdange.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/luxemburg/"
++ $(INSTALL_DATA) "$(srcdir)/alzette.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/luxemburg/alzette.krp"
++ $(INSTALL_DATA) "$(srcdir)/esch.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/luxemburg/esch.krp"
+ $(INSTALL_DATA) "$(srcdir)/walferdange.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/luxemburg/walferdange.krp"
+
+-
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/luxemburg/alzette.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/luxemburg/esch.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/luxemburg/walferdange.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/Makefile.am kradio-3.5.13.1/kradio3/presets/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/Makefile.am 2012-11-30 23:52:48.000000000 +0100
+@@ -1 +1 @@
+-SUBDIRS = switzerland norway bulgaria new-zealand ireland sweden iceland italy portugal brazil germany russia catalonia usa australia finland lithuania england slovakia canada spain luxemburg turkey belgium argentina romania netherlands south-africa austria uruguay hungary poland czechia france
++SUBDIRS = argentina australia austria belarus belgium brazil bulgaria canada catalonia colombia croatia czechia england finland france germany greece hungary iceland india ireland italy lithuania luxemburg netherlands new-zealand norway poland portugal romania russia slovakia south-africa spain sweden switzerland turkey ukraine uruguay usa vietnam
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/netherlands/ede.krp kradio-3.5.13.1/kradio3/presets/netherlands/ede.krp
+--- kradio-3.5.13.1/kradio3/presets.old/netherlands/ede.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/netherlands/ede.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,360 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_11_27</creator>
++ <maintainer>Wilfred van den Assem</maintainer>
++ <changed>2004-08-14T13:45:29</changed>
++ <country>Netherlands</country>
++ <city>Ede</city>
++ <media>cable</media>
++ <comments>got data from http://www.upc.nl/</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1061768916D6D60211155A9867579BD00D8BAAB1B161379528845A471C2473820166ACE223</stationID>
++ <name>Radio 1</name>
++ <shortname>Radio 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916674F270FB0E48154D32C1348A18098757C8FBB5B2E6DD4DBE531C44F80E55850</stationID>
++ <name>Radio 2</name>
++ <shortname>Radio 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916521DF9F0D8CC313B63094A26C58A3EF43281F65F7405DC7ED9F250F50877E6A8</stationID>
++ <name>Radio 3</name>
++ <shortname>Radio 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916875497BD80A8B3EB56FDD97D8BCD15143EF3A7FB072C8B3AF77BFC9B8B077F41</stationID>
++ <name>Radio 4</name>
++ <shortname>Radio 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106176891671E2CAEA45B3503F03EC1C51826002CBD7B24604CA6379650E39A727905D27A9</stationID>
++ <name>Radio 747 AM</name>
++ <shortname>Radio 747 AM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106176891660FD79DFF18BF25EE5732FDAE5A7F4DE53C34511719A9D9A192A52FCDAB424FB</stationID>
++ <name>VRT Radio 1</name>
++ <shortname>VRT Radio 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161153582384EAC06B0BE166AB53A183932FF5B20B5E78210FDACD304E3E73F651DCD3C03</stationID>
++ <name>VRT Radio 2</name>
++ <shortname>VRT Radio 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10617689169CF30DDBE712348BEF827B9C3992B2E4761C7BE090E611BA3F3639F4C1B9ED68</stationID>
++ <name>VRT Radio Klara</name>
++ <shortname>VRT Radio Klara</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116115361665D32BD758259F77358067404F00097689E170441AE61F4A31352285D328250E</stationID>
++ <name>Radio Oost</name>
++ <shortname>Radio Oost</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161153652CCFDA5E3632D597D89537123A32442359230A708945E6893FC34A713DAF3CFB7</stationID>
++ <name>Omroep Fryslan</name>
++ <shortname>Omroep Fryslan</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916CCBEFA171CFA37C0C9504D15C9E5D25D4307FAB210169CE31D93B3EC2639EFC1</stationID>
++ <name>Omroep Gelderland</name>
++ <shortname>Omroep Gelderland</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916DAD184A2F4074D993CBB883601E987A73B79E77DF27EC7B59BBE06D9E3F1C25A</stationID>
++ <name>Lokale Omroep</name>
++ <shortname>Lokale Omroep</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10617689169DB2EDD8EC100A91AEE995A3803046E75F4C2E9FD96C4A9F4F4E572ACFD76E60</stationID>
++ <name>BBC Radio 3</name>
++ <shortname>BBC Radio 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161153719E945B75BBAE2BE88E1D6708CA899C38812377F524084DC17799B28EF95A7449F</stationID>
++ <name>WDR 1</name>
++ <shortname>WDR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11611537345314B57844DCB83ED1854B2DD0AF2C0F35DE85056B2C31076E0C233C546ED8FA</stationID>
++ <name>WDR 2</name>
++ <shortname>WDR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161153750FEF87459094374CCA4D2C2D3184881B0E0490493088F22BF3F9EBA30857E4256</stationID>
++ <name>WDR 3</name>
++ <shortname>WDR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116115377178116A777931577FF53165625081CB5D288FD6584D5FDA80359B75305E9CE512</stationID>
++ <name>WDR 4</name>
++ <shortname>WDR 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916B8192E1A210DEA36E235662832013CA5A99264A14A07BA0933F5079FA526A1CE</stationID>
++ <name>Arrow Rock Radio</name>
++ <shortname>Arrow Classic Rock Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116115335888BB7FB1792AB5778FA5020D15B6D27B83D36DA1707E3135AED4395FA4DC6DEA</stationID>
++ <name>Arrow 90,7 FM</name>
++ <shortname>Arrow 90,7 FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11611538298006F042F5BA4800CCB6E984D134258D0ED47B33E519D2D3E29AA1D3A138D734</stationID>
++ <name>Het Gelders Geluid</name>
++ <shortname>Het Gelders Geluid</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11611538849F64970DCE09509546044C9CA3819FF67DD1EC1EF0ECCE744D74D2E4F1C64E6E</stationID>
++ <name>BBC World Service</name>
++ <shortname>BBC World Service</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161153903EFD4B3ED578A480A62461EEBA0EABBE5603346C9DF183154881E81A7080A6F83</stationID>
++ <name>BNR Nieuwsradio</name>
++ <shortname>BNR Nieuwsradio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10617689169DB024ABAAA652F2C5476890B717855DBD52903DA0E0F5255A8E98AC2BB3E732</stationID>
++ <name>Classic FM</name>
++ <shortname>Classic FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10617689164394C7A3D38B4FEDE5625C2E7534ED6AD44B8EE956712A802388A26DB075E098</stationID>
++ <name>Concertzender</name>
++ <shortname>Concertzender</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916FC58F6080AA9D2E99E4EF096A27242230717633F27CEAD62834C228FEE869BCC</stationID>
++ <name>RTL FM</name>
++ <shortname>RTL FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11611539802AD1AF72DE7F31516F32690C20DF5CDFCBD9FFF73B11B5B7066A3F17EDEF95F6</stationID>
++ <name>Hot Radio</name>
++ <shortname>Hot Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161154009DFC37030D6C2614E5E925F3B92CA4F8987B0C6079BF0A79CA6C69D0810CE5DCA</stationID>
++ <name>Slam FM</name>
++ <shortname>Slam FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116115403704F8DC30EF1E672D16616263E4423BECE77A6247368F1003E605F23E3CADAB70</stationID>
++ <name>Keizerstad FM</name>
++ <shortname>Keizerstad FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106176891684678CE4B308A8A6F724F5C73506E16E27268EB819FC720AE7AD5B483473E4B6</stationID>
++ <name>Kink FM</name>
++ <shortname>Kink FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916248E70F2866B0754758FA4F16D395369F9B3550559E24A77C1B48B5C1EEB0684</stationID>
++ <name>Q-Music</name>
++ <shortname>Q-Music</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10617689161657EC736540B26C223EC40019E316770DD54F30EDD58351F305A7CCF58CF42E</stationID>
++ <name>Radio 10 Gold</name>
++ <shortname>Radio 10 Gold</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916495B2FFD8C70DEA15BCE8BCD882F1ECB21F05F8713D6610A04BE9690F59CD956</stationID>
++ <name>Radio 538</name>
++ <shortname>Radio 538</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161154174EE98D5510463A0C07109A56AD2303F0B1E6EC5A22EF3B9918775924D8921C7B5</stationID>
++ <name>Radio Donna</name>
++ <shortname>Radio Donna</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1061768916C3BBEBD88D7BE50E0D66854AAFC41402F07BCC2B609B8D70D7B1BE9E0551D162</stationID>
++ <name>Radio Veronica</name>
++ <shortname>Radio Veronica</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161154202F08ECD8CB447AAD23BB63C38C144E82BCC2C6258E4E774BEB0AC1E958B9945BF</stationID>
++ <name>Rebecca</name>
++ <shortname>Rebecca</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10617689165763D6C843F7F6EC887BCB341263385A26A6AF2E11CB926DE91932882C30DCF7</stationID>
++ <name>Sky Radio</name>
++ <shortname>Sky Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10617689166BA97C6B690CD30B8E86DA28E1B815A478FD6B58504AF435C114B2CFD4177318</stationID>
++ <name>Yorin FM</name>
++ <shortname>Yorin FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11611542299B25F62676B0D3F897FE54E785DFE3A527F5EBD866C1F49207CADEBF1A1EDB6A</stationID>
++ <name>2e Kamerlijn</name>
++ <shortname>2e Kamerlijn</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/netherlands/Makefile.am kradio-3.5.13.1/kradio3/presets/netherlands/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/netherlands/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/netherlands/Makefile.am 2012-11-25 00:48:00.000000000 +0100
+@@ -1,30 +1,31 @@
+ SUBDIRS =
+-EXTRA_DIST = "alphen-aan-den-rijn-cable.krp" "amersfoort-cable.krp" "amsterdam-cable-2.krp" "amsterdam-cable.krp" "arnhem-cable.krp" "enschede-cable.krp" "groningen.krp" "ijhorst.krp" "rotterdam-cable.krp" "tegelen-cable.krp" "the-hague-antenna.krp"
++EXTRA_DIST = "alphen-aan-den-rijn-cable.krp" "amersfoort-cable.krp" "amsterdam-cable-2.krp" "amsterdam-cable.krp" "arnhem-cable.krp" "ede.krp" "enschede-cable.krp" "groningen.krp" "ijhorst.krp" "rotterdam-cable.krp" "tegelen-cable.krp" "the-hague-antenna.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/"
+- $(INSTALL_DATA) "$(srcdir)/amsterdam-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/amsterdam-cable-2.krp"
+- $(INSTALL_DATA) "$(srcdir)/arnhem-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/arnhem-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/alphen-aan-den-rijn-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/alphen-aan-den-rijn-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/rotterdam-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/rotterdam-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/enschede-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/enschede-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/the-hague-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/the-hague-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/tegelen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/tegelen-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/amersfoort-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/amersfoort-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/ijhorst.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/ijhorst.krp"
++ $(INSTALL_DATA) "$(srcdir)/amsterdam-cable-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/amsterdam-cable-2.krp"
+ $(INSTALL_DATA) "$(srcdir)/amsterdam-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/amsterdam-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/arnhem-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/arnhem-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/ede.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/ede.krp"
++ $(INSTALL_DATA) "$(srcdir)/enschede-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/enschede-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/groningen.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/groningen.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/ijhorst.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/ijhorst.krp"
++ $(INSTALL_DATA) "$(srcdir)/rotterdam-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/rotterdam-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/tegelen-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/tegelen-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/the-hague-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/the-hague-antenna.krp"
+
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/amsterdam-cable-2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/arnhem-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/alphen-aan-den-rijn-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/rotterdam-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/enschede-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/the-hague-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/tegelen-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/amersfoort-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/ijhorst.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/amsterdam-cable-2.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/amsterdam-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/arnhem-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/ede.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/enschede-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/groningen.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/ijhorst.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/rotterdam-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/tegelen-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/netherlands/the-hague-antenna.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/czestochowa.krp kradio-3.5.13.1/kradio3/presets/poland/czestochowa.krp
+--- kradio-3.5.13.1/kradio3/presets.old/poland/czestochowa.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/poland/czestochowa.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,104 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>rado-1.0beta3b</creator>
++ <maintainer>Mario, &lt;mariuszwr@o2.pl&gt;</maintainer>
++ <changed>2008-03-30T14:19:27</changed>
++ <country>poland</country>
++ <city>czestochowa</city>
++ <media></media>
++ <comments>antenna</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>109569822506C857816E13E27DEC856024B05151EB43DE1B656728CCA49EB2B9427D135846</stationID>
++ <name>Polskie Radio Bis</name>
++ <shortname>Bis</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1094719793C323351FB798EF728B232148DC066B49C9E7C8CF11D7F9AC32CBFF70F79F25B0</stationID>
++ <name>Trójka</name>
++ <shortname>Trójka</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1095697872BBA803C49A13E8248BEA59AEE7B241A7AC35BDAC2A07159E8935A7768571ED15</stationID>
++ <name>Radio C</name>
++ <shortname>C</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>96.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1095697962016FBF883B757A23FDD3AD28778C46353A6FF8D656EA6AE8A7377F44AF09B63D</stationID>
++ <name>Radio Katowice</name>
++ <shortname>Katowice</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10956981207850CC6E93BB5799DE6342A15BCBBC2F6EA512A458D1624CFF503292FB19F94A</stationID>
++ <name>Jedynka</name>
++ <shortname>Jedynka</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>109569817873B0C0A37E18F984E4D9CF9E9A9F2C7B3A48D230ADDEABD4DF0CFB7D4F220B79</stationID>
++ <name>RMFMAXX</name>
++ <shortname>RMFMAXX</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.55</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1095697990DB89F838E5B480B6023336F88A88670804126D366D2D42B241FB499AE0EDC18F</stationID>
++ <name>Radio Zet</name>
++ <shortname>Zet</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1094719872EA2412A37C582F0EE766611FB36914F824B944B872DDD8D42DF884F1682F485B</stationID>
++ <name>RMF FM</name>
++ <shortname>RMF FM</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>105.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1094720563210A2A1BCA82A429BECEC40E1CC444660EE2B573EA7E032282B2B66E89A8B8A5</stationID>
++ <name>Dwójka</name>
++ <shortname>Dwójka</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>109569825516562B261D7E9C26E0DCA51E196A1F79A8B0AA5978B7D2AD4003D354DA8FB186</stationID>
++ <name>Radio Fiat</name>
++ <shortname>Fiat</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1095698040CF98DFCCAFF2E5690ED9E44F33E5F9DA2A96FF5FE1D6B81D5BFAA6A578E3791B</stationID>
++ <name>Radio Jasna Góra</name>
++ <shortname>Jasna Góra</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.55</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/gdansk.krp kradio-3.5.13.1/kradio3/presets/poland/gdansk.krp
+--- kradio-3.5.13.1/kradio3/presets.old/poland/gdansk.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/poland/gdansk.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,151 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Marcin Dabek</maintainer>
++ <changed>2005-05-02T12:01:20</changed>
++ <country>Poland</country>
++ <city>Gdansk</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>12215568287C61A88AEC8635FC5CCFF7171F303401B1DCFD2CA5CE3D81AA7F3224E90BC742</stationID>
++ <name>RMF Classic</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>122155684736B50D0EAE6D579A11236D29B3B4469F8F9C1CDBEA36913DBD03F5FFFE7B1204</stationID>
++ <name>Radio Maryja</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12215568727DFE9D88CDC83160CCC15526A6CF26D8701917D5244503A3B7E285F14E141377</stationID>
++ <name>Polskie Radio Program 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1229710262F4878A7B00BE2D7F76D54B3BA03B9A47463EC5FD828B08F5D0BFA7EE0B966028</stationID>
++ <name>Chilli ZET</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1221556917BE7AC365D5DDF2C108946E1D0152AD5A703D3C68DA2DDBB40B911CBB6A6E693B</stationID>
++ <name>Radio Kaszebe</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1221556932BF6B314ECB047845EF8614D8B46B954ECD37DD45B8DF865F9743E15AF2D64CA8</stationID>
++ <name>Polskie Radio Euro</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12215569572CE92640C495542FFB927F221407B75D9BF2555272C335DBA68110863E696996</stationID>
++ <name>Radio Eska Trójmiasto</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1221556988D9342A99AFC0B1A9E59692FC1FB6E06F164791963D1F5D88F9065195F35C37C6</stationID>
++ <name>Polskie Radio Program 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1221557013882E0532BD346FFFD9A5EA1CD212D9C8E152E98DAB619AC6E927E7DDD1233BAB</stationID>
++ <name>RMF Maxxx Trójmiasto</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1221557038E31C4C464C57757EB85F937BA47741C3B136900BD84054C1CE3452114747163A</stationID>
++ <name>Radio TOK FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1219857722931B3EEF9145FBCFF13C6034AB67BA25D1207ADCA53F82364AA593224F7109CF</stationID>
++ <name>RMF FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1221557083CE00FD4802E76A9C8E7FBF6379D9AC6BC454404BDCDD1E517F5BA60209B1D3DD</stationID>
++ <name>Polskie Radio Program 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1221557119075B6D8D3C90DFC53DBEE7AD2FDA2B6B9D025437E41D40C49DB45EDE918430DC</stationID>
++ <name>Radio Plus Gdańsk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1221557141040C86265FA2B11B772DB78368F5D3FFCD9A20DAEB3BA239B0D04864925CAACB</stationID>
++ <name>Radio Złote Przeboje</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1221557171CAB3A2B6E4E3CAD3F6E293D318C15489374FF7EE504CB68DFAA2E08B704C14B7</stationID>
++ <name>Polskie Radio Gdańsk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>122155719504D8B63D209DF87C9FAB419641D87FFED865596883C203FDDE6E86F663BEDC81</stationID>
++ <name>Radio Eska Rock</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1219857671CD41C2FF7BAB36A8B4E4FCD5B5675ABC24E423D3DFE2705995D5719CFDDC022D</stationID>
++ <name>Radio Zet</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/lodz-cable.krp kradio-3.5.13.1/kradio3/presets/poland/lodz-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/poland/lodz-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/poland/lodz-cable.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,197 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer></maintainer>
++ <changed>2007-06-20T00:25:42</changed>
++ <country>Poland</country>
++ <city>Lodz</city>
++ <media>Multimedia_cable</media>
++ <comments>Contains merged Data</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>11822951592B62AD0B29DA188FC37D5BC6DF251E8831E9B25E1B08D8217AC8C820314A5E87</stationID>
++ <name>Tok FM</name>
++ <shortname>Tok</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11822954375392ACECD74C5E8F829F49E89C6538C88A683A95FCB11D5E442DDD7B5EDD3841</stationID>
++ <name>Polskie Radio BIS</name>
++ <shortname>BIS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1182295070AD54E88C72A2EA8AE4C3EFBDFEA8522D6E560D5FE3C8EC0371C49CA6E65BF29A</stationID>
++ <name>RMF FM</name>
++ <shortname>RMF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11872808081B25C94B7555C7F8A4B9888E9AF25C6358CDF7F9B27C951BB0E9A7E7230BCFA8</stationID>
++ <name>Sunshine Live</name>
++ <shortname>Sunshine</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11872803804CA47D3949558F9F50EDC13DB1BE5D6067FE476C4C3A52378A7C2608AB8D9FDD</stationID>
++ <name>Klassik Radio</name>
++ <shortname>Klassik</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11872804261AA8FF934BC24FA59871DC47CCED08ECDDB0A9B5B16EB8E4208775A98DBA10F4</stationID>
++ <name>RTL Radio</name>
++ <shortname>RTL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11822950461598E1CEBE4AD1116E623E7F82824779228D49FCADF3F6967F2D3A7C5A5E9DA2</stationID>
++ <name>Radio Zet</name>
++ <shortname>Zet</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>118229530168E7CC202D9FCE6928BE23CD43DDEA8EBDED271636F820F3396FD86454CC3C5B</stationID>
++ <name>Radio Z�ote Przeboje</name>
++ <shortname>Z�ote Przeboje</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1182294924AA0C337B114539C8878F2697138156C0DBD5AF8CB4E6BEDDEF2C6AB020BFC334</stationID>
++ <name>Radio Pogoda</name>
++ <shortname>Pogoda</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>118229190344092EF2F0D2AA89D78EF8CFE8A2BEFE42FAFAB2F4D9C2C57C6D54D384A366BD</stationID>
++ <name>Radio Maryja</name>
++ <shortname>Maryja</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11822950051DEE65FC7A6D1FD85B2A696A21081EFAC6A3492731946B1B99E99C2F31FEF73A</stationID>
++ <name>Polskie Radio Program 2</name>
++ <shortname>PR2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>118728050865D611D8D6A580F01787B91B3C88FE6ED168D744FE6597A6A3832AC1C506CDA1</stationID>
++ <name>Jam FM</name>
++ <shortname>Jam</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1182295497B82166CE2968E66B97BA2BD60C955F6076B475B0713DA5CFD1F3A855347991FD</stationID>
++ <name>Polskie Radio Program 1</name>
++ <shortname>PR1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1182295121FE742DD14B3861BE7C0767ACD3C14BD1CEF344EC37AFCC8E69DB26C706202EB4</stationID>
++ <name>Radio Parada</name>
++ <shortname>Parada</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>118229519080D140BF6665ED6B0E319197C0796B202C344D457245805ADCA1A324BD6DB024</stationID>
++ <name>Radio Eska Rock</name>
++ <shortname>Eska Rock</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1182295224A5CFF0376073A55D56260F2D0BDF72CC0D9E0CD0444C96E5B053B12352276040</stationID>
++ <name>Polskie Radio ��d�</name>
++ <shortname>Radio ��d�</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11872802306FD47B3725D04E5C840EA16346C835BE25A43B27AE9EA709ECCC5A60E400AC12</stationID>
++ <name>Polskie Radio Program 3</name>
++ <shortname>PR3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11822952706BCBA8B1F212D43FF9CD77304D15248CCBB36D99CBFE1717E6FC70B5328FB9AA</stationID>
++ <name>Radio Vox FM ��d�</name>
++ <shortname>Vox</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1182291526776BF1C96CE85AC3882781A6821B58BDA25507033F693A442094A1E6CF7B40CE</stationID>
++ <name>Radiostacja</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11872807143C41BCDB4450D8F024BB289D4434AB639B2C9BB430A5F37BE3CF44F40BACAEFF</stationID>
++ <name>Eska ��d�</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/Makefile.am kradio-3.5.13.1/kradio3/presets/poland/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/poland/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/poland/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -1,30 +1,47 @@
+ SUBDIRS =
+-EXTRA_DIST = "bialystock-antenna.krp" "elblang-antenna-fm.krp" "katowice.krp" "krakow-antenna.krp" "torun-cable.krp" "warsaw-antenna.2.krp" "warsaw-antenna.krp" "warsaw-cable2.krp" "warsaw.krp" "warsaw-upc_cable.krp" "warsaw-ursynow.krp"
++EXTRA_DIST = "bialystock-antenna.krp" "czestochowa.krp" "elblang-antenna-fm.krp" "gdansk.krp" "katowice.krp" "krakow-antenna.krp" "lodz-cable.krp" "nowy-sacz-antenna.krp" "opole-antenna.krp" "poznan-antenna.krp" "tarnow.krp" "torun-cable.krp" "warsaw-antenna.2.krp" "warsaw-antenna.krp" "warsaw-cable2.krp" "warsaw.krp" "warsaw-upc_cable.krp" "warsaw-ursynow.krp" "warszawa-cable.krp" "warszawa-ursynow.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/"
+- $(INSTALL_DATA) "$(srcdir)/warsaw-upc_cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-upc_cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/warsaw-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/bialystock-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/bialystock-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/torun-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/torun-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/czestochowa.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/czestochowa.krp"
+ $(INSTALL_DATA) "$(srcdir)/elblang-antenna-fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/elblang-antenna-fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/warsaw-ursynow.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-ursynow.krp"
+- $(INSTALL_DATA) "$(srcdir)/krakow-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/krakow-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/gdansk.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/gdansk.krp"
+ $(INSTALL_DATA) "$(srcdir)/katowice.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/katowice.krp"
+- $(INSTALL_DATA) "$(srcdir)/warsaw-cable2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-cable2.krp"
++ $(INSTALL_DATA) "$(srcdir)/krakow-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/krakow-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/lodz-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/lodz-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/nowy-sacz-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/nowy-sacz-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/opole-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/opole-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/poznan-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/poznan-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/tarnow.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/tarnow.krp"
++ $(INSTALL_DATA) "$(srcdir)/torun-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/torun-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/warsaw-antenna.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-antenna.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/warsaw-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/warsaw-cable2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-cable2.krp"
+ $(INSTALL_DATA) "$(srcdir)/warsaw.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/warsaw-upc_cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-upc_cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/warsaw-ursynow.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-ursynow.krp"
++ $(INSTALL_DATA) "$(srcdir)/warszawa-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warszawa-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/warszawa-ursynow.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warszawa-ursynow.krp"
+
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-upc_cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/bialystock-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/torun-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/czestochowa.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/elblang-antenna-fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-ursynow.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/krakow-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/gdansk.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/katowice.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-cable2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/krakow-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/lodz-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/nowy-sacz-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/opole-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/poznan-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/tarnow.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/torun-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-antenna.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-cable2.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-upc_cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warsaw-ursynow.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warszawa-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/poland/warszawa-ursynow.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/nowy-sacz-antenna.krp kradio-3.5.13.1/kradio3/presets/poland/nowy-sacz-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/poland/nowy-sacz-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/poland/nowy-sacz-antenna.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,70 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-1.0beta2</creator>
++ <maintainer>Marcin&quot;WASYL&quot;Basiaga,
++WasylNS@interia.pl</maintainer>
++ <changed>2005-11-30T14:36:51</changed>
++ <country>Poland</country>
++ <city>Nowy Sącz</city>
++ <media>antenna</media>
++ <comments>Contains merged Data</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1104422521ECAFDA4C92BFABDCA1C6CE092CD4E64C696A81194D6FE9F26DEF7D9999466F8E</stationID>
++ <name>RMF FM</name>
++ <shortname>RMF FM</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>103.196</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1104426638C6D4851AD1CE10470FBE94C2FFF50A6011843F618E3E5453686AFA1C1EB1AE23</stationID>
++ <name>Radio Zet</name>
++ <shortname>Zetka</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>97.796</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1104429437CB3574C52E0E9C7C5D92D4C557A2B457B005AE4DF83176CC2CD5F9E9DE65FD04</stationID>
++ <name>Polskie Radio PR 3</name>
++ <shortname>Trójka</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.796</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1104429442C8D842CAF84FE1C33EA30EC6CA2E7653E11E1C384D4EF4946409D66EB2334273</stationID>
++ <name>Polskie Radio PR 1</name>
++ <shortname>Jedynka</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>99.2007</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>110449736641CF389791C851CE7ACA60328CECD88E3722CC969EB7C3DF4ABA7DDEF7D86FA3</stationID>
++ <name>Złote Przeboje ECHO</name>
++ <shortname>ECHO</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.7999</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1104849921CBBF6A08B9FF1C1FAE90125D357C387AB173C28038A02076EF970BB49C181077</stationID>
++ <name>Radio Kraków</name>
++ <shortname>Radio Kraków</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>90.05</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/opole-antenna.krp kradio-3.5.13.1/kradio3/presets/poland/opole-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/poland/opole-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/poland/opole-antenna.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,100 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_11_27</creator>
++ <maintainer>Krzysztof Kusiak,
++&lt;szyszart@poczta.onet.pl&gt;</maintainer>
++ <changed>2007-01-24T16:57:09</changed>
++ <country>Poland</country>
++ <city>Opole</city>
++ <media>Antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1</stationID>
++ <name>Polskie Radio Program 2</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>2</stationID>
++ <name>Tr�jka</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>3</stationID>
++ <name>Radio Eska</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>4</stationID>
++ <name>Radio Zet</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>5</stationID>
++ <name>Radio Z�ote Przeboje</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>6</stationID>
++ <name>RMF FM</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>7</stationID>
++ <name>Radio Maryja</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>8</stationID>
++ <name>Radio Opole</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>9</stationID>
++ <name>Radio Planeta</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>10</stationID>
++ <name>Radio Plus Opole</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/poznan-antenna.krp kradio-3.5.13.1/kradio3/presets/poland/poznan-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/poland/poznan-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/poland/poznan-antenna.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,213 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0-rc4</creator>
++ <maintainer>artur.zaprzala@gmail.com</maintainer>
++ <changed>2009-05-23T11:21:38</changed>
++ <country>Poland</country>
++ <city>Poznań</city>
++ <media>antenna</media>
++ <comments>Na podstawie http://nadaje.com/miasta/Poznan.html</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1243073856B7CB5AE3A8DD7F64D99162701127E8EB17921157D47B4F1CD2C1B35300AC</stationID>
++ <name>Radio Merkury</name>
++ <shortname>Merkury</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1181345500C8D8A94219DBBC463934BEFA6CB0DAB24F33C6ABA71DFB08DF33AB483E441B55</stationID>
++ <name>PR Program III</name>
++ <shortname>Trójka</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1243091725823AD6BA86EF676F69423FC8246C52646B4D3AC6A598D678C8FC8DECBA06</stationID>
++ <name>PR Program II</name>
++ <shortname>Program II</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11813450874FEFBFE9D9664744CED00CC429A41AF491A0F341950699E506F2833995048115</stationID>
++ <name>PR Program I</name>
++ <shortname>Program I</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>124307402214A45EF45919BAFF02EA193FD2BFD73C6A1489C197787A21C309564028FC</stationID>
++ <name>Polskie Radio Euro</name>
++ <shortname>Euro</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>100.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1181310720D76397D1E0CE3FA017DE0FF960A280D3994F75AB6512563E93B6BCC932D2C33E</stationID>
++ <name>Radio Złote Przeboje</name>
++ <shortname>Złote Przeboje</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1243092477BD500CBB54A00F1BBDEF4DD16A2F7E2EC9B6F8E2047E22A40611BCB7476D</stationID>
++ <name>Chilli ZET</name>
++ <shortname>Chilli ZET</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>101.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12430741057023A3CC5976ADC55C0E886946A60A4205CBF98A166CFC41C4CFEB8C198D</stationID>
++ <name>Radio Eska Rock</name>
++ <shortname>Eska Rock</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1243073700ECE65C3E99B2CE8049C7498B1732137742C789DFC70A2113D921DBE69A02</stationID>
++ <name>MC Radio</name>
++ <shortname>MC Radio</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1181345133A04BF742C340E1FC6BDA16A09CF9612919DA70DDEA02798BD190B0F0762FB7C9</stationID>
++ <name>RMF FM</name>
++ <shortname>RMF FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>94.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11813451171B80122E5B2FC18587A666F545EBCA4E45F41A816A2C9FD381DA957E0188263B</stationID>
++ <name>Radio Z</name>
++ <shortname>Z</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>97</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1243074060EBA788F812C95004302AB34F8D515473E912E93F3E6DC9006E712955F619</stationID>
++ <name>Radio Z</name>
++ <shortname>Z</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11813107167D3CC8996BCF9B44DDADB08B9AAE804FA337940B03AA28F18B2AB02E28CDDD51</stationID>
++ <name>Radio Blue FM</name>
++ <shortname>Blue FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1181345115714F0A6908202C3FE5BC5ED7D62A8B0A0DF97CFFCE612011CD1EDAF67CFC4AC2</stationID>
++ <name>RMF MAXXX</name>
++ <shortname>RMF MAXXX</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>93.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1181345101A37EB521C0D4DA7736962278AD3B3961D3DB8853572FD1AAF554A20C2D68B89D</stationID>
++ <name>Radio Eska</name>
++ <shortname>Eska</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>93</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11813451194A150D2B5165FA1DB1E53F35E32978BDBE46BAB7D4445AD3333CE5D7EC48095F</stationID>
++ <name>Radio Afera</name>
++ <shortname>Afera</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>98.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1243092539C04A6CD4C5B25CD713CCD794592A56DE0274843B85D9FADA0064A9DE8456</stationID>
++ <name>Radio Roxy FM</name>
++ <shortname>Roxy FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1243073918646EC6C3D2F64E7C33C1B2C375E6130AB50FFFB0CC15BCE2DF66E82F219A</stationID>
++ <name>Radio Planeta</name>
++ <shortname>Planeta</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12430739360FD65A37249E783AE38ED70BB151627FBE6B6CADDAF83EC4A4445EEACAFF</stationID>
++ <name>Radio Planeta</name>
++ <shortname>Planeta</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>99.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>118131069508E2B7F26DF1C5B1CE1A577EC08E051873B7C21C86B13ADBE50257B825F6C941</stationID>
++ <name>Radio TOK FM</name>
++ <shortname>TOK FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>97.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11813450899FC57789CC3A44DDAE5C22E6BB61251A7438BC16C1566D9ABA9C2A9EA5B27698</stationID>
++ <name>Radio Emaus</name>
++ <shortname>Emaus</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>89.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1243074085F655034EB7C8D95088C8A951706DA80D4DB373C89ED8DFA968CF396FDA4C</stationID>
++ <name>Radio Maryja</name>
++ <shortname>Maryja</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>106.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/tarnow.krp kradio-3.5.13.1/kradio3/presets/poland/tarnow.krp
+--- kradio-3.5.13.1/kradio3/presets.old/poland/tarnow.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/poland/tarnow.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,167 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-1.0beta3b</creator>
++ <maintainer>Jacek Drobiecki, j.drobiecki@mwi.pl</maintainer>
++ <changed>2006-08-13T13:05:16</changed>
++ <country>Poland</country>
++ <city>Tarnow</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>11554744911E6260E25520A4AF03462D1BF650D3A46C33D2DF18E13B711A0B093BD9B0C97D</stationID>
++ <name>Polskie Radio Program 2</name>
++ <shortname>PR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474531FC82F3BA0DEC16DE3BD16B08971EDE5158F6ADE06830918279C8ECB6418ADEA9</stationID>
++ <name>RMF FM</name>
++ <shortname>RMF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115547460387D53144D776A4650C37E47E15D549DB99E130D7FF101CEABAE3B24887F22DE3</stationID>
++ <name>Polskie Radio Program 2</name>
++ <shortname>PR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474640001219B3008B89483DB18A6FF42AAD83D6707D0C985063B4E848D5731369B58F</stationID>
++ <name>Polskie Radio Program 2 (Bochnia)</name>
++ <shortname>PR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115547434749EC4CD78DAF20EF8E4B6E5333C45F003ACFBD12AE2C32298739B8B7DE02AF6F</stationID>
++ <name>Radio Krakow</name>
++ <shortname>Krakow</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474669C49CEC64EE4291EA8A8CEE82E09F00DEE28C746C3D111AABDF776A0168D0F773</stationID>
++ <name>Polskie Radio BIS</name>
++ <shortname>PR BIS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474725CCD85AFA6208AD4153E9335229304383B405A12BE66C7898150B48B976FC2EDC</stationID>
++ <name>RMF FM</name>
++ <shortname>RMF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11554747499B0D4864A56811C0894BD0900CCAA7FD2505CEA0C5110492C072EE7A93A4947D</stationID>
++ <name>RMF FM</name>
++ <shortname>RMF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474784D6818BED1604A6E700CF77A5403ADE565C559553F56FFAE046586F7BEF76B2D8</stationID>
++ <name>Radio MAKS</name>
++ <shortname>MAKS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115547481284433E6F0785342958176E418F731D56E1BDB9A28A6CBFAE1278B26BAA3BBC8B</stationID>
++ <name>Polskie Radio Program 3</name>
++ <shortname>PR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474827CDDBE861AEF4E59966935D8DE6DD1534825BF9877CFF5467F78F2A2161669997</stationID>
++ <name>Polskie Radio Program 1</name>
++ <shortname>PR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115547485978A3B6D7231EB91CB3E4FBD591C21233389FD21B0F23CD69DDD81063B7FA920F</stationID>
++ <name>Radio Krakow</name>
++ <shortname>Krakow</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474884CD983E4A9E47EA99CD475E1287382B5B43A8B9971F26AA5725D15601D075ABF9</stationID>
++ <name>RDN Malopolska (Nowy Sacz)</name>
++ <shortname>RDN</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115547489596B110A4C03019FF4EE2856C2E1110DDD10E37BFEBD32D8AB2F2EBE2472E76D1</stationID>
++ <name>Radio Krakow</name>
++ <shortname>Krakow</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11554749149AE9DBE9A8C74D5237F782051EEDB4417F3D784F19323506F3DDCF2FB48609DD</stationID>
++ <name>Radio Maryja</name>
++ <shortname>Maryja</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474928C7C7EE5700DCEC117911DD5E0424E053B50A99FDD440B9825AE78B530A824B07</stationID>
++ <name>RMF FM</name>
++ <shortname>RMF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474940ED3934C9676750AB9D3BA445FDF5E129BA3663825AA3C85476F8C9878ABBAB9D</stationID>
++ <name>RDN Malopolska</name>
++ <shortname>RDN</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155474965831D096128378DE1965F5323CF342B7058B96847CA59CF9905AD7760B68CAD35</stationID>
++ <name>Radio ZET (Krakow)</name>
++ <shortname>ZET</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1155475014BBDCB24424B44D1097D4B2D69580AAD5AE0A045EFC0FD28813BCF95113EAD5CE</stationID>
++ <name>Radio ZET</name>
++ <shortname>ZET</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/warszawa-cable.krp kradio-3.5.13.1/kradio3/presets/poland/warszawa-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/poland/warszawa-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/poland/warszawa-cable.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,97 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>andrzejk@aster.net.pl</maintainer>
++ <changed>2008-12-08T09:11:31</changed>
++ <country>Poland</country>
++ <city>Warszawa</city>
++ <media>astercity cable</media>
++ <comments>pakiet basic</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>10882367971EBA4B1B9F1F17EEFC1C249AF259256AC8CE59D9F47558CAD65E64E3FD3B070E</stationID>
++ <name>PR Program 1</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>1</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>108823682322199A3A26A0CC4935DF81456C046D5473FA11B89A799AB92536C1524B7FE4D9</stationID>
++ <name>PR Program 2</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236820C1AB035EEB576C5E772194080D9EC1936C2A7CDE21E088FF0AEC7812D3FCE244</stationID>
++ <name>PR Program 3</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236812CCED5AB431EBC6CB0950BB44398F71408BA41B76161F5224F462F85FBB3EBC11</stationID>
++ <name>Radio Dla Ciebie</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122872309592995F81CBC12BF16FFDDA976EF54E3ACEEEDAF287D916DA723E1CFA3BD173FC</stationID>
++ <name>Radio Wawa</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236814091D61464F50B5EBB55C6E93212666024A0108312DECFA0523C7503752293BB8</stationID>
++ <name>Radio Zet</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>108823682553AF90DFFFF097021348B489A54CDB9D1F7BB805D3AD198548C191CAA2887471</stationID>
++ <name>RMF-FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236805DD37389D670DADEFFB7240BC4A69F7C84A6C2588580B6E3AB31FF649E769A667</stationID>
++ <name>Radio Bis</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236818F98AEF0C8A67C0A142086FAE09B7ADFEEA10DEA2F70BF9BD85C281DFDF43A65F</stationID>
++ <name>Radio Maryja</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/poland/warszawa-ursynow.krp kradio-3.5.13.1/kradio3/presets/poland/warszawa-ursynow.krp
+--- kradio-3.5.13.1/kradio3/presets.old/poland/warszawa-ursynow.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/poland/warszawa-ursynow.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,88 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Andrzej Koz�owski, &lt;andrzejk@astercity.net&gt;</maintainer>
++ <changed>2007-10-10T18:21:22</changed>
++ <country>Poland</country>
++ <city>Warszawa-Ursynow</city>
++ <media>astercity cable</media>
++ <comments>pakiet basic</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>10882367971EBA4B1B9F1F17EEFC1C249AF259256AC8CE59D9F47558CAD65E64E3FD3B070E</stationID>
++ <name>PR Program 1</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>108823682322199A3A26A0CC4935DF81456C046D5473FA11B89A799AB92536C1524B7FE4D9</stationID>
++ <name>PR Program 2</name>
++ <shortname>23</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236820C1AB035EEB576C5E772194080D9EC1936C2A7CDE21E088FF0AEC7812D3FCE244</stationID>
++ <name>PR Program 3</name>
++ <shortname>21</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>108823682553AF90DFFFF097021348B489A54CDB9D1F7BB805D3AD198548C191CAA2887471</stationID>
++ <name>Radio Wawa</name>
++ <shortname>24</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236812CCED5AB431EBC6CB0950BB44398F71408BA41B76161F5224F462F85FBB3EBC11</stationID>
++ <name>Radio Dla Ciebie</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236805DD37389D670DADEFFB7240BC4A69F7C84A6C2588580B6E3AB31FF649E769A667</stationID>
++ <name>Radio Bis</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236814091D61464F50B5EBB55C6E93212666024A0108312DECFA0523C7503752293BB8</stationID>
++ <name>Radio Zet</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1088236818F98AEF0C8A67C0A142086FAE09B7ADFEEA10DEA2F70BF9BD85C281DFDF43A65F</stationID>
++ <name>Radio Maryja</name>
++ <shortname>20</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/portugal/aveiro-antenna.krp kradio-3.5.13.1/kradio3/presets/portugal/aveiro-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/portugal/aveiro-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/portugal/aveiro-antenna.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,71 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-1.0beta2</creator>
++ <maintainer>Hélio Guilherme &lt;helio.guilherme@bluebottle.com&gt;</maintainer>
++ <changed>2006-11-18T22:54:01</changed>
++ <country>Portugal</country>
++ <city>Aveiro</city>
++ <media></media>
++ <comments>Sintonizados a 10km a Sul da cidade.</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1116455444F91ED21F1D7BA697D3CCCA4F80412D98E84AC5EEE8E9FD8802E8239245117BE5</stationID>
++ <name>Antena 2</name>
++ <shortname>ANTENA2</shortname>
++ <icon></icon>
++ <volumepreset>0.5</volumepreset>
++ <frequency>87.34</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554449DE41CDB4FBD7A49098CC696567AD524945B94899CC3498B6C5752A8B04D06B8</stationID>
++ <name>Rádio Renascença</name>
++ <shortname>RR</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>88.17</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444DCD642C7A6C7E5EB8768969BA1504A0B12AF82D9B3B42EF1A943AD01C56B1878</stationID>
++ <name>Aveiro FM</name>
++ <shortname>AvFM</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>88.57</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>111645544469DB377E2239117F981CCE57F05666F7D20638D4B79949FCF6B9046A5504FBF8</stationID>
++ <name>Antena3</name>
++ <shortname>ANT3NA</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>93.06</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444150CB66C475C9CB684A9CCAB396CEB9A29EEE7E5536B3E7E272032275E24187A</stationID>
++ <name>AveiroFM</name>
++ <shortname>AvFM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.81</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11172936389B2769CBDCDC246EE4A75B8E6727EE985F3A839B55A40DBA9B558400165B803F</stationID>
++ <name>Rádio Clube de Aveiro</name>
++ <shortname>RCA/RCP</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>115075507171272DFC8631DB6A60AE46717B8FF41F7927414A02E38E3E9A0B1C732A6B584C</stationID>
++ <name>Antena 2</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>101.245</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/portugal/Makefile.am kradio-3.5.13.1/kradio3/presets/portugal/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/portugal/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/portugal/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -1,10 +1,11 @@
+ SUBDIRS =
+-EXTRA_DIST = "lisboa-antenna.krp"
++EXTRA_DIST = "aveiro-antenna.krp" "lisboa-antenna.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/portugal/"
++ $(INSTALL_DATA) "$(srcdir)/aveiro-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/portugal/aveiro-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/lisboa-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/portugal/lisboa-antenna.krp"
+
+-
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/portugal/aveiro-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/portugal/lisboa-antenna.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/russia/khabarovsk.krp kradio-3.5.13.1/kradio3/presets/russia/khabarovsk.krp
+--- kradio-3.5.13.1/kradio3/presets.old/russia/khabarovsk.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/russia/khabarovsk.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,159 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.2</creator>
++ <maintainer>Andrey Tomilenko (aka Thom) thom82@mail.ru</maintainer>
++ <changed>2012-06-22T20:57:29</changed>
++ <country>Russia</country>
++ <city>Khabarovsk</city>
++ <media>Antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1305638939C1FD865E64BAC19C5F57AA772A41E3154D83B787C6A8BBE41BA59C2D4F50</stationID>
++ <name>Радио Юность</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>71.24</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305638967B8157796236B9C31EA6815AB3C48379EF65E79F49A3C79C36703B1F4D915</stationID>
++ <name>Радио Маяк</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>72.02</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13056389922F1F70C837614DE48AE22EF0FEFBFCBF25660BC1196A68629EE08CB0F3C1</stationID>
++ <name>Радио России</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>72.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130563904442B5A2DDA4F2CE53202F339A5EDE755CEE833D693FC05B308A26E05303B5</stationID>
++ <name>Ретро FM</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13056390981FCC9EC91AA3DC33CE07779742EDC01DFAD322F810AA5C641578B689A25B</stationID>
++ <name>Авторадио</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13056391188DDE01EF727CF401895206DAA0BB3FF7E907AC8105D76121359DEA67894A</stationID>
++ <name>Русское Радио</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>89.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13403587309CACBC90948F03CBCD705121A11FCB3C08F1015195B38A61E19CA9FF1B7C</stationID>
++ <name>Юмор FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13056391680029FBFC1E1A539CD8847454B89ACC8B316221B4FE23591283568D29EB74</stationID>
++ <name>Милицейская волна</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13056392023511D5D2255D527F78A9F3A2773304264B21F4431550D50A0C7935A891B0</stationID>
++ <name>Радио 101.8 FM</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1340358776C1D2B150D77B86BB2AC6634B476162CAE427444FC5FD63B7F5428393489A</stationID>
++ <name>Серебряный дождь</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130563925202974C20BE1F41D064DF0F58F50BF73A3FD4C3DFD97D4CF50362D7ADC943</stationID>
++ <name>Радио Дача</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305639289B512A628A955D08E53324832FB8CDCEBDA010C75CD50714594D7633004AC</stationID>
++ <name>Восток России</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130563932489FDF6E2BD0FE5CE07D11879AB3EC67D4504F7245EBE90EC3372BF8E9401</stationID>
++ <name>Дорожное радио</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305639357C85ADEAA9CE0A129200D98B6FC5343251C2F74FBE88C22E5A5808BE77F0C</stationID>
++ <name>Вести FM</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305639381A545F9CA03ED0BFEAAE4186B78418905B20AF41ADF875DFF7E13F9282768</stationID>
++ <name>Европа Плюс Хабаровск</name>
++ <shortname>15</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305639414A15F8313B28FA6B1F1DD6DB5C43F107C068A2E9F0B46D5C3C024F5CA8562</stationID>
++ <name>Маяк FM</name>
++ <shortname>16</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/russia/Makefile.am kradio-3.5.13.1/kradio3/presets/russia/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/russia/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/russia/Makefile.am 2012-11-25 00:48:00.000000000 +0100
+@@ -1,12 +1,27 @@
+ SUBDIRS =
+-EXTRA_DIST = "moscow.krp" "saint-petersburg-antenna.krp"
++EXTRA_DIST = "khabarovsk.krp" "moscow.2.krp" "moscow.3.krp" "moscow.4.krp" "moscow.5.krp" "moscow.krp" "saint-petersburg-antenna2.krp" "saint-petersburg-antenna.krp" "samara.krp" "vladivostok-antenna.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/"
+- $(INSTALL_DATA) "$(srcdir)/saint-petersburg-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/saint-petersburg-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/khabarovsk.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/khabarovsk.krp"
++ $(INSTALL_DATA) "$(srcdir)/moscow.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/moscow.3.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.3.krp"
++ $(INSTALL_DATA) "$(srcdir)/moscow.4.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.4.krp"
++ $(INSTALL_DATA) "$(srcdir)/moscow.5.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.5.krp"
+ $(INSTALL_DATA) "$(srcdir)/moscow.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/saint-petersburg-antenna2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/saint-petersburg-antenna2.krp"
++ $(INSTALL_DATA) "$(srcdir)/saint-petersburg-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/saint-petersburg-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/samara.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/samara.krp"
++ $(INSTALL_DATA) "$(srcdir)/vladivostok-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/vladivostok-antenna.krp"
+
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/saint-petersburg-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/khabarovsk.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.3.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.4.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.5.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/moscow.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/saint-petersburg-antenna2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/saint-petersburg-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/samara.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/russia/vladivostok-antenna.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/russia/moscow.2.krp kradio-3.5.13.1/kradio3/presets/russia/moscow.2.krp
+--- kradio-3.5.13.1/kradio3/presets.old/russia/moscow.2.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/russia/moscow.2.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,142 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Wasiliy Cheremisinov &lt;wasiliy.ch@gmaill.com&gt;</maintainer>
++ <changed>2007-12-08T10:59:46</changed>
++ <country>Russia</country>
++ <city>Moscow</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1064330466317A41A714F7A3C70B72A8F4F88EFF1AD5870570230FAC49A74C6528C4359C32</stationID>
++ <name>Busines FM</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1064330466947F92FD80D121BD0DF4EDFEE9874FC5EB83A080586606778F480426C7442561</stationID>
++ <name>Humor</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10643304662D3779EBD6858C0583607EBF2788213464832A85F4205B19D671A503DF4BAB30</stationID>
++ <name>Jazz</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1014</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106433046664F3991076F0870D839F4065A92B11B3059FAAF1F7AF006AFE06F56FDEC49E93</stationID>
++ <name>Auto</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106433046619C3366A5F5A7EC91799AAEF32A445F3424E9E10E41C636539CF59CC24C082AB</stationID>
++ <name>Nashe</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1064330466E07BE61B89FE49C799EFEB5F0ABA72E6CCFC08267015CFDD367F702D64E79AED</stationID>
++ <name>MonteKarlo</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.102</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1064330466CA4EED0736CAAB36E71A839D40008B0C5AC9AA2C82C643A9AFED34C2B1B13AED</stationID>
++ <name>Maximum</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.727</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1064330466979D59DE67FAA40E5E5408F6F709FC01B7A01AAA3434B64A6270A375091BD753</stationID>
++ <name>Europe Plus</name>
++ <shortname>Europe Plus</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.203</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>106433046610DCFA997911331B73CDB8ECD23DE325DD1105AF6768E6E071D4CD51DAF72FF5</stationID>
++ <name>Love radio</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.603</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10643304660D5013C5720489386C78C7990FEB7F6A8AC21D623CB23A6B02B123D892B08E02</stationID>
++ <name>Seven Hills</name>
++ <shortname>Seven Hills</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1064330466E85A0C0833E61EED4D7180C6B2186A20ED80D94859E7B7764ED980E964796459</stationID>
++ <name>BestFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>10643304668EE856A49266E70C96D6371545017E454330FFC78F72BDA85BE1B1A7D8BEF6E7</stationID>
++ <name>Silver Rain</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1064330466EE8DA6A56D9A920D2BF0E7C52A7B72423B0552B652EE24CD3859998B5702B762</stationID>
++ <name>Classic</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.902</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1194197244ED4A8A191D1807FCF73D636896F020AFDFB2DF7A765FFAD1F322D06AA154B896</stationID>
++ <name>Relax</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/russia/moscow.3.krp kradio-3.5.13.1/kradio3/presets/russia/moscow.3.krp
+--- kradio-3.5.13.1/kradio3/presets.old/russia/moscow.3.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/russia/moscow.3.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,466 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Ser Moro</maintainer>
++ <changed>2008-11-09T07:40:00</changed>
++ <country>Russia</country>
++ <city>Moscow</city>
++ <media></media>
++ <comments>На 09 ноября 2008 г. (09 nov 2008)</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>12122828023F212F976473C4E93995D4891E8C777646EC34AA187F3448C0EC7E543609CBC2</stationID>
++ <name>Бизнес FM</name>
++ <shortname>Buziness</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12122827990F65AFCF6B3859E87971677CE6871AA71F6DA2E00B58C3BCFDF04A57035AE67F</stationID>
++ <name>Сити FM</name>
++ <shortname>City</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121228279796B23241487AFED5155A28232E67B9EA7CE628A67F0AC2F6BCC433C01A4369D8</stationID>
++ <name>Ретро FM</name>
++ <shortname>Retro</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212282794C55B646493A81EF00526173AAD59794E0A8C92E10D5E87C4A47973F2379A26F2</stationID>
++ <name>Юмор FM</name>
++ <shortname>Юмор</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212282794B5DE3840CC9B45A581943EF925529837BEC12B66C3D85E90F3996B65BA0DCA58</stationID>
++ <name>Радио Джаз</name>
++ <shortname>Джаз</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12122596825C81908E711F49D34E2488F9E0CBC975C4B3DCA073F6DE213A8A01920BC096E0</stationID>
++ <name>Megapolis FM</name>
++ <shortname>Megapolis</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5002</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12122597039752418C5847057F3705AC380BE3BA5FD830328E221B3D353EED65850266ACE7</stationID>
++ <name>Кекс FM</name>
++ <shortname>Kex</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121225968579A6748F6F0976C2DE6D1CB4A53B97CE0F1C3ABBB08FCBB45106E48DC5BFDD98</stationID>
++ <name>Авто Радио</name>
++ <shortname>АвтоРадио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212259688DA536296403BFE6C53E376FEBC230247FF0A589D0483AB91AD8F08557DEB6A41</stationID>
++ <name>Relax</name>
++ <shortname>Relax</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121225968939C1C287EFC31157B5BACC22FD61CB81A7A785C097349863FC892E23DBF888AA</stationID>
++ <name>Эхо Москвы</name>
++ <shortname>Эхо</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212259691C099D02DD657FDC1D535FFCC843C096BAA4D230DF1D0EF937282F477A9CB1AD3</stationID>
++ <name>Культура</name>
++ <shortname>Культура</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212259692167C08E0C5F1453D16DE8A855A0938E10641E9C7FE41B77FD5948D32F68F74D2</stationID>
++ <name>Говорит Москва</name>
++ <shortname>92</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12122596961F2F8798C4AF031DC06C680A36A17247A632141493DA9C57B21540155AF20194</stationID>
++ <name>Радио Дача</name>
++ <shortname>Дача</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12122596993B33CE7223A502CDE834AC553FD5B1ACBE52DA72FDF905583CCC03252456B392</stationID>
++ <name>Радио Карнавал</name>
++ <shortname>Карнавал</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225098463FAF803940A48CC5DD762C9533BDC42913313BC62C9A3E7C2459348A3E851558B</stationID>
++ <name>Спорт</name>
++ <shortname>Спорт</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12138945622084AC7C25C48D647BBC4E3E0CE9AD45BA5AEFA5B9B4E5458B9EC833ECCC0A9F</stationID>
++ <name>Radio Newton</name>
++ <shortname>Newton</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12250982552FF63D58F730C6F74FE8EE55569A165B6AEAF01CE9F319C8E21A8556B9436B82</stationID>
++ <name>Radio Unost</name>
++ <shortname>U</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>123196465419618E775ADB30B8FBA7BC0AC4ED246FCC72C7933EEC9D8A313395649F4C76E2</stationID>
++ <name>Radio Lornet</name>
++ <shortname>Lornet</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12122827767F54AF294458E31567320F8D23209CDEE586C3DA2FCA907480AD37C291805057</stationID>
++ <name>Радио Моя семья</name>
++ <shortname>Семья</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121228278574DD0761AB27D245495CE6B980B40D7E886D1AB6B1C42091B893E48A46783853</stationID>
++ <name>Rock Radio</name>
++ <shortname>Rock</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12123390445BBF6A3ED8F754C4156A0BB2B470DA04733F19754E36F1ED6FC19AC85F1D64C2</stationID>
++ <name>Радио Звезда</name>
++ <shortname>Звезда</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12348480920036E7BC9624E105EFE480CF03DC713FF687375B2041F2E26BA12F0BF95A6540</stationID>
++ <name>96</name>
++ <shortname>96</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339046DDCBDF85F15BE3CAB54C1C0F0A8334B83255E9131C72C5F1E831B2E0F7CD2984</stationID>
++ <name>X-FM</name>
++ <shortname>X-FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12123390461714F20182DBDDF585EC9929A50864AE86074C3C8E1E02F5AED483D5B462D980</stationID>
++ <name>Детское Радио</name>
++ <shortname>Детям</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1219914057D2886AC3FAF181A0F36D2A9D76A1C252631C40E6E39BDF5ED016BE8242F100B9</stationID>
++ <name>Radio Комсомольская правда</name>
++ <shortname>Radio КП</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339047DFFBBFF46ADF915EDF6CA7D1FE79038F088FFF2291DBD34D9EEC0DA84893D70F</stationID>
++ <name>Радио России</name>
++ <shortname>Вести</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339054BC3DCB9C2D81802E0E77E6E82336E2D17F87C6ED63F400C263BBE6DB3C2E14E2</stationID>
++ <name>98</name>
++ <shortname>98</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12155099273AA79DF72C4062FA8C04E9D964815CB91829824065AFE9A8D2BAB1F4AA94463D</stationID>
++ <name>Свежее радио</name>
++ <shortname>Fresh</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339385229EBB7819AC5442AC0E1F41E58F10C72CA249BEF2BE9E3A659006684E6A8944</stationID>
++ <name>Радио Алла</name>
++ <shortname>Алла</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1226205404FBE117B1B15AECDF62B6FF796F9658061C68CCBD7A57E8CE1DF50CE7E1A4AA14</stationID>
++ <name>Radio Orpheus Classic</name>
++ <shortname>Orphey</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339386F7157F3BFC0DD589711E42FEE85071B689BEE4534AFFF55523ED54A7528BA870</stationID>
++ <name>Финам</name>
++ <shortname>Финам</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12123393868B5B553B02B25F4DAD23C73657402F8383C1B9FC1E8620894774526C4AF6C1E1</stationID>
++ <name>Радио Серебряный дождь</name>
++ <shortname>Silver</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12123393873AB899D7246EB39485864B2F04EAFDD1765682408BA8192975DA61DB7A83B3F1</stationID>
++ <name>Радио Best FM</name>
++ <shortname>Best</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339387F11C65FEA6E51B7B8E93C7CA337F5DFDFCA2F8ADAD249503D3C9D0E84EA26351</stationID>
++ <name>Classic</name>
++ <shortname>Classic</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339388EEE39E0BC4D3DA35192A71CE62993C32CEF36856FF682F80DDD3EF6B98C536D6</stationID>
++ <name>D FM</name>
++ <shortname>DFM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339659E2E4B8321BABF68F83B40DBB5178D9982E286066E756532578AE9312F77EA3E2</stationID>
++ <name>Наше Радио</name>
++ <shortname>Наше</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339658E751B53B44FE1F1A6CB6D173CFDE7BFD900D63319CAC8AD2BD17B5E130AADB83</stationID>
++ <name>Radio Monte-Carlo</name>
++ <shortname>Monte-Carlo</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12123396589CF758161886D9EBCB3F9935FD928E7B62EAF419F10636D9E74CE75F03ADEC0B</stationID>
++ <name>Радио Попса</name>
++ <shortname>Попса</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121233979036412BB8D5C8E91549545A821460D7CD25921A5823B83D48072EB378C6CFE6D5</stationID>
++ <name>Радио Шансон</name>
++ <shortname>Шансон</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12123397914DC4E206CE83692E6403D4A60E2B618F648D59DE5B1B86E0F1CC5BA7346A4E55</stationID>
++ <name>Маяк</name>
++ <shortname>Маяк</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212339791D7BD41F55ACAC72BB37828705B336858ED3872404B84D4B756CA3BC1C043B2A3</stationID>
++ <name>Radio Maximum</name>
++ <shortname>Maximum</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121233979674E163A4CB1750E1B5695178A3E6B6D2633C72DDB810B1E769975DB3B0A3301A</stationID>
++ <name>Radio Energy</name>
++ <shortname>Energy</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121234007486004F788B3D4D98C280330FFA2D9B472961C33C1604CFDAE47B0662F4864611</stationID>
++ <name>Radio 7</name>
++ <shortname>Radio7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212340074EE1D11E026C89F078E0829E75A80904A3503AE203E09F1620F350B680B74E472</stationID>
++ <name>Radio Next FM</name>
++ <shortname>Next</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212340075589879A76AA393BAFDF5DF4555B287B418A2225B182A0851A599A46B31FC6990</stationID>
++ <name>Русское Радио</name>
++ <shortname>РусРадио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12123400752D0B01A4845E3747674600730689641EF7D2A58F5A6F9E475F590C2B17B3FB31</stationID>
++ <name>Europe +</name>
++ <shortname>Europe+</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>121234007591A90762201E3A7A025C8089D71E7D010F1BD6C1DC67621A5445559100BABE20</stationID>
++ <name>Love Radio</name>
++ <shortname>Love</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12123400761B5688D434BA35EFEA9E23F61FE0C066EF18F45E751B61F700466DA357388236</stationID>
++ <name>Русская Служба Новостей</name>
++ <shortname>РСН</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212340077A657F5A456F3AC7A05F638034484ED6CB2C508B5B7CE45CA49E4943B7AD3CB16</stationID>
++ <name>Hit FM</name>
++ <shortname>HitFM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1212340373F23364BD99C0FD26A8FE62CCC1FC2326409F5E1952746C8D45D693B34297DC61</stationID>
++ <name>Радио Милицейская волна</name>
++ <shortname>Милиция</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/russia/moscow.4.krp kradio-3.5.13.1/kradio3/presets/russia/moscow.4.krp
+--- kradio-3.5.13.1/kradio3/presets.old/russia/moscow.4.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/russia/moscow.4.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,486 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer>Basil &lt;614@mail.ru&gt;</maintainer>
++ <changed>2006-12-24T14:00:31</changed>
++ <country>Russia</country>
++ <city>Moscow</city>
++ <media>Aver media studio 307</media>
++ <comments>http://www.radioo.ru/</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1166957632E1E6B773B16FAB3C9BBE8D8781249B51B85183FB4644F8B5BD4AFFC80B99918C</stationID>
++ <name>Love Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>66.02</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166957579D0832BBA97ACA268BF14E56BD550D114E1FDDE0BD8951CBFE0A2163E4069E3F9</stationID>
++ <name>Radio of Russia</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>66.44</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166957557AD5CF65A33753EB4783380B2D909A75959EA7DB49335DBCDA806DF576F9E88D1</stationID>
++ <name>Maximum</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>66.86</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166957531EE4C210521F42A6074AF09772AF1A72431482C98A0574EDBCB64D424B7939184</stationID>
++ <name>Mayak</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>67.22</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116695750623A2EE2D00B86A33412D256B8498339EBB7B57DE4BA1463879A1DCA077792B41</stationID>
++ <name>Avtoradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>68</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669574847289DE68C47E37F6D780471358D18F59C685C0038723C9DDFBFF6BB204CAD87D</stationID>
++ <name>Radio-1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>68.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669574457A4DC4E624827B2B132AE6A093289F54D91510995EA005AD458EBE226D3276C5</stationID>
++ <name>Yunost&apos;</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>68.84</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669574079F9EC2AEF3ADB2D01D5FB77DA8E5101C2B1F33A47E7CB7A48C01E46DB5733E6B</stationID>
++ <name>Russian radio-2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>69.26</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166957372D0EFB9DD0E58F11A669F20C7636C4C7359BC74B57859603CABD6EA3E383F73E8</stationID>
++ <name>Europe plus</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>69.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166957329444CE214B5282ACBCCC9D0CFBB923D38FBD5881C2D85B762A6030FBD68B8790F</stationID>
++ <name>Ultra</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>70.19</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669572935247BDFDED87C62DE211E85F85958BB19922B8A5CF4368B61D78548CA9A940D1</stationID>
++ <name>Russian radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>71.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166957221E055943148E8F9463BE8D5818BEA3BA30A08203786FB4ED16D913CDF79B0780A</stationID>
++ <name>Orfey</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>72.14</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116695719350C9F89CDA632EE1E5E8228C51FFB348E380A567776482D28A61E1FDAF919BCC</stationID>
++ <name>Radio-Retro</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>72.92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166957083101FD14C6FB1C54314BE3FB7D301DE25AEBB388FA5E519560BF675C254B5D85B</stationID>
++ <name>Radio 7 na 7 holmah</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>73.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669570483021426130F14BA799C4532A1E94CA33C15510D0808D726993F2D5CD12BF1A4B</stationID>
++ <name>Echo of Moscow</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>73.82</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956990CD8B8893868F6156B295FE27607F49EEC77AFB3FB72CAAF4D565FD83074C5F42</stationID>
++ <name>Radio-Arsenal</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956756A12CD220E711648DAEB58CB7ED10154187C2C0E24785EA12DDFA4BD25252DC69</stationID>
++ <name>City-FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669569236286CCBF2A0E5EA3DED4BC8C67FBE7FC72D3B80B331BC8C961A71BB176355171</stationID>
++ <name>Retro-FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669560101DEA7A9DD968F07112FDC44DD324224A38FBA5D5B865FB6D2955B682FC37D8BB</stationID>
++ <name>Humor FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1064330466E07BE61B89FE49C799EFEB5F0ABA72E6CCFC08267015CFDD367F702D64E79AED</stationID>
++ <name>Radio Jazz</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166955883D8A04151E06D760E4DF7842990744F8A91720F94CF971EC619F0740C4B6B3AE4</stationID>
++ <name>Megapolis-FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669558359E63EA7B5B2DEB6FE1FB2FEE89F013636EFD33BC5A9A9F45C2AD71A498C515F7</stationID>
++ <name>Melodiya</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>89.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669557934A98B4E710AD5AF9869B1B2D144B8DC5561089B2955338935CBE122A135EA4BF</stationID>
++ <name>Avtoradio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116695559236C1ED99206B33F508E21FEE76AC7FE98FD022956184B0589A0F6676F99EAF4C</stationID>
++ <name>Relax FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116695562015B618A6F9D0548252841B7979C5E390A1B4F83B3FF1EE8E2D5D6405D5A00041</stationID>
++ <name>Echo of Moscow</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669556985A865C27C521C9C97FACBEDCF297A972C453C4EC9044639AA5CDD4FE360B3393</stationID>
++ <name>Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>91.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166955387C3ABE1CF31ADA0BFAD068F592100A89A0BA5C06332ED7ECA15D66D9D7897FC42</stationID>
++ <name>Govorit Moskva</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166955534C99366F4574B49157C6E49B1BE8C521C8D7C4369DFB4E11E1964C3939D654FC1</stationID>
++ <name>Radio Udacha</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669554443AC0849DBF480743A2A75F80D1A5A0961437C1ABC792FE3B493E3B99B98FE438</stationID>
++ <name>Radio Sport</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>93.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166955327A5A60A1BA10F9E45AB03057448A48CCC6BB6E2B869CF0347F5DEC4E5892865AB</stationID>
++ <name>Zvezda</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>95.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669552470238A75168E4067074193A8BE904A83C4B142DF39BCAEB354B07C4B6505325E2</stationID>
++ <name>M-Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116695519894B4CA3641876C66F34BDB9784EC7FFDB8888F16901B26407D7D67389CCB8601</stationID>
++ <name>Radio Rossiya</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>97.602</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166955120CE8553D7E2FA57F6C9CCDD1260A217C10EAA121E6193B630764EA91F2AB47692</stationID>
++ <name>Russian Songs</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>98.802</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116695501694031750D1F39D2B677CC9174F963EE0200C0F375F176DE5F2C1206D3BD73F34</stationID>
++ <name>Silver rain</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>100.102</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956114A7783981473BE9C2773D90392F9C647F1ACC07B4A630F92202E4921619FF571C</stationID>
++ <name>Best FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956189FC9213CF6C51999DE90A5029DD8717E31A6C0C32C67C9B2704A6D23823E0F8F2</stationID>
++ <name>Radio Classic</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956224013A6F091F5FACC187C80B7799774F17A454E988CDEDF05D3571BCA00A3CD0DA</stationID>
++ <name>Dinamit-FM</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669562690A11198557EE507FFB7954DA34C38B676DEDA1509A6D66786C56203A28F9F94F</stationID>
++ <name>Nashe radio</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669563019B8DB055ADA960C32A8AFC23AAE3940B38EE3C8F8766B91C8245D87E7932C8E4</stationID>
++ <name>Radio Monte-Carlo</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116695636884CCD5D7C5900B5796DFA6C9667EBBEB7B38A426B4D759A17C2BD91336829EAA</stationID>
++ <name>Radio Popsa</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956399B5023480C7B42DA089AA87F6EDE92EC88AA4A3075D0D5B4FC80C9FEA397C2CE2</stationID>
++ <name>Shanson</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956417F021C66B643D13FD46C17672F93228108D2E40A921E65C18643DB8A52F239201</stationID>
++ <name>Mayak-FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116695644332BD22B7C117952C90E15739DA0F472D7E709C986DD3BB722CC9686304300B31</stationID>
++ <name>Maximum</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956467C3FE528365A3FE4F02A089BDA4538722A94D5750B9B9F9B92E5C65E96C35C20A</stationID>
++ <name>Energy</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956491E7F82945D14B1E17BDDFA8CE2DCF38607B2825A5D5384BC86C52724284AB0DCB</stationID>
++ <name>Radio 7 na 7 holmah</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956520D811ADD05B13F61CEF11C3BC6077C25A641C2EED304AD183722B29C5E4B2EB44</stationID>
++ <name>Radio Next</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116695655702F1446544A6D8FDDF1F18783C2E1250224F31BD4F1E52973D1762B1DE305B26</stationID>
++ <name>Russian radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956582FCEEECE6B71538020E0FEE80F48B730A887DD24272958D8A3B833E67FA1A9CE8</stationID>
++ <name>Europe plus</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956665BBE158E4AB6982810081D0CC0A8DB510A065244FC65E7E7DCDEC5375AC84CA46</stationID>
++ <name>Love radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669566898A71C985BD4F702BD8E37FDD0FEFB4C061B8C1C0A173E3F78A2B3A78710C4531</stationID>
++ <name>Russian news service</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11669567303B9760EE6E437AE2AB08E9A17A2863B75CA17AAA838C2EFB8BE4C68940A036C0</stationID>
++ <name>Hit-FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1166956816C5E7650467CD2ED1AA3DEA8FDB61220C5B53C6DC983094B1EE9A0F78F875B255</stationID>
++ <name>Milicejskaya volna</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/russia/moscow.5.krp kradio-3.5.13.1/kradio3/presets/russia/moscow.5.krp
+--- kradio-3.5.13.1/kradio3/presets.old/russia/moscow.5.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/russia/moscow.5.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,456 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Дмитрий Смелков &lt;das@sidero.ru&gt;</maintainer>
++ <changed>2009-09-29T12:52:24</changed>
++ <country>Russia</country>
++ <city>Moscow</city>
++ <media>FM tuner</media>
++ <comments>from http://www.radivo.ru/</comments>
++ </info>
++ <FrequencyRadioStation>
++<stationID>1254113419B3C18A92D0E731CE42E8D1B5422801904B133FA665DD97FAE73E96A00FBE8DB2</stationID>
++ <name>87.5 Business FM</name>
++ <shortname>business</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254113603879D10C2B96E3183D52959B8856D666C01DD7A0D3E2241083206A2DB0960B2D3</stationID>
++ <name>87.9 City FM</name>
++ <shortname>city</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254115232366C9DEA47B3A7116316F1EBE11D09C33A82D9CE30A7476990E14F8C8757ED0E</stationID>
++ <name>88.2 Retro FM</name>
++ <shortname>retro</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12541150826343FCCBF4C9FE2C48DC3AFF72223EC870B294904B965C7786164418D1ECEB61</stationID>
++ <name>89.1 Radio Hour</name>
++ <shortname>radiohour</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254115595A961F47B9FA95B97E461DB06938647202A847D49C0C24C59CFDBDEDEFE840190</stationID>
++ <name>89.5 Megapolis FM</name>
++ <shortname>megapolis</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254115803EE8AEC14BE9ED5C558908548FF16F6218299D22BBCC1EA13F357B4B2CB8C3D55</stationID>
++ <name>89.8 Kex FM</name>
++ <shortname>kex</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>125411663098D26141ECE7630E94EC91620E2B11B29F55D97E66353E635912278CD06408EC</stationID>
++ <name>90.3 Auto Radio</name>
++ <shortname>auto</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12541167464545487460A4DFFC5CE6F8B50604319D36561246F36B8339961D7A05BFC02642</stationID>
++ <name>90.8 Relax FM</name>
++ <shortname>relax</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254116837998FD1B2F1CB9E369CC14D023BFD0E3F28C30E5670D2B3F90F3ADC7A329895B9</stationID>
++ <name>91.2 Echo Moscow</name>
++ <shortname>echo</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>125411883682FF181084BEB9506C2BD92D573167086EA5E6A970BA7BF89C2F31C10F141BE7</stationID>
++ <name>91.6 Cultura Radio</name>
++ <shortname>cult</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254118931AEDBCC2332E787FB1BD109EF5339D3ADD39EC0D9BEF4D1647FC2E424B4D3DA80</stationID>
++ <name>92.0 Speak Moscow</name>
++ <shortname>speakmoscow</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>125411900574B23E44E4A814887A6254349FF7EA6A63CF785968BDC2D4EB96235EC27FC613</stationID>
++ <name>92.4 Radio Dacha</name>
++ <shortname>dacha</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254119087D1C80EEDD9D50AE4C7EF5CE7AC1AC1924A2A151B0D06EABFACF49505FD189A22</stationID>
++ <name>92.8 Karnaval</name>
++ <shortname>karnaval</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254208038DC6388DAD27AEEC081627D18A85ECD56B732DFEDEFBD0EDFD3269B423E1FB0E1</stationID>
++ <name>93.2 Radio Sport</name>
++ <shortname>sport</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542080899D30F2FBBC0E46D5E7C438DB8250612B1BB1B295383A2B1F02B67523F2B26E0C</stationID>
++ <name>93.6 NewTONE FM</name>
++ <shortname>newtone</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254209832885D8EACB4781D6A59A016B0342F474B31C89E12FF6CD69C257924A82C368E8D</stationID>
++ <name>94.0 Youth FM</name>
++ <shortname>youth</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542099761A361B34C331CA5822DBF2A247297A1D420D89742BF3107DBA8E8C10AEEB7B81</stationID>
++ <name>94.4 Lornet</name>
++ <shortname>lornet</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254210228ED1569120CACBF54781E22BA8E1F327B44FE51705A8E9ACDECB3E416B1C97439</stationID>
++ <name>94.8 My family</name>
++ <shortname>family</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542103277D90DA1B11C2382160EF2748D4CCFFFAC5C27EF5231C933C41132EE1A00B3132</stationID>
++ <name>92.5 FM</name>
++ <shortname>92_5_fm</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>125421040801C66994144AE1BF4130B6E61B509D327F18D375A7DB7E0295834139FB18F2FB</stationID>
++ <name>95.6 Star FM</name>
++ <shortname>star</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254210555DC625D856752C6B8F5AD7E20419BB318E01A1895DBC9FA38BA755A9433240257</stationID>
++ <name>96.0 Tour</name>
++ <shortname>tour</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254210690E4B1BBA290BBC0633D3C5428B80A238A1EE76F8A8B78DE207ABE627BFA4EAE47</stationID>
++ <name>96.4 X FM</name>
++ <shortname>x</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542107788E5E6BBB75B20D94E632DEC2F2271010DCEDEB30464F9A9A9E6C1D1989B49D6C</stationID>
++ <name>96.8 Kids FM</name>
++ <shortname>kids</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542109468DF4D861CC4352DD73492D57049D752D0B7699AC2A8E21FFBD9AAA3E0ECA2BBD</stationID>
++ <name>97.2 Kommi FM</name>
++ <shortname>kommy</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254211077FFBB611A4952B42E012F454F9A6856ACDD141621E0B1FD46EE1063A64B7732EC</stationID>
++ <name>97.6 Vesty FM</name>
++ <shortname>vesty</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542111368120FA07696D76E9051198BF7DD2A2203D1207D98DF67B154C158D950006022E</stationID>
++ <name>98.0 98-Hits FM</name>
++ <shortname>hits</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542111955D1C8602DD46E46EB51F985EB9B7D18B321EAE5AA52A367CC0DCD615F4E70DAE</stationID>
++ <name>98.4 Fresh FM</name>
++ <shortname>fresh</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542112900E007DE37B5945C000F14A7BDF6FE9353595FFDD5B7F10F70777B4A70769D98C</stationID>
++ <name>98.8 Alla</name>
++ <shortname>alla</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>125421137786885E1A519D06FC665D843621D57F354569E748BAED5BCC4ED24A45AA3BACDF</stationID>
++ <name>99.2 Orpheus</name>
++ <shortname>orpheus</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254211405D36EF5FFB3C3F976726AC733CF85E6C8D6010FDA058D7D4853FE4EA22DEB7AAA</stationID>
++ <name>99.6 FinAm FM</name>
++ <shortname>finam</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254211511B2F2B33598DF20767D683FEDBF14BCF48B8E421FB06B5CA7DC7FA48225B347F2</stationID>
++ <name>100.1 Silver Rain</name>
++ <shortname>rain</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254211695A7414A14CD8B6C8AEEA25BE7255BF911A2F49A43015857C206A89AD8A8F23FD3</stationID>
++ <name>100.5 Best FM</name>
++ <shortname>best</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542118336B9184DC2526A04E26068352F769930C2C179E0A0C1B4C97F13479AD80F92AE2</stationID>
++ <name>100.9 Radio Classic</name>
++ <shortname>classic</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254211957B53A0D5717BBFE765D179B97462295F20170616066BE0EBEFE3AB432F207ECA1</stationID>
++ <name>101.2 D-FM</name>
++ <shortname>dfm</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254212095CABACDDF1849CDE516C3721C546F839B688C25583C6B76BDE71F5A37365CDD4F</stationID>
++ <name>101.7 Our Radio</name>
++ <shortname>our</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>125421218101C4242DE07C4952D972476E047C29905300CD40E2C956ABAAB93F1343FF0703</stationID>
++ <name>102.1 Monte Carlo</name>
++ <shortname>montecarlo</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542122574A490326E90BA2143ED3CBA9ECE84D51ACE9888179A851E019D49C1BFD902E9E</stationID>
++ <name>102.5 POP-SA</name>
++ <shortname>popsa</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254212409B14B1DDD97729A43EFF2196C938431A6DFFFDDDEB708F71BFE3BA5FCD9481CD0</stationID>
++ <name>103.0 Shanson</name>
++ <shortname>shanson</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254212449AF5CCA7CCD0A0A429F6A0B1A280D071FF498AFFA110761B26A01FFBD3AE9AB54</stationID>
++ <name>103.4 Lighthouse</name>
++ <shortname>lighthouse</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>125421248712D3B6413968F909481424D8D32E99BDF14FD58DA9DA2FA8B624DCB6007035E4</stationID>
++ <name>103.7 Maximum</name>
++ <shortname>maximum</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542127050D97BAA80BDCE7504703E2A9C6F161999453E46AD3CC6D99F6767C6CF76C3743</stationID>
++ <name>104.2 Energy</name>
++ <shortname>energy</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>125421278240CFAB908AE144C301C4A01EB0C7D48A5CECE281E1B8C6E815B17B6496499C3A</stationID>
++ <name>104.7 Radio 7</name>
++ <shortname>radio7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254213566627DCF077D632A14DD76250EC1060682EE482A4AAC10315DA36711C347E50874</stationID>
++ <name>105.2 Next</name>
++ <shortname>next</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>125421372931ED002928F13BD48B38C77F57176B136C93C8A595624BEC8BD6A6B707AE695F</stationID>
++ <name>105.7 Russian Radio</name>
++ <shortname>russian</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254213794A88ECDB89C81F42B2CDDA09B66B4FCA62E33624331AA1BDE4031DB6169377C36</stationID>
++ <name>106.2 Europe+</name>
++ <shortname>europe</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254213892F9F02154427DE2C906EC61A784CF7ED2438EE6559BDE0A88AC1E42BE44A39AAE</stationID>
++ <name>106.6 Love Radio</name>
++ <shortname>love</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12542141315B35477A88C0C075181F1C74FFE56A2FA2087A6D8D06EB8BD7DA827B8EAB252C</stationID>
++ <name>107.0 RSN</name>
++ <shortname>rsn</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254214188565B3064EC814AA6F693342B771BF65AE9F77CAF3656E059FAECAEE6980134F9</stationID>
++ <name>107.4 Hits FM</name>
++ <shortname>hitsfm</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1254214270622D673398308291D95016FA8228F590BC02522A14F14D3018F9303B44B72CC8</stationID>
++ <name>107.8 Police wave</name>
++ <shortname>police</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/russia/saint-petersburg-antenna2.krp kradio-3.5.13.1/kradio3/presets/russia/saint-petersburg-antenna2.krp
+--- kradio-3.5.13.1/kradio3/presets.old/russia/saint-petersburg-antenna2.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/russia/saint-petersburg-antenna2.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,177 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0</creator>
++ <maintainer>Hanataro (Александр Николаевич &lt;hanataro25@gmail.com&gt;)</maintainer>
++ <changed>2011-03-04T16:29:42</changed>
++ <country>Russia</country>
++ <city>Saint-Petersburg</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>12992427093FBA5E1570243458E2D5F851F3BBFC99DF2268059177356E9A652BFD2E3F</stationID>
++ <name>Дорожное радио</name>
++ <shortname>Дорожное радио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12992267583B237AB8A0CA36A5978FDB4D934789809AA63B645C0D7EFB86FF3B224776</stationID>
++ <name>Ретро</name>
++ <shortname>Ретро</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>87.9996</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12992267615D79138BF78E489668066A5F161E95CB0C2E1F0D2D2C7E8B3AED74947879</stationID>
++ <name>Авто Радио</name>
++ <shortname>Авто Радио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.3496</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1299245224DFDE600C4E78F81A578FBA1F2A45006C1A483D5738B2BF48ED284BC2C9FC</stationID>
++ <name>Для Двоих</name>
++ <shortname>Для Двоих</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>90.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1299226770ED601040E43EE3B93E2438C4AC6AFC01DDEACC98B1EE08302A04F82068E7</stationID>
++ <name>Кекс FM</name>
++ <shortname>Кекс FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.0996</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1299226773D02C541B6C989B46A7BE9E07EF3C544185FC9341F54F2EDBE86E17D89BC7</stationID>
++ <name>Эхо Москвы</name>
++ <shortname>Эхо Москвы</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.4996</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12992450064E4AAA3432B8FCA126079FA296A86E336905CE3ABF2EFED8C373D58C3798</stationID>
++ <name>Радио Рокс</name>
++ <shortname>Радио Рокс</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12992268058FEAF0C94EF06273EB673743E6258F75242AB4295D51C5B66F4EC057F2AF</stationID>
++ <name>Студио</name>
++ <shortname>Студио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.349</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12992435281FDB16BE9B711DE92E41FCEA928DDD2FC1ABA6AFCD5B07A578393BD0EC54</stationID>
++ <name>Динамит FM</name>
++ <shortname>Динамит FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12992268107030A254DC106BD62B943CE1313E4BADD282E927475E0B571AA5F3694D92</stationID>
++ <name>Наше Радио</name>
++ <shortname>Наше</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1299226813353F96B553C09BB1CC06CB806CA6EE34705D76534B42A70C5E8C2BB99596</stationID>
++ <name>Русский Шансон</name>
++ <shortname>Русский Шансон</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.399</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1299226815509A209761FCE70F2AA153A6D6118E92DD70A6516B2E44535A25AC5A117C</stationID>
++ <name>Балтика</name>
++ <shortname>Балтика</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.849</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12992439342FE6A60DC705889C54E4E43102EE5BD7A70338627821A114AEA10A547484</stationID>
++ <name>Love</name>
++ <shortname>Love</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>129922681953A87D8654349F7F46E20C2482A6BE6EA8C59008AE1DD6F9650CFD33F414</stationID>
++ <name>Спутник</name>
++ <shortname>Спутник</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.899</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1299226822C937A9D0C21E95F9AB1D7A36CACD1AAD8751DF1E0868B8499D496E10F3E1</stationID>
++ <name>record</name>
++ <shortname>record</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.299</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1299226825ADD93E9496FBE70152AEF5833A1B98A1B2EEC51A47DE80A35C432EE4A6D7</stationID>
++ <name>Маяк</name>
++ <shortname>Маяк</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.949</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12992448213D3022DC21C96DB5D1AED00A71539ABED1EB113698432D0D45C6B9CA1540</stationID>
++ <name>Бизнес FM</name>
++ <shortname>Бизнес FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12992448794E7CF4A66A7FAFC810B559EFE948480288CC3288AB469C6F84B28CC51F89</stationID>
++ <name>Русское радио</name>
++ <shortname>Русское радио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.8</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/russia/samara.krp kradio-3.5.13.1/kradio3/presets/russia/samara.krp
+--- kradio-3.5.13.1/kradio3/presets.old/russia/samara.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/russia/samara.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,239 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0</creator>
++ <maintainer>slider</maintainer>
++ <changed>2010-11-25T11:06:47</changed>
++ <country>Russia</country>
++ <city>Samara</city>
++ <media></media>
++ <comments>ver 0.01</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>12906697574C22D12352F932FBC406C8E4D27AA805ACCE94C1128DA618D2781B04FCB5</stationID>
++ <name>Добрые песни</name>
++ <shortname>Добрые песни</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>68.51</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12906699108A5C3D49F59F5AA489785116892F2745E5025BFDAB5E583F3BF2926C83BE</stationID>
++ <name>Радио России</name>
++ <shortname>Радио России</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>mono</stereomode>
++ <frequency>70.31</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290670109AC03A5A7B274C46EF2F54FB75D0E973F01E5E2CF14968E6D60D838D8DD69</stationID>
++ <name>Радио Маяк</name>
++ <shortname>Радио Маяк</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>mono</stereomode>
++ <frequency>72.05</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669458F93F12F39C5CF1E698F318744E109C1D43985D0DFDDABCFCEDCB0D74F184</stationID>
++ <name>Русское радио</name>
++ <shortname>Русское радио</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>mono</stereomode>
++ <frequency>72.83</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>129066946284D16DEFE6A632919C49CC7B59DE24C76FF17D6659DE4F709941C1923CBF</stationID>
++ <name>Самара-Максимум</name>
++ <shortname>Самара-Максимум</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>mono</stereomode>
++ <frequency>73.61</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669966CAFF3D2FE0BCA9C4ABE31755A703071613797EDBAE8220DFF911F71223C3</stationID>
++ <name>Экспресс FM</name>
++ <shortname>Экспресс FM</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>90.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669496B23BBAB0F7EA2F53447A2D2B5062D6F95A5634B03B8C642B2B6AB0DA857F</stationID>
++ <name>Милицейская волна</name>
++ <shortname>Милицейская волна</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>90.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>129066949955CCCD9BDF1541E3CBF2BD80CCD9D2169927CB1B7783CBD7EB7C84AB4E52</stationID>
++ <name>Радио 7</name>
++ <shortname>Радио 7</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>91</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12906695025E8878640F18551035279789653DC1847C3ED7FCE3C17DA0DE00814C1277</stationID>
++ <name>Ток FM / Серебряный дождь</name>
++ <shortname>Ток FM / Серебряный дождь</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12906701432579FB12F26EC4143B4075C5CA32161561C67469F2674F1D000639924769</stationID>
++ <name>Радио Маяк</name>
++ <shortname>Радио Маяк</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>mono</stereomode>
++ <frequency>92.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669512AA728A2909B5DA1766DCBA8FEE7319FB691CC904D364B5FD63F0E091086C</stationID>
++ <name>Юмор FM</name>
++ <shortname>Юмор FM</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>95.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290670209D53A20DBE72609B8DD5D1C949AD9C717D957B7EA737EE0AF4555783A9568</stationID>
++ <name>Kot FM</name>
++ <shortname>Kot FM</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>96.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669520AFD73B2A79481561F353ADAAA8019C899B98EBD5BBC7C8C523D8B5E1F4AC</stationID>
++ <name>Ретро FM</name>
++ <shortname>Ретро FM</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>98.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669523EB55855C02E8D1466C0DD69923D0AECA8D1EA4638A4324CF005F1B9396B4</stationID>
++ <name>Эхо Москвы</name>
++ <shortname>Эхо Москвы</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>99.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669526015A03960BBB8AFEAE8434E5774A10912CE23D3F30E715BC3F6AF63E2B01</stationID>
++ <name>Европа плюс</name>
++ <shortname>Европа плюс</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669529F2C34EF9C4054325268B74145214ED93301E756EEF49D0B6B369F0472357</stationID>
++ <name>Русское радио</name>
++ <shortname>Русское радио</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>100.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>129066953365186F4B19E0FFA6970EA7CF9BBE4CB8B4C8B29585CBEDCCADE3E0438A6B</stationID>
++ <name>Радио Шансон</name>
++ <shortname>Радио Шансон</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12906695360BE1FF43000028BE7DFFAC09A6D1C3D8D82F4230ADAFB8A97EA67063A617</stationID>
++ <name>Радио Рекорд</name>
++ <shortname>Радио Рекорд</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>101.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290670428DB6665C4DA8315E1F9C1C3AEE22FE5F400B378BF01D0C2091AD1D6351815</stationID>
++ <name>Радио Дача</name>
++ <shortname>Радио Дача</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669541A995A471FD47505C9A854FA3283E543CFCF2CF49D755684FA403A8B707AE</stationID>
++ <name>NRJ</name>
++ <shortname>NRJ</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669543FBF9E4CC1B1852F655B37CAB7142F34981CBEE8CED47387B2B1D416A3818</stationID>
++ <name>DFM</name>
++ <shortname>DFM</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669547A5146B3B559C4AF1D19A78B25BCBC6C96FC3FB2CE096DBBC08E1121BED6C</stationID>
++ <name>Радио Мегаполис</name>
++ <shortname>Радио Мегаполис</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>103.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669551EF9AAACB0ED236913B13084702FB32333DA1D6057709066AE87252E866F0</stationID>
++ <name>Самара-Максимум</name>
++ <shortname>Самара-Максимум</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290670579C8F92CAD2D08031E938BAAC59BBE4DE2F00B83A172121D8E030078F04F1B</stationID>
++ <name>Авторадио</name>
++ <shortname>Авторадио</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12906695578486108D25E6524980F6692BAAD184350B1AD0404E9FF46D5E553E800991</stationID>
++ <name>Радио Алла</name>
++ <shortname>Радио Алла</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12906695610B4001861F6297000F9E0163510F013380B0230CB87871A69A947A5603F6</stationID>
++ <name>Дорожное радио</name>
++ <shortname>Дорожное радио</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>106.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290670650697A6A61F958CCF9DA5BBC65D36276B78CF50F7837A6B0102BDF4E3D51D0</stationID>
++ <name>Love радио</name>
++ <shortname>Love радио</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>106.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1290669568AF4C3FA28BC38A7BFB9FB288E3CD453E4E732F49B3C509F3FDECA89B4E16</stationID>
++ <name>Детское радио</name>
++ <shortname>Детское радио</shortname>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>107.2</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/russia/vladivostok-antenna.krp kradio-3.5.13.1/kradio3/presets/russia/vladivostok-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/russia/vladivostok-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/russia/vladivostok-antenna.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,141 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.2</creator>
++ <maintainer>Andrey Tomilenko (aka Thom) thom82@mail.ru</maintainer>
++ <changed>2012-06-22T20:47:29</changed>
++ <country>Russia</country>
++ <city>Vladivostok</city>
++ <media>Antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1305629847E4E1C8DFAE28601AA9FF6FED89E658E93D0FB8E6CD6E38CAE5F9FD312294</stationID>
++ <name>Радио Маяк</name>
++ <shortname>1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>69.68</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13056302742651484CC5912F72A23F69F67301C3D59DE23FEE9DDBB143FD366F972D12</stationID>
++ <name>Радио России</name>
++ <shortname>2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>71.84</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305630309F71DD598694A4024E35B0E728919D3C07279C5A8517CCD3CAF6665D50FDE</stationID>
++ <name>Авторадио</name>
++ <shortname>3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>88.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305630337CE26C7EFFA5A35679CA6A2014859F842B5784AE6CD400457AAB500DA93CA</stationID>
++ <name>Радио 7</name>
++ <shortname>4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305630407C3530D192583FA82B955F4DC456E7280CA9FAAF485DCDB1017EF8AFDBCAD</stationID>
++ <name>Радио VBC</name>
++ <shortname>5</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130563042542AAA24D5F407A403C4A7197B4CFA710A0DC193EBD8830AAC41C95A4ADF1</stationID>
++ <name>Радио Лемма</name>
++ <shortname>6</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305630440AAD7287143E964761B40147B5B4300A6F0E875FD2F16CB7CF19636145C52</stationID>
++ <name>Радио Шансон</name>
++ <shortname>7</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13056304542589A59330FDFD3BC5C59CF6F361BD834A851576B85BC0B2DD0882E7A094</stationID>
++ <name>Ретро FM</name>
++ <shortname>8</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>13056304729BC63FBCDAEACF9BF8E31BB50C14D2A3BA718D7CC67516720549D43308ED</stationID>
++ <name>Европа Плюс Владивосток</name>
++ <shortname>9</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>130563049042596A28FF0B0A75A1EEE2646A0F66383E7ADACD04F3CCFEF9CD2D291A32</stationID>
++ <name>Радио Дача</name>
++ <shortname>10</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305630506C7D70286FAD616EDC0D58CE0E911282596E00793C5A5D9E1D402700207F7</stationID>
++ <name>DFM</name>
++ <shortname>11</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305630522CCF6CD3D24E933D486C62C00D4279BC46C85AA7B71F9170ECB4900CF7899</stationID>
++ <name>Хит FM</name>
++ <shortname>12</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305630536EF153D9BA1638772799D7C1D066D0C8E431B98476DD073FC4B05AA07C4A9</stationID>
++ <name>Владивосток FM</name>
++ <shortname>13</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1305630551DEB55372DD2D6225FD2472EB4B5926B50BD2F6D652E4E9DBB8F8E8E590B8</stationID>
++ <name>Русское Радио</name>
++ <shortname>14</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/slovakia/bratislava2.krp kradio-3.5.13.1/kradio3/presets/slovakia/bratislava2.krp
+--- kradio-3.5.13.1/kradio3/presets.old/slovakia/bratislava2.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/slovakia/bratislava2.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,114 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_11_27</creator>
++ <maintainer>Karol Slanina</maintainer>
++ <changed>2007-01-30T23:57:25</changed>
++ <country>Slovakia</country>
++ <city>Bratislava</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>11701979358557D176BE181F7A4D73F6B3E363053727BB4B2865AEBDF6522AA23B496A4BC6</stationID>
++ <name>R�dio FM</name>
++ <shortname>R�dio FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1170197995A51B2D6F23369B1E32CD8732D47EF18E7DF3DE59A10F1E552EF0D5192E082F2F</stationID>
++ <name>Lumen</name>
++ <shortname>Lumen</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1170197864908C92A275FF4EB11D627A70C50F184AC5025AD1EA23B1F2C2E5545DF4604377</stationID>
++ <name>Fun Radio</name>
++ <shortname>Fun</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1170198029A2525F10FCA4A80FC4C9920DE5317291C7E3FA88F7439AF8554FABEF2C505A7B</stationID>
++ <name>R�dio Slovensko</name>
++ <shortname>R�dio Slovensko</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1170198058FF77AB835BD24D973DBD19FEE90CD52C897DBD56454EAC40FF6EE6299530E2BA</stationID>
++ <name>Lumen</name>
++ <shortname>Lumen</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1170197883FEF499284D6512B6D124C6AEE06954813B19D0677B9FAE1E25841F047E506DAB</stationID>
++ <name>Regina</name>
++ <shortname>Regina</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11701981540C8BA3C5FEE26BFEBC1C21757EAECF0F8812D60536CF462229E28D88D79D3614</stationID>
++ <name>Hey!</name>
++ <shortname>Hey!</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>117019818318BF1A3FB6743C67752E82D4040BEE751A2DFA097586C0745590238E429B140D</stationID>
++ <name>Viva</name>
++ <shortname>Viva</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>117019823636B4E4B502BC79238346E03946C14B71DBF94119255C2C80249382E9E9596E76</stationID>
++ <name>Dev�n</name>
++ <shortname>Dev�n</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1170198249A7B52138DFC2490C760F9B63E3089848E5530558F197A85AF75E491DE3752EF8</stationID>
++ <name>Okey</name>
++ <shortname>Okey</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1170198200C27DA842FC3E41A94178717FD57CDA4B3637AEE94EE432559A51406C152BE867</stationID>
++ <name>Jemn� mel�die</name>
++ <shortname>Jemn� mel�die</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1170198173C7877B76C83C5A1D305D71333F95BF44E85E4981BFC901138A6D8B4161CB9DDE</stationID>
++ <name>Expres</name>
++ <shortname>Expres</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/slovakia/bratislava.krp kradio-3.5.13.1/kradio3/presets/slovakia/bratislava.krp
+--- kradio-3.5.13.1/kradio3/presets.old/slovakia/bratislava.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/slovakia/bratislava.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,95 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_11_27</creator>
++ <maintainer></maintainer>
++ <changed>2007-01-03T17:10:50</changed>
++ <country></country>
++ <city></city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1167837266A46C6BD80A9B05DB8191BBA2DF07FBD9C06260FFCD10A5C14F99B37A4A1264E1</stationID>
++ <name>Radio FM</name>
++ <shortname>radiofm</shortname>
++ <icon></icon>
++ <volumepreset>0</volumepreset>
++ <frequency>89.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1167837523A6FCDE20D4D66BFB2D2DEC1BE1027C01007A26E6BBB1E674B7E9B1B5F2B69282</stationID>
++ <name>Radio Wien</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>89.95</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1167906947508A1DFDFB2DCC3217FE7DE77F0896F34EFCE5C1F01A3481D8B13DEA5AAE0D03</stationID>
++ <name>BBC World</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11678375991034A86E0C2F24E0262CECC9917EEADEAAAC6738B5CE2DB74B4210B84E60E6DC</stationID>
++ <name>Fun Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1167837739B15816FFEC00FA6F46359F18C7E4B88DEDD1D1EDF4E2E25A5DA0117CB3CF1E73</stationID>
++ <name>SR1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>96.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1167840523320901F854CBA0C6099B0F680738AB4EF8B7375882DD6C1C9BC639C14A0075DB</stationID>
++ <name>Radio FM4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11679064372E55132CD63194C6DF57BED568063822F8DB897F58D7F1F2AEAE396B1E0BF242</stationID>
++ <name>Radio Okey</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1167906269AA3003C8F5BAE787A4B93AC008C8DF8FCE0F184E50FBA8C7EAB68F194DD47442</stationID>
++ <name>Krone Hit</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11679069873DD5DB69565B0F08A2A6C7D0922333B8E956C9B23DC2066513ED88F091BDF922</stationID>
++ <name>Jemné Melódie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1167906370C374296A0729322F2FE591A959E9927D815F5AC53FEC71DF3EEF3A2B6868B6E1</stationID>
++ <name>Radio Expres</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/slovakia/Makefile.am kradio-3.5.13.1/kradio3/presets/slovakia/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/slovakia/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/slovakia/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -1,10 +1,13 @@
+ SUBDIRS =
+-EXTRA_DIST = "kosice.krp"
++EXTRA_DIST = "bratislava2.krp" "bratislava.krp" "kosice.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/slovakia/"
++ $(INSTALL_DATA) "$(srcdir)/bratislava2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/slovakia/bratislava2.krp"
++ $(INSTALL_DATA) "$(srcdir)/bratislava.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/slovakia/bratislava2.krp"
+ $(INSTALL_DATA) "$(srcdir)/kosice.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/slovakia/kosice.krp"
+
+-
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/slovakia/bratislava2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/slovakia/bratislava.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/slovakia/kosice.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/spain/leon.krp kradio-3.5.13.1/kradio3/presets/spain/leon.krp
+--- kradio-3.5.13.1/kradio3/presets.old/spain/leon.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/spain/leon.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,114 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <maintainer>Roberto Garrido &lt;garrido251@terra.es&gt;</maintainer>
++ <changed>2006-10-16T18:47:38</changed>
++ <country>Spain</country>
++ <city>Leon</city>
++ <media></media>
++ <comments>Emisoras de Leon capital</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1116455444F91ED21F1D7BA697D3CCCA4F80412D98E84AC5EEE8E9FD8802E8239245117BE5</stationID>
++ <name>RNE 1</name>
++ <shortname>RNE 1</shortname>
++ <icon></icon>
++ <frequency>87.60</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1116455444F58348060F6B3951D032CE2AE3962570045A854578FE3718D634442C77547493</stationID>
++ <name>40 Principales</name>
++ <shortname>40 Prin.</shortname>
++ <icon></icon>
++ <frequency>88.2</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>111645544469DB377E2239117F981CCE57F05666F7D20638D4B79949FCF6B9046A5504FBF8</stationID>
++ <name>Radio Clasica</name>
++ <shortname>R. Clas.</shortname>
++ <icon></icon>
++ <frequency>91.10</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1116455444E3C16AFC5033065A79EA2ACB983CD130F211DD90B5191135A7A0406A415E9E32</stationID>
++ <name>Radio 3</name>
++ <shortname>Radio 3</shortname>
++ <icon></icon>
++ <frequency>89.30</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554446CAC6C1662A7B7CED73A73B393EDB080B0BDF83DB7FF69DADA2B1CE6EEB5227C</stationID>
++ <name>Cadena Ser</name>
++ <shortname>C. Ser</shortname>
++ <icon></icon>
++ <frequency>92.60</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11164554447A9C68C227A551F40419A4A90C43709DE94082A0EE08024CCC55365C051D497B</stationID>
++ <name>Cadena 100</name>
++ <shortname>C. 100</shortname>
++ <icon></icon>
++ <frequency>93.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444DCD642C7A6C7E5EB8768969BA1504A0B12AF82D9B3B42EF1A943AD01C56B1878</stationID>
++ <name>Cadena Dial</name>
++ <shortname>C. Dial</shortname>
++ <icon></icon>
++ <frequency>94.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1116455444509F0036299C12C83B7ABEA8000845DC5D38E34AAEA04346433F6ACC64860751</stationID>
++ <name>M80 Radio</name>
++ <shortname>M80</shortname>
++ <icon></icon>
++ <frequency>95.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444787E3904290A56E16C4808EE0C7117893EE19A27D621326FA4FEA44334A6AAB4</stationID>
++ <name>Kiss FM</name>
++ <shortname>Kiss FM</shortname>
++ <icon></icon>
++ <frequency>96.5</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444C8F7100921C174D17234BB109181FB1D1891D59C31A09771D0400BA46015D36F</stationID>
++ <name>Onda Cero</name>
++ <shortname>O. Cero</shortname>
++ <icon></icon>
++ <frequency>98.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1116455444524D3835E4E98FA48D0822236F7A2C4881D4D3314D9740CDE086B1DCF400850C</stationID>
++ <name>Radio Maria</name>
++ <shortname>R. Maria</shortname>
++ <icon></icon>
++ <frequency>101.3</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>111645544434E00A4B79D5AF6F50BCA073B4F0075DB98363F2965208360ADB384FC9C9261F</stationID>
++ <name>Radio 5</name>
++ <shortname>Radio 5</shortname>
++ <icon></icon>
++ <frequency>102.2</frequency>
++ <volumepreset>-1</volumepreset>
++ </FrequencyRadioStation>
++
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/spain/Makefile.am kradio-3.5.13.1/kradio3/presets/spain/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/spain/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/spain/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -1,26 +1,27 @@
+ SUBDIRS =
+-EXTRA_DIST = "barcelona2.krp" "barcelona.krp" "bilbao.krp" "lugo.krp" "madrid-2.krp" "madrid.krp" "malaga.krp" "mieres-del-camino.krp" "sevilla.krp"
++EXTRA_DIST = "barcelona2.krp" "barcelona.krp" "bilbao.krp" "leon.krp" "lugo.krp" "madrid-2.krp" "madrid.krp" "malaga.krp" "mieres-del-camino.krp" "sevilla.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/"
+- $(INSTALL_DATA) "$(srcdir)/malaga.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/malaga.krp"
+- $(INSTALL_DATA) "$(srcdir)/madrid.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/madrid.krp"
+ $(INSTALL_DATA) "$(srcdir)/barcelona2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/barcelona2.krp"
+- $(INSTALL_DATA) "$(srcdir)/mieres-del-camino.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/mieres-del-camino.krp"
+ $(INSTALL_DATA) "$(srcdir)/barcelona.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/barcelona.krp"
+ $(INSTALL_DATA) "$(srcdir)/bilbao.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/bilbao.krp"
+- $(INSTALL_DATA) "$(srcdir)/sevilla.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/sevilla.krp"
+- $(INSTALL_DATA) "$(srcdir)/madrid-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/madrid-2.krp"
++ $(INSTALL_DATA) "$(srcdir)/leon.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/leon.krp"
+ $(INSTALL_DATA) "$(srcdir)/lugo.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/lugo.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/madrid-2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/madrid-2.krp"
++ $(INSTALL_DATA) "$(srcdir)/madrid.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/madrid.krp"
++ $(INSTALL_DATA) "$(srcdir)/malaga.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/malaga.krp"
++ $(INSTALL_DATA) "$(srcdir)/mieres-del-camino.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/mieres-del-camino.krp"
++ $(INSTALL_DATA) "$(srcdir)/sevilla.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/sevilla.krp"
+
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/malaga.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/madrid.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/barcelona2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/mieres-del-camino.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/barcelona.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/bilbao.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/sevilla.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/madrid-2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/leon.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/lugo.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/madrid-2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/madrid.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/malaga.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/mieres-del-camino.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/spain/sevilla.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/sweden/linkoeping.krp kradio-3.5.13.1/kradio3/presets/sweden/linkoeping.krp
+--- kradio-3.5.13.1/kradio3/presets.old/sweden/linkoeping.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/sweden/linkoeping.krp 2012-11-25 00:48:01.000000000 +0100
+@@ -0,0 +1,87 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_11_27</creator>
++ <maintainer>Magnus Holmgren &lt;magnus@kibibyte.se&gt;</maintainer>
++ <changed>2006-10-19T16:57:24</changed>
++ <country>Sweden</country>
++ <city>Link�ping</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>11612679722C3AE9D70B2B3DD46C4065608BA1CAACE6896B3D6F823A492BBC2530D8F59698</stationID>
++ <name>Sveriges Radio P1</name>
++ <shortname>P1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161268014C8DA05F96C556DF58C27DCA0B7EB4D76C21088188AB8FD914878185BD0F9D949</stationID>
++ <name>Sveriges Radio P2</name>
++ <shortname>P2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161267649469715870FF0D03695CA6A24454360C86BFBE9C63852DBE7C345B2F78588CDCA</stationID>
++ <name>Sveriges Radio P3</name>
++ <shortname>P3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161266725517FE1ECC390A4AD8164724F361C1BBC9663B69AE58DA4D18E922C95E7B94877</stationID>
++ <name>Sveriges Radio P4 �sterg�tland</name>
++ <shortname>P4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1161267804D5E933F12EFCD66F8EEF4B28C4345A2D2986DE5A121E68825E481A4197D46171</stationID>
++ <name>Link�pings n�rradio</name>
++ <shortname>N�r</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11612659565F0D48B7FB6AE89FFFA0F61FFC2C342AFF99E6AFC86F0E8FFAE65DE6AEAE3BCA</stationID>
++ <name>Rix FM</name>
++ <shortname>Rix</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.376</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11612667154BB764EE3775FEA4FC6159E50300742ADD5E58B519E357ACAE84BA532BCDD8E8</stationID>
++ <name>Lugna favoriter</name>
++ <shortname>LF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>116126856640E5698A4438B690C4BFE5601F11D852BAC3164C921A42AAB231681183E40603</stationID>
++ <name>East FM</name>
++ <shortname>East</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.2</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/sweden/Makefile.am kradio-3.5.13.1/kradio3/presets/sweden/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/sweden/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/sweden/Makefile.am 2012-11-25 00:48:01.000000000 +0100
+@@ -1,18 +1,19 @@
+ SUBDIRS =
+-EXTRA_DIST = "gothenburg.krp" "oestersunds-kommun.krp" "stockholm.2.krp" "stockholm.krp" "vaxholm.krp"
++EXTRA_DIST = "gothenburg.krp" "linkoeping.krp" "oestersunds-kommun.krp" "stockholm.2.krp" "stockholm.krp" "vaxholm.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/"
+- $(INSTALL_DATA) "$(srcdir)/vaxholm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/vaxholm.krp"
+- $(INSTALL_DATA) "$(srcdir)/oestersunds-kommun.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/oestersunds-kommun.krp"
+ $(INSTALL_DATA) "$(srcdir)/gothenburg.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/gothenburg.krp"
++ $(INSTALL_DATA) "$(srcdir)/linkoeping.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/linkoeping.krp"
++ $(INSTALL_DATA) "$(srcdir)/oestersunds-kommun.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/oestersunds-kommun.krp"
+ $(INSTALL_DATA) "$(srcdir)/stockholm.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/stockholm.2.krp"
+ $(INSTALL_DATA) "$(srcdir)/stockholm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/stockholm.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/vaxholm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/vaxholm.krp"
+
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/vaxholm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/oestersunds-kommun.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/gothenburg.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/linkoeping"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/oestersunds-kommun.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/stockholm.2.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/stockholm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/sweden/vaxholm.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/switzerland/baar-cable.krp kradio-3.5.13.1/kradio3/presets/switzerland/baar-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/switzerland/baar-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/switzerland/baar-cable.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,421 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer></maintainer>
++ <changed>2008-10-29T08:32:41</changed>
++ <country>Schweiz</country>
++ <city>Baar (ZG)</city>
++ <media>Cable</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>12252731615C37190398400074872507711380CC9F801C63990D7D1216B681209CEA7786A9</stationID>
++ <name>Deutsche Schweiz 1�</name>
++ <shortname>DRS 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731615F3EC8840F1D28547F96E5F851757FD7E43F14DAC1D84B35BBD2E4B3CBACA8EC</stationID>
++ <name>Deutsche Schweiz 2</name>
++ <shortname>DRS 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161571CAE333F51B6DF76B9FC350D3B8241CB010CC415F45A11DDF89938B7E48F20</stationID>
++ <name>Deutsche Schweiz 3</name>
++ <shortname>DRS 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122527316101F7DBAA4FC8D120BA86942BB54C774119B175AEFDBF07313E9BC380645E5979</stationID>
++ <name>Deutsche Schweiz 4</name>
++ <shortname>DRS 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731610FD0B97EA983008980BC88F6C246C1B0DCA90B2298759E39A2485A68FBD08284</stationID>
++ <name>Radio Eviva</name>
++ <shortname>EVIVA</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161DD5A7B47F06219EE6B287410846E68A2F9645FBE56CDA64055EBE9FD50F400CA</stationID>
++ <name>DRS Musikwelle</name>
++ <shortname>DRS M</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122527316150F8094927669160C81E11488EE683D7D51643444F74930B441A71E741AA8D1E</stationID>
++ <name>Radio Swiss Jazz</name>
++ <shortname>CH-Jazz</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122527316144A1588DA40CC54E54E8FD1955699F6E590FF05128F551C188B50781BFA2E429</stationID>
++ <name>Swiss Clasic</name>
++ <shortname>CH-Class</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161E93DBEAB0A4B385E7F8638081FF4FE77F082AE85AFD05E79A86074C450274ED4</stationID>
++ <name>Swiss POP</name>
++ <shortname>CH-POP</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161A8049CE900367D1B4609C408D051B68E68CC148E1E4AFAE7C6210EB569563F5F</stationID>
++ <name>Tropica</name>
++ <shortname>TROP</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731615AE584B8080DBA4FA802E756A6CA14DC0B1999843A435E10D0C016073AC04964</stationID>
++ <name>Rock Nation</name>
++ <shortname>SM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161F381A9211F4AD4D44F7DF22218F520FD15E20AEC8F90520E8EF44FDBA9D8BE49</stationID>
++ <name>Radio Virus</name>
++ <shortname>VIRUS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731616CA06E1C2AE30BB75D0A55BEBCDBB0430F29D75E9065E394C07C91234513F35D</stationID>
++ <name>Radio Sunshine</name>
++ <shortname>RSH</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161425F93755AFA25B35C884916F0ADC90D5AD7C7FBB55A6FD8CBDC5F9FEF5DCB9F</stationID>
++ <name>Radio Pilatus</name>
++ <shortname>PIL</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161AB5F78DEF5E32376FDFD550AEFEBC2B8D3870C2F241C3B2A799343A4B8E181C2</stationID>
++ <name>Radio Central</name>
++ <shortname>RAS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161422E70DA14D5688197F0463779CDB698D20B05A5EF117F0EA81F427FF665E65D</stationID>
++ <name>Radio 105</name>
++ <shortname>R105</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731613B91C4CE87B38152A108B17DFF853A5EF3E30A85E31709BF2A86FF4E6FAE1EB7</stationID>
++ <name>Radio 24</name>
++ <shortname>R24</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161DEE2378679617AC0F38BFBE73B34344C5DAAB629FD54F6CA96BDE14AAE8307F8</stationID>
++ <name>Radio LORA</name>
++ <shortname>LORA</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161B50423C2C6D3A258BAE99CC96F1C2A7DBFA5632C321CE714DB38AAE38C346710</stationID>
++ <name>Radio Energy</name>
++ <shortname>NRJ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731614A07E5A4D217F410E3D11188E49B4FB392835BB6B33BB5667D39EEF9C77DFFDD</stationID>
++ <name>Suisse Romande 1</name>
++ <shortname>RSR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161EE7A4CB25EA346F4C855D21D92C8DA38A3FFAFDE9BFBD109E3FA6791FD9ED0C5</stationID>
++ <name>Suisse Romande 2</name>
++ <shortname>RSR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731617BF310CCF020C3ECB8AF3A1F9FC7ECCF63C53B2D2CDF1E8E6314EBDBB84A48FB</stationID>
++ <name>Suisse Romande 3</name>
++ <shortname>Couleur 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731612E058C045EB2E699CE7A457AD516992A350A702579000BA6C5A17EF171454EBF</stationID>
++ <name>Svizzera Italiana 1</name>
++ <shortname>Rete uno</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161774BDACFA3A2D1010ACDA1358A21BDEE9D11EB4BD544ACAABA25E9C81D3D9877</stationID>
++ <name>Raetoromanisch</name>
++ <shortname>RAT</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161DA24AD3329D2F6A2F676CD4A618F3E9B00F3398DBA3248F87B18C1062C566065</stationID>
++ <name>Suedwestrundfunk 1</name>
++ <shortname>SWR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731612C2E8DB69C060D2B9F6D99B76A0C6915CA9C1F570DAD0BA21633CCDCA6968999</stationID>
++ <name>Suedwestrundfunk 2</name>
++ <shortname>SWR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161D5A748788A860FA1780DD3A85D63C4B7A24338B84D949FE74913F310D1281550</stationID>
++ <name>Suedwestrundfunk 3</name>
++ <shortname>SWR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161017919BC747D3C3050F193AB1FDD0F0B82062E2AFE4A9A04A9164264186C2298</stationID>
++ <name>Suedwestrundfunk 4</name>
++ <shortname>SWR 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161310AC50726DB4819FF3E73563B2121FC09B2624B0AAD25AC1C639DB73EED8DD7</stationID>
++ <name>Bayern 1</name>
++ <shortname>BR 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161BCF2994106AAD995088C4AEDD8F0901CE0864622EA856A5E4BD8B09C8C0A481F</stationID>
++ <name>Bayern 2</name>
++ <shortname>BR 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161F93BA8D4C7D85846202BC721054391B03E0FE53A0A25A5CFB27E56D49F5A84ED</stationID>
++ <name>Bayern 3</name>
++ <shortname>BR 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161C5E00C7CED1D20457FD741161A38C3D2E89849DA70700FD9B4053AA554FF31D4</stationID>
++ <name>Bayern 4</name>
++ <shortname>BR 4</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161E936AD3F2AA5E9AE3C541FF6AE99ABB898C3D8FB485F46E811C7FC68DD14D70B</stationID>
++ <name>Deutschlandfunk</name>
++ <shortname>DLF</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122527316144EFE270366507B0E1DC5B5D9CA2650577187AC960D27D0B063152EBCF43A076</stationID>
++ <name>RTL Radio</name>
++ <shortname>OLDI</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731615F50D3ADC6C7CADAEED6BE118E60ACE86C254FF12BE25AFC2A578EEA92F7A1A3</stationID>
++ <name>Oesterreich 1</name>
++ <shortname>Oe 1</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161EB926A11E10642DFF9732D249A77006949B6141F7E541DC09149F03447AA1B5C</stationID>
++ <name>Oesterreich 3</name>
++ <shortname>Oe 3</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122527316111AD7DEF5739C998C08D84F388A1E7AC8B6A3B44BFC614A83E2894F818E015C4</stationID>
++ <name>Radio Vorarlberg</name>
++ <shortname>Oe 2</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122527316181DDE5688DAC8A726278689857F789B201D9BFECA62AACFAD6039B1FF103AEDF</stationID>
++ <name>Klassik Radio</name>
++ <shortname>KLAS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731619C8109156AB1A348BF532BBCF4DAF1B77311C8B00BBC1AE4259A2BF82F1A2C99</stationID>
++ <name>Sky Radio</name>
++ <shortname>SKY</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731613FD044AB1BEE2C8AF97A15DC1A1558AEDA9FAB84399E834459AAA8E73BD6F6E6</stationID>
++ <name>Deutsche Welle</name>
++ <shortname>DW</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161B078B9CCFB310C45D6DF651133CF77D5E9CD6C4162A1292BF5FF9DCE6CEA6A58</stationID>
++ <name>France musique</name>
++ <shortname>FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161247F897CFB0D11FF8DDCF3BF74EEF92D78187BF0FC3BF6A48B726DE551B65D44</stationID>
++ <name>France culture</name>
++ <shortname>FC</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161089D4E01B7FCDE677247DBBE8112EC1B6D59860843F08720DEB6C0F314150928</stationID>
++ <name>France inter</name>
++ <shortname>FI</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1225273161FB03759B05089B0E9B49DD4C1BAFBA08AF0F697E11D37F931A337DB02710F30A</stationID>
++ <name>BBC World Service</name>
++ <shortname>BBCW</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12252731612C2CF11CF81CAB1D6BF82A4CDFC854050815CDEFF9FC3F4EC54A3B5B9DFF71B1</stationID>
++ <name>World Radio Switzerland</name>
++ <shortname>WRS</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.6</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/switzerland/Makefile.am kradio-3.5.13.1/kradio3/presets/switzerland/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/switzerland/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/switzerland/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -1,14 +1,19 @@
+ SUBDIRS =
+-EXTRA_DIST = "diepoldsau-cable.krp" "stansstad-cable.krp" "wrenlos-cable.krp"
++EXTRA_DIST = "baar-cable.krp" "diepoldsau-cable.krp" "egg-cable.krp" "spiez-cable.krp" "stansstad-cable.krp" "wrenlos-cable.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/"
++ $(INSTALL_DATA) "$(srcdir)/baar-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/baar-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/diepoldsau-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/diepoldsau-cable.krp"
+- $(INSTALL_DATA) "$(srcdir)/wrenlos-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/wrenlos-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/egg-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/egg-cable.krp"
++ $(INSTALL_DATA) "$(srcdir)/spiez-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/spiez-cable.krp"
+ $(INSTALL_DATA) "$(srcdir)/stansstad-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/stansstad-cable.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/wrenlos-cable.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/wrenlos-cable.krp"
+
+ uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/baar-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/diepoldsau-cable.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/wrenlos-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/egg-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/spiez-cable.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/stansstad-cable.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/switzerland/wrenlos-cable.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/switzerland/spiez-cable.krp kradio-3.5.13.1/kradio3/presets/switzerland/spiez-cable.krp
+--- kradio-3.5.13.1/kradio3/presets.old/switzerland/spiez-cable.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/switzerland/spiez-cable.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,361 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-09-20</creator>
++ <maintainer></maintainer>
++ <changed>2006-11-25T18:25:59</changed>
++ <country></country>
++ <city></city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++ <stationID>1164475721C836B02D3F9FB5323F9B91DCC801F18604275400966F77F8438EE0DFD21004A3</stationID>
++ <name>Musigw�lle 531</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>87.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164476030DBDA7CE1895880614BD880D190BFF85874123D1EA380A59325BA85DAD0E36B75</stationID>
++ <name>Radio BEO</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>116447645722BEEB11FBAE650D5B6E528AA5BE6550F03E5A316B7D12360F42AD9ABBE71A49</stationID>
++ <name>Virus</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164476485623C22102A116C99B38AFFB8899E4C63E7CED92DF119968181A3D45E6B1E082D</stationID>
++ <name>Radio Regenbogen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164476522F136F4B1AB6D4A0F9B8640C7C52001600D8812FC2AC614AF11B13117F9100683</stationID>
++ <name>DRS 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644766088531147C8EBFB983BD17E35EFAEFAB6AA2910217FB62BF2CC43087B928E20052</stationID>
++ <name>DRS 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164476645F8334668B73282FC0CDDE1E642E1A4B1F4068638961E8E73BFCEEEEB21E08A08</stationID>
++ <name>Oesterreich 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644767132F795AABE1F145F8EC35E7EA1D9FDD1125452F31152EF022E3D77DDE4002C436</stationID>
++ <name>SW-Rundfunk 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.29</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644768047E4A9DAFF301C6C6B33D8CC33F9BA07E6000AB137E484161BD939A14063DFCA4</stationID>
++ <name>Bayern 4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>116447709817EED4BED4A4579737F308C6D1510E8578017F10D3D3DB349B32AAB44A1ED9CC</stationID>
++ <name>Radio Melodie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164476632F724A008F02E6D3AD51D39DC085CE1B82F9FA9EFB1608AC16C5F26D9020A9C82</stationID>
++ <name>Oesterreich 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>116447711474A26EC5B9D08F4F13D196CEBA8A340ACE82EBD0B8E9FC61BAC8125C82C013D0</stationID>
++ <name>RTL-Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164476846FC95432884DBDC07B8FF2792A20AA3D097403536C233BD1BAF0BBF08C2C58F13</stationID>
++ <name>Radio Svizzera Italiana</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644771468AA776EFE5705F034B7D8C34A8825AA572D8C8EABC803DE94A4F540E4018EF89</stationID>
++ <name>Radio Rumantsch</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>116447673275A830CAE620C2602AC63CF04DC44B22EF74C7B9C0B7D34F9559968C3FA5DDC7</stationID>
++ <name>SW-Rundfunk 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164476871DC16BE6BE1FC8EBF76E8C1D96294EB0AFDFDBB681D07C6E629295715E93760EB</stationID>
++ <name>Radio Suisse Romand 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>116447719145CA243A149CFC3CC5B277C8C952C68CC4AFE241170805028B9D8F4C6F8EFC6D</stationID>
++ <name>Sky Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164476689247ADCA226D16E3A1A47B3F109347DC3A07082682F51A09946D8CDEF76FADBF0</stationID>
++ <name>SW-Rundfunk 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644772145A80A226FE3438AEB2CD7C67CC50D04D9A6963445C389F8544829335827FB68B</stationID>
++ <name>Swiss Pop</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644768870A3FC50ED9BB1F3FDEFFBBECC9510AA8113A440A46895F6467573AFFB1DF7D82</stationID>
++ <name>Swiss Culture + Jazz</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164477240CF1F4C25E2A3F009578B936EE6802812D0351938C0B0A38F7E268D4F5D010653</stationID>
++ <name>Radio Eviva</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644767613828AAB12B9DA61869FF71B91D28FA83ADEF88D7FA446D0927C3DB626A0FB90C</stationID>
++ <name>Bayern 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644772595D1023FE4609DB5BC01A162A2A370269F79F81AFB6F8C6B575C778A3CD11B4BE</stationID>
++ <name>Swiss Music Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>116447700658B7827F2F1C3EEC396586A5694F03645A8C0BC343E030D1B49F58CBE66B3E03</stationID>
++ <name>France Inter</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>116447727511838E69F94FB51A15470F7EFA96E9AE099AA1836A7562ED95671C0F1E0E0C31</stationID>
++ <name>Radio BE 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164476665D42950581695565798A8D7D864F8ABCE5D945CF141430F2D7EF9245F54829B88</stationID>
++ <name>Swiss Classic</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164477303B8282E6DA0AA48A55E59F852CA2935F99E6E4ADE05329EDC2F39F90064B8E914</stationID>
++ <name>MDR Sputnik</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>116447703272325203D3A39FF25A9013A17926FC95911E8A2B3E0508C8A1911F65B54316E9</stationID>
++ <name>France Musique</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164477369E78B9920982741ACE5BF2403152CBF4EBE4E51E9AFDDE6481FD84B61DCB539AA</stationID>
++ <name>DRS 1 Regional</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644767869F8A1A9D954FDA85F658D53C4C4F463ABF512D00DD6ACE2A7E183AE736C3E2E7</stationID>
++ <name>Radio Network 105</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644770561E9A7C4F01D692E947D4EB715F243D6340CAEB5FDA1AFF9BB6C38ABBC75427F0</stationID>
++ <name>Klassik Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>11644777782CECEA00CDCCCA218FADB5451F25842A2AB8C8D397694C6A7235EF1A892EDC9A</stationID>
++ <name>Couleur 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164477077DF2B858361FA4F6EF082A705A96D694DCA0E7665C753CBC1EFD9117753616E08</stationID>
++ <name>Capital FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164477882C2E4BE3D45186DC9A9DAB61CCDD0FA342DD5865C8154713B73638D36E76FC1CF</stationID>
++ <name>France Culture</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164478027D46AFC7CD8F5F0F27BC708272780F0447F1FC0E532845417F4900ED08038267C</stationID>
++ <name>BBC W-Service</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164478081D5D6FD1F78B4466274D593B544F3484C1CADE593A1668D108C4C451E287E2ED6</stationID>
++ <name>Bayern 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164477159F2E7FEB9CAF1D312DC9D665718F264E2B23BEFEF956E0F53F4D48DB4E9829CB1</stationID>
++ <name>Sky Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++ <stationID>1164478115A1CBD0F9B921FF6D38E14579A8AA498D2A05DCB3A7020A5C059EE4A507B6CAAD</stationID>
++ <name>Radio BE 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.3</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/turkey/istanbul-antenna.krp kradio-3.5.13.1/kradio3/presets/turkey/istanbul-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/turkey/istanbul-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/turkey/istanbul-antenna.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,239 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Tolga Kaprol &lt;tolga@kaprol.net&gt;</maintainer>
++ <changed>2009-03-22T16:56:00</changed>
++ <country>Turkiye</country>
++ <city>Istanbul</city>
++ <media>antenna</media>
++ <comments>Based for Besiktas District</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1133103256F976C1C9EE76F2A0358FF48D0C8CA359A63AB04AE6170E6E6DD15E535DEDCE6F</stationID>
++ <name>TRT FM 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>113310325667257411AA7CDAA02CF2BF8682CFAE0730F602AE53D1E377B6AAEA8D73644F41</stationID>
++ <name>CNN Türk Radyo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032568361DC126F4320BB3A88CB142BAA17B6381608ED1FE62C0C23E09BC8385E7A40</stationID>
++ <name>NTV Radyo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032560BC71AF1443D07D68F7AA660D6ED3CB72F51561D0868328E48112C379A2ECEFF</stationID>
++ <name>Haberturk Radyo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1133103256027AE7ACDDA8B25B6DD21B02DA5E86924D65EAC985866CA95C42D97D285CA211</stationID>
++ <name>Radio N101</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032564E7A550EEE6211419FBC18C3E9B0AB9BC2A5E73A99F889A811893A0BCE956F81</stationID>
++ <name>Lig Radyo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1133103256B7EB1EBEEFA0A2990C6F6E6CA8BBF4EDB07B47E815062EBD5D39B497610F843B</stationID>
++ <name>Radio Dinamo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032560F7121DBCB34D537AD1A03F44CA586717903F6A5A280127C508F5CBFCD924991</stationID>
++ <name>Metro FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032566E340315A3C3FFD132FE6A71D036623CD6A6D3437FF98BD12681CA47B71A784C</stationID>
++ <name>Number One</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1133103256F9BF82DF0814AD9897CB0CEDFBEBA9911945B367CA3271986F54C6F7A31D9A07</stationID>
++ <name>Radio Mynodose</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1133103256AAC27E61C4EBB1104FBA47A7912A2D1FE2741E5C2A770041D85BE6EDC05B1BDA</stationID>
++ <name>Radyo D</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032560DAF105BA4EF17AEB45103D9129DFEA293409989B56A7C8952D1818DBB25042C</stationID>
++ <name>İstanbul FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123773385189517947A19528E9A57CAC0894995D3247B4AD8B5C2448FF8A873901995B2C54</stationID>
++ <name>Joy Türk</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032563063855FA8319AA8C9683B9329810FCD7AFC25153815CFF082FB5235EA02B146</stationID>
++ <name>Alem FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1133103256DA5A6933830D45EE5115C15AEBC121DA36ADCD16308642B9FE159234C4FDA992</stationID>
++ <name>TGRT FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032564A1086A845369C8F051B1FBC9F021A505A4BD4A812D2A5049418CB3EE677E07E</stationID>
++ <name>TRT FM 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032563CCD20721596677CE8F9F5590205147CA1F6D2E9F2F0C638C3C2A9138AB733B4</stationID>
++ <name>TRT FM 2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1133103256993932C327E1E6728B2991C26A117AA31507B69F280FC07885EDD4B6C94444F9</stationID>
++ <name>TRT FM 4</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032564133D26A4C9D715126DA6A05821C2C8547ADB0B6E292ED2AC5D886CD695A9AA3</stationID>
++ <name>Pal Station</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>113310325652A761312F07237C7671866B97CBE6B48547F34456FCEE48957F9607C6569023</stationID>
++ <name>Akra FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11331032560A559D71BE292F346B96164129EB47905681168232A8129E3FFDCD626BB1F9B3</stationID>
++ <name>Power FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12377345702367CB1D14908BAF372C84879F6014A9EB3C2D84388EE34A0786123B38D10913</stationID>
++ <name>Radyo 5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12377345953C28151FC597DC78EAE3322BD8C12AEAD7337873397BE9C3A350BE4A90D67C5C</stationID>
++ <name>K-Rock FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1237734609DFBDCB3B4121E1080EB6F6791918B96C2EC8453558FC2131B60AE9CB393C9FF0</stationID>
++ <name>Açık Radyo</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1237734626985324B699C0AC2C37DDE0AF723CB325AEF1AFCA5C66DC4E9DBD1DB35570F599</stationID>
++ <name>Radio Oxigen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123773464032B65D46D84318ABFEB1E880E6B9B9691E282445A5DDB69E68E8375FA73ED14B</stationID>
++ <name>Radyo Eksen</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12377346804EA0ABAE9A3C8BA69FABB4F07B268E771F7F0BD5DE98389DF80D9F800F28E128</stationID>
++ <name>Capital Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12377346942C7A5A6FDE6C5A6E1FDFF7D6F040C823E9D0DBB9923884C7AFB5200AA05F9047</stationID>
++ <name>Joy FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.6</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/turkey/izmir.krp kradio-3.5.13.1/kradio3/presets/turkey/izmir.krp
+--- kradio-3.5.13.1/kradio3/presets.old/turkey/izmir.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/turkey/izmir.krp 2012-11-25 00:48:00.000000000 +0100
+@@ -0,0 +1,501 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot_2005_12_04</creator>
++ <maintainer>leopartux, &lt;leopartux@yahoo.com.tr&gt;</maintainer>
++ <changed>2006-09-24T16:19:46</changed>
++ <country>Turkiye</country>
++ <city>İzmir</city>
++ <media>antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1159105607FA7E2E4A53A41AE958DB98159D59BEEBD842C5DF5F6322151D6BBB2A029A07D9</stationID>
++ <name>RADYO KARADENİZ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>87.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607B40A26E67591AE45B92DC144480D83B900716DBCD0608DC88818AD7C74264ADA</stationID>
++ <name>TRT-3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607DC9FC312AF54A5820F54F6D69F13B6DA7834E3EB8449B1001039ABD906FFAB6F</stationID>
++ <name>MORAL FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607EFF83345BFCEFBAEFAF1881B9FEB912ED88EBB5F9C4C28450B4A1C3430EDDCBF</stationID>
++ <name>RADYO 35</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115910560775C8F2F2262D92720199F1766DC82E20C507D29B926D7F027CBF7F7040CEEC62</stationID>
++ <name>ALEM - FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056078312289400695553F47805AC33DDE809782DE802697526527568315202F9FAED</stationID>
++ <name>SHOW RADYO</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607B5E20EC323A8E43E9553520088A61D9B0BFB32B8E61EB1A089FEF16654F633A9</stationID>
++ <name>İMBAT FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607EC1A0C9EF7B06E83D93436764017E649C1B4F90CDE9C09E1CD414EBBCD4CCCCC</stationID>
++ <name>NUMBER ONE FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607FAE384F5B5F1E3B604B5612D64BCD9450BF8385755621A2DEAEEA0B1DE1AE04D</stationID>
++ <name>SÜPER FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607E505526A4CAF0C67C9579B9DE0ADAF67664515CA85DC1780BC78EAA24A23075C</stationID>
++ <name>TRT-FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115910560756282CAC18B01D0EC3397BF5B75167B3A0B249DB684EAE9336C14A4FB71BAEE5</stationID>
++ <name>TATLISES</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115910560734851591640F1FB0B7CC04962AD8C2EF2CF8097700FCB7B1567A3630B9031AD0</stationID>
++ <name>TGRT FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607B8C8EE6D45D70363E9D5FDEEA005097D8CFE64BCFB17C55CF4997EA999CF5DF6</stationID>
++ <name>RADYO EGE</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115910560798C8FD6E5B3CFFCDAE6FF62B05835EBA661CDAD465511335D4CE222E5EDA796C</stationID>
++ <name>S SBS TÜRK</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056070F3750DB792C0D8E7A82C170894000493F167FC34457EA674E4C5E918F36A3C7</stationID>
++ <name>CAN RADYO</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115910560752926AA64A6B4EB4BF08023558E67F3934CA10086150EED0E6D724AB2D0D7F61</stationID>
++ <name>BATI RADYO</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607C2B3A02FE39ED42C6C500CC73BC8F3348B3B0384180C28440220F9BCFBC95EB0</stationID>
++ <name>RADYO HERKÜL</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056073C37C0249646B9579684894FCBF257164C13EC62E959F45959314281D8292F84</stationID>
++ <name>DİNİ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115910560748518A040B4D49C702A8234BA8B2F7F7535D057275B82E35B774E7448977B1A8</stationID>
++ <name>TRT</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607E4D0917B5CC0C5C73B223F6F22D7027E88EC628B76F5714628215FDA0DC0B455</stationID>
++ <name>ROMANTİK RADYO</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056071310D735CBD17F34FC9E0796AD7224AA70652439B4373BCA9FCCDC28C5C8F02A</stationID>
++ <name>NTV RADYO</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607C63D293FFC07F5D40C466CBC59E902DF12D5053986DF725ECA46E9C1E6A2B5B9</stationID>
++ <name>RADYO KLAS</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607E2AA531318CED2328BEFD30BE86DD8AB6C938D99A12E140D9DAFBF5FFFB5CA16</stationID>
++ <name>KRAL FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607F7EAB9637AC2DEC25EF87FC9C4BA3E6053E105E3267439970F74E23271C9A94F</stationID>
++ <name>KORDON FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056075AE767CC1742EE410890A3434BF841DE4CCF8E04384C668F48FCF7A295EBB241</stationID>
++ <name>AKRA</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607E23C551FF00DA5D3B6900CFC96A53967A5A3D06B321E20F272B10D52B66D3A9D</stationID>
++ <name>METRO FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607C29AEC7E64F2BD94D8F90B69DDD92AEF6F8219916B6A4C1D6370AC3986BFE78A</stationID>
++ <name>RADYO ÖZMEN</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056070AE78D419999974A013C8B1DE244AE6F8AB229050B4BFC3EF2A3C8E1818AECDD</stationID>
++ <name>RADYO ÇAĞ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607A0554A722F050281FB640527CD582CD086A783D05314DF7DA99868FB51027C6E</stationID>
++ <name>BEST FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607261BF429647FEC9AF5F182BECE1ABFDE5E6841AB4751779F19AA4E44A48C2064</stationID>
++ <name>TRT RADYO 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607DC02FAA3C60B19BF7D463FE4E57FF6D1754E336F2EB5C09269A0C4CC9FADED7F</stationID>
++ <name>KAPİTAL RADYO</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115910560718F41B55DA2C22C8CAFC7E646FB818DD5F3FA899E4B716D0B081E9783EF2EB1E</stationID>
++ <name>POWER FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607AC13C9B2E73B51979ADC9E07FE4E975B0EB34CEACEEDCE31338BD8CEAFC1565E</stationID>
++ <name>POWER FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056070DE8C2C54FC76A0CE7A5804E004F6843E0993FF66783850FD14B5A27B9B06B00</stationID>
++ <name>TRT</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607B5377E3FDAE59A8798658C4F60F97AF71D8B83DCF21BB780E63EB31AAB6A9F6A</stationID>
++ <name>FM İZMİR 101</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607A2D18FDB42A8746E13B11517D5399E0C3E97810CA2137BE97264E6174A1C5F2A</stationID>
++ <name>RADYO 7</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056070AE74CCF17E01A748B57E7FB9B90E1CBD7832D22D52808F73DB4B74FF73A1B90</stationID>
++ <name>BUCA FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056078A9AA84174307D34A82FB4934AF5AA9FE8D127E21ED075EEDC81D3B10EF660C3</stationID>
++ <name>YAYIN</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607866A5463E5CDE0B629E0448E2019F9DF6BF9FF6CAB3E5CC01371F184743D6161</stationID>
++ <name>YAYIN</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607F161CDA7E8B7716584D06C42DCBC31ADEA54E41A89E5533C7C755FBD01457233</stationID>
++ <name>ÇAĞRI FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607E3DB104F21C6D584C2470DA6757609FCB5F041BC8DF37995D178CD501CD6E3E7</stationID>
++ <name>RADYO KLAS</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056074FBE7B317764E18E47444F0C5605B7A4AA0E6E8C48E995846ED16A9D447F5DF4</stationID>
++ <name>KISS FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607813B68DE1187BC92E8443057F779259412E0F5C5A19B6F48234809F58ED80E74</stationID>
++ <name>RADYO SAHİL GÜVENLİK</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607FDD595CBC65F79B5308FA63D07B3492AF46849A8892EECF9D50907E5A49F75C3</stationID>
++ <name>RADYO MEGA</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607FD0B95759823566EF1414449C2B4A747605E9C9994A559E3DD3AE72B603ED397</stationID>
++ <name>YILDIZ - FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11591056072E1066F35321AE34E12FEEF7B0EDBBB65CB33830D9026DFC936049285A0F7F90</stationID>
++ <name>RADYO İZMİR 1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607F87CE144CC085AE076248CE7689A592571F142D16E26261229BE68BD99E69C0F</stationID>
++ <name>POWER TÜRK</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607957DCEA71BC3720EC830BA271A93149816AF306870516E1B4E5F62EFD22DC213</stationID>
++ <name>RADYO MAYDANOZ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>115910560765128416B0A5B64C0F1ACD2416FA82F09BC57C729FA982D1333C43016761F906</stationID>
++ <name>RADYO 5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607ABADBA5D050666CD5490144F32CC52C8DFCB1697610B885FA4B3E4ACA0489C5D</stationID>
++ <name>MARMARA FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607B430DF02D6E1DF350808F9BB1259A2DA0C0610EF236A642DC8EB6015DE926E2B</stationID>
++ <name>RADİO SPORT</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607DEFBE0652474F7C9279D33917322527B9B49AB91D0F5BA571B38BCFCEC5746D4</stationID>
++ <name>DEMOKRAT RADYO</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607D69CD982A9991158EF55CF55931CE256E36CB987D47EE8F96BAB7599DF323996</stationID>
++ <name>RADYO GÖKKUŞAĞI</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1159105607C5C1733FC47A4D8400C1FE885FFF45C80A378DC50971AB47AA459209E7B188B9</stationID>
++ <name>RADYO DOKUZ EYLÜL</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>108</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/turkey/Makefile.am kradio-3.5.13.1/kradio3/presets/turkey/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/turkey/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/turkey/Makefile.am 2012-11-25 00:48:00.000000000 +0100
+@@ -1,10 +1,14 @@
+ SUBDIRS =
+-EXTRA_DIST = "adapazari-antenna.krp"
++EXTRA_DIST = "adapazari-antenna.krp" "istanbul-antenna.krp" "izmir.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/turkey/"
+ $(INSTALL_DATA) "$(srcdir)/adapazari-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/turkey/adapazari-antenna.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/istanbul-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/turkey/istanbul-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/izmir.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/turkey/izmir.krp"
+
+ uninstall-local:
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/turkey/adapazari-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/turkey/istanbul-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/turkey/izmir.krp"
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/ukraine/kyiv-antenna.krp kradio-3.5.13.1/kradio3/presets/ukraine/kyiv-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/ukraine/kyiv-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/ukraine/kyiv-antenna.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,285 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-1.0beta3b</creator>
++ <maintainer>Igor Shavrin shih@i.ua</maintainer>
++ <changed>2007-09-24T01:34:37</changed>
++ <country>Ukraine</country>
++ <city>Kyiv</city>
++ <media>antenna</media>
++ <comments>Generated from http://www.proradio.org.ua</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1190568285E2B7D4E87359DE08E1C16FF2A41E2CC4B4079B9D587F66F9DAE1943C32413C48</stationID>
++ <name>1+1 TV</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568345ADD24685A544861E9BB16C04C9E3D475CC7A53B57AB349052F68D130F313C4B1</stationID>
++ <name>Retro FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190585238FF5CDED1F6E49D979E1C6E8586464ABC5963D3821EE8A2700E280242DBEAD939</stationID>
++ <name>Europa Plus Ukraina</name>
++ <shortname>Europa+</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568386558A019551B727BAA9B7E6597371BE9B786A7FA4D579B90CE762BB193AA7B441</stationID>
++ <name>Radio Kontinent</name>
++ <shortname>Kontinent</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11905684061104A7FFAF246E4D84AA2387207120AA39C33D45E589BB89055F4F7FDEFB82DD</stationID>
++ <name>Love Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11905684242BF5811F0423AFCB4073E9C8A3CFFBF24665B4F909CA9A4F99CBD5BBC036BE3B</stationID>
++ <name>Jam FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119056843858C509C9C78DF4C47EA8A8DAC2C52B0A337905BA53708A22DD133B01C0B1B824</stationID>
++ <name>ERA FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568357D10207D487D67CF384A86594ECAFE68E392EFCA113BFF7E46CEB0D8B931DAFB8</stationID>
++ <name>HIT FM Ukraina</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119056848271CC0E7F7A1FBFBCF9199138ED8A9A0C523EA5108ABA25E1307C126E7BD74401</stationID>
++ <name>Renesans</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11905684983370750F90BD5C902D66EBDFE5296BD5651766EFD709E4704B22548DBDAF7308</stationID>
++ <name>Radio Kyiv</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568511F84481912290B9578CF4B8E7919E6638815FCD4570430CD1B0DEB4C711F64BF0</stationID>
++ <name>Russkoe Radio </name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190585757834E40A75A390555FDAF2FD8F879BE84C1A4200B48576DE998BCEA2FC5E62DF8</stationID>
++ <name>Nostalgie</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568560F0EE4F93BBB53A68B0281C926A5BD23C335B5D1D329947E2C0A52DAE396749C7</stationID>
++ <name>Radio One</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11905679324E90F6002986D3368F12F1CFEE67E990F11A9C6DEE84CB5AF68299405FD665D2</stationID>
++ <name>Gala Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568578411C4F3F6FA8981F3F2BFD5CCA61C19A25F35BEE712D3C71E030FACD22E99B0B</stationID>
++ <name>Narodne Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11905686031692090120A5CCB19D0C832CE9CBAF0F82401488F5D50998B59251BE3ABED287</stationID>
++ <name>Melodiya</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119056861728940CAC20705F67C7F2C856BBA6848E21899374B76A38EBDB313B8591A9686B</stationID>
++ <name>Music Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119056862470D26DB3B12FED7B8ED2DC4508E163BD9BAABA42D048F56B213F13C597D69025</stationID>
++ <name>Garne Radio &quot;Shanson&quot;</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11905686391B87595BB9BEC38746C9C3E947AA6D55A0A4C552772A10E0F80CE500953927FC</stationID>
++ <name>Prosto Radi.O</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568655B5EB86D24DD802856EC39BBEBC51BF22050169329E05C2F860A484FBD6313DFB</stationID>
++ <name>Lux FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11905686799F70922A7C9F9FD1EB52C97F2151C5AB4821C2C3BAEAB8A665CC01994442666C</stationID>
++ <name>Radio Rox</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568692FD2A3434E88AE180B7DDD0B4F56A5E5AE51759D6F3F56DF9CC27718AFA269676</stationID>
++ <name>Radio Sharmanka</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568717454DE097A03235C880EACCC7C40BDDBFC2EB270C88B8734B91595DF4BA8D5249</stationID>
++ <name>NRJ Hit Music Only</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119056872687EECA44E2309197D198412A1887DE7F0B2449EF314EA607FF35B5F170FC7A37</stationID>
++ <name>Ukrainske Radio 1, Promin 2, Kultura 3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568745E5015664A7B31B09C9613B79F8EC8962BF2CB26175427DAF927F844A0287C479</stationID>
++ <name>Perets FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119056875609A0A52CFBE42B09E02389F481B47B3A0F4788D7FA244C0348D39A55E58022B0</stationID>
++ <name>Dorosle Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>119056876964244E846B8E8C747093DD99C135F11B0CD12BCD83B3425453F00E76FE83686E</stationID>
++ <name>Dance radio &quot;Kiss FM&quot;</name>
++ <shortname>Kiss FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568784E96F88515B6C5A632D94FD3DDA890DF833807614BA2B3B48B73E6FA2A47D2CA1</stationID>
++ <name>Europa FM Kiev</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>11905687949FDD940404BDB04A08D1D424537F3BA1B276ADDC688AC7B08BA7F8509C9DF904</stationID>
++ <name>Auto-Radio Ukraina</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1190568804C04E9CCFBED42FE3B715B52A019A58DDA156C4E489D2F782F2E63C96D1DEF49C</stationID>
++ <name>Nashe radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/ukraine/kyiv.krp kradio-3.5.13.1/kradio3/presets/ukraine/kyiv.krp
+--- kradio-3.5.13.1/kradio3/presets.old/ukraine/kyiv.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/ukraine/kyiv.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,274 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer></maintainer>
++ <changed></changed>
++ <country></country>
++ <city></city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>119273391379030B77DD389261E2FBA0A991B6701AF3A5862288308F40C544DA814C20062B</stationID>
++ <name>Перший Національний</name>
++ <shortname>ТБ1</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>65.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193316494B73351D34EF40803093A58359F67A37F7E8ED38E149F13D094A7905E06E42474</stationID>
++ <name>Українське Радіо 1</name>
++ <shortname>Радіо1</shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>68.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933165321752787BF1002D79ACE570EE9B87CCBBCF246E72E419A7BE774439E089F5D44A</stationID>
++ <name>GALA Радіо</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>69</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193316570E34F57BD024F9CB7EF6C51C4F87FBF1411D36A02B804C5087321F7D3DD0ECA90</stationID>
++ <name>Радіо &quot;Промінь&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>71.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933167682F7B1489DDF8BA166B64AEAC020BD9AB32BC286C12CCABDBEA80A35B5E43BD6E</stationID>
++ <name>Студія Майдан</name>
++ <shortname></shortname>
++ <volumepreset>1</volumepreset>
++ <frequency>72.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11934927917C3A29AD199B030CBC096B56CF0305BA7D65E112F492AB599F562F27493D6107</stationID>
++ <name>Радіо &quot;Культура&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>72.86</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11934928943D70A4E7FE3DAF3F5BF2705C3969F3B99BB6C0553CA824E1F68E5EA9F1A8C884</stationID>
++ <name>Радіо &quot;Ренесанс&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>73.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193316628EC33AA5B9929BF4C2631419F0D92BD2F7383D5D729D88DBAC41A26E508A85A7A</stationID>
++ <name>1+1</name>
++ <shortname>ТБ2</shortname>
++ <volumepreset>-0.01</volumepreset>
++ <frequency>91.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193316720AA067FCA76F0C1D40116F62296E77CA12F35FD747922056E9A187C9EB78BB8B4</stationID>
++ <name>Радіо 5 - Ретро FM</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193316785C490D8F8B28F9162A65D003FFEF4671633A4A077142D6B289FB47C3FE3EC79CA</stationID>
++ <name>Радіо &quot;Europa Plus Україна&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119331681445D8A1D12737761FAC73F3EBEDE3D113C96F8D7A3072F6BA50107BEC2E20C561</stationID>
++ <name>Радіо &quot;Континент&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193316826104C89BB1C8D151978F203860D8365D823887E838A590C5647A7888B4EA98EC9</stationID>
++ <name>Love Radio</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.2</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933168995119FD101E5D954F34B599ABB081A108B810AF992A1373662764B3D225A1BCB6</stationID>
++ <name>Радіо &quot;Джем FM&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11927339390C925CC6F4D2FFC1A39CB31E29BD522BCE8D9ABA40F583629678876816CE2A98</stationID>
++ <name>Радіо &quot;ЕРА FM&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>96</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933169254CD9D9791B9F273C4813420DC8FC90514E836161B3CDC2F991AC54E6BC3A28A5</stationID>
++ <name>ХIT FM Україна</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933169780A493D079BFF56533C5053CEA8FE02353BD90310F14495816E68CF86A74DF015</stationID>
++ <name>Радіо &quot;Ренесанс&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119331699790CF2CEFAC144AC8DE31A870920A047FC7C6032AA36CE108C2F8650447949673</stationID>
++ <name>Радіо Київ</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>98</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317011853A0311E4EC1F465CECA08BAB32174E31A836E55DF7CBA4888BC6F5F5A0C127</stationID>
++ <name>Русское радио Україна</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>98.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317033B598FBEDC8EABE2B9D942948474DE8A883AA4C7F8A67D09A3E95A76EE9173005</stationID>
++ <name>Радіо &quot;Nostalgie&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>99</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317086C9C8D6C58704A210A165F228AEC16247F8B762407EA5310529D31452E916770D</stationID>
++ <name>Radio One</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317113A97FA7ECBFA63810E2A2057D466C163AFA77A84ED004D6B68D24C64D5B58F260</stationID>
++ <name>GALA Радіо</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>100</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933171496457288D14D60DC35B0881F57DDF96C69A4A11E1DB04F13586FAF5E6D864C2DE</stationID>
++ <name>Народне радіо</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.45</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317177C554C7CF311160E3FD986FC8CAA7BDA7710B3CB1558E3BF482BCBBABE7F5653C</stationID>
++ <name>Радіо Мелодія</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>119331719696B32B0FC85E58AA2DBE73FABAE6E48F944E6DDF47149319834D58BF72709178</stationID>
++ <name>MusicРадіо 101.5FM</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11934929310E6587D3850F1271122E6F0EDB876906C8322E0AC9D7420EBFE33412288DB24B</stationID>
++ <name>Гарне радіо &quot;Шансон&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317221249DCB1C7B41AD3B55410BE79B37A6A0255EFE17FCD590BF2555F1EBBA79696B</stationID>
++ <name>Просто Раді.О</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317243B36E1F3F4F27D1638AD01331ABB4A2CF35E3614E64E54BB245A8BF4646FD9098</stationID>
++ <name>Люкс FM</name>
++ <shortname>Люкс FM</shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317469ABB39852E8DC69F360F2D9D920193307D7333BE3DC2B6A661F796B316709FEA1</stationID>
++ <name>Радіо РОКС Україна</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317255835DCE993DBAD5D6179A124D84301373F933B474A95849C1B29CA26B416D6271</stationID>
++ <name>Радіо Шарманка</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933172801EACE4A7FE3F78FCAE40F4C93C5C3C4E44F57967CD206D7567429A11898B05F7</stationID>
++ <name>NRJ Hit Music Only</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933172951418D970E5224A322D5D3CDE884E17FF9A77AFEE45038A700C283BCDF4546971</stationID>
++ <name>Промінь</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>105</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193493005253C16A430195E9F18969767B0A2C3F2ED37DF1A2C9307977481F7848345F23B</stationID>
++ <name>Радіо &quot;Перець FM&quot;</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933173102BF63585CC18E76ECAE440C6EF690DDD1F564FC7F98B900A640DA0F9FAA97FEB</stationID>
++ <name>Доросле радіо</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>106</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933173320EB03AC65D7E9302C66AC44B173E19A37F5075E812B5C13413B3E38E6AED2244</stationID>
++ <name>Dance radio &quot;Kiss FM&quot;</name>
++ <shortname>Kiss FM</shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193317353991E196D4840CAA699A52C9560081AC37D77CC34073594673069F8B347017151</stationID>
++ <name>Радіо &quot;Europa FM&quot;</name>
++ <shortname>Europa FM</shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>107</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11933173660CA24F98EDC6DE77443FE71898A479B6BACAC5FE7B85C6A08CC96714689CE881</stationID>
++ <name>Авторадіо-Україна</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1193462232F3BBCE734B7DE4DE9B2158DC76B0AB5A88910A99720CFEC43C02F16E87E22E23</stationID>
++ <name>Наше Радіо</name>
++ <shortname></shortname>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/ukraine/lugansk.krp kradio-3.5.13.1/kradio3/presets/ukraine/lugansk.krp
+--- kradio-3.5.13.1/kradio3/presets.old/ukraine/lugansk.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/ukraine/lugansk.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,143 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Igor Lobov &lt;ivl@front.ru&gt;</maintainer>
++ <changed>2009-03-09T15:03:15</changed>
++ <country>Ukraine</country>
++ <city>Lugansk</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1064330466317A41A714F7A3C70B22A8F4F88EFF1AD5870570230FAC49A74C6528C435FC32</stationID>
++ <name>Люкс FM</name>
++ <shortname>Люкс FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236531204D675F1E3913FCD945685B736986EB65B4576DBEF430FA337D3355E6655114EC7</stationID>
++ <name>Шансон</name>
++ <shortname>Шансон</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236532766B6BB266A8C8AF15F1FA2F7A1F4461D5DE0E36260BD220F78729380ACA3406C9B</stationID>
++ <name>Ретро FM</name>
++ <shortname>Ретро FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123652999119E06577B29B9481F49463944679117D38DE47AB2BEE399E28B27C513527092D</stationID>
++ <name>Шарманка</name>
++ <shortname>Шарманка</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123653079854CDC1FA489FD9BC0C9018688138439EF1748E7BAE978D1CF37CEE1DC221B809</stationID>
++ <name>Мелодия</name>
++ <shortname>Мелодия</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236530818BA5A7BD0D0F5C8054A78EE43566C46EAABF99A316503E0B994C39788CCE173DC</stationID>
++ <name>Авторадио</name>
++ <shortname>Авторадио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236532798123231CCB6DC001884D40CE507985DC23093DE1B72397A6D81CD9D2DC6BA286E</stationID>
++ <name>М-FM</name>
++ <shortname>М-FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236532812AB511522487A6B437E83DB867BD18E756C18FE228864BCE14210651F5FAC9F80</stationID>
++ <name>Русское радио</name>
++ <shortname>Русское радио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236530838F517539CE7C5DFC59F97A7B561EA5F01A545D5142C6F3D85CBA980B86B55AE19</stationID>
++ <name>Пульс</name>
++ <shortname>Пульс</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123653086143C3C71D4F8FCF61645F0655E43058A049124EB95D09189797463C0A6DA402F1</stationID>
++ <name>Хит FM</name>
++ <shortname>Хит FM</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236530899DE7E038C4D62B940D7BEF4D05B90384E131BE490EEA2AEEF870D8160EDCB96B1</stationID>
++ <name>Европа +</name>
++ <shortname>Европа +</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123653093974B772F5351BF4CE172C68E24EF386EB62BEDE1A1180BB09765AB49F261B2A1C</stationID>
++ <name>Эхо</name>
++ <shortname>Эхо</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123653099504B71EFC17B5F7F3EBDE2EA0617249C65BB59B7741BF1F3D849E26650E9F2C3C</stationID>
++ <name>Наше радио</name>
++ <shortname>Наше радио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1236531097D21AAB0774E01FCA1CFF26D1EF66074A64E316210A998AD806A60DBB741F0E18</stationID>
++ <name>Гала радио</name>
++ <shortname>Гала радио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123653114112A4E959FB3005DF5381500039A1F9FC4AC640902606A73982B3F0532CDBEFB8</stationID>
++ <name>Скайвэй (KISS FM)</name>
++ <shortname>Скайвэй (KISS FM)</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>123653282541358FF62E3196D45E6B221CB959E72B914B0D929AA066ADC7D49F90F6B1F7F6</stationID>
++ <name>Радио ЭРА</name>
++ <shortname>Радио ЭРА</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.3</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/ukraine/lviv.krp kradio-3.5.13.1/kradio3/presets/ukraine/lviv.krp
+--- kradio-3.5.13.1/kradio3/presets.old/ukraine/lviv.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/ukraine/lviv.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,160 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Volodymyr Petlovy</maintainer>
++ <changed>2008-11-30T16:59:00</changed>
++ <country>Ukraine</country>
++ <city>Lviv</city>
++ <media>Radio</media>
++ <comments>All stations in my city</comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>122799021780C192F2D1A07BFE06D065A65E515F0C739CDFCD1AA6BCDF826A4F302ED9C252</stationID>
++ <name>Національне Радіо</name>
++ <shortname>Національне Радіо</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>67</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122799022189C2C08CBAB32132F909F1D32133FAA5D8B64531FB163C2274EC9D739AC3F934</stationID>
++ <name>Радіо Промінь</name>
++ <shortname>Радіо Промінь</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>68.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12279902652D4188864C39EFFC4FF5477D13D243F6B8F3C8EAAF74C37941251E9D7739B29F</stationID>
++ <name>Ера ФМ</name>
++ <shortname>Ера ФМ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1227990268237C351DE729E01F7FE8A905B3C6D2C9AB20955F906700DA9DB36C079BCC623D</stationID>
++ <name>Еко ФМ</name>
++ <shortname>Еко ФМ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.6515</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1227990272C61931B94C013586810D19FA1F67FC13C5BD6CCB00B09353D41AE2C9FC113D30</stationID>
++ <name>Радіо Ман</name>
++ <shortname>Радіо Ман</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122799027388059A3A027955641E923A4867BC6C48355F7D08781AF8BE81AD0F9C220A1815</stationID>
++ <name>Love Радіо</name>
++ <shortname>Love Радіо</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12279902969752ED3FD1DEC7E32F6B113D4E98DFD955287B2AE274B75B0E87235E66367D43</stationID>
++ <name>Львівська Хвиля</name>
++ <shortname>Львівська Хвиля</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>100.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1227990297623905720B162E2F976651CAB458673C653A82D4A4C6DA8909E9B38A9B3B867B</stationID>
++ <name>Гала Радіо</name>
++ <shortname>Гала</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1227990300A33527E201DA266374163FB150CF5CA19161D3980488E92D3BDD8086BA9F7970</stationID>
++ <name>Ретро ФМ</name>
++ <shortname>Ретро ФМ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12279903043A16C0F1AABD2687E1E3BE3FD9E65EC3F3194117FAB45A4F9B4C3374658E6720</stationID>
++ <name>Радіо One</name>
++ <shortname>Радіо One</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.902</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1227990305979E314884161454A31F33EC95684D57F542C0C3E78721F4995C4BE15AE0FFE4</stationID>
++ <name>М ФМ</name>
++ <shortname>М ФМ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122799030605312B35769EDF40268CFB4824B5C1B88C9A9DC0A5AFCB729A3A8E0E78693D04</stationID>
++ <name>Радіо Люкс</name>
++ <shortname>Люкс</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1227990308187904A3FD5401A07636FA3D523DF6D59A2C25B950519986D576180F9AA897CB</stationID>
++ <name>Авторадіо</name>
++ <shortname>Авторадіо</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12279903109883D98CC3DF88D59F8574CCD0E71A9B9A23180889A31A979703D600022E47A9</stationID>
++ <name>Наше Радіо</name>
++ <shortname>Наше</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12279903121852B0BB31EFCC3B65D74FBC51A71F89C8D83D65FE6C7BEFD78DBD8B0215A47E</stationID>
++ <name>Радіо Незалежність</name>
++ <shortname>Незалежність</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>122799031353196770DF4ED04D9D1C1CE3BB21C661B7E58D45F0A9675601C99746619519F6</stationID>
++ <name>Радіо Мелодія</name>
++ <shortname>Мелодія</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.103</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/ukraine/Makefile.am kradio-3.5.13.1/kradio3/presets/ukraine/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/ukraine/Makefile.am 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/ukraine/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,17 @@
++SUBDIRS =
++EXTRA_DIST = "kyiv-antenna.krp" "kyiv.krp" "lugansk.krp" "lviv.krp" "nikolayev.krp"
++
++install-data-local:
++ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/"
++ $(INSTALL_DATA) "$(srcdir)/kyiv-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/kyiv-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/kyiv.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/kyiv.krp"
++ $(INSTALL_DATA) "$(srcdir)/lugansk.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/lugansk.krp"
++ $(INSTALL_DATA) "$(srcdir)/lviv.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/lviv.krp"
++ $(INSTALL_DATA) "$(srcdir)/nikolayev.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/nikolayev.krp"
++
++uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/kyiv-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/kyiv.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/lugansk.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/lviv.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/ukraine/nikolayev.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/ukraine/nikolayev.krp kradio-3.5.13.1/kradio3/presets/ukraine/nikolayev.krp
+--- kradio-3.5.13.1/kradio3/presets.old/ukraine/nikolayev.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/ukraine/nikolayev.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,150 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0</creator>
++ <maintainer>Vadim Bu &lt;panoptus@gmail.com&gt;</maintainer>
++ <changed>2000-01-01T00:00:00</changed>
++ <country>Ukraine</country>
++ <city>Nikolayev</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>1281291324881640300A9656B36F2C8FB7C0CBF62F9876BF91EF206ADCD406E3854756</stationID>
++ <name>ТВ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>65.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128129138506DF5A35A7530F941618DD6AFE504718D2EC8394947C3E26F33BCAD769D4</stationID>
++ <name>Первый канал укр. радио</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>69.85</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12812013750E66C763E47D9FD3AA8F5A5C0833B02B80757ABC86852CFB2538D8EE1769</stationID>
++ <name>ХитФМ</name>
++ <shortname>ХитФМ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1281201553DF8B2D6C7D312C77A4B85AC6D831ACA3FD386E2ACE23ECD292C52CAD4BF8</stationID>
++ <name>Радио Алла</name>
++ <shortname>Радио Алла</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1281201897F0FEDF0D65FA7843847268C92807EC96BDFE3A601F49B2C40CC3D8256369</stationID>
++ <name>ОкФМ</name>
++ <shortname>ОкФМ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100.8</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12812014665AC9DD7F71ABF382654AA324D618DD173C0CD43166B35167FFA6D5977CEE</stationID>
++ <name>Русское радио</name>
++ <shortname>Русское радио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>101.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12812015256E6C171F895496A945901A91FF91C92E2F37800C256AB29AB1C5AAE8D9BF</stationID>
++ <name>Кисс ФМ</name>
++ <shortname>Кисс ФМ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12812015381A12F5CEB14337821BD569BFB00F016CF21617F60B718F9C8E70E9563AAC</stationID>
++ <name>Наше радио</name>
++ <shortname>Наше радио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>102.75</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12812909149BEFA3A4DD95C41B19CE8110C3BE638D33F712C45D21272C119512A1D552</stationID>
++ <name>Авторадио</name>
++ <shortname>Авторадио</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>103.35</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12812898487D26BFE955AF336F67A743540DBB78557C3DC79C18FB7281BE35CB6ED8A2</stationID>
++ <name>Взрослое</name>
++ <shortname>Взрослое</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128120125873F1C0A0B9F8F7844149BB02E340FB8B117B27EB34E755BF77D67BAD5A08</stationID>
++ <name>Просто</name>
++ <shortname>Просто</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>104.6</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128120159508376D674AB7C609B1B38CFE0592A3F53AA7C2F2E5D369514888DF9BC255</stationID>
++ <name>Мелодия</name>
++ <shortname>Мелодия</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>128120161385DDA12FD03D03056C8707135DDC5D04AF9D8E0B91E5E1AE68BC8F8A0163</stationID>
++ <name>Ретро</name>
++ <shortname>Ретро</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>106.4</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1281201626F402B08396B731E230EA16EFE90C3889ACF99F4E2E4DC4AB445D980141FD</stationID>
++ <name>Люкс ФМ</name>
++ <shortname>Люкс ФМ</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1281201639D78071860C8AB2ED93CB078E4EEDDD2B02620617AE124B5F9AB0F0D66A7E</stationID>
++ <name>Эра</name>
++ <shortname>Эра</shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>107.7</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/usa/Indiana-newburgh.krp kradio-3.5.13.1/kradio3/presets/usa/Indiana-newburgh.krp
+--- kradio-3.5.13.1/kradio3/presets.old/usa/Indiana-newburgh.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/usa/Indiana-newburgh.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,193 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-1.0beta3b</creator>
++ <maintainer>Lester Hinton</maintainer>
++ <changed>2007-08-19T22:25:00</changed>
++ <country>USA</country>
++ <city>Newburgh, IN</city>
++ <media>FM Radio</media>
++ <comments>Evansville,IN area Stations</comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>11875741170887A5CACEB53D24EC0C7E6446F3A2C6BEBFD9D2EC483839162385C9C7C4EB96</stationID>
++ <name>WABX Classic Rock</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>118757413136CB812379364A402F733E1BEDC25E60D77645F00831F07BE96FF30888324EBD</stationID>
++ <name>Jack Fm</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.15</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187574832B2142319AC87045E95B530F52CA9F24B6E980A33BD87DFD04A6360A7B9768BC9</stationID>
++ <name>Kiss FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11875754000F53E03278CB5C0450067CFDBE79C3BD498890A966610D9A621D2E872821D056</stationID>
++ <name>CJ Classic Hits</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187575470E6F0B059EEB24BCA55192507774F5AD1F0ECB78742AA260B767B22064D067140</stationID>
++ <name>WJLT Super Hits</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11875757671EBA54F567804703E6B930BF68D50673086F33AFCEB24287086044932E622792</stationID>
++ <name></name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11875758930AB9977E06DC0FA833EF912E98B3B9E37B31D6DA9CC5A69E229955C315BF70A6</stationID>
++ <name>WIKY Evansville,IN</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>118757661829503869856F302C684C9C601EB4CD0CE53178A44C81955A7C7807C43E92A7A9</stationID>
++ <name>WGBF River City Rocker </name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187576723EC47FF2944185BF9C69026961B2CB67841231B5BA5E097BEA9A066318DDD386C</stationID>
++ <name>WLME Lewisport, Kentucky</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187576885BAF94B352929D819FFDA48B3E2CC49FA4810DB9479760A951E1877585E64B8C9</stationID>
++ <name>WQXQ 101.9 FM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187577250796D54BAB65FF0838225F239224D8F4C101895811597D16E8B5779F88F0AE4D4</stationID>
++ <name>WBGW Religious Fort Branch</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>101.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11875778905CB94237C96056BEF23AC744D8C26E97ADC80A26800757CC4AE54965AF744463</stationID>
++ <name>97X Classic Rock Owensboro, Kentucky</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187578481AF82158EBA23A77E7F9BC8FB829E837A56979F8466923C39C8D6A35819F8B94F</stationID>
++ <name>Hot 96 WSTO Owensboro, Kentucky</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11875787904D7AE91F09E8FE5B81045E192A2899C1650FDE2FE93ED0FC3FAE6F1249075FFA</stationID>
++ <name>Classic Rock</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>94.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187578936195A8EE8BC81E698E18BA81AC866D658B940BC852EFB48F6AE04067439D24866</stationID>
++ <name>WKTG Power Rock Owensboro, Kentucky </name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187579126CAB93F22412297E9BECBD5D4B65207F2223EDE413AE49F6B210CCFF9DB58BA58</stationID>
++ <name>WUEV College Evansville, IN</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187579275AFEB205731B134D9C4ABB89CAAFE5EEBD97C251C883F31DDB87A5558BACA39D4</stationID>
++ <name>WVUB Vincennes</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187579552DAB2CFE1FF6469FF4E9862013915EBF64AC189171BD06C156F12474A0C7C248B</stationID>
++ <name>WPSR Evansville, IN</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187579681CFB4798BD9824971407C55F42514477C425A8D365844185D328C1A31F79CB744</stationID>
++ <name></name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>118757983754300B648DF30B8BCCE734305204B4F33FC53CA4C30AE14FF6A750C22896CD00</stationID>
++ <name>Western, Kentucky Public Radio</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1187579929C4932368D87672C2DDE6B8E396BC108893903533E0567703B2F4F8E88D3DD9FC</stationID>
++ <name>The Bash Wabash Valley College</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11875800416C2FDE228F9D079430B49B1B156D28B464F36A0281D09DD1DEB2A1A62F4D8021</stationID>
++ <name>WNIN Public Radio Evansville,IN</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.3</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
++
++
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/usa/Makefile.am kradio-3.5.13.1/kradio3/presets/usa/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/usa/Makefile.am 2012-06-26 02:49:50.000000000 +0200
++++ kradio-3.5.13.1/kradio3/presets/usa/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -1,390 +1,395 @@
+ SUBDIRS =
+-EXTRA_DIST = "Alabama_am.krp" "Alabama_fm.krp" "Alabama.krp" "Alaska_am.krp" "Alaska_fm.krp" "Alaska.krp" "Alberta_am.krp" "Alberta_fm.krp" "Alberta.krp" "Ann Arbor (Michigan).krp" "Arizona_am.krp" "Arizona_fm.krp" "Arizona.krp" "Arkansas_am.krp" "Arkansas_fm.krp" "Arkansas.krp" "Austin.krp" "British Columbia_am.krp" "British Columbia_fm.krp" "British Columbia.krp" "California_am.krp" "California_fm.krp" "California.krp" "Chicago-antenna.krp" "college-park,GA.krp" "Colorado_am.krp" "Colorado_fm.krp" "Colorado.krp" "Connecticut_am.krp" "Connecticut_fm.krp" "Connecticut.krp" "Dallas.krp" "Delaware_am.krp" "Delaware_fm.krp" "Delaware.krp" "District of Columbia_am.krp" "District of Columbia_fm.krp" "District of Columbia.krp" "Florida_am.krp" "Florida_fm.krp" "Florida.krp" "Guam_am.krp" "Guam_fm.krp" "Guam.krp" "Hawaii_am.krp" "Hawaii_fm.krp" "Hawaii.krp" "houston.krp" "Idaho_am.krp" "Idaho_fm.krp" "Idaho.krp" "Illinois_am.krp" "Illinois_fm.krp" "Illinois.krp" "Indiana_am.krp" "Indiana_fm.krp" "Indiana.krp" "Iowa_am.krp" "Iowa_fm.krp" "Iowa.krp" "Kansas_am.krp" "Kansas_fm.krp" "Kansas.krp" "Kentucky_am.krp" "Kentucky_fm.krp" "Kentucky.krp" "los-angeles-antenna.krp" "Louisiana_am.krp" "Louisiana_fm.krp" "Louisiana.krp" "Maine_am.krp" "Maine_fm.krp" "Maine.krp" "Manitoba_am.krp" "Manitoba_fm.krp" "Manitoba.krp" "Maryland_am.krp" "Maryland_fm.krp" "Maryland.krp" "Massachusetts_am.krp" "Massachusetts_fm.krp" "Massachusetts.krp" "Michigan_am.krp" "Michigan_fm.krp" "Michigan.krp" "Minnesota_am.krp" "Minnesota_fm.krp" "Minnesota.krp" "Mississippi_am.krp" "Mississippi_fm.krp" "Mississippi.krp" "Missouri_am.krp" "Missouri_fm.krp" "Missouri.krp" "Montana_am.krp" "Montana_fm.krp" "Montana.krp" "Nebraska_am.krp" "Nebraska_fm.krp" "Nebraska.krp" "Nevada_am.krp" "Nevada_fm.krp" "Nevada.krp" "New Brunswick_am.krp" "New Brunswick_fm.krp" "New Brunswick.krp" "Newfoundland_am.krp" "Newfoundland_fm.krp" "Newfoundland.krp" "New Hampshire_am.krp" "New Hampshire_fm.krp" "New Hampshire.krp" "New Jersey_am.krp" "New Jersey_fm.krp" "New Jersey.krp" "New Mexico_am.krp" "New Mexico_fm.krp" "New Mexico.krp" "New York_am.krp" "New York_fm.krp" "New York.krp" "North Carolina_am.krp" "North Carolina_fm.krp" "North Carolina.krp" "North Dakota_am.krp" "North Dakota_fm.krp" "North Dakota.krp" "Nova Scotia_am.krp" "Nova Scotia_fm.krp" "Nova Scotia.krp" "Ohio_am.krp" "Ohio_fm.krp" "Ohio.krp" "Oklahoma_am.krp" "Oklahoma_fm.krp" "Oklahoma.krp" "Ontario_am.krp" "Ontario_fm.krp" "Ontario.krp" "Oregon_am.krp" "Oregon_fm.krp" "Oregon.krp" "oregon-portland-antenna.2.krp" "oregon-portland-antenna.krp" "Pennsylvania_am.krp" "Pennsylvania_fm.krp" "Pennsylvania.krp" "Quebec_am.krp" "Quebec_fm.krp" "Quebec.krp" "Rhode Island_am.krp" "Rhode Island_fm.krp" "Rhode Island.krp" "Saint Paul (Minneapolis).krp" "Salina (Kansas)_fm.krp" "Saskatchewan_am.krp" "Saskatchewan_fm.krp" "Saskatchewan.krp" "South Carolina_am.krp" "South Carolina_fm.krp" "South Carolina.krp" "South Dakota_am.krp" "South Dakota_fm.krp" "South Dakota.krp" "Tennessee_am.krp" "Tennessee_fm.krp" "Tennessee.krp" "Texas_am.krp" "Texas_fm.krp" "Texas.krp" "Utah_am.krp" "Utah_fm.krp" "Utah.krp" "Vermont_am.krp" "Vermont_fm.krp" "Vermont.krp" "Virginia_am.krp" "Virginia_fm.krp" "Virginia.krp" "Washington_am.krp" "Washington_fm.krp" "Washington.krp" "West Virginia_am.krp" "West Virginia_fm.krp" "West Virginia.krp" "Wisconsin_am.krp" "Wisconsin_fm.krp" "Wisconsin.krp" "Wyoming_am.krp" "Wyoming_fm.krp" "Wyoming.krp"
++EXTRA_DIST = "Alabama_am.krp" "Alabama_fm.krp" "Alabama.krp" "Alaska_am.krp" "Alaska_fm.krp" "Alaska.krp" "Alberta_am.krp" "Alberta_fm.krp" "Alberta.krp" "Ann Arbor (Michigan).krp" "Arizona_am.krp" "Arizona_fm.krp" "Arizona.krp" "Arkansas_am.krp" "Arkansas_fm.krp" "Arkansas.krp" "Austin.krp" "British Columbia_am.krp" "British Columbia_fm.krp" "British Columbia.krp" "California_am.krp" "California_fm.krp" "California.krp" "Chicago-antenna.krp" "college-park,GA.krp" "Colorado_am.krp" "Colorado_fm.krp" "Colorado.krp" "Connecticut_am.krp" "Connecticut_fm.krp" "Connecticut.krp" "Dallas.krp" "Delaware_am.krp" "Delaware_fm.krp" "Delaware.krp" "District of Columbia_am.krp" "District of Columbia_fm.krp" "District of Columbia.krp" "Florida_am.krp" "Florida_fm.krp" "Florida.krp" "Guam_am.krp" "Guam_fm.krp" "Guam.krp" "Hawaii_am.krp" "Hawaii_fm.krp" "Hawaii.krp" "houston.krp" "Idaho_am.krp" "Idaho_fm.krp" "Idaho.krp" "Illinois_am.krp" "Illinois_fm.krp" "Illinois.krp" "Indiana_am.krp" "Indiana_fm.krp" "Indiana.krp" "Indiana-newburgh.krp" "Iowa_am.krp" "Iowa_fm.krp" "Iowa.krp" "Kansas_am.krp" "Kansas_fm.krp" "Kansas.krp" "Kentucky_am.krp" "Kentucky_fm.krp" "Kentucky.krp" "los-angeles-antenna.krp" "Louisiana_am.krp" "Louisiana_fm.krp" "Louisiana.krp" "Maine_am.krp" "Maine_fm.krp" "Maine.krp" "Manitoba_am.krp" "Manitoba_fm.krp" "Manitoba.krp" "Maryland_am.krp" "Maryland_fm.krp" "Maryland.krp" "Massachusetts_am.krp" "Massachusetts_fm.krp" "Massachusetts.krp" "Michigan_am.krp" "Michigan_fm.krp" "Michigan.krp" "Minnesota_am.krp" "Minnesota_fm.krp" "Minnesota.krp" "Mississippi_am.krp" "Mississippi_fm.krp" "Mississippi.krp" "Missouri_am.krp" "Missouri_fm.krp" "missouri-joplin-antenna.krp" "Missouri.krp" "Montana_am.krp" "Montana_fm.krp" "Montana.krp" "Nebraska_am.krp" "Nebraska_fm.krp" "Nebraska.krp" "Nevada_am.krp" "Nevada_fm.krp" "Nevada.krp" "New Brunswick_am.krp" "New Brunswick_fm.krp" "New Brunswick.krp" "Newfoundland_am.krp" "Newfoundland_fm.krp" "Newfoundland.krp" "New Hampshire_am.krp" "New Hampshire_fm.krp" "New Hampshire.krp" "New Jersey_am.krp" "New Jersey_fm.krp" "New Jersey.krp" "New Mexico_am.krp" "New Mexico_fm.krp" "New Mexico.krp" "New York_am.krp" "New York_fm.krp" "New York.krp" "North Carolina_am.krp" "North Carolina_fm.krp" "North Carolina.krp" "North Dakota_am.krp" "North Dakota_fm.krp" "North Dakota.krp" "Nova Scotia_am.krp" "Nova Scotia_fm.krp" "Nova Scotia.krp" "Ohio_am.krp" "Ohio_fm.krp" "Ohio.krp" "Oklahoma_am.krp" "Oklahoma_fm.krp" "Oklahoma.krp" "Ontario_am.krp" "Ontario_fm.krp" "Ontario.krp" "Oregon_am.krp" "Oregon_fm.krp" "Oregon.krp" "oregon-portland-antenna.2.krp" "oregon-portland-antenna.krp" "Pennsylvania_am.krp" "Pennsylvania_fm.krp" "Pennsylvania.krp" "Quebec_am.krp" "Quebec_fm.krp" "Quebec.krp" "Rhode Island_am.krp" "Rhode Island_fm.krp" "Rhode Island.krp" "Saint Paul (Minneapolis).krp" "Salina (Kansas)_fm.krp" "Saskatchewan_am.krp" "Saskatchewan_fm.krp" "Saskatchewan.krp" "South Carolina_am.krp" "South Carolina_fm.krp" "South Carolina.krp" "South Dakota_am.krp" "South Dakota_fm.krp" "South Dakota.krp" "Tennessee_am.krp" "Tennessee_fm.krp" "Tennessee.krp" "Texas_am.krp" "Texas_fm.krp" "Texas.krp" "texas-odessa.krp" "Utah_am.krp" "Utah_fm.krp" "Utah.krp" "Vermont_am.krp" "Vermont_fm.krp" "Vermont.krp" "Virginia_am.krp" "Virginia_fm.krp" "Virginia.krp" "Washington_am.krp" "Washington_fm.krp" "Washington.krp" "West Virginia_am.krp" "West Virginia_fm.krp" "West Virginia.krp" "Wisconsin_am.krp" "Wisconsin_fm.krp" "Wisconsin.krp" "Wyoming_am.krp" "Wyoming_fm.krp" "Wyoming.krp"
+
+ install-data-local:
+ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/"
+- $(INSTALL_DATA) "$(srcdir)/New York_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Illinois_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Tennessee.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee.krp"
+- $(INSTALL_DATA) "$(srcdir)/District of Columbia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia.krp"
+- $(INSTALL_DATA) "$(srcdir)/Utah_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Rhode Island.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island.krp"
+- $(INSTALL_DATA) "$(srcdir)/Nevada_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Louisiana_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Vermont.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Vermont.krp"
+- $(INSTALL_DATA) "$(srcdir)/Alberta_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Pennsylvania_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Ohio.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio.krp"
+- $(INSTALL_DATA) "$(srcdir)/Washington_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/New York_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Idaho_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Nevada_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Nebraska_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Missouri_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Manitoba_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Wisconsin.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin.krp"
+- $(INSTALL_DATA) "$(srcdir)/Newfoundland.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland.krp"
+- $(INSTALL_DATA) "$(srcdir)/Hawaii_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/North Carolina_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Kentucky_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kentucky_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Quebec.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec.krp"
+- $(INSTALL_DATA) "$(srcdir)/Montana_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Alaska.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska.krp"
+- $(INSTALL_DATA) "$(srcdir)/Washington.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington.krp"
+- $(INSTALL_DATA) "$(srcdir)/Missouri_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Mexico_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Indiana_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/South Dakota.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota.krp"
+- $(INSTALL_DATA) "$(srcdir)/Mississippi_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Kentucky.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kentucky.krp"
+- $(INSTALL_DATA) "$(srcdir)/South Dakota_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Salina (Kansas)_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Salina (Kansas)_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Ontario_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Washington_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Minnesota_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Saskatchewan_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/oregon-portland-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/oregon-portland-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/Oklahoma_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Hampshire.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire.krp"
+- $(INSTALL_DATA) "$(srcdir)/Colorado_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Mississippi_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Delaware_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Florida.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida.krp"
+- $(INSTALL_DATA) "$(srcdir)/Dallas.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Dallas.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alabama_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alabama_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alabama.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama.krp"
+ $(INSTALL_DATA) "$(srcdir)/Alaska_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Ontario.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario.krp"
+- $(INSTALL_DATA) "$(srcdir)/South Carolina_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Saint Paul (Minneapolis).krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saint Paul (Minneapolis).krp"
+- $(INSTALL_DATA) "$(srcdir)/West Virginia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alaska_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alaska.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alberta_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alberta_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Alberta.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ann Arbor (Michigan).krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ann Arbor (Michigan).krp"
++ $(INSTALL_DATA) "$(srcdir)/Arizona_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Arizona_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Arizona.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona.krp"
++ $(INSTALL_DATA) "$(srcdir)/Arkansas_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Arkansas_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Arkansas.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas.krp"
++ $(INSTALL_DATA) "$(srcdir)/Austin.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Austin.krp"
++ $(INSTALL_DATA) "$(srcdir)/British Columbia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/British Columbia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/British Columbia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia.krp"
++ $(INSTALL_DATA) "$(srcdir)/California_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/California_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Kansas_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Nova Scotia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Quebec_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Brunswick_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Michigan_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Massachusetts.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts.krp"
+- $(INSTALL_DATA) "$(srcdir)/Maine_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/California.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California.krp"
++ $(INSTALL_DATA) "$(srcdir)/Chicago-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Chicago-antenna.krp"
+ $(INSTALL_DATA) "$(srcdir)/college-park,GA.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/college-park,GA.krp"
+- $(INSTALL_DATA) "$(srcdir)/Alaska_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Texas.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas.krp"
+- $(INSTALL_DATA) "$(srcdir)/Wyoming_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Missouri.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri.krp"
+- $(INSTALL_DATA) "$(srcdir)/Idaho.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho.krp"
+- $(INSTALL_DATA) "$(srcdir)/Maryland.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland.krp"
+- $(INSTALL_DATA) "$(srcdir)/Iowa.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa.krp"
+- $(INSTALL_DATA) "$(srcdir)/houston.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/houston.krp"
+- $(INSTALL_DATA) "$(srcdir)/Louisiana_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Brunswick_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Virginia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia.krp"
++ $(INSTALL_DATA) "$(srcdir)/Colorado_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Colorado_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado_fm.krp"
+ $(INSTALL_DATA) "$(srcdir)/Colorado.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado.krp"
+- $(INSTALL_DATA) "$(srcdir)/Kansas_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Oregon_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Minnesota.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota.krp"
+- $(INSTALL_DATA) "$(srcdir)/Utah.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah.krp"
+- $(INSTALL_DATA) "$(srcdir)/Ohio_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/oregon-portland-antenna.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/oregon-portland-antenna.2.krp"
+- $(INSTALL_DATA) "$(srcdir)/Guam_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Wyoming.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming.krp"
+- $(INSTALL_DATA) "$(srcdir)/North Dakota_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Idaho_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Arizona_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Delaware.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Mexico_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Brunswick.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick.krp"
++ $(INSTALL_DATA) "$(srcdir)/Connecticut_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Connecticut_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Connecticut.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut.krp"
++ $(INSTALL_DATA) "$(srcdir)/Dallas.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Dallas.krp"
++ $(INSTALL_DATA) "$(srcdir)/Delaware_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/Delaware_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Arkansas.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas.krp"
+- $(INSTALL_DATA) "$(srcdir)/Alberta_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Oregon.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon.krp"
+- $(INSTALL_DATA) "$(srcdir)/Massachusetts_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Oklahoma.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma.krp"
++ $(INSTALL_DATA) "$(srcdir)/Delaware.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware.krp"
+ $(INSTALL_DATA) "$(srcdir)/District of Columbia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Illinois_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/West Virginia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/North Dakota.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota.krp"
+- $(INSTALL_DATA) "$(srcdir)/Nebraska.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska.krp"
+- $(INSTALL_DATA) "$(srcdir)/Quebec_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/North Dakota_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Austin.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Austin.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Jersey.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey.krp"
++ $(INSTALL_DATA) "$(srcdir)/District of Columbia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/District of Columbia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia.krp"
++ $(INSTALL_DATA) "$(srcdir)/Florida_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/Florida_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Texas_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Maryland_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Arizona_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Illinois.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois.krp"
+- $(INSTALL_DATA) "$(srcdir)/Oklahoma_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Rhode Island_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/los-angeles-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/los-angeles-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/Saskatchewan_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Florida.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida.krp"
++ $(INSTALL_DATA) "$(srcdir)/Guam_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Guam_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam_fm.krp"
+ $(INSTALL_DATA) "$(srcdir)/Guam.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam.krp"
++ $(INSTALL_DATA) "$(srcdir)/Hawaii_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Hawaii_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Hawaii.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii.krp"
++ $(INSTALL_DATA) "$(srcdir)/houston.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/houston.krp"
++ $(INSTALL_DATA) "$(srcdir)/Idaho_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Idaho_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Idaho.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho.krp"
++ $(INSTALL_DATA) "$(srcdir)/Illinois_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Illinois_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Illinois.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois.krp"
++ $(INSTALL_DATA) "$(srcdir)/Indiana_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Indiana_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Indiana.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana.krp"
++ $(INSTALL_DATA) "$(srcdir)/Indiana-newburgh.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana-newburgh.krp"
++ $(INSTALL_DATA) "$(srcdir)/Iowa_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Iowa_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Iowa.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa.krp"
++ $(INSTALL_DATA) "$(srcdir)/Kansas_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Kansas_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Kansas.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas.krp"
++ $(INSTALL_DATA) "$(srcdir)/Kentucky_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kentucky_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/Kentucky_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kentucky_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Arizona.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona.krp"
+- $(INSTALL_DATA) "$(srcdir)/North Carolina.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina.krp"
+- $(INSTALL_DATA) "$(srcdir)/Rhode Island_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Kentucky.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kentucky.krp"
++ $(INSTALL_DATA) "$(srcdir)/los-angeles-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/los-angeles-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/Louisiana_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Louisiana_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Louisiana.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana.krp"
+ $(INSTALL_DATA) "$(srcdir)/Maine_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Oregon_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Kansas.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Mexico.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico.krp"
+- $(INSTALL_DATA) "$(srcdir)/Connecticut_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Maine_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Maine.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine.krp"
++ $(INSTALL_DATA) "$(srcdir)/Manitoba_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/Manitoba_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Hampshire_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Guam_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Iowa_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Saskatchewan.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan.krp"
+- $(INSTALL_DATA) "$(srcdir)/Colorado_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Pennsylvania.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania.krp"
++ $(INSTALL_DATA) "$(srcdir)/Manitoba.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba.krp"
++ $(INSTALL_DATA) "$(srcdir)/Maryland_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Maryland_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Maryland.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland.krp"
++ $(INSTALL_DATA) "$(srcdir)/Massachusetts_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Massachusetts_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Massachusetts.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts.krp"
++ $(INSTALL_DATA) "$(srcdir)/Michigan_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Michigan_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Michigan.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan.krp"
++ $(INSTALL_DATA) "$(srcdir)/Minnesota_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Minnesota_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Minnesota.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota.krp"
++ $(INSTALL_DATA) "$(srcdir)/Mississippi_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Mississippi_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Mississippi.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi.krp"
++ $(INSTALL_DATA) "$(srcdir)/Missouri_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Missouri_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/missouri-joplin-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/missouri-joplin-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/Missouri.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri.krp"
++ $(INSTALL_DATA) "$(srcdir)/Montana_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Montana_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Montana.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nebraska_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nebraska_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nebraska.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nevada_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nevada_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nevada.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Brunswick_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Brunswick_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Brunswick.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick.krp"
++ $(INSTALL_DATA) "$(srcdir)/Newfoundland_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/Newfoundland_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/South Carolina.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina.krp"
++ $(INSTALL_DATA) "$(srcdir)/Newfoundland.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Hampshire_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Hampshire_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Hampshire.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Jersey_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/New Jersey_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Arkansas_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Ann Arbor (Michigan).krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ann Arbor (Michigan).krp"
+- $(INSTALL_DATA) "$(srcdir)/Ohio_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Virginia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Minnesota_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Hawaii_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Jersey.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Mexico_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Mexico_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/New Mexico.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico.krp"
++ $(INSTALL_DATA) "$(srcdir)/New York_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/New York_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York_fm.krp"
+ $(INSTALL_DATA) "$(srcdir)/New York.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York.krp"
++ $(INSTALL_DATA) "$(srcdir)/North Carolina_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/North Carolina_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/North Carolina.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina.krp"
++ $(INSTALL_DATA) "$(srcdir)/North Dakota_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/North Dakota_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/North Dakota.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nova Scotia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nova Scotia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Nova Scotia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ohio_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ohio_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ohio.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio.krp"
++ $(INSTALL_DATA) "$(srcdir)/Oklahoma_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Oklahoma_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Oklahoma.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ontario_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ontario_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Ontario.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario.krp"
++ $(INSTALL_DATA) "$(srcdir)/Oregon_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Oregon_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Oregon.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon.krp"
++ $(INSTALL_DATA) "$(srcdir)/oregon-portland-antenna.2.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/oregon-portland-antenna.2.krp"
++ $(INSTALL_DATA) "$(srcdir)/oregon-portland-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/oregon-portland-antenna.krp"
++ $(INSTALL_DATA) "$(srcdir)/Pennsylvania_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/Pennsylvania_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Iowa_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Louisiana.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana.krp"
+- $(INSTALL_DATA) "$(srcdir)/Wisconsin_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Montana.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana.krp"
+- $(INSTALL_DATA) "$(srcdir)/Alabama.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama.krp"
+- $(INSTALL_DATA) "$(srcdir)/Maryland_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Utah_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Alberta.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta.krp"
++ $(INSTALL_DATA) "$(srcdir)/Pennsylvania.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania.krp"
++ $(INSTALL_DATA) "$(srcdir)/Quebec_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Quebec_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Quebec.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec.krp"
++ $(INSTALL_DATA) "$(srcdir)/Rhode Island_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Rhode Island_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Rhode Island.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island.krp"
++ $(INSTALL_DATA) "$(srcdir)/Saint Paul (Minneapolis).krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saint Paul (Minneapolis).krp"
++ $(INSTALL_DATA) "$(srcdir)/Salina (Kansas)_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Salina (Kansas)_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Saskatchewan_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Saskatchewan_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Saskatchewan.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan.krp"
++ $(INSTALL_DATA) "$(srcdir)/South Carolina_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/South Carolina_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/South Carolina.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina.krp"
++ $(INSTALL_DATA) "$(srcdir)/South Dakota_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/South Dakota_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/South Dakota.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota.krp"
++ $(INSTALL_DATA) "$(srcdir)/Tennessee_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/Tennessee_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Tennessee.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee.krp"
++ $(INSTALL_DATA) "$(srcdir)/Texas_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Texas_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Texas.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas.krp"
++ $(INSTALL_DATA) "$(srcdir)/texas-odessa.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/texas-odessa.krp"
++ $(INSTALL_DATA) "$(srcdir)/Utah_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Utah_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Utah.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah.krp"
+ $(INSTALL_DATA) "$(srcdir)/Vermont_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Vermont_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/North Carolina_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Massachusetts_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/California_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/Vermont_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Vermont_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Alabama_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Michigan_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Vermont.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Vermont.krp"
++ $(INSTALL_DATA) "$(srcdir)/Virginia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Virginia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Virginia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia.krp"
++ $(INSTALL_DATA) "$(srcdir)/Washington_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Washington_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Washington.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington.krp"
++ $(INSTALL_DATA) "$(srcdir)/West Virginia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/West Virginia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia_fm.krp"
+ $(INSTALL_DATA) "$(srcdir)/West Virginia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia.krp"
+- $(INSTALL_DATA) "$(srcdir)/Manitoba.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba.krp"
+- $(INSTALL_DATA) "$(srcdir)/Texas_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Tennessee_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Nevada.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada.krp"
+- $(INSTALL_DATA) "$(srcdir)/Connecticut_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Hampshire_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Connecticut.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut.krp"
+- $(INSTALL_DATA) "$(srcdir)/Michigan.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan.krp"
+ $(INSTALL_DATA) "$(srcdir)/Wisconsin_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Montana_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Arkansas_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/British Columbia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia.krp"
+- $(INSTALL_DATA) "$(srcdir)/Mississippi.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi.krp"
+- $(INSTALL_DATA) "$(srcdir)/Indiana.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana.krp"
+- $(INSTALL_DATA) "$(srcdir)/Nova Scotia.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia.krp"
+- $(INSTALL_DATA) "$(srcdir)/South Carolina_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina_am.krp"
++ $(INSTALL_DATA) "$(srcdir)/Wisconsin_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin_fm.krp"
++ $(INSTALL_DATA) "$(srcdir)/Wisconsin.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin.krp"
++ $(INSTALL_DATA) "$(srcdir)/Wyoming_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming_am.krp"
+ $(INSTALL_DATA) "$(srcdir)/Wyoming_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Alabama_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/British Columbia_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Indiana_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Florida_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Nebraska_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Virginia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Hawaii.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii.krp"
+- $(INSTALL_DATA) "$(srcdir)/Ontario_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Chicago-antenna.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Chicago-antenna.krp"
+- $(INSTALL_DATA) "$(srcdir)/District of Columbia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/South Dakota_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/British Columbia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/New Jersey_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/Nova Scotia_fm.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia_fm.krp"
+- $(INSTALL_DATA) "$(srcdir)/Newfoundland_am.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland_am.krp"
+- $(INSTALL_DATA) "$(srcdir)/California.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California.krp"
+- $(INSTALL_DATA) "$(srcdir)/Maine.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine.krp"
+-
++ $(INSTALL_DATA) "$(srcdir)/Wyoming.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming.krp"
+
+ uninstall-local:
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Vermont.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta_am.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ann Arbor (Michigan).krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Austin.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Chicago-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/college-park,GA.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Dallas.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/houston.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana-newburgh.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kentucky_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kentucky_fm.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kentucky.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Salina (Kansas)_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/los-angeles-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/oregon-portland-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi_am.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Dallas.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saint Paul (Minneapolis).krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/college-park,GA.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alaska_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/missouri-joplin-antenna.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Missouri.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/houston.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick_am.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/oregon-portland-antenna.2.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Idaho_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico_am.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Brunswick.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Delaware_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Austin.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey_fm.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Illinois.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Dakota.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oklahoma.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/oregon-portland-antenna.2.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/oregon-portland-antenna.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Quebec.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/los-angeles-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kentucky_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arizona.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Oregon_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Kansas.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Mexico.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Guam_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Rhode Island.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saint Paul (Minneapolis).krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Salina (Kansas)_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan_fm.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Saskatchewan.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Colorado_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina_fm.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ann Arbor (Michigan).krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ohio_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Minnesota_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New York.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Pennsylvania_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Iowa_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Louisiana.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maryland_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alberta.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee_am.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/texas-odessa.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Utah.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Vermont_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/North Carolina_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Massachusetts_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California_am.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Vermont_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Vermont.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Washington.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia_fm.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/West Virginia.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Manitoba.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Texas_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Tennessee_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nevada.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Hampshire_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Connecticut.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Michigan.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Montana_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Arkansas_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Mississippi.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Carolina_am.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin_fm.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wisconsin.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming_am.krp"
+ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Alabama_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Indiana_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Florida_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nebraska_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Virginia_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Hawaii.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Ontario_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Chicago-antenna.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/District of Columbia_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/South Dakota_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/British Columbia_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/New Jersey_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Nova Scotia_fm.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Newfoundland_am.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/California.krp"
+- -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Maine.krp"
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/usa/Wyoming.krp"
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/usa/missouri-joplin-antenna.krp kradio-3.5.13.1/kradio3/presets/usa/missouri-joplin-antenna.krp
+--- kradio-3.5.13.1/kradio3/presets.old/usa/missouri-joplin-antenna.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/usa/missouri-joplin-antenna.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,96 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer>Vanessa Ezekowitz</maintainer>
++ <changed>2008-03-06T03:27:22</changed>
++ <country>USA</country>
++ <city>Joplin, Missouri</city>
++ <media>Antenna</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++
++<stationID>1204795416D327B29628F9A516E5FB37E10FE87051EC4814A5DB9310CE50567FB8CDAD8C0E</stationID>
++ <name>KXMS (Fine Arts Radio Int&apos;l)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>88.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1204795416E12EDA0A2654A5BE583984CAAFC558B39A76BB7A1CD8CE2FB94A27F204F1934C</stationID>
++ <name>KSYN (Kissin&apos;)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>120479541625C6582240A6ACB64070E43AEDF4652A7FD0B3D8F48BDD8ABAA3DA2794C6D4D8</stationID>
++ <name>KJMK (Lite Rock)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1204795417914AAC2F66691FA07212B02F77AA7F5A3FCACC1F6217E9907D15444CC75D91CB</stationID>
++ <name>KXDG (Big Dog)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>97.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12047954174FB5470F53D45D70CA84226BC5F64B0566C0EAE6DDF701E0D6F7BC7791EE1471</stationID>
++ <name>KBIN (Classic Country)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>12047954170ABC15063AD62CEEECF710F339727F3F073C66C12713BBCBB2FA44C46254D61E</stationID>
++ <name>KIXQ (Kix)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1204795417E9D264C67939C2CA96378EE4BE54256EAF1C9DB6C5C75BA91D38AC4BFC966237</stationID>
++ <name>KCAR (Cool 104)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>104.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1204795417E494F0F8E67F42AE4CFB364E20AC2E3B832C1724C5912E85C8DE2B06C467A4E1</stationID>
++ <name>KMOQ (Q105)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>105.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++
++<stationID>1204795417E91429BBC4986C1F9B9BDCA2CF6FC0FFD829A66480FE077C75B70650B9FF5B36</stationID>
++ <name>KJML (Rock 107)</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.1</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/usa/texas-odessa.krp kradio-3.5.13.1/kradio3/presets/usa/texas-odessa.krp
+--- kradio-3.5.13.1/kradio3/presets.old/usa/texas-odessa.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/usa/texas-odessa.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,151 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-snapshot-2006-11-12-r497</creator>
++ <maintainer></maintainer>
++ <changed></changed>
++ <country>USA</country>
++ <city>Odessa,Texas</city>
++ <media></media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>116846129002F1F8194388299FC3139319A930591722CECB86569BAC9725A06B36B2FD8CC4</stationID>
++ <name>KLVW</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11684613150AE00B186451ABD6D71B8367D23F52446D5F025EE36FED385E460193E70491A3</stationID>
++ <name>KAWZ</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>89.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168461334AF8D607D7EF147FF8B65CDD5C023A41ED5B062E5BC222D146F60020275063078</stationID>
++ <name>KBMM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11684613599F7116FBE9A5114CA9B4A2CE8D56B90F4E8C910A185DBDE551323127B9B3A568</stationID>
++ <name>KFLB</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>90.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168460870B8292553C2CF19E2E5FD3CA914DFC0C547A173C7B35562C20761A9BB0AE8E4D9</stationID>
++ <name>KOCV</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>91.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168460975331463C5B45FAB68AAFDA87E7459F3988B480B10A375BD6C1ECF8A23DE73A288</stationID>
++ <name>KNFM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>92.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168461002342CFC649119A91BF7D0F4D53702C5EE4E74996C5995805A4C889B2714926578</stationID>
++ <name>KZVT</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>93.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168461019B99600290F3A77F620C3F956088E3543B5DB1490495E36E5BAA7240A80A95132</stationID>
++ <name>KQRX</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>95.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168461042CF2067ED36AAB605B6DD61F3DB4ABA0A2B62BBC7ECA3723193B29FFB6CA3CA68</stationID>
++ <name>KMRK</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168461068C54AB8B0F3EB77D0B55914ACC9C2C3C91A17EA3AB0BB7B62479B06962539B095</stationID>
++ <name>KMCM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>116846108171A02F30F18036E75C6BFAC283F7F68B87AEEAB39D03C07A3D0590A4B4578F79</stationID>
++ <name>KODM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>96.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11684610993661B95209C8CC24B3A153BD2AB1D538BB28BF41AAC4E940E24130725F8B82AF</stationID>
++ <name>KHKX</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168461120A076395C093FB1BA6315362B58A11EFADE461C5ACAD61AA51F7E66FB0FBEAA69</stationID>
++ <name>KBAT</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>99.9</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>11684611436094D7F632AB1EB4FAD57028DB098DB6E0D2055F0A96FD55525137EBD5C47A5B</stationID>
++ <name>KFZX</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>102.1</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168461195282D1688F40C7FC5AA003DDC700EC5DD797FC632097B5E56176E024E04B4AF84</stationID>
++ <name>KCRS</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>103.3</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168461220137A9E713D061D38E11FB474360C007F1866EBA09325F489B29B345A15AF28F5</stationID>
++ <name>KCHX</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>106.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1168461240BCBE9B8FD990C788128803DF787B796306066505548D89F71F3505D3BC837A6E</stationID>
++ <name>KQLM</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <frequency>107.9</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/vietnam/hanoi.krp kradio-3.5.13.1/kradio3/presets/vietnam/hanoi.krp
+--- kradio-3.5.13.1/kradio3/presets.old/vietnam/hanoi.krp 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/vietnam/hanoi.krp 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,60 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<kradiorc>
++ <stationlist>
++ <format>kradio-1.0</format>
++ <info>
++ <creator>kradio-4.0.0</creator>
++ <maintainer>Pham Thanh Nam &lt;phamthanhnam.ptn@gmail.com&gt;</maintainer>
++ <changed>2009-11-08T13:14:16</changed>
++ <country>Vietnam</country>
++ <city>Hanoi</city>
++ <media>FM</media>
++ <comments></comments>
++ </info>
++ <FrequencyRadioStation>
++ <stationID>12576571600E343C50AE64ABBB128131D2438689F9BEA2D9C2BACE297416E68B309EA2</stationID>
++ <name>Hanoi</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>90</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12576573057937209E795F1B379958B917FFDDD421456F10C75CC5AE901FFC55BC47DC</stationID>
++ <name>VOV2</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>96.5</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1257657101D508873DA1965BB87A96601283B0F78920CAD7DA951DD6DF74F1C98553F5</stationID>
++ <name>VOV1</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>100</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>12571038920FB7D70277EEDB473F783FF9C4BE09036A58A570581103530069FD2F7B7B</stationID>
++ <name>VOV3</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>stereo</stereomode>
++ <frequency>102.7</frequency>
++ </FrequencyRadioStation>
++ <FrequencyRadioStation>
++ <stationID>1257657210A2BBEDF17CAE4283E948AAFFE9A8CF59ED4705780CB6C91189A1488DA04D</stationID>
++ <name>VOV5</name>
++ <shortname></shortname>
++ <icon></icon>
++ <volumepreset>-1</volumepreset>
++ <stereomode>dontcare</stereomode>
++ <frequency>105.5</frequency>
++ </FrequencyRadioStation>
++ </stationlist>
++</kradiorc>
+diff -Nuar kradio-3.5.13.1/kradio3/presets.old/vietnam/Makefile.am kradio-3.5.13.1/kradio3/presets/vietnam/Makefile.am
+--- kradio-3.5.13.1/kradio3/presets.old/vietnam/Makefile.am 1970-01-01 01:00:00.000000000 +0100
++++ kradio-3.5.13.1/kradio3/presets/vietnam/Makefile.am 2012-11-25 00:48:02.000000000 +0100
+@@ -0,0 +1,9 @@
++SUBDIRS =
++EXTRA_DIST = "hanoi.krp"
++
++install-data-local:
++ $(mkinstalldirs) "$(DESTDIR)$(kde_datadir)/kradio/presets/vietnam/"
++ $(INSTALL_DATA) "$(srcdir)/hanoi.krp" "$(DESTDIR)$(kde_datadir)/kradio/presets/vietnam/hanoi.krp"
++
++uninstall-local:
++ -rm -f "$(DESTDIR)$(kde_datadir)/kradio/presets/vietnam/hanoi.krp"
diff --git a/redhat/applications/kradio/trinity-kradio-3.5.13.1.spec b/redhat/applications/kradio/trinity-kradio-3.5.13.1.spec
index a41be01e2..cc5903e88 100644
--- a/redhat/applications/kradio/trinity-kradio-3.5.13.1.spec
+++ b/redhat/applications/kradio/trinity-kradio-3.5.13.1.spec
@@ -26,7 +26,7 @@
Name: trinity-%{kdecomp}
Summary: Comfortable Radio Application for KDE [Trinity]
Version: 0.1.1.1
-Release: 4%{?dist}%{?_variant}
+Release: 5%{?dist}%{?_variant}
License: GPLv2+
Group: Applications/Utilities
@@ -40,6 +40,8 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Source0: %{kdecomp}-3.5.13.1.tar.gz
+Patch1: kradio-3.5.13.1-updated_preset.patch
+
BuildRequires: trinity-tqtinterface-devel >= 3.5.13.1
BuildRequires: trinity-tdelibs-devel >= 3.5.13.1
BuildRequires: trinity-tdebase-devel >= 3.5.13.1
@@ -87,6 +89,7 @@ of new plugins (e.g. Internet Radio Streams, new cool GUIs) are welcome.
%prep
%setup -q -n %{kdecomp}-3.5.13.1
+%patch1 -p1
# Ugly hack to modify TQT include directory inside autoconf files.
# If TQT detection fails, it fallbacks to TQT4 instead of TQT3 !
@@ -161,6 +164,9 @@ update-desktop-database %{tde_appdir} -q &> /dev/null ||:
%{tde_datadir}/locale/*/LC_MESSAGES/kradio-*.mo
%changelog
+* Sat Dec 01 2012 Francois Andriot <francois.andriot@free.fr> - 0.1.1.1-5
+- Updates presets
+
* Wed Oct 03 2012 Francois Andriot <francois.andriot@free.fr> - 0.1.1.1-4
- Initial build for TDE 3.5.13.1
diff --git a/redhat/components-3.5.13.txt b/redhat/components-3.5.13.txt
index f154e050b..220a664ee 100644
--- a/redhat/components-3.5.13.txt
+++ b/redhat/components-3.5.13.txt
@@ -120,3 +120,4 @@ extras/kasablanca
extras/ksensors
extras/style-ia-ora
extras/trinity-desktop
+extras/theme-baghira
diff --git a/redhat/extras/kasablanca/trinity-kasablanca-3.5.13.1.spec b/redhat/extras/kasablanca/trinity-kasablanca-3.5.13.1.spec
index 5cd2ae5aa..effbdeefa 100644
--- a/redhat/extras/kasablanca/trinity-kasablanca-3.5.13.1.spec
+++ b/redhat/extras/kasablanca/trinity-kasablanca-3.5.13.1.spec
@@ -87,7 +87,6 @@ Kasablanca is an ftp client, among its features are currently:
unset QTDIR || : ; . /etc/profile.d/qt3.sh
export PATH="%{tde_bindir}:${PATH}"
export LDFLAGS="-L%{tde_libdir} -I%{tde_includedir}"
-
export KDEDIR=%{tde_prefix}
## Needed(?) for older/legacy setups, harmless otherwise
diff --git a/redhat/extras/kdebluetooth/trinity-kdebluetooth.spec b/redhat/extras/kdebluetooth/trinity-kdebluetooth.spec
index 69360204b..27bac51d2 100644
--- a/redhat/extras/kdebluetooth/trinity-kdebluetooth.spec
+++ b/redhat/extras/kdebluetooth/trinity-kdebluetooth.spec
@@ -106,7 +106,7 @@ KDE Bluetooth framework development libraries and headers.
%patch3 -p1 -b .gcc46
%if 0%{?rhel} >= 6 || 0%{?fedora} || 0%{?mdkversion} || 0%{?mgaversion}
-%patch4 -p1 -b .bluez4
+#patch4 -p1 -b .bluez4
%endif
%patch11 -p1
@@ -120,6 +120,7 @@ KDE Bluetooth framework development libraries and headers.
# If TQT detection fails, it fallbacks to TQT4 instead of TQT3 !
%__sed -i "admin/acinclude.m4.in" \
-e "s|/usr/include/tqt|%{tde_includedir}/tqt|g" \
+ -e "s|include/kde|include/tde|g" \
-e "s|kde_htmldir='.*'|kde_htmldir='%{tde_tdedocdir}/HTML'|g"
%__cp -f "/usr/share/aclocal/libtool.m4" "admin/libtool.m4.in"
@@ -128,10 +129,9 @@ KDE Bluetooth framework development libraries and headers.
%build
-unset QTDIR || : ; . /etc/profile.d/qt.sh
+unset QTDIR || : ; . /etc/profile.d/qt3.sh
export PATH="%{tde_bindir}:${PATH}"
export LDFLAGS="-L%{tde_libdir} -I%{tde_includedir}"
-
export KDEDIR=%{tde_prefix}
# FIXME: dbus-tqt headers are not found without this ...
diff --git a/redhat/extras/theme-baghira/baghira-0.8.tar.bz2 b/redhat/extras/theme-baghira/baghira-0.8.tar.bz2
new file mode 100644
index 000000000..e6549b4ae
--- /dev/null
+++ b/redhat/extras/theme-baghira/baghira-0.8.tar.bz2
Binary files differ
diff --git a/redhat/extras/theme-baghira/baghira-3.5.13.1-fix_ftbfs.patch b/redhat/extras/theme-baghira/baghira-3.5.13.1-fix_ftbfs.patch
new file mode 100644
index 000000000..f9a78a566
--- /dev/null
+++ b/redhat/extras/theme-baghira/baghira-3.5.13.1-fix_ftbfs.patch
@@ -0,0 +1,140 @@
+--- baghira-0.8/bab/main.cpp.ORI 2012-11-20 19:33:04.093794934 +0100
++++ baghira-0.8/bab/main.cpp 2012-11-20 19:33:08.022717622 +0100
+@@ -330,7 +330,7 @@
+ delete config;
+ }
+
+-QPoint *BabSwitcher::globalPos = new QPoint::QPoint(0,0);
++QPoint *BabSwitcher::globalPos = new QPoint(0,0);
+
+ BabSwitcher::BabSwitcher(bab *parent, const char *name)
+ : KSystemTray(parent,name), DCOPObject("babInterface") {
+--- baghira-0.8/bab/Makefile.am.ORI 2012-11-20 19:34:26.540172464 +0100
++++ baghira-0.8/bab/Makefile.am 2012-11-20 19:34:35.265000752 +0100
+@@ -19,4 +19,4 @@
+ # the application source, library search path, and link libraries
+ bab_SOURCES = main.cpp styleconfdialog.cpp bab_iface.skel
+ bab_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+-bab_LDADD = $(LIB_KDEUI)
++bab_LDADD = $(LIB_KDEUI) $(LIB_QT)
+--- baghira-0.8/config/generatePixmaps.sh.OLD 2012-11-20 19:53:24.431860823 +0100
++++ baghira-0.8/config/generatePixmaps.sh 2012-11-20 19:53:47.753402165 +0100
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ top_srcdir="${1:-../..}"
+ imagebase="$top_srcdir/imagebase"
+-UIC=$(grep "UIC = " ../Makefile | cut -f3- -d" ")
++UIC=$QTDIR/bin/uic
+ echo -e "#ifndef SCPIXMAPS_H\n#define SCPIXMAPS_H\n" > pixmaps.h
+ $UIC -embed baghira \
+ $imagebase/button-base \
+--- baghira-0.8/config/Makefile.am.ORI 2012-11-20 19:55:33.699318284 +0100
++++ baghira-0.8/config/Makefile.am 2012-11-20 19:55:37.841236807 +0100
+@@ -7,7 +7,7 @@
+
+ kstyle_baghira_config_la_SOURCES = kstyle_baghira_config.cpp colordialog.cpp colorpicker.cpp configdialog.ui help.ui about.ui
+ # kstyle_baghira_config_la_METASOURCES = AUTO
+-kstyle_baghira_config_la_LIBADD = $(LIB_KDEUI) $(LIB_KIO)
++kstyle_baghira_config_la_LIBADD = $(LIB_KDEUI) $(LIB_KIO) $(LIB_QT) $(LIB_KDECORE) -lDCOP
+ kstyle_baghira_config_la_LDFLAGS = -module -avoid-version $(all_libraries) -no-undefined $(KDE_PLUGIN)
+
+
+--- baghira-0.8/deco/config/generatePixmaps.sh.ORI 2012-11-20 19:59:34.835573683 +0100
++++ baghira-0.8/deco/config/generatePixmaps.sh 2012-11-20 19:59:45.590362018 +0100
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ top_srcdir="${1:-../..}"
+ imagebase="$top_srcdir/imagebase"
+-UIC=$(grep "UIC = " ../../Makefile | cut -f3- -d" ")
++UIC=$QTDIR/bin/uic
+ echo -e "#ifndef DCPIXMAPS_H\n#define DCPIXMAPS_H\n" > pixmaps.h
+ $UIC -embed baghira \
+ $imagebase/icon_help \
+--- baghira-0.8/deco/config/Makefile.am.ORI 2012-11-20 20:00:37.549339366 +0100
++++ baghira-0.8/deco/config/Makefile.am 2012-11-20 20:00:50.370087013 +0100
+@@ -9,7 +9,7 @@
+ kde_module_LTLIBRARIES = kwin_baghira_config.la
+ kwin_baghira_config_la_SOURCES = baghiraconfig.cc aquariusbutton.cc colorpicker.cc configdialog.ui
+ kwin_baghira_config_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+-kwin_baghira_config_la_LIBADD = $(LIB_KDEUI)
++kwin_baghira_config_la_LIBADD = $(LIB_KDEUI) $(LIB_QT) $(LIB_KDECORE)
+ kwin_baghira_config_la_METASOURCES = AUTO
+
+ DISTCLEANFILES = $(kwin_baghira_config_la_METASOURCES)
+--- baghira-0.8/deco/generatePixmaps.sh.ORI 2012-11-20 20:03:20.543131500 +0100
++++ baghira-0.8/deco/generatePixmaps.sh 2012-11-20 20:03:29.464956023 +0100
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ top_srcdir="${1:-../..}"
+ imagebase="$top_srcdir/imagebase"
+-UIC=$(grep "UIC = " ../Makefile | cut -f3- -d" ")
++UIC=$QTDIR/bin/uic
+ echo -e "#ifndef DPIXMAPS_H\n#define DPIXMAPS_H\n" > pixmaps.h
+ $UIC -embed baghira \
+ $imagebase/brushed-gradient \
+--- baghira-0.8/deco/Makefile.am.ORI 2012-11-20 20:04:20.899944322 +0100
++++ baghira-0.8/deco/Makefile.am 2012-11-20 20:04:44.230485387 +0100
+@@ -16,7 +16,7 @@
+ kde_module_LTLIBRARIES = kwin3_baghira.la
+ kwin3_baghira_la_SOURCES = baghiraclient.cc
+ kwin3_baghira_la_LIBADD = $(kde_libraries)/libkdecorations.la
+-kwin3_baghira_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -lkdecore -module
++kwin3_baghira_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) -lkdefx -module
+ kwin3_baghira_la_METASOURCES = AUTO
+
+ DISTCLEANFILES = $(kwin3_baghira_la_METASOURCES)
+--- baghira-0.8/sessionapplet/dmctl.cpp~ 2005-07-11 21:23:58.000000000 +0200
++++ baghira-0.8/sessionapplet/dmctl.cpp 2012-11-20 20:16:58.925023092 +0100
+@@ -37,7 +37,7 @@
+
+ DM::DM() : fd( -1 )
+ {
+- char *ptr;
++ const char *ptr;
+ struct sockaddr_un sa;
+
+ if (DMType == Dunno) {
+--- baghira-0.8/style/generatePixmaps.sh.ORI 2012-11-20 20:20:08.024297835 +0100
++++ baghira-0.8/style/generatePixmaps.sh 2012-11-20 20:20:22.149019999 +0100
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ top_srcdir="${1:-../..}"
+ imagebase="$top_srcdir/imagebase"
+-UIC=$(grep "UIC = " ../Makefile | cut -f3- -d" ")
++UIC=$QTDIR/bin/uic
+ echo -e "#ifndef SPIXMAPS_H\n#define SPIXMAPS_H\n" > pixmaps.h
+ $UIC -embed baghira \
+ $imagebase/brushed-gradient \
+--- baghira-0.8/style/Makefile.am.ORI 2012-11-20 20:21:23.703809116 +0100
++++ baghira-0.8/style/Makefile.am 2012-11-20 20:21:34.795590907 +0100
+@@ -5,7 +5,7 @@
+ METASOURCES = AUTO
+ kde_style_LTLIBRARIES = baghira.la
+ baghira_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+-baghira_la_LIBADD = -lkdefx -lXtst $(LIB_KDEUI)
++baghira_la_LIBADD = -lkdefx -lXtst $(LIB_KDEUI) $(LIB_QT) $(LIB_KDECORE)
+ baghira_la_SOURCES = baghira.cpp optionHandler.cpp polish.cpp utils.cpp
+ lnkdir = $(kde_datadir)/kstyle/themes
+ lnk_DATA = baghira.themerc
+--- baghira-0.8/kickermenu/Makefile.am.ORI 2012-11-20 20:23:35.843209238 +0100
++++ baghira-0.8/kickermenu/Makefile.am 2012-11-20 20:23:41.101105774 +0100
+@@ -9,7 +9,7 @@
+ b_menu_panelapplet_la_METASOURCES = AUTO
+
+ b_menu_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+-b_menu_panelapplet_la_LIBADD = $(LIB_KDEUI)
++b_menu_panelapplet_la_LIBADD = $(LIB_KDEUI) $(LIB_QT) $(LIB_KDECORE) -lDCOP
+
+ messages:
+ $(XGETTEXT) *.cpp *.h -o $(podir)/kmenuapplet.pot
+--- baghira-0.8/sidebar/Makefile.am.ORI 2012-11-20 20:25:55.797454906 +0100
++++ baghira-0.8/sidebar/Makefile.am 2012-11-20 20:26:05.393266033 +0100
+@@ -7,7 +7,7 @@
+
+ konqsidebar_baghirasidebar_la_SOURCES = baghiralinkdrag.cpp baghirasidebar.cpp linkview.cpp listboxlink.cpp dndlistbox.cpp linkconfig.ui baghirasidebariface.skel
+ konqsidebar_baghirasidebar_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -lkonqsidebarplugin
+-konqsidebar_baghirasidebar_la_LIBADD = $(LIB_KPARTS) $(LIB_KFILE)
++konqsidebar_baghirasidebar_la_LIBADD = $(LIB_KPARTS) $(LIB_KFILE) $(LIB_QT) -lDCOP $(LIB_KDECORE) $(LIB_KDEUI)
+
+ baghirasidebar_entry_DATA = baghirasidebar.desktop
+ baghirasidebar_entrydir = $(kde_datadir)/konqsidebartng/entries
diff --git a/redhat/extras/theme-baghira/theme-baghira.tar.gz b/redhat/extras/theme-baghira/theme-baghira.tar.gz
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/redhat/extras/theme-baghira/theme-baghira.tar.gz
diff --git a/redhat/extras/theme-baghira/trinity-theme-baghira.spec b/redhat/extras/theme-baghira/trinity-theme-baghira.spec
new file mode 100644
index 000000000..78d77eed8
--- /dev/null
+++ b/redhat/extras/theme-baghira/trinity-theme-baghira.spec
@@ -0,0 +1,204 @@
+# If TDE is built in a specific prefix (e.g. /opt/trinity), the release will be suffixed with ".opt".
+%if "%{?tde_prefix}" != "/usr"
+%define _variant .opt
+%endif
+
+# Speed build options
+%define debug_package %{nil}
+%define __spec_install_post %{nil}
+AutoReq: no
+
+# TDE 3.5.13 specific building variables
+%define tde_bindir %{tde_prefix}/bin
+%define tde_datadir %{tde_prefix}/share
+%define tde_docdir %{tde_datadir}/doc
+%define tde_includedir %{tde_prefix}/include
+%define tde_libdir %{tde_prefix}/%{_lib}
+%define tde_mandir %{tde_datadir}/man
+
+%define tde_tdeappdir %{tde_datadir}/applications/kde
+%define tde_tdedocdir %{tde_docdir}/tde
+%define tde_tdeincludedir %{tde_includedir}/tde
+%define tde_tdelibdir %{tde_libdir}/trinity
+
+%define _docdir %{tde_docdir}
+
+Name: trinity-theme-baghira
+Version: 0.8
+Release: 1%{?dist}%{?_variant}
+Summary: Baghira theme for Trinity
+License: GPL
+Group: Graphical desktop/KDE
+Source0: http://prdownloads.sourceforge.net/baghira/baghira-%{version}.tar.bz2
+Source1: admin-3.5.13.1.tar.gz
+Patch0: baghira-3.5.13.1-fix_ftbfs.patch
+Url: http://baghira.sourceforge.net/
+BuildRequires: X11-devel
+BuildRequires: jpeg-devel
+BuildRequires: qt3-devel
+BuildRequires: trinity-tdebase-devel
+BuildRoot: %{_tmppath}/baghira-%{version}-buildroot
+
+%description
+Baghira is a very nice native Trinity style and windec
+originally based on Mosfet's Liquid style.
+
+This package contains non-free icons..
+
+%package devel
+Summary: Header files and static libraries from %name
+Group: Development/C
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Libraries and includes files for
+developing programs based on %name
+
+This package is in PLF because it contains non-free icons.
+
+%if 0%{?suse_version} || 0%{?pclinuxos}
+%debug_package
+%endif
+
+%prep
+%setup -q -n baghira-%{version}
+%setup -q -n baghira-%{version} -a 1
+%patch0 -p1 -b .ftbfs
+
+%__rm -rf admin
+%__mv -f admin-3.5.13.1 admin
+
+# Ugly hack to modify TQT include directory inside autoconf files.
+# If TQT detection fails, it fallbacks to TQT4 instead of TQT3 !
+%__sed -i "admin/acinclude.m4.in" \
+ -e "s|/usr/include/tqt|%{tde_includedir}/tqt|g" \
+ -e "s|kde_htmldir='.*'|kde_htmldir='%{tde_tdedocdir}/HTML'|g"
+
+%__cp -f "/usr/share/aclocal/libtool.m4" "admin/libtool.m4.in"
+%__cp -f "/usr/share/libtool/config/ltmain.sh" "admin/ltmain.sh" || %__cp -f "/usr/share/libtool/ltmain.sh" "admin/ltmain.sh"
+%__make -f "admin/Makefile.common"
+
+%build
+unset QTDIR || : ; . /etc/profile.d/qt3.sh
+export PATH="%{tde_bindir}:${PATH}"
+export LDFLAGS="-L%{tde_libdir} -I%{tde_includedir}"
+export KDEDIR=%{tde_prefix}
+
+%configure \
+ --prefix=%{tde_prefix} \
+ --exec-prefix=%{tde_prefix} \
+ --bindir=%{tde_bindir} \
+ --libdir=%{tde_libdir} \
+ --includedir=%{tde_tdeincludedir} \
+ --datadir=%{tde_datadir} \
+ --with-qt-libraries=${QTLIB:-${QTDIR}/%{_lib}} \
+ --disable-static \
+ --disable-rpath \
+ --disable-debug --disable-warnings \
+ --disable-dependency-tracking --enable-final \
+ --with-extra-includes=%{tde_includedir}/tqt
+
+%__make %{?_smp_mflags}
+
+%install
+%__rm -rf $RPM_BUILD_ROOT
+%__make install DESTDIR=$RPM_BUILD_ROOT
+
+install -d %{buildroot}/%{tde_libdir}/baghira-%{version}
+install -d %{buildroot}/%{tde_tdeincludedir}/baghira-%{version}
+
+mv %{buildroot}/%{tde_libdir}/libbaghirastarter.la %{buildroot}/%{tde_libdir}/baghira-%{version}/libbaghirastarter.la
+mv %{buildroot}/%{tde_libdir}/libbaghirastarter.so %{buildroot}/%{tde_libdir}/baghira-%{version}/libbaghirastarter.so.%{major}
+mv %{buildroot}/%{tde_libdir}/usermanager_panelapplet.la %{buildroot}/%{tde_libdir}/baghira-%{version}/usermanager_panelapplet.la
+mv %{buildroot}/%{tde_libdir}/usermanager_panelapplet.so %{buildroot}/%{tde_libdir}/baghira-%{version}/usermanager_panelapplet.so.%{major}
+mv %{buildroot}/%{tde_tdeincludedir}/baghirasidebar.h %{buildroot}/%{tde_tdeincludedir}/baghira-%{version}/baghirasidebar.h
+mv %{buildroot}/%{tde_tdeincludedir}/baghirasidebariface.h %{buildroot}/%{tde_tdeincludedir}/baghira-%{version}/baghirasidebariface.h
+mv %{buildroot}/%{tde_tdeincludedir}/dndlistbox.h %{buildroot}/%{tde_tdeincludedir}/baghira-%{version}/dndlistbox.h
+mv %{buildroot}/%{tde_tdeincludedir}/linkview.h %{buildroot}/%{tde_tdeincludedir}/baghira-%{version}/linkview.h
+mv %{buildroot}/%{tde_tdeincludedir}/listboxlink.h %{buildroot}/%{tde_tdeincludedir}/baghira-%{version}/listboxlink.h
+
+ln -s libbaghirastarter.so.%{major} %{buildroot}/%{tde_libdir}/baghira-%{version}/libbaghirastarter.so
+ln -s usermanager_panelapplet.so.%{major} %{buildroot}/%{tde_libdir}/baghira-%{version}/usermanager_panelapplet.so
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root)
+%doc README AUTHORS ChangeLog COPYING NEWS TODO
+%{tde_bindir}/bab
+%{tde_tdelibdir}/b_menu_panelapplet.*
+%{tde_tdelibdir}/kstyle_baghira_config.*
+%{tde_tdelibdir}/kwin3_baghira.*
+%{tde_tdelibdir}/kwin_baghira_config.*
+%{tde_tdelibdir}/plugins/styles/baghira.*
+%{tde_datadir}/apps/kdisplay/color-schemes/Aqua*
+#%{tde_datadir}/apps/kicker/applets/b_menuapplet.desktop
+%{tde_datadir}/apps/kicker/applets/usermanager.desktop
+%{tde_datadir}/apps/konqsidebartng/add/baghirasidebar_add.desktop
+%{tde_datadir}/apps/konqsidebartng/entries/baghirasidebar.desktop
+%{tde_datadir}/apps/kicker/applets/starter.desktop
+%{tde_datadir}/apps/kstyle/themes/baghira.themerc
+%{tde_datadir}/apps/kwin/baghira.desktop
+%{tde_datadir}/icons/crystalsvg/*/*/baghira*
+%{tde_datadir}/icons/crystalsvg/*/*/bab_*
+%{tde_datadir}/apps/baghira/poof.png
+%{tde_datadir}/icons/crystalsvg/22x22/actions/bStarter.png
+%{tde_datadir}/icons/crystalsvg/22x22/actions/bStarter_down.png
+%{tde_datadir}/icons/crystalsvg/22x22/actions/bStarter_hover.png
+
+
+%files devel
+%defattr(-,root,root)
+%{tde_libdir}/baghira-%{version}/libbaghirastarter.la
+%{tde_libdir}/baghira-%{version}/libbaghirastarter.so*
+%{tde_tdelibdir}/konqsidebar_baghirasidebar.la
+%{tde_tdelibdir}/konqsidebar_baghirasidebar.so
+%{tde_libdir}/baghira-%{version}/usermanager_panelapplet.la
+%{tde_libdir}/baghira-%{version}/usermanager_panelapplet.so*
+%{tde_tdeincludedir}/baghira-%{version}/baghirasidebar.h
+%{tde_tdeincludedir}/baghira-%{version}/baghirasidebariface.h
+%{tde_tdeincludedir}/baghira-%{version}/dndlistbox.h
+%{tde_tdeincludedir}/baghira-%{version}/linkview.h
+%{tde_tdeincludedir}/baghira-%{version}/listboxlink.h
+
+
+%changelog
+* Tue Nov 20 2012 Francois Andriot <francois.andriot@free.fr> - 0.8.1
+- Initial build for TDE 3.5.13.1
+
+* Tue Jan 8 2008 Javier Rodas <jrodas@zarb.org> 0.8-2plf2008.1
+- KDE 3.5.8 version in Mandriva 2008.1
+- KDE svn admin headers now packaged in Source1
+
+* Mon Sep 18 2006 Javier Rodas <jrodas@zarb.org> 0.8-2plf2007.0
+- Fix Source0 local reference
+- KDE 3.5.4 admin headers are downloaded with subversion
+- Fix Baghira devel package directory paths
+- Fix BuildRequires
+
+* Fri Sep 15 2006 Javier Rodas <jrodas@zarb.org> 0.8-1plf2007.0
+- 0.8
+- Replaced KDE admin headers in the source file (for KDE 3.5.4)
+- Fix BuildRequires
+- Removed the patch file
+
+* Thu Oct 13 2005 neoclust <neoclust@mandriva.com> 0.7-1plf
+- 0.7
+- remove redundant buildrequires
+
+* Mon Mar 04 2005 Nicolas L�ureuil <neoclust@zarb.org> 0.6-3plf
+- Add PLF reason
+- bzipped patch
+- Make rpmlint happier
+
+* Mon Mar 04 2005 Nicolas L�ureuil <neoclust@zarb.org> 0.6-2plf
+- New version
+- Fix compile ( Patch0 from Gentoo)
+- Spec Cleanup
+- rpmbuildupdatable
+
+* Mon Dec 06 2004 Laurent Culioli <laurent@zarb.org> 0.6-1plf
+- Initial Release.
diff --git a/redhat/kdebase/kdebase-3.5.13.1-fix_startkde_path.patch b/redhat/kdebase/kdebase-3.5.13.1-fix_startkde_path.patch
new file mode 100644
index 000000000..971daf16f
--- /dev/null
+++ b/redhat/kdebase/kdebase-3.5.13.1-fix_startkde_path.patch
@@ -0,0 +1,107 @@
+--- bin/startkde.ORI 2012-11-16 20:44:01.763131101 +0100
++++ bin/startkde 2012-11-16 21:24:12.865147976 +0100
+@@ -15,6 +15,26 @@
+ source $HOME/.xprofile
+ fi
+
++# Some functions to parse and check path correctly ...
++is_in_path() {
++ search="$1"; ifs="$IFS"; IFS=":"; set $PATH; IFS="$ifs"
++ for i in $*; do
++ [ "${i}" = "${search}" ] && return 0
++ done
++ return 1
++}
++
++# Usage: place_before_in_path /opt/trinity/games /usr/games
++place_before_in_path() {
++ insert="$1"; before="$2"; ifs="$IFS"; IFS=":"; set $PATH; IFS="$ifs"
++ NPATH=""
++ for i in $*; do
++ [ "${i}" = "${before}" ] && NPATH="${NPATH}:${insert}"
++ NPATH="${NPATH}:${i}"
++ done
++ export PATH=${NPATH}
++}
++
+ echo "[startkde] Starting startkde." 1>&2
+ echo "[startkde] This script is $0" 1>&2
+
+@@ -29,7 +49,7 @@
+ # Do not use kde-config to determine the version. That command creates a
+ # profile directory in the root of the file system. Refer to Bug Report 293.
+ if [ -x $BIN_DIR/konqueror ]; then
+- KDE_VERSION="`$BIN_DIR/konqueror --version | grep KDE | awk '{print $2}'`"
++ KDE_VERSION=$($BIN_DIR/konqueror --version | while IFS=: read a b; do [[ "$a" =~ "KDE" ]] && echo $b; done)
+ echo "[startkde] TDE version is $KDE_VERSION" 1>&2
+ export KDEDIR=${BIN_DIR%/bin}
+ echo "[startkde] TDE base directory is $KDEDIR" 1>&2
+@@ -105,27 +125,12 @@
+ # This script and kstandardirs.h and kstandardirs.cpp must match.
+ # The latter two must be edited/patched before compiling.
+ echo "[startkde] KDEHOME is not set." 1>&2
+- if [ -d $HOME/.trinity ]; then
+- # OK, this one is obvious.
+- export KDEHOME=$HOME/.trinity
+- elif [ -f /usr/bin/kde4-config ]; then
+- # Looks like KDE4 is installed.
+- if [ -d $HOME/.kde ] && [ ! -d $HOME/.trinity ]; then
+- # Presume $HOME/.kde is being used for KDE4 as it already exists.
+- export KDEHOME=$HOME/.trinity
+- else
+- # Presume $HOME/.kde is being used for KDE4 to be on the safe side.
+- export KDEHOME=$HOME/.trinity
+- fi
+- elif [ -f /opt/trinity/bin/kde-config ]; then
+- # Looks like Trinity is installed.
+- export KDEHOME=$HOME/.trinity
+- elif [ -f /usr/bin/kde-config ] && [ -d $HOME/.kde ]; then
++ # Default value: $HOME/.trinity. Most users will use this.
++ export KDEHOME=$HOME/.trinity
++
++ if [ ! -d $HOME/.trinity ] && [ ! -f /usr/bin/kde4-config ] && [ -f /usr/bin/kde-config ] && [ -d $HOME/.kde ]; then
+ # Looks like Trinity is installed and not playing second fiddle to KDE4.
+ export KDEHOME=$HOME/.kde
+- else
+- # Resort to this and hope for the best!
+- export KDEHOME=$HOME/.trinity
+ fi
+ echo "[startkde] Set KDEHOME to $KDEHOME." 1>&2
+ fi
+@@ -149,30 +154,30 @@
+
+ # Modify the following environment variables only as necessary.
+ if [ -d $KDEDIR/games ]; then
+- if [ "`echo $PATH | grep \"$KDEDIR/games\"`" = "" ]; then
++ if ! is_in_path "$KDEDIR/games" ; then
+ # Respect the traditional path order. Don't blindly place $KDEDIR/games
+ # first in the path. Only place $KDEDIR/games before /usr/games. If packagers
+ # are adding $KDEDIR/games elsewhere, then they need to ensure the traditional
+ # search patch is respected.
+ # Is there a way we can check that $KDEDIR/games is always placed only just before
+ # /usr/games in the search path?
+- if [ "`echo $PATH | grep \"^\\(.*:\\)\\?/usr/games\\(:.*\\)\\?$\"`" != "" ]; then
+- export PATH="`echo $PATH | sed \"s|^\\(.*:\\)\\?/usr/games\\(:.*\\)\\?$|\\1$KDEDIR/games:/usr/games\\2|\"`"
++ if is_in_path "/usr/games"; then
++ place_before_in_path "$KDEDIR/games" "/usr/games"
+ else
+ export PATH=$KDEDIR/games:$PATH
+ fi
+ fi
+ fi
+ if [ -d $KDEDIR/bin ]; then
+- if [ "`echo $PATH | grep \"$KDEDIR/bin\"`" = "" ]; then
++ if ! is_in_path "$KDEDIR/bin" ]; then
+ # Respect the traditional path order. Don't blindly place $KDEDIR/bin
+ # first in the path. Only place $KDEDIR/bin before /usr/bin. This order is
+ # consistent with kdelibs/kdesu/stub.cpp. If packagers are adding $KDEDIR/bin
+ # elsewhere, then they need to ensure the traditional search patch is respected.
+ # Is there a way we can check that $KDEDIR/bin is always placed only just before
+ # /usr/bin in the search path?
+- if [ "`echo $PATH | grep \"^\\(.*:\\)\\?/usr/bin\\(:.*\\)\\?$\"`" != "" ]; then
+- export PATH="`echo $PATH | sed \"s|^\\(.*:\\)\\?/usr/bin\\(:.*\\)\\?$|\\1$KDEDIR/bin:/usr/bin\\2|\"`"
++ if is_in_path "/usr/bin"; then
++ place_before_in_path "$KDEDIR/bin" "/usr/bin"
+ else
+ export PATH=$KDEDIR/bin:$PATH
+ fi
diff --git a/redhat/kdebase/kdebase-3.5.13.1-fix_tdm_pid_file.patch b/redhat/kdebase/kdebase-3.5.13.1-fix_tdm_pid_file.patch
new file mode 100644
index 000000000..8ddad87e1
--- /dev/null
+++ b/redhat/kdebase/kdebase-3.5.13.1-fix_tdm_pid_file.patch
@@ -0,0 +1,11 @@
+--- kdebase-3.5.13.1/kdm/config.def.ORI 2012-12-01 12:45:04.820426652 +0100
++++ kdebase-3.5.13.1/kdm/config.def 2012-12-01 12:45:16.291197270 +0100
+@@ -883,7 +883,7 @@
+ Type: string
+ Default: ""
+ User: core
+-Instance: "/var/run/kdm.pid"
++Instance: "/var/run/tdm.pid"
+ Merge: xdm
+ Comment:
+ Where &kdm; should store its PID (do not store if empty).
diff --git a/redhat/kdebase/pamd.kcheckpass-trinity.pclos2012 b/redhat/kdebase/pamd.kcheckpass-trinity.pclos2012
new file mode 100644
index 000000000..0a37e6e13
--- /dev/null
+++ b/redhat/kdebase/pamd.kcheckpass-trinity.pclos2012
@@ -0,0 +1,5 @@
+#%PAM-1.0
+auth include system-auth
+account include system-auth
+password include system-auth
+session include system-auth
diff --git a/redhat/kdebase/pamd.kdm-trinity-np.pclos2012 b/redhat/kdebase/pamd.kdm-trinity-np.pclos2012
new file mode 100644
index 000000000..690b4df08
--- /dev/null
+++ b/redhat/kdebase/pamd.kdm-trinity-np.pclos2012
@@ -0,0 +1,7 @@
+#%PAM-1.0
+auth required pam_env.so
+auth required pam_permit.so
+account include system-auth
+password include system-auth
+session include system-auth
+session optional pam_console.so
diff --git a/redhat/kdebase/pamd.kdm-trinity.pclos2012 b/redhat/kdebase/pamd.kdm-trinity.pclos2012
new file mode 100644
index 000000000..87d080f58
--- /dev/null
+++ b/redhat/kdebase/pamd.kdm-trinity.pclos2012
@@ -0,0 +1,8 @@
+#%PAM-1.0
+auth include system-auth
+auth required pam_nologin.so
+account include system-auth
+password include system-auth
+session include system-auth
+session optional pam_console.so
+session required pam_namespace.so
diff --git a/redhat/kdebase/pamd.kscreensaver-trinity.pclos2012 b/redhat/kdebase/pamd.kscreensaver-trinity.pclos2012
new file mode 100644
index 000000000..0a37e6e13
--- /dev/null
+++ b/redhat/kdebase/pamd.kscreensaver-trinity.pclos2012
@@ -0,0 +1,5 @@
+#%PAM-1.0
+auth include system-auth
+account include system-auth
+password include system-auth
+session include system-auth
diff --git a/redhat/kdebase/suse-displaymanagers-tdm b/redhat/kdebase/suse-displaymanagers-tdm
new file mode 100644
index 000000000..7170ca8f2
--- /dev/null
+++ b/redhat/kdebase/suse-displaymanagers-tdm
@@ -0,0 +1,21 @@
+tdm_start_proc() {
+ splashcopy 0 6
+ # stop plymouth (bug#775548)
+ plymouth_quit
+
+ return 0
+}
+
+tdm_vars() {
+ TDM_BIN=/opt/trinity/bin/kdm
+ case "${DISPLAYMANAGER##*/}" in
+ tdm)
+ export KDEROOTHOME=/root/.kdm
+ DISPLAYMANAGER=$TDM_BIN
+ STARTPROC=tdm_start_proc
+ ;;
+ *) return 1 ;;
+ esac
+ return 0
+}
+
diff --git a/redhat/kdebase/trinity-kdebase-3.5.13.1.spec b/redhat/kdebase/trinity-kdebase-3.5.13.1.spec
index 46de06000..ad481b77e 100644
--- a/redhat/kdebase/trinity-kdebase-3.5.13.1.spec
+++ b/redhat/kdebase/trinity-kdebase-3.5.13.1.spec
@@ -24,7 +24,7 @@
Name: trinity-tdebase
Version: 3.5.13.1
-Release: 1%{?dist}%{?_variant}
+Release: 2%{?dist}%{?_variant}
License: GPL
Summary: Trinity Base Programs
Group: User Interface/Desktops
@@ -60,6 +60,9 @@ Source4: pamd.kcheckpass-trinity%{?dist}
Source5: pamd.kscreensaver-trinity%{?dist}
%endif
+# openSUSE: configuration file for TDM
+Source6: suse-displaymanagers-tdm
+
# TDE 3.5.13 patches
## [kdebase] Fix syntax error in icon
@@ -68,6 +71,7 @@ Patch1: kdebase-3.5.13.1-fix_displayconfig_icon.patch
Patch11: kdebase-3.5.12-desktop-openterminalhere.patch
## [kdebase/kdm/kfrontend] Global Xsession file is '/etc/X11/xinit/Xsession' [RHEL/Fedora]
Patch13: kdebase-3.5.13-genkdmconf_Xsession_location.patch
+Patch14: kdebase-3.5.13-genkdmconf_Xsession_location_xdm.patch
## [kdebase/startkde] Sets default Start Icon in 'kickerrc' [RHEL/Fedora]
Patch15: kdebase-3.5.13.1-startkde_icon.patch
## [kdebase/kioslave/man] Fix kio_man for older distros without 'man-db' [Bug #714]
@@ -76,6 +80,8 @@ Patch21: kdebase-3.5.13-kio_man_utf8.patch
Patch30: kdebase-3.5.12-kdm_hide_menu_button.patch
## [kdebase/startkde] Fix wrong path setting
Patch31: kdebase-3.5.13.1-fix_startkde_path.patch
+## [kdebase/kdm] Fix PID file is 'tdm.pid' instead of 'kdm.pid' (needed for openSUSE)
+Patch32: kdebase-3.5.13.1-fix_tdm_pid_file.patch
### Patches for RHEL4 (should not go upstream)
@@ -1887,6 +1893,9 @@ already. Most users won't need this.
%{_sysconfdir}/pam.d/kdm-trinity
%{_sysconfdir}/pam.d/kdm-trinity-np
%endif
+%if 0%{?suse_version}
+/usr/lib/X11/displaymanagers/tdm
+%endif
# Distribution specific stuff
%if 0%{?rhel} || 0%{?fedora} || 0%{?suse_version}
@@ -3028,12 +3037,16 @@ Konqueror libraries.
%if 0%{?rhel} || 0%{?fedora}
%patch13 -p1 -b .Xsession
%endif
+%if 0%{?suse_version}
+%patch14 -p1 -b .Xsession
+%endif
%patch15 -p1 -b .tdeicon
%if 0%{?rhel} || 0%{?mgaversion} || 0%{?mdkversion}
%patch21 -p1 -b .man
%endif
%patch30 -p1 -b .xtestsupport
%patch31 -p1 -b .startkde
+%patch32 -p1 -b .pid
%if 0%{?rhel} == 4
%patch201 -p1 -b .libdetect
@@ -3232,6 +3245,12 @@ EOF
%__mv -f %{buildroot}%{tde_datadir}/apps/konqueror/servicemenus/media_safelyremove.desktop %{buildroot}%{tde_datadir}/apps/konqueror/servicemenus/media_safelyremove.desktop_tdebase
%__ln_s /etc/alternatives/media_safelyremove.desktop_tdebase %{buildroot}%{tde_datadir}/apps/konqueror/servicemenus/media_safelyremove.desktop
+# SUSE: creates DM config file, used by '/etc/init.d/xdm'
+# You must set 'DISPLAYMANAGER=tdm' in '/etc/sysconfig/displaymanager'
+%if 0%{?suse_version}
+%__install -D -m 644 "%{SOURCE6}" "%{?buildroot}/usr/lib/X11/displaymanagers/tdm"
+%__sed -i "%{?buildroot}/usr/lib/X11/displaymanagers/tdm" -e "s|/opt/trinity/bin|%{tde_bindir}|g"
+%endif
%clean
%__rm -rf %{?buildroot}
@@ -3240,5 +3259,8 @@ EOF
%changelog
+* Thu Nov 29 2012 Francois Andriot <francois.andriot@free.fr> - 3.5.13.1-2
+- openSUSE: fix TDM detection by XDM scripts
+
* Mon Sep 24 2012 Francois Andriot <francois.andriot@free.fr> - 3.5.13.1-1
- Initial build for TDE 3.5.13.1
diff --git a/redhat/kdelibs/kdelibs-3.5.13.1-disable_invalid_certificate_always_prompt.patch b/redhat/kdelibs/kdelibs-3.5.13.1-disable_invalid_certificate_always_prompt.patch
new file mode 100644
index 000000000..72346c83b
--- /dev/null
+++ b/redhat/kdelibs/kdelibs-3.5.13.1-disable_invalid_certificate_always_prompt.patch
@@ -0,0 +1,15 @@
+--- kdelibs-3.5.13.1/kio/kio/tcpslavebase.cpp.ORI 2012-12-29 11:25:06.736204632 +0100
++++ kdelibs-3.5.13.1/kio/kio/tcpslavebase.cpp 2012-12-29 11:25:32.731669416 +0100
+@@ -853,10 +853,12 @@
+ permacache = d->cc->isPermanent(pc);
+ }
+
++/*
+ if (!_IPmatchesCN && cp == KSSLCertificateCache::Accept) {
+ cp = KSSLCertificateCache::Prompt;
+ // ksv = KSSLCertificate::Ok;
+ }
++*/
+
+ // Precondition: cp is one of Reject, Accept or Prompt
+ switch (cp) {
diff --git a/redhat/kdelibs/trinity-kdelibs-3.5.13.1.spec b/redhat/kdelibs/trinity-kdelibs-3.5.13.1.spec
index 7bca4cd14..82df03623 100755
--- a/redhat/kdelibs/trinity-kdelibs-3.5.13.1.spec
+++ b/redhat/kdelibs/trinity-kdelibs-3.5.13.1.spec
@@ -18,7 +18,7 @@
Name: trinity-tdelibs
Version: 3.5.13.1
-Release: 1%{?dist}%{?_variant}
+Release: 2%{?dist}%{?_variant}
License: GPL
Summary: TDE Libraries
Group: Environment/Libraries
@@ -32,6 +32,10 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Source0: kdelibs-3.5.13.1.tar.gz
+# [kdelibs] Security popup always appear on invalid SSL certificate, even when set
+# to "always accept" [Bug #1287]
+Patch1: kdelibs-3.5.13.1-disable_invalid_certificate_always_prompt.patch
+
Obsoletes: tdelibs < %{version}-%{release}
Provides: tdelibs = %{version}-%{release}
Obsoletes: trinity-kdelibs < %{version}-%{release}
@@ -147,12 +151,21 @@ BuildRequires: libXcomposite-devel
BuildRequires: xorg-x11-devel
%endif
+# ICEAUTH
+%if 0%{?mgaversion} || 0%{?mdkversion} || 0%{?suse_version}
+Requires: iceauth
+%endif
+%if 0%{?rhel} >= 5 || 0%{?fedora}
+Requires: xorg-x11-server-utils
+%endif
+%if 0%{?rhel} == 4
+Requires: xorg-x11
+%endif
Requires: trinity-tqtinterface >= %{version}
Requires: trinity-arts >= %{version}
Requires: qt3 >= 3.3.8.d
-
%description
Libraries for the Trinity Desktop Environment:
TDE Libraries included: tdecore (TDE core library), kdeui (user interface),
@@ -332,6 +345,7 @@ applications for TDE.
%prep
%setup -q -n kdelibs-3.5.13.1
+%patch1 -p1
%build
diff --git a/redhat/kdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch b/redhat/kdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch
new file mode 100644
index 000000000..80ca10ff8
--- /dev/null
+++ b/redhat/kdesdk/kdesdk-3.5.13.1-fix_kdecachegrind_ftbfs.patch
@@ -0,0 +1,39683 @@
+commit cfccedd9c8db3af36d7c5635ca212fa170bb6ff5
+Author: Timothy Pearson <kb9vqf@pearsoncomputing.net>
+Date: 1327976424 -0600
+
+ Part 2 of prior commit
+
+diff --git a/kdecachegrind/AUTHORS b/kdecachegrind/AUTHORS
+new file mode 100644
+index 0000000..ded6005
+--- /dev/null
++++ b/kdecachegrind/AUTHORS
+@@ -0,0 +1 @@
++Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
+diff --git a/kdecachegrind/COPYING b/kdecachegrind/COPYING
+new file mode 100644
+index 0000000..c13faf0
+--- /dev/null
++++ b/kdecachegrind/COPYING
+@@ -0,0 +1,340 @@
++ GNU GENERAL PUBLIC LICENSE
++ Version 2, June 1991
++
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++ Preamble
++
++ The licenses for most software are designed to take away your
++freedom to share and change it. By contrast, the GNU General Public
++License is intended to guarantee your freedom to share and change free
++software--to make sure the software is free for all its users. This
++General Public License applies to most of the Free Software
++Foundation's software and to any other program whose authors commit to
++using it. (Some other Free Software Foundation software is covered by
++the GNU Library General Public License instead.) You can apply it to
++your programs, too.
++
++ When we speak of free software, we are referring to freedom, not
++price. Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++ To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if you
++distribute copies of the software, or if you modify it.
++
++ For example, if you distribute copies of such a program, whether
++gratis or for a fee, you must give the recipients all the rights that
++you have. You must make sure that they, too, receive or can get the
++source code. And you must show them these terms so they know their
++rights.
++
++ We protect your rights with two steps: (1) copyright the software, and
++(2) offer you this license which gives you legal permission to copy,
++distribute and/or modify the software.
++
++ Also, for each author's protection and ours, we want to make certain
++that everyone understands that there is no warranty for this free
++software. If the software is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original, so
++that any problems introduced by others will not reflect on the original
++authors' reputations.
++
++ Finally, any free program is threatened constantly by software
++patents. We wish to avoid the danger that redistributors of a free
++program will individually obtain patent licenses, in effect making the
++program proprietary. To prevent this, we have made it clear that any
++patent must be licensed for everyone's free use or not licensed at all.
++
++ The precise terms and conditions for copying, distribution and
++modification follow.
++
++ GNU GENERAL PUBLIC LICENSE
++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++ 0. This License applies to any program or other work which contains
++a notice placed by the copyright holder saying it may be distributed
++under the terms of this General Public License. The "Program", below,
++refers to any such program or work, and a "work based on the Program"
++means either the Program or any derivative work under copyright law:
++that is to say, a work containing the Program or a portion of it,
++either verbatim or with modifications and/or translated into another
++language. (Hereinafter, translation is included without limitation in
++the term "modification".) Each licensee is addressed as "you".
++
++Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope. The act of
++running the Program is not restricted, and the output from the Program
++is covered only if its contents constitute a work based on the
++Program (independent of having been made by running the Program).
++Whether that is true depends on what the Program does.
++
++ 1. You may copy and distribute verbatim copies of the Program's
++source code as you receive it, in any medium, provided that you
++conspicuously and appropriately publish on each copy an appropriate
++copyright notice and disclaimer of warranty; keep intact all the
++notices that refer to this License and to the absence of any warranty;
++and give any other recipients of the Program a copy of this License
++along with the Program.
++
++You may charge a fee for the physical act of transferring a copy, and
++you may at your option offer warranty protection in exchange for a fee.
++
++ 2. You may modify your copy or copies of the Program or any portion
++of it, thus forming a work based on the Program, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++ a) You must cause the modified files to carry prominent notices
++ stating that you changed the files and the date of any change.
++
++ b) You must cause any work that you distribute or publish, that in
++ whole or in part contains or is derived from the Program or any
++ part thereof, to be licensed as a whole at no charge to all third
++ parties under the terms of this License.
++
++ c) If the modified program normally reads commands interactively
++ when run, you must cause it, when started running for such
++ interactive use in the most ordinary way, to print or display an
++ announcement including an appropriate copyright notice and a
++ notice that there is no warranty (or else, saying that you provide
++ a warranty) and that users may redistribute the program under
++ these conditions, and telling the user how to view a copy of this
++ License. (Exception: if the Program itself is interactive but
++ does not normally print such an announcement, your work based on
++ the Program is not required to print an announcement.)
++
++These requirements apply to the modified work as a whole. If
++identifiable sections of that work are not derived from the Program,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works. But when you
++distribute the same sections as part of a whole which is a work based
++on the Program, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Program.
++
++In addition, mere aggregation of another work not based on the Program
++with the Program (or with a work based on the Program) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++ 3. You may copy and distribute the Program (or a work based on it,
++under Section 2) in object code or executable form under the terms of
++Sections 1 and 2 above provided that you also do one of the following:
++
++ a) Accompany it with the complete corresponding machine-readable
++ source code, which must be distributed under the terms of Sections
++ 1 and 2 above on a medium customarily used for software interchange; or,
++
++ b) Accompany it with a written offer, valid for at least three
++ years, to give any third party, for a charge no more than your
++ cost of physically performing source distribution, a complete
++ machine-readable copy of the corresponding source code, to be
++ distributed under the terms of Sections 1 and 2 above on a medium
++ customarily used for software interchange; or,
++
++ c) Accompany it with the information you received as to the offer
++ to distribute corresponding source code. (This alternative is
++ allowed only for noncommercial distribution and only if you
++ received the program in object code or executable form with such
++ an offer, in accord with Subsection b above.)
++
++The source code for a work means the preferred form of the work for
++making modifications to it. For an executable work, complete source
++code means all the source code for all modules it contains, plus any
++associated interface definition files, plus the scripts used to
++control compilation and installation of the executable. However, as a
++special exception, the source code distributed need not include
++anything that is normally distributed (in either source or binary
++form) with the major components (compiler, kernel, and so on) of the
++operating system on which the executable runs, unless that component
++itself accompanies the executable.
++
++If distribution of executable or object code is made by offering
++access to copy from a designated place, then offering equivalent
++access to copy the source code from the same place counts as
++distribution of the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++ 4. You may not copy, modify, sublicense, or distribute the Program
++except as expressly provided under this License. Any attempt
++otherwise to copy, modify, sublicense or distribute the Program is
++void, and will automatically terminate your rights under this License.
++However, parties who have received copies, or rights, from you under
++this License will not have their licenses terminated so long as such
++parties remain in full compliance.
++
++ 5. You are not required to accept this License, since you have not
++signed it. However, nothing else grants you permission to modify or
++distribute the Program or its derivative works. These actions are
++prohibited by law if you do not accept this License. Therefore, by
++modifying or distributing the Program (or any work based on the
++Program), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Program or works based on it.
++
++ 6. Each time you redistribute the Program (or any work based on the
++Program), the recipient automatically receives a license from the
++original licensor to copy, distribute or modify the Program subject to
++these terms and conditions. You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++ 7. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License. If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Program at all. For example, if a patent
++license would not permit royalty-free redistribution of the Program by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Program.
++
++If any portion of this section is held invalid or unenforceable under
++any particular circumstance, the balance of the section is intended to
++apply and the section as a whole is intended to apply in other
++circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system, which is
++implemented by public license practices. Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++ 8. If the distribution and/or use of the Program is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Program under this License
++may add an explicit geographical distribution limitation excluding
++those countries, so that distribution is permitted only in or among
++countries not thus excluded. In such case, this License incorporates
++the limitation as if written in the body of this License.
++
++ 9. The Free Software Foundation may publish revised and/or new versions
++of the General Public License from time to time. Such new versions will
++be similar in spirit to the present version, but may differ in detail to
++address new problems or concerns.
++
++Each version is given a distinguishing version number. If the Program
++specifies a version number of this License which applies to it and "any
++later version", you have the option of following the terms and conditions
++either of that version or of any later version published by the Free
++Software Foundation. If the Program does not specify a version number of
++this License, you may choose any version ever published by the Free Software
++Foundation.
++
++ 10. If you wish to incorporate parts of the Program into other free
++programs whose distribution conditions are different, write to the author
++to ask for permission. For software which is copyrighted by the Free
++Software Foundation, write to the Free Software Foundation; we sometimes
++make exceptions for this. Our decision will be guided by the two goals
++of preserving the free status of all derivatives of our free software and
++of promoting the sharing and reuse of software generally.
++
++ NO WARRANTY
++
++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
++REPAIR OR CORRECTION.
++
++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGES.
++
++ END OF TERMS AND CONDITIONS
++
++ How to Apply These Terms to Your New Programs
++
++ If you develop a new program, and you want it to be of the greatest
++possible use to the public, the best way to achieve this is to make it
++free software which everyone can redistribute and change under these terms.
++
++ To do so, attach the following notices to the program. It is safest
++to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least
++the "copyright" line and a pointer to where the full notice is found.
++
++ <one line to give the program's name and a brief idea of what it does.>
++ Copyright (C) <year> <name of author>
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++
++
++Also add information on how to contact you by electronic and paper mail.
++
++If the program is interactive, make it output a short notice like this
++when it starts in an interactive mode:
++
++ Gnomovision version 69, Copyright (C) year name of author
++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
++ This is free software, and you are welcome to redistribute it
++ under certain conditions; type `show c' for details.
++
++The hypothetical commands `show w' and `show c' should show the appropriate
++parts of the General Public License. Of course, the commands you use may
++be called something other than `show w' and `show c'; they could even be
++mouse-clicks or menu items--whatever suits your program.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the program, if
++necessary. Here is a sample; alter the names:
++
++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
++ `Gnomovision' (which makes passes at compilers) written by James Hacker.
++
++ <signature of Ty Coon>, 1 April 1989
++ Ty Coon, President of Vice
++
++This General Public License does not permit incorporating your program into
++proprietary programs. If your program is a subroutine library, you may
++consider it more useful to permit linking proprietary applications with the
++library. If this is what you want to do, use the GNU Library General
++Public License instead of this License.
+diff --git a/kdecachegrind/ChangeLog b/kdecachegrind/ChangeLog
+new file mode 100644
+index 0000000..05f3081
+--- /dev/null
++++ b/kdecachegrind/ChangeLog
+@@ -0,0 +1,89 @@
++2004/06/30
++ * Leak fixes
++ * Crash fixes on reload (make setData() synchroneous)
++ * Some update fixes in the data model (tracedata.cpp)
++ * Fix update problems in Function Profile
++ * Reselect active function on refresh in function profile
++ with grouping on
++
++2004/04/28
++ * toplevel.h/cpp, kdecachegrindui.rc
++ - Switching Layouts
++ * multiview.cpp: Removed some qDebug's
++ * Same term fixes
++
++2004/04/26
++ * cachegrindloader.cpp, fixcost.cpp:
++ - Allow Ranges in Subposition Spec, currently not used
++ - Correctly parse "Desc: Trigger:"
++ - Allow Event Spec (Long Name, Formula) with "event:"
++ * listutils.cpp:
++ - make level meters for costs only 1 bar
++ (2 with upper from 0..50%, lower 50%..100% is really confusing)
++ - Besides from Call graph and Tree maps, truncate bars to
++ only use needed size (removes lots of empty rectangles)
++ * CallGraphView:
++ - some fixes when no data is loaded
++ * functionselection.cpp (Function Profile)
++ - activation on mouse release to allow for context menu
++ * tracedata.cpp
++ - more robust parsing of events lists
++ - Introduction of Ranges (not currently used)
++ * utils.cpp:
++ - more robust parsing functions
++
++2004/04/05
++ * CallGraphView:
++ - Add Context menu item "Export as Image"
++ - Hide Birdseye-View if call-graph fits into widget
++ - Error messages in Canvas when something goes wrong
++ * Some Fixes, qDebug->kdDebug
++
++2004/04/02
++ * In most views columns for 2nd Event Type added
++ * Context menus modified to allow quick change of 2nd Event Type
++ * Toolbar simplified (only most used actions)
++ * Terminology fixes ("cost type"->"event type",
++ "trace data"->"profile data", long names of Ir,Dr,...)
++ * Sorting costs in lists is always descending now
++ * New File menu item: "Add..." other profile data to current window
++ * Detect Cachegrind format by "events:" content, not file name
++ Allows for arbitrary names of profile data files.
++
++2004/03/25
++ * New Class Addr as wrapper for memory addresses. Use 64bit
++ to allow loading of data produced on 64bit architectures
++
++2004/03/17
++
++ * costtypeview.cpp, tracedata.h/cpp:
++ Fixed deletion of custom types
++ * cachegrindloader.cpp, tracedata.h/cpp:
++ Moved String compression handling in Cachegrind files
++ to CachegrindLoader
++ * Do not show inclusive cost column in FunctionSelection
++ side bar if not available
++ * Remove "isPartOfTrace" from Loader interface
++ (we allow parts from multiple experiments for comp.)
++ * partview.cpp, partlistitem.h/cpp:
++ Remove Column Callees, add Trigger
++
++2003/05/10
++
++ * Status progress on loading and cycle calculation
++ * Corrected order of trace parts (PID/PartNo/ThreadID)
++ * Allow adding traces (BUGGY...)
++
++2003/02/06
++
++ * Version 0.3a
++ * Bugfixes:
++ - Compiles with KDE 3.0.x
++ - Always select a first cost type
++ - Loading from another directory
++
++
++2002/11/28
++
++ * Version 0.3
++
+diff --git a/kdecachegrind/INSTALL b/kdecachegrind/INSTALL
+new file mode 100644
+index 0000000..02a4a07
+--- /dev/null
++++ b/kdecachegrind/INSTALL
+@@ -0,0 +1,167 @@
++Basic Installation
++==================
++
++ These are generic installation instructions.
++
++ The `configure' shell script attempts to guess correct values for
++various system-dependent variables used during compilation. It uses
++those values to create a `Makefile' in each directory of the package.
++It may also create one or more `.h' files containing system-dependent
++definitions. Finally, it creates a shell script `config.status' that
++you can run in the future to recreate the current configuration, a file
++`config.cache' that saves the results of its tests to speed up
++reconfiguring, and a file `config.log' containing compiler output
++(useful mainly for debugging `configure').
++
++ If you need to do unusual things to compile the package, please try
++to figure out how `configure' could check whether to do them, and mail
++diffs or instructions to the address given in the `README' so they can
++be considered for the next release. If at some point `config.cache'
++contains results you don't want to keep, you may remove or edit it.
++
++ The file `configure.in' is used to create `configure' by a program
++called `autoconf'. You only need `configure.in' if you want to change
++it or regenerate `configure' using a newer version of `autoconf'.
++
++The simplest way to compile this package is:
++
++ 1. `cd' to the directory containing the package's source code and type
++ `./configure' to configure the package for your system. If you're
++ using `csh' on an old version of System V, you might need to type
++ `sh ./configure' instead to prevent `csh' from trying to execute
++ `configure' itself.
++
++ Running `configure' takes a while. While running, it prints some
++ messages telling which features it is checking for.
++
++ 2. Type `make' to compile the package.
++
++ 3. Type `make install' to install the programs and any data files and
++ documentation.
++
++ 4. You can remove the program binaries and object files from the
++ source code directory by typing `make clean'.
++
++Compilers and Options
++=====================
++
++ Some systems require unusual options for compilation or linking that
++the `configure' script does not know about. You can give `configure'
++initial values for variables by setting them in the environment. Using
++a Bourne-compatible shell, you can do that on the command line like
++this:
++ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
++
++Or on systems that have the `env' program, you can do it like this:
++ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
++
++Compiling For Multiple Architectures
++====================================
++
++ You can compile the package for more than one kind of computer at the
++same time, by placing the object files for each architecture in their
++own directory. To do this, you must use a version of `make' that
++supports the `VPATH' variable, such as GNU `make'. `cd' to the
++directory where you want the object files and executables to go and run
++the `configure' script. `configure' automatically checks for the
++source code in the directory that `configure' is in and in `..'.
++
++ If you have to use a `make' that does not supports the `VPATH'
++variable, you have to compile the package for one architecture at a time
++in the source code directory. After you have installed the package for
++one architecture, use `make distclean' before reconfiguring for another
++architecture.
++
++Installation Names
++==================
++
++ By default, `make install' will install the package's files in
++`/usr/local/bin', `/usr/local/man', etc. You can specify an
++installation prefix other than `/usr/local' by giving `configure' the
++option `--prefix=PATH'.
++
++ You can specify separate installation prefixes for
++architecture-specific files and architecture-independent files. If you
++give `configure' the option `--exec-prefix=PATH', the package will use
++PATH as the prefix for installing programs and libraries.
++Documentation and other data files will still use the regular prefix.
++
++ If the package supports it, you can cause programs to be installed
++with an extra prefix or suffix on their names by giving `configure' the
++option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
++
++Optional Features
++=================
++
++ Some packages pay attention to `--enable-FEATURE' options to
++`configure', where FEATURE indicates an optional part of the package.
++They may also pay attention to `--with-PACKAGE' options, where PACKAGE
++is something like `gnu-as' or `x' (for the X Window System). The
++`README' should mention any `--enable-' and `--with-' options that the
++package recognizes.
++
++ For packages that use the X Window System, `configure' can usually
++find the X include and library files automatically, but if it doesn't,
++you can use the `configure' options `--x-includes=DIR' and
++`--x-libraries=DIR' to specify their locations.
++
++Specifying the System Type
++==========================
++
++ There may be some features `configure' can not figure out
++automatically, but needs to determine by the type of host the package
++will run on. Usually `configure' can figure that out, but if it prints
++a message saying it can not guess the host type, give it the
++`--host=TYPE' option. TYPE can either be a short name for the system
++type, such as `sun4', or a canonical name with three fields:
++ CPU-COMPANY-SYSTEM
++
++See the file `config.sub' for the possible values of each field. If
++`config.sub' isn't included in this package, then this package doesn't
++need to know the host type.
++
++ If you are building compiler tools for cross-compiling, you can also
++use the `--target=TYPE' option to select the type of system they will
++produce code for and the `--build=TYPE' option to select the type of
++system on which you are compiling the package.
++
++Sharing Defaults
++================
++
++ If you want to set default values for `configure' scripts to share,
++you can create a site shell script called `config.site' that gives
++default values for variables like `CC', `cache_file', and `prefix'.
++`configure' looks for `PREFIX/share/config.site' if it exists, then
++`PREFIX/etc/config.site' if it exists. Or, you can set the
++`CONFIG_SITE' environment variable to the location of the site script.
++A warning: not all `configure' scripts look for a site script.
++
++Operation Controls
++==================
++
++ `configure' recognizes the following options to control how it
++operates.
++
++`--cache-file=FILE'
++ Use and save the results of the tests in FILE instead of
++ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
++ debugging `configure'.
++
++`--help'
++ Print a summary of the options to `configure', and exit.
++
++`--quiet'
++`--silent'
++`-q'
++ Do not print messages saying which checks are being made.
++
++`--srcdir=DIR'
++ Look for the package's source code in directory DIR. Usually
++ `configure' can determine that directory automatically.
++
++`--version'
++ Print the version of Autoconf used to generate the `configure'
++ script, and exit.
++
++`configure' also accepts some other, not widely useful, options.
++
+diff --git a/kdecachegrind/Makefile.am b/kdecachegrind/Makefile.am
+new file mode 100644
+index 0000000..e93f6af
+--- /dev/null
++++ b/kdecachegrind/Makefile.am
+@@ -0,0 +1,6 @@
++SUBDIRS = kdecachegrind pics converters
++
++EXTRA_DIST = \
++ AUTHORS COPYING NEWS ChangeLog INSTALL README TODO \
++ kdecachegrind.lsm kdecachegrind.spec version.h
++
+diff --git a/kdecachegrind/NEWS b/kdecachegrind/NEWS
+new file mode 100644
+index 0000000..e69de29
+diff --git a/kdecachegrind/README b/kdecachegrind/README
+new file mode 100644
+index 0000000..0866eb8
+--- /dev/null
++++ b/kdecachegrind/README
+@@ -0,0 +1,62 @@
++KCachegrind
++===========
++
++
++What is all this about ?
++-------------------------
++
++Profiling, i.e. determinating most time consuming execution parts,
++is an important last step when developing applications.
++KCachegrind visualizes traces, generated by profiling, in various ways;
++most notable is the TreeMap visualization of the calls happening
++and a condensed version of it, the Coverage analysis.
++KCachegrind is designed to allow fast browsing and to provide a quick
++overview of very large programs, such as KDE applications (but not
++limited to!).
++
++At the moment, it uses Cachegrind as profiling backend, which is using
++the excellent CPU simulator in Valgrind. Thus, profiling does not
++need any preparation, can cope with shared libraries and plugin
++architectures, and allows for profile runs to not influence the measuring
++by the profile itself (all in contrast to e.g. GProf). Disadvantage is
++slower profile runs, unfortunately.
++
++For Cachegrind to provide call tree information, a patch is provided.
++This enables the most interesting visualization features of KCachegrind.
++
++
++Requirements
++------------
++
++A call-tree version of Cachegrind:
++ - X86 Linux
++ - Valgrind 1.0.x with call-tree patch from KCachegrind Website
++ - Valgrind 2.0.x with call-tree skin installed
++
++Cachegrind runs on x86 platforms, KCachegrind on all KDE enabled
++platforms (KDE 3.0.x).
++
++
++Compilation and Installation
++----------------------------
++
++Simple do the command sequence
++
++ ./configure --prefix=<KDE base directory>
++ make
++ make install
++
++
++
++KCachegrind features
++--------------------
++
++Most important: TreeMap calltree visualisation.
++For the rest, see the detailed "What's this?" help for
++each part of KCachegrind and the quick starter on the
++WWW page ( http://kcachegrind.sourceforge.net/cgi-bin/show.cgi )
++
++
++
++Happy Profiling,
++ Josef Weidendorfer
+diff --git a/kdecachegrind/TODO b/kdecachegrind/TODO
+new file mode 100644
+index 0000000..1eca67e
+--- /dev/null
++++ b/kdecachegrind/TODO
+@@ -0,0 +1,100 @@
++TODO/Wishlist Items
++===================
++
++
++KCachegrind
++-----------
++
++All cost Lists:
++* Show up to a number of items, not down to a threadshold.
++ If more, add a "..." with number of items not shown, and context option
++ to show more
++* "Copy from Top" converts lists into ASCII, puts into clipboard
++
++
++Configuration:
++ Source dirs per ELF object
++
++Layout:
++* 1/2/3/4 vertical/horizontal FunctionInfos
++ with Shift/Wraparound selection mode
++* Inside each FunctionInfo different Layouts
++ - tabbed layout
++ - top: info, bottom left: calls/coverage, bottom right: graph/source
++* Long/short info tab
++
++General:
++* Selected Item can be a object/file/class/function/line
++* Configuration Dlg
++ - Local config (?)
++ - Cost Types
++ - function colors
++ - Try to reload source after config.
++* Session Management
++
++
++
++Annotation Views:
++
++ BUGS:
++ * Draw problem with multiple srcs to one target
++ * REP case...
++
++ TODO:
++ * Selectable Jumps (Arrows)
++ * Tooltip for Jumps (Kind, from/to, jump count)
++ * Show direction (arrows) on jump lines
++
++ Source view TODO:
++ * Implicit jumps (green) [needs support from the tool?]
++
++
++
++Callgraph:
++* Fix Arrows for back-arcs
++* Less "Jumps" for minimap
++* Correct Keyboard navigation (how?)
++
++Types:
++* Ratios
++* Automatic subtypes
++
++WISHS:
++* Support for Data tracing
++ Which variables are touched how often from which function?
++ - Some graphical visualisation...
++
++* GCC -pg (gmon.out) as Profiling Backend
++* Demangler (use c++filt)
++* Calculation of call weights (if not given)
++* OProfile, DynaProf
++
++Support for KCachegrind in Calltree
++-----------------------------------
++
++WISHS:
++- store more details of calltree
++ - for every function call: executed from shared lib
++ (Not needed, if function names are unique in whole app)
++ - adaptive call chain context (Really needed ? MUCH Data!)
++- dump at
++ - breakpoints
++ - watchpoints (with data tracing!)
++ - every xxx BBs (DONE)
++- dump around
++ - function invocation
++ - KAction event
++ - DCOP event
++
++- data accesses from (instr address/count)
++ stack: -> (function, stackframe-offset)
++ dynamic: -> (mem region start, [type], offset)
++ type can be get when a constructor is called for region
++ static: -> (mem region start, type, offset)
++
++* Generate full instr/data access trace for offline analysis.
++
++* Appending mode
++
++
++
+diff --git a/kdecachegrind/configure.in.in b/kdecachegrind/configure.in.in
+new file mode 100644
+index 0000000..dfc8508
+--- /dev/null
++++ b/kdecachegrind/configure.in.in
+@@ -0,0 +1,8 @@
++KCACHEGRIND_VERSION=0.4.6kde
++AC_SUBST(KCACHEGRIND_VERSION)
++
++AC_FUNC_MMAP
++
++dnl AC_OUTPUT( kdecachegrind/version.h )
++dnl AC_OUTPUT( kdecachegrind/kdecachegrind.spec )
++dnl AC_OUTPUT( kdecachegrind/kdecachegrind.lsm )
+diff --git a/kdecachegrind/converters/Makefile.am b/kdecachegrind/converters/Makefile.am
+new file mode 100644
+index 0000000..08b3696
+--- /dev/null
++++ b/kdecachegrind/converters/Makefile.am
+@@ -0,0 +1,2 @@
++bin_SCRIPTS = hotshot2calltree op2calltree pprof2calltree dprof2calltree \
++ memprof2calltree
+diff --git a/kdecachegrind/converters/README b/kdecachegrind/converters/README
+new file mode 100644
+index 0000000..c27d3c6
+--- /dev/null
++++ b/kdecachegrind/converters/README
+@@ -0,0 +1,24 @@
++This directory contains some scripts to convert output of different
++profiling tools into the format which can be loaded by KCachegrind.
++See the comment at start of every script for details.
++
++In the long run, these should be replaced by import filters in
++KCachegrind directly, but I can't promise anything. Partly, this
++is because some scripts are provided as contribution from others.
++
++hotshot2calltree Converter from Python Hotshot Profiler.
++op2calltree Converter from OProfile sampling data.
++dprof2calltree Converter from PERL::DProf Profiler.
++pprof2calltree Converter from APD PHP Profiler.
++
++Thanks go to
++* George Schlossnagle <george@omniti.com> for
++ dprof2calltree and pprof2calltree,
++* Jrg Beyer <job@webde-ag.de> for
++ hotshot2calltree
++
++If you want to write a converter, have a look at the calltree format
++description on the web site (kdecachegrind.sf.net).
++
++Josef
++
+diff --git a/kdecachegrind/converters/dprof2calltree b/kdecachegrind/converters/dprof2calltree
+new file mode 100644
+index 0000000..f276e18
+--- /dev/null
++++ b/kdecachegrind/converters/dprof2calltree
+@@ -0,0 +1,199 @@
++#!/usr/bin/perl
++#
++# Redistribution and use in source and binary forms, with or without
++# modification, are permitted provided that the following conditions are met:
++#
++# - Redistributions of source code must retain the above copyright notice,
++# this list of conditions and the following disclaimer.
++#
++# - Redistributions in binary form must reproduce the above copyright
++# notice, this list of conditions and the following disclaimer in the
++# documentation and/or other materials provided with the distribution.
++#
++# - All advertising materials mentioning features or use of this software
++# must display the following acknowledgement: This product includes software
++# developed by OmniTI Computer Consulting.
++#
++# - Neither name of the company nor the names of its contributors may be
++# used to endorse or promote products derived from this software without
++# specific prior written permission.
++#
++# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS `AS IS'' AND ANY
++# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
++# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++#
++# Copyright (c) 2004 OmniTI Computer Consulting
++# All rights reserved
++# The following code was written by George Schlossnagle <george@omniti.com>
++# and is provided completely free and without any warranty.
++#
++
++#
++# This script is designed to convert the tmon.out output emitted
++# from Perl's Devel::DProf profiling package. To use this:
++#
++# 1) Run your perl script as
++# > perl -d:DProf yoursript.pl
++# This will create a file called tmon.out. If you want to
++# inspect it on the command line, look at the man page
++# for dprofp for details.
++#
++# 2) Run
++# > dprof2calltree -f tmon.out
++# or
++# > dprof2calltree -f tmon.out -o cachegrind.out.foo
++#
++# This creates a cachegrind-style file called cachgrind.out.tmon.out or
++# cachegrind.out.foo, respecitvely.
++#
++# 3) Run kdecachegrind cachegrind.out.foo
++#
++# 4) Enjoy!
++
++use strict;
++use Config;
++use Getopt::Std;
++use IO::File;
++
++my @callstack;
++my %function_info;
++my $tree = {};
++my $total_cost = 0;
++my %opts;
++
++getopt('f:o:', \%opts);
++
++my $infd;
++usage() unless ($opts{'f'} && ($infd = IO::File->new($opts{'f'}, "r")));
++
++my $outfd;
++my $outfile = $opts{'o'};
++unless($outfile) {
++ $opts{'f'} =~ m!([^/]+)$!;
++ $outfile = "cachegrind.out.$1";
++}
++$outfd = new IO::File $outfile, "w";
++usage() unless defined $outfd;
++
++while(<$infd>) {
++ last if /^PART2/;
++}
++while(<$infd>) {
++ chomp;
++ my @args = split;
++ if($args[0] eq '@') {
++ # record timing event
++ my $call_element = pop @callstack;
++ if($call_element) {
++ $call_element->{'cost'} += $args[3];
++ $call_element->{'cumm_cost'} += $args[3];
++ $total_cost += $args[3];
++ push @callstack, $call_element;
++ }
++ }
++ elsif($args[0] eq '&') {
++ # declare function
++ $function_info{$args[1]}->{'package'} = $args[2];
++ if($args[2] ne 'main') {
++ $function_info{$args[1]}->{'name'} = $args[2]."::".$args[3];
++ } else {
++ $function_info{$args[1]}->{'name'} = $args[3];
++ }
++ }
++ elsif($args[0] eq '+') {
++ # push myself onto the stack
++ my $call_element = { 'specifier' => $args[1], 'cost' => 0 };
++ push @callstack, $call_element;
++ }
++ elsif($args[0] eq '-') {
++ my $called = pop @callstack;
++ my $called_id = $called->{'specifier'};
++ my $caller = pop @callstack;
++ if (exists $tree->{$called_id}) {
++ $tree->{$called_id}->{'cost'} += $called->{'cost'};
++ }
++ else {
++ $tree->{$called_id} = $called;
++ }
++ if($caller) {
++ $caller->{'child_calls'}++;
++ my $caller_id = $caller->{'specifier'};
++ if(! exists $tree->{$caller_id} ) {
++ $tree->{$caller_id} = { 'specifier' => $caller_id, 'cost' => 0 };
++# $tree->{$caller_id} = $caller;
++ }
++ $caller->{'cumm_cost'} += $called->{'cumm_cost'};
++ $tree->{$caller_id}->{'called_funcs'}->[$tree->{$caller_id}->{'call_counter'}++]->{$called_id} += $called->{'cumm_cost'};
++ push @callstack, $caller;
++ }
++ }
++ elsif($args[0] eq '*') {
++ # goto &func
++ # replace last caller with self
++ my $call_element = pop @callstack;
++ $call_element->{'specifier'} = $args[1];
++ push @callstack, $call_element;
++ }
++ else {print STDERR "Unexpected line: $_\n";}
++}
++
++#
++# Generate output
++#
++my $output = '';
++$output .= "events: Tick\n";
++$output .= "summary: $total_cost\n";
++$output .= "cmd: your script\n\n";
++foreach my $specifier ( keys %$tree ) {
++ my $caller_package = $function_info{$specifier}->{'package'} || '???';
++ my $caller_name = $function_info{$specifier}->{'name'} || '???';
++ my $include = find_include($caller_package);
++ $output .= "ob=\n";
++ $output .= sprintf "fl=%s\n", find_include($caller_package);
++ $output .= sprintf "fn=%s\n", $caller_name;
++ $output .= sprintf "1 %d\n", $tree->{$specifier}->{'cost'};
++ if(exists $tree->{$specifier}->{'called_funcs'}) {
++ foreach my $items (@{$tree->{$specifier}->{'called_funcs'}}) {
++ while(my ($child_specifier, $costs) = each %$items) {
++ $output .= sprintf "cfn=%s\n", $function_info{$child_specifier}->{'name'};
++ $output .= sprintf "cfi=%s\n", find_include($function_info{$child_specifier}->{'package'});
++ $output .= "calls=1\n";
++ $output .= sprintf "1 %d\n", $costs;
++ }
++ }
++ }
++ $output .= "\n";
++}
++print STDERR "Writing kdecachegrind output to $outfile\n";
++$outfd->print($output);
++
++
++
++sub find_include {
++ my $module = shift;
++ $module =~ s!::!/!g;
++ for (@INC) {
++ if ( -f "$_/$module.pm" ) {
++ return "$_/$module.pm";
++ }
++ if ( -f "$_/$module.so" ) {
++ return "$_/$module.so";
++ }
++ }
++ return "???";
++}
++
++sub usage() {
++ print STDERR "dprof2calltree -f <tmon.out> [-o outfile]\n";
++ exit -1;
++}
++
++
++# vim: set sts=2 ts=2 bs ai expandtab :
+diff --git a/kdecachegrind/converters/hotshot2calltree b/kdecachegrind/converters/hotshot2calltree
+new file mode 100644
+index 0000000..f62a46e
+--- /dev/null
++++ b/kdecachegrind/converters/hotshot2calltree
+@@ -0,0 +1,394 @@
++#!/usr/bin/env python
++# _*_ coding: latin1 _*_
++
++#
++# Copyright (c) 2003 by WEB.DE, Karlsruhe
++# Autor: Jrg Beyer <job@webde-ag.de>
++#
++# hotshot2cachegrind is free software; you can redistribute it and/or
++# modify it under the terms of the GNU General Public
++# License as published by the Free Software Foundation, version 2.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
++
++# You should have received a copy of the GNU General Public License
++# along with this program; see the file COPYING. If not, write to
++# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++# Boston, MA 02110-1301, USA.
++#
++#
++# This script transforms the pstat output of the hotshot
++# python profiler into the input of kdecachegrind.
++#
++# example usage:
++# modify you python script to run this code:
++#
++# import hotshot
++# filename = "pythongrind.prof"
++# prof = hotshot.Profile(filename, lineevents=1)
++# prof.runcall(run) # assuming that "run" should be called.
++# prof.close()
++#
++# it will run the "run"-method under profiling and write
++# the results in a file, called "pythongrind.prof".
++#
++# then call this script:
++# hotshot2cachegrind -o <output> <input>
++# or here:
++# hotshot2cachegrind cachegrind.out.0 pythongrind.prof
++#
++# then call kdecachegrind:
++# kdecachegrind cachegrind.out.0
++#
++# TODO:
++# * es gibt Probleme mit rekursiven (direkt und indirekt) Aufrufen - dann
++# stimmen die Kosten nicht.
++#
++# * einige Funktionen werden mit "?" als Name angezeigt. Evtl sind
++# das nur die C/C++ extensions.
++#
++# * es fehlt noch ein Funktionsnamen Mangling, dass die Filenamen bercksichtigt,
++# zZ sind alle __init__'s und alle run's schwer unterscheidbar :-(
++#
++version = "$Revision$"
++progname = "hotshot2cachegrind"
++
++import os, sys
++from hotshot import stats,log
++import os.path
++
++file_limit=0
++
++what2text = {
++ log.WHAT_ADD_INFO : "ADD_INFO",
++ log.WHAT_DEFINE_FUNC : "DEFINE_FUNC",
++ log.WHAT_DEFINE_FILE : "DEFINE_FILE",
++ log.WHAT_LINENO : "LINENO",
++ log.WHAT_EXIT : "EXIT",
++ log.WHAT_ENTER : "ENTER"}
++
++# a pseudo caller on the caller stack. This represents
++# the Python interpreter that executes the given python
++# code.
++root_caller = ("PythonInterpreter",0,"execute")
++
++class CallStack:
++ """A tiny Stack implementation, based on python lists"""
++ def __init__(self):
++ self.stack = []
++ self.recursion_counter = {}
++ def push(self, elem):
++ """put something on the stack"""
++ self.stack.append(elem)
++ rc = self.recursion_counter.get(elem, 0)
++ self.recursion_counter[elem] = rc + 1
++
++ def pop(self):
++ """get the head element of the stack and remove it from teh stack"""
++ elem = self.stack[-1:][0]
++ rc = self.recursion_counter.get(elem) - 1
++ if rc>0:
++ self.recursion_counter[elem] = rc
++ else:
++ del self.recursion_counter[elem]
++ return self.stack.pop()
++
++ def top(self):
++ """get the head element of the stack, stack is unchanged."""
++ return self.stack[-1:][0]
++ def handleLineCost(self, tdelta):
++ p, c = self.stack.pop()
++ self.stack.append( (p,c + tdelta) )
++ def size(self):
++ """ return how many elements the stack has"""
++ return len(self.stack)
++
++ def __str__(self):
++ return "[stack: %s]" % self.stack
++
++ def recursion(self, pos):
++ return self.recursion_counter.get(pos, 0)
++ #return self.recursion_dict.has_key((entry[0][0], entry[0][2]))
++
++def return_from_call(caller_stack, call_dict, cost_now):
++ """return from a function call
++ remove the function from the caller stack,
++ add the costs to the calling function.
++ """
++ called, cost_at_enter = caller_stack.pop()
++ caller, caller_cost = caller_stack.top()
++
++ #print "return_from_call: %s ruft %s" % (caller, called,)
++
++ per_file_dict = call_dict.get(called[0], {})
++ per_caller_dict = per_file_dict.get(called[2], {})
++ cost_so_far, call_counter = per_caller_dict.get(caller, (0, 0))
++
++ if caller_stack.recursion(called):
++ per_caller_dict[caller] = (cost_so_far, call_counter + 1)
++ else:
++ per_caller_dict[caller] = (cost_so_far + cost_now - cost_at_enter, call_counter + 1)
++
++ per_file_dict[called[2]] = per_caller_dict
++ call_dict[called[0]] = per_file_dict
++
++
++def updateStatus(filecount):
++ sys.stdout.write("reading File #%d \r" % filecount)
++ sys.stdout.flush()
++def convertProfFiles(output, inputfilenames):
++ """convert all the given input files into one kdecachegrind
++ input file.
++ """
++ call_dict = {}
++ cost_per_pos = {}
++ cost_per_function = {}
++ caller_stack = CallStack()
++ caller_stack.push((root_caller, 0))
++
++ total_cost = 0
++ filecount = 1
++ number_of_files = len(inputfilenames)
++ for inputfilename in inputfilenames:
++ updateStatus(filecount)
++ cost, filecount = convertHandleFilename(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount)
++ total_cost += cost
++ if (file_limit > 0) and (filecount > file_limit):
++ break
++
++ print
++ print "total_cost: % d Ticks",total_cost
++ dumpResults(output, call_dict, total_cost, cost_per_pos, cost_per_function)
++
++def convertHandleFilename(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount):
++ updateStatus(filecount)
++ if not ((file_limit > 0) and (filecount > file_limit)):
++ if os.path.isdir(inputfilename):
++ cost, filecount = convertProfDir(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount)
++ elif os.path.isfile(inputfilename):
++ cost = convertProfFile(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function)
++ filecount += 1
++ else:
++ sys.stderr.write("warn: ignoring '%s', is no file and no directory\n" % inputfilename)
++ cost = 0
++ return (cost, filecount)
++
++def convertProfDir(start, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount):
++ cost = 0
++ filenames = os.listdir(start)
++ for f in filenames:
++ if (file_limit > 0) and (filecount > file_limit):
++ break
++ full = os.path.join(start, f)
++ c, filecount = convertHandleFilename(full, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount)
++ cost += c;
++ return (cost, filecount)
++
++def handleCostPerPos(cost_per_pos, pos, current_cost):
++ """
++ the cost per source position are managed in a dict in a dict.
++
++ the cost are handled per file and there per function.
++ so, the per-file-dict contains some per-function-dicts
++ which sum up the cost per line (in this function and in
++ this file).
++ """
++ filename = pos[0]
++ lineno = pos[1]
++ funcname = pos[2]
++ file_dict = cost_per_pos.get(filename, {})
++ func_dict = file_dict.get(funcname, {})
++ func_dict.setdefault(lineno, 0)
++ func_dict[lineno] += current_cost
++ file_dict[funcname] = func_dict
++ cost_per_pos[filename] = file_dict
++
++def convertProfFile(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function):
++ """convert a single input file into one kdecachegrind
++ data.
++
++ this is the most expensive function in this python source :-)
++ """
++
++ total_cost = 0
++ try:
++ logreader = log.LogReader(inputfilename)
++ current_cost = 0
++ hc = handleCostPerPos # shortcut
++ for item in logreader:
++ what, pos ,tdelta = item
++ (file, lineno, func) = pos
++ #line = "%s %s %d %s %d" % (what2text[what], file, lineno, func, tdelta)
++ #print line
++ # most common cases first
++ if what == log.WHAT_LINENO:
++ # add the current cost to the current function
++ hc(cost_per_pos, pos, tdelta)
++ total_cost += tdelta
++ elif what == log.WHAT_ENTER:
++ caller_stack.push((pos, total_cost))
++ hc(cost_per_pos, pos, tdelta)
++ total_cost += tdelta
++ elif what == log.WHAT_EXIT:
++ hc(cost_per_pos, pos, tdelta)
++ total_cost += tdelta
++ return_from_call(caller_stack, call_dict, total_cost)
++ else:
++ assert 0, "duh: %d" % what
++
++
++ # I have no idea, why sometimes the stack is not empty - we
++ # have to rewind the stack to get 100% for the root_caller
++ while caller_stack.size() > 1:
++ return_from_call(caller_stack, call_dict, total_cost)
++
++ except IOError:
++ print "could not open inputfile '%s', ignore this." % inputfilename
++ except EOFError, m:
++ print "EOF: %s" % (m,)
++ return total_cost
++
++def pretty_name(file, function):
++ #pfile = os.path.splitext(os.path.basename(file)) [0]
++ #return "%s_[%s]" % (function, file)
++ return "%s" % function
++ #return "%s::%s" % (file, function)
++ #return "%s_%s" % (pfile, function)
++
++class TagWriter:
++ def __init__(self, output):
++ self.output = output
++ self.last_values = {}
++
++ def clearTag(self, tag):
++ if self.last_values.has_key(tag):
++ del self.last_values[ tag ]
++ def clear(self):
++ self.last_values = {}
++
++ def write(self, tag, value):
++ self.output.write("%s=%s\n" % (tag, value))
++ #if (not self.last_values.has_key(tag)) or self.last_values[tag] != value:
++ # self.last_values[ tag ] = value
++ # self.output.write("%s=%s\n" % (tag, value))
++
++def dumpResults(output, call_dict, total_cost, cost_per_pos, cost_per_function):
++ """write the collected results in the format kdecachegrind
++ could read.
++ """
++ # the intro
++ output.write("events: Tick\n")
++ output.write("summary: %d\n" % total_cost)
++ output.write("cmd: your python script\n")
++ output.write("\n")
++ tagwriter = TagWriter(output)
++
++ # now the costs per line
++ for file in cost_per_pos.keys():
++ func_dict = cost_per_pos[file]
++ for func in func_dict.keys():
++ line_dict = func_dict[func]
++ tagwriter.write("ob", file)
++ tagwriter.write("fn", func)# pretty_name(file, func)) ; output.write("# ^--- 2\n")
++ tagwriter.write("fl", file)
++ for line in line_dict:
++ output.write("%d %d\n" %( line, line_dict[line] ))
++
++ output.write("\n\n")
++ # now the function calls. For each caller all the called
++ # functions and their costs are written.
++ for file in call_dict.keys():
++ per_file_dict = call_dict[file]
++ #print "file %s -> %s" % (file, per_file_dict)
++ for called_x in per_file_dict.keys():
++ #print "called_x:",called_x
++ per_caller_dict = per_file_dict[called_x]
++ #print "called_x %s wird gerufen von: %s" % (called_x, per_caller_dict)
++ for caller_x in per_caller_dict.keys():
++ tagwriter.write("ob", caller_x[0])
++ tagwriter.write("fn", caller_x[2])# pretty_name(caller_x[2], caller_x[0])) ; output.write("# ^--- 1\n")
++ tagwriter.write("fl", caller_x[0])
++ tagwriter.write("cob", file)
++ tagwriter.write("cfn", called_x) #pretty_name(file, called_x))
++ tagwriter.write("cfl", file)
++ cost, count = per_caller_dict[caller_x]
++ #print "called_x:",called_x
++ output.write("calls=%d\n%d %d\n" % (count, caller_x[1], cost))
++ tagwriter.clear()
++ #tagwriter.clearTag("cob")
++ # is it a bug in kdecachegrind, that the "cob=xxx" line has
++ # to be rewritten after a calls entry with costline ?
++ #assert cost <= total_cost, "caller_x: %s, per_caller_dict: %s " % (caller_x, per_caller_dict, )
++ #output.write("calls=%d\n%d %d\n" % (count, caller_x[1], cost))
++ output.write("\n")
++
++def run_without_optparse():
++ """parse the options without optparse, use sys.argv"""
++ if len(sys.argv) < 4 or sys.argv[1] != "-o" :
++ print "usage: hotshot2cachegrind -o outputfile in1 [in2 [in3 [...]]]"
++ return
++ outputfilename = sys.argv[2]
++ try:
++ output = file(outputfilename, "w")
++ args = sys.argv[3:]
++ convertProfFiles(output, args)
++ output.close()
++ except IOError:
++ print "could not open '%s' for writing." % outputfilename
++
++def run_with_optparse():
++ """parse the options with optparse"""
++
++ global file_limit
++
++ versiontext = "%s version: %s" % ( progname, version.split()[1], )
++ parser = OptionParser(version=versiontext)
++ parser.add_option("-o", "--output",
++ action="store", type="string", dest="outputfilename",
++ help="write output into FILE")
++ parser.add_option("--file-limit",
++ action="store", dest="file_limit", default=0,
++ help="stop after given number of input files")
++ output = sys.stdout
++ close_output = 0
++ (options, args) = parser.parse_args()
++ file_limit = int(options.file_limit)
++ try:
++ if options.outputfilename and options.outputfilename != "-":
++ output = file(options.outputfilename, "w")
++ close_output = 1
++ except IOError:
++ print "could not open '%s' for writing." % options.outputfilename
++ if output:
++ convertProfFiles(output, args)
++ if close_output:
++ output.close()
++
++
++def profile_myself():
++ import hotshot
++ filename = "self.prof"
++ if not os.path.exists(filename):
++ prof = hotshot.Profile(filename, lineevents=1)
++ prof.runcall(run)
++ prof.close()
++ else:
++ print "not profiling myself, since '%s' exists, running normal" % filename
++ run()
++
++# check if optparse is available.
++try:
++ from optparse import OptionParser
++ run = run_with_optparse
++except ImportError:
++ run = run_without_optparse
++
++if __name__ == "__main__":
++ try:
++ run()
++ #profile_myself()
++ except KeyboardInterrupt:
++ sys.exit(1)
+diff --git a/kdecachegrind/converters/memprof2calltree b/kdecachegrind/converters/memprof2calltree
+new file mode 100755
+index 0000000..e82d6e8
+--- /dev/null
++++ b/kdecachegrind/converters/memprof2calltree
+@@ -0,0 +1,38 @@
++#!/usr/bin/perl
++#
++# Convert the memory profiles of memprof to calltree format,
++# loadable with KCachegrind
++#
++# (C) 2004, Josef Weidendorfer
++
++print "events: Allocated\n";
++
++while(<>) {
++ if (/^(\S.*)$/) {
++ $next = 0;
++ print "\nfn=$1\n";
++ next;
++ }
++ if (/^ children:/) {
++ $next = 1; #children
++ next;
++ }
++ if (/^ inherited:/) {
++ $next = 2; #inherited
++ next;
++ }
++ if (/^ total:/) {
++ # ignore, is calculated
++ next;
++ }
++ if (/^ self:\s*(\d+)/) {
++ if ($1 ne "0") {
++ print "0 $1\n";
++ }
++ next;
++ }
++ if (/^\s+(\S.*?):\s*(\d+)$/) {
++ if ($next < 2) { next; }
++ print "cfn=$1\ncalls=0 0\n0 $2\n";
++ }
++}
+diff --git a/kdecachegrind/converters/op2calltree b/kdecachegrind/converters/op2calltree
+new file mode 100755
+index 0000000..ca121a2
+--- /dev/null
++++ b/kdecachegrind/converters/op2calltree
+@@ -0,0 +1,238 @@
++#!/usr/bin/perl
++#
++# Copyright (c) 2004
++# Author: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++#
++# op2calltree is free software; you can redistribute it and/or
++# modify it under the terms of the GNU General Public
++# License as published by the Free Software Foundation, version 2.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
++
++# You should have received a copy of the GNU General Public License
++# along with this program; see the file COPYING. If not, write to
++# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++# Boston, MA 02110-1301, USA.
++#
++#
++# Converter from OProfile's output of "opreport -gdf" (v 0.8)
++# into callgrind format.
++#
++# Generate a OProfile report with opreport and flags -gdf
++# and pipe this as standard input into this script.
++# This will generate separate cachegrind files for every application.
++#
++
++
++# parse symbol line. example (with 1 event type, $has_image==0):
++# 308 0.1491 /path/source.c:6 /path/app main
++sub parseSymSpec {
++ $e = 0;
++ while($e < $eventCount) {
++ ($line) = ($line =~ /\d+\s+\S+\s+(.*)/);
++ $e++;
++ }
++ if ($line =~ s/^\(no location information\)\s+//) {
++ $file = "???";
++ $linenr = 0;
++ }
++ else {
++ ($file,$linenr) = ($line =~ s/(\S+?):(\d+)\s+//);
++ }
++ if ($has_image) {
++ if ($line =~ s/^(\S+)\s+//) { $img = $1; }
++ }
++ if ($has_app) {
++ if ($line =~ s/^(\S+)\s+//) { $app = $1; }
++ if (!$has_image) { $img = $app; }
++ }
++ $sym = $line;
++
++ $app =~ s/^.*\///;
++ if ($sym eq "(no symbols)") { $sym = "???"; }
++ $file{$sym} = $file;
++ $linenr{$sym} = $linenr;
++ $app{$sym} = $app;
++ $img{$app,$sym} = $img;
++ $syms{$app}++;
++
++ if ($app ne $oldApp) {
++ $oldApp = $app;
++ print "\n\nApp $app\n";
++ }
++ print " Symbol $sym (Image $img)\n";
++}
++
++
++
++$eventCount = 0;
++$descCount = 0;
++$lnr = 0;
++$has_image = 0;
++$has_app = 0;
++$app = "unnamed";
++$img = "???";
++
++# first loop till first symbol specification
++while(<>) {
++ $lnr++;
++ chomp;
++ if (/^CPU:/) {
++ $desc[$descCount++] = $_;
++ next;
++ }
++ if (/^Counted\s*(\S+)/) {
++ $desc[$descCount++] = $_;
++ $eventCount++;
++ $events[$eventCount] = $1;
++ next;
++ }
++ if (/^(Profiling through timer.*)/) {
++ $desc[$descCount++] = $_;
++ $eventCount++;
++ $events[$eventCount] = "Timer";
++ next;
++ }
++ if (/^vma/) {
++ # title row: adapt to separation options of OProfile
++ if (/image/) { $has_image = 1; }
++ if (/app/) { $has_app = 1; }
++ next;
++ }
++ if (/^([0-9a-fA-F]+)\s*(.*)$/) {
++ $vmaSym = $1;
++ $line = $2;
++ last;
++ }
++}
++
++if ($eventCount == 0) {
++ die "No Events found";
++}
++
++print "Description:\n";
++foreach $d (@desc) { print " $d\n"; }
++print "\n";
++
++print "Events:";
++foreach $e (@events) { print " $e"; }
++print "\n";
++
++parseSymSpec;
++
++while(<>) {
++ $lnr++;
++ if (/^([0-9a-fA-F]+)\s*(.*)$/) {
++ $vmaSym = $1;
++ $line = $2;
++
++ parseSymSpec;
++ next;
++ }
++ if (/^\s+([0-9a-fA-F]+)\s*(.*)$/) {
++
++ $sampleCount{$app,$sym}++;
++ $sc = $sampleCount{$app,$sym};
++
++ $vma{$app,$sym,$sc} = $1;
++ $line = $2;
++
++ $e = 1;
++ while($e <= $eventCount) {
++ ($cost, $line) = ($line =~ /(\d+)\s+\S+\s+(.*)/);
++ $summary{$app,$e} += $cost;
++ $cost{"$app,$sym,$sc,$e"} = $cost;
++ $e++;
++ }
++ if ($line =~ /\(no location information\)/) {
++ $file = "???";
++ $linenr = 0;
++ }
++ else {
++ ($file,$linenr) = ($line =~ /(\S+?):(\d+)/);
++ }
++ $sFile{$app,$sym,$sc} = $file;
++ $linenr{$app,$sym,$sc} = $linenr;
++
++ $file =~ s/^.*\///;
++ print " Sample $sc: $vma{$app,$sym,$sc} ($file:$linenr):";
++ foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; print " $c"; }
++ print "\n";
++ next;
++ }
++ die "ERROR: Reading line $lnr '$_'\n";
++}
++
++foreach $app (keys %syms) {
++ if ($app eq "") { next; }
++ print "Generating dump for App '$app'...\n";
++
++ $out = "# Generated by op2cg, using OProfile with opreport -gdf\n";
++ $out .= "positions: instr line\n";
++
++ $out .= "events:";
++ foreach $e (@events) { $out .= " $e"; }
++ $out .= "\n";
++
++ $out .= "summary:";
++ foreach $e (1 .. $eventCount) { $out .= " $summary{$app,$e}"; }
++ $out .= "\n\n";
++
++ %fileNum = ();
++ $fileNum = 1;
++ $sf = "";
++
++ $img = "";
++
++ foreach $sym (keys %file) {
++ if ($sampleCount{$app,$sym} eq "") { next; }
++
++ if ($img{$app,$sym} ne $img) {
++ $img = $img{$app,$sym};
++ $out .= "ob=$img\n";
++ }
++
++ $file = $file{$sym};
++ if ($sf ne $file) {
++ if ($fileNum{$file} eq "") {
++ $fileNum{$file} = $fileNum;
++ $out .= "fl=($fileNum) $file\n";
++ $fileNum++;
++ }
++ else {
++ $out .= "fl=($fileNum{$file})\n";
++ }
++ $sf = $file;
++ }
++
++ $out .= "fn=$sym\n";
++ foreach $sc (1 .. $sampleCount{$app,$sym}) {
++ if ($sf ne $sFile{$app,$sym,$sc}) {
++ $sf = $sFile{$app,$sym,$sc};
++ if ($sf eq $file) {
++ $out .= "fe=($fileNum{$file})\n";
++ }
++ else {
++ if ($fileNum{$sf} eq "") {
++ $fileNum{$sf} = $fileNum;
++ $out .= "fi=($fileNum) $sf\n";
++ $fileNum++;
++ }
++ else {
++ $out .= "fi=($fileNum{$sf})\n";
++ }
++ }
++ }
++ $out .= "0x$vma{$app,$sym,$sc} $linenr{$app,$sym,$sc}";
++ foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; $out .= " $c"; }
++ $out .= "\n";
++ }
++ }
++
++ open OUT, ">oprof.out.$app";
++ print OUT $out;
++ close OUT;
++}
+diff --git a/kdecachegrind/converters/pprof2calltree b/kdecachegrind/converters/pprof2calltree
+new file mode 100644
+index 0000000..0e70e1c
+--- /dev/null
++++ b/kdecachegrind/converters/pprof2calltree
+@@ -0,0 +1,218 @@
++#!/usr/bin/env php
++# Redistribution and use in source and binary forms, with or without
++# modification, are permitted provided that the following conditions are met:
++#
++# - Redistributions of source code must retain the above copyright notice,
++# this list of conditions and the following disclaimer.
++#
++# - Redistributions in binary form must reproduce the above copyright
++# notice, this list of conditions and the following disclaimer in the
++# documentation and/or other materials provided with the distribution.
++#
++# - All advertising materials mentioning features or use of this software
++# must display the following acknowledgement: This product includes software
++# developed by OmniTI Computer Consulting.
++#
++# - Neither name of the company nor the names of its contributors may be
++# used to endorse or promote products derived from this software without
++# specific prior written permission.
++#
++# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS `AS IS'' AND ANY
++# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
++# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++#
++# Copyright (c) 2004 OmniTI Computer Consulting
++# All rights reserved
++# The following code was written by George Schlossnagle <george@omniti.com>
++# and is provided completely free and without any warranty.
++#
++# This script is designed to convert the pprof output from
++# APD (http://pecl.php.net/apd/) to one readable by kdecachegrind. To use
++# this script:
++#
++# 1) Install APD.
++# 2) Profile your script with APD accordingto the directions in it's
++# README file.
++# 3) Take the pprof trace file for your script (pprof.XXXXX.Y) and run it
++# through this script as follows:
++# > pprof2calltree -f pprof.12345.1
++# This creates a new file cachegrind.out.12345.1
++# 4) View your trace with pprof2calltree cachegrind.out.12345.1
++
++<?php
++
++require "Console/Getopt.php";
++
++$con = new Console_Getopt;
++$args = $con->readPHPArgv();
++array_shift($args);
++$shortoptions = 'f:';
++$retval = $con->getopt( $args, $shortoptions);
++if(is_object($retval)) {
++ usage();
++}
++foreach ($retval[0] as $kv_array) {
++ $opt[$kv_array[0]] = $kv_array[1];
++}
++if(!$opt['f']) {
++ usage();
++}
++if(!file_exists($opt['f'])) {
++ print "Trace file ${opt['f']} does not exist\n";
++ exit;
++}
++$IN = fopen($opt['f'], "r");
++if(!$IN) {
++ print "Trace file ${opt['f']} could not be opened\n";
++ exit;
++}
++
++$path_parts = pathinfo($opt['f']);
++$outfile = "cachegrind.out.".$path_parts['basename'];
++$OUT = fopen($outfile, "w");
++if(!$OUT) {
++ print "Destination file $outfile could not be opened.\n";
++ exit;
++}
++
++while(($line = fgets($IN)) !== false) {
++ $line = rtrim($line);
++ if($line == "END_HEADER") {
++ break;
++ }
++}
++$tree = array();
++$callstack = array();
++while(($line = fgets($IN)) !== false) {
++ $line = rtrim($line);
++ $args = explode(" ", $line);
++ if($args[0] == '!') {
++ $file_lookup[$args[1]] = $args[2];
++ }
++ else if($args[0] == '&') {
++ $function_lookup[$args[1]] = $args[2];
++ $function_type[$args[1]] = ($args[3] == 2)?"USER":"INTERNAL";
++ }
++ else if($args[0] == '+') {
++ $val = array(function_id => $args[1],
++ file_id => $args[2],
++ line => $args[3],
++ cost => 0);
++ array_push($callstack, $val);
++ }
++ else if($args[0] == '-') {
++ // retrieve $called to discard
++ $called = array_pop($callstack);
++ // retrieve $caller for reference
++ $caller = array_pop($callstack);
++ $called_id = $called['function_id'];
++
++ // Set meta data if not already set'
++ if(!array_key_exists($called_id, $tree)) {
++ $tree[$called_id] = $called;
++ // initialize these to 0
++ $tree[$called_id]['cost_per_line'] = array();
++ }
++ if($caller !== null) {
++ $caller['child_calls']++;
++ $caller_id = $caller['function_id'];
++ if(!array_key_exists($caller_id, $tree)) {
++ $tree[$caller_id] = $caller;
++ }
++ $caller['cost'] += $called['cost'];
++ $tree[$caller_id]['called_funcs'][$tree[$caller_id]['call_counter']++][$called_id][$called['file_id']][$called['line']] += $called['cost'];
++ array_push($callstack, $caller);
++ }
++ if(is_array($called['cost_per_line'])) {
++ foreach($called[cost_per_line] as $file => $lines) {
++ foreach($lines as $line => $cost) {
++ $tree[$called_id]['cost_per_line'][$file][$line] += $cost;
++ }
++ }
++ }
++ }
++ else if($args[0] == '@') {
++ $called = array_pop($callstack);
++ switch(count($args)) {
++ // support new and old-style pprof data
++ case 6:
++ $file = $args[1];
++ $line = $args[2];
++ $real_tm = $args[5];
++ break;
++ case 4:
++ $file = $called['file_id'];
++ $line = $called['line'];
++ $real_tm = $args[3];
++ break;
++
++ }
++ $called['cost_per_line'][$file][$line] += $real_tm;
++ $called['cost'] += $real_tm;
++ $total_cost += $real_tm;
++ array_push($callstack, $called);
++ }
++}
++
++ob_start();
++print "events: Tick\n";
++print "summary: $total_cost\n";
++printf("cmd: %s\n", $file_lookup[1]);
++print "\n";
++
++foreach($tree as $caller => $data) {
++ $filename = $file_lookup[$data['file_id']]?$file_lookup[$data['file_id']]:"???";
++ printf("ob=%s\n", $function_type[$caller]);
++ printf("fl=%s\n", $filename);
++ printf("fn=%s\n", $function_lookup[$caller]);
++ if(is_array($data['cost_per_line'])) {
++ foreach($data['cost_per_line'] as $file => $lines) {
++ foreach($lines as $line => $cost) {
++ print "$line $cost\n";
++ }
++ }
++ }
++ else if ($data['cost']) {
++ printf("COST %s %s\n", $items['line'], $items['cost']);
++ }
++ else {
++ print_r($items);
++ }
++ if(is_array($data['called_funcs'])) {
++ foreach($data['called_funcs'] as $counter => $items) {
++ foreach($items as $called_id => $costs) {
++ if(is_array($costs)) {
++ printf("cfn=%s\n", $function_lookup[$called_id]);
++ foreach($costs as $file => $lines) {
++ printf("cfi=%s\ncalls=1\n", $file_lookup[$file]);
++ foreach($lines as $line => $cost) {
++ print "$line $cost\n";
++ }
++ }
++ }
++ }
++ }
++ }
++ print "\n";
++}
++print "\ntotals=$total_cost\n";
++$buffer = ob_get_clean();
++print "Writing kdecachegrind compatible output to $outfile\n";
++fwrite($OUT, $buffer);
++
++function usage()
++{
++ print <<<EOD
++pprof2calltree -f <tracefile>
++
++EOD;
++ exit(1);
++}
++?>
+diff --git a/kdecachegrind/pics/Makefile.am b/kdecachegrind/pics/Makefile.am
+new file mode 100644
+index 0000000..f4a3186
+--- /dev/null
++++ b/kdecachegrind/pics/Makefile.am
+@@ -0,0 +1,3 @@
++kdecachegrindicondir = $(kde_datadir)/kdecachegrind/icons
++kdecachegrindicon_ICON = AUTO
++SUBDIRS = hicolor
+diff --git a/kdecachegrind/pics/hicolor/Makefile.am b/kdecachegrind/pics/hicolor/Makefile.am
+new file mode 100644
+index 0000000..068e319
+--- /dev/null
++++ b/kdecachegrind/pics/hicolor/Makefile.am
+@@ -0,0 +1,2 @@
++kdecachegrindicondir = $(kde_datadir)/kdecachegrind/icons
++kdecachegrindicon_ICON = AUTO
+diff --git a/kdecachegrind/pics/hicolor/hi16-action-fromrec.png b/kdecachegrind/pics/hicolor/hi16-action-fromrec.png
+new file mode 100644
+index 0000000..a5cb430
+Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi16-action-fromrec.png differ
+diff --git a/kdecachegrind/pics/hicolor/hi16-action-percent.png b/kdecachegrind/pics/hicolor/hi16-action-percent.png
+new file mode 100644
+index 0000000..7a4ba47
+Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi16-action-percent.png differ
+diff --git a/kdecachegrind/pics/hicolor/hi16-action-recrec.png b/kdecachegrind/pics/hicolor/hi16-action-recrec.png
+new file mode 100644
+index 0000000..ec11bfa
+Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi16-action-recrec.png differ
+diff --git a/kdecachegrind/pics/hicolor/hi16-action-torec.png b/kdecachegrind/pics/hicolor/hi16-action-torec.png
+new file mode 100644
+index 0000000..c092c01
+Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi16-action-torec.png differ
+diff --git a/kdecachegrind/pics/hicolor/hi22-action-percent.png b/kdecachegrind/pics/hicolor/hi22-action-percent.png
+new file mode 100644
+index 0000000..c64a378
+Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi22-action-percent.png differ
+diff --git a/kdecachegrind/pics/hicolor/hi32-action-percent.png b/kdecachegrind/pics/hicolor/hi32-action-percent.png
+new file mode 100644
+index 0000000..e876c30
+Binary files /dev/null and b/kdecachegrind/pics/hicolor/hi32-action-percent.png differ
+diff --git a/kdecachegrind/kdecachegrind.lsm.in b/kdecachegrind/kdecachegrind.lsm.in
+new file mode 100644
+index 0000000..fab7ced
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind.lsm.in
+@@ -0,0 +1,11 @@
++Begin3
++Title: kdecachegrind
++Version: @KCACHEGRIND_VERSION@
++Description: KDE Profiling Visualisation Tool
++Keywords: Profiling, Performance Analysis, Visualisation, Development
++Author: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++Maintained-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++Home-page: http://kcachegrind.sourceforge.net
++Platforms: Linux and other Unices
++Copying-policy: GNU Public License
++End
+diff --git a/kdecachegrind/kdecachegrind.spec.in b/kdecachegrind/kdecachegrind.spec.in
+new file mode 100644
+index 0000000..42b3e24
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind.spec.in
+@@ -0,0 +1,55 @@
++Summary: KDE Profiling Visualisation Tool
++Name: kdecachegrind
++Version: @KCACHEGRIND_VERSION@
++Release: 1
++Copyright: GPL
++Group: Development/Tools
++Vendor: (none)
++URL: http://kcachegrind.sourceforge.net
++Packager: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++Source: kdecachegrind-@KCACHEGRIND_VERSION@.tar.gz
++BuildRoot: /var/tmp/build
++
++%description
++KCachegrind is a GPL'd tool for quick browsing in and visualisation
++of performance data of an application run. This data is produced by
++profiling tools and typically includes distribution of cost events
++to source code ranges (instructions, source lines, functions, C++ classes)
++and call relationship of functions.
++KCachegrind has a list of functions sorted according to different cost
++types, and can provide various performance views for a function like
++direct/indirect callers/callees, TreeMap visualisation of cost distribution
++among callees, call graph sectors centered around the function and
++annotated source/assembler.
++Currently, KCachegrind depends on data delivered by the profiling tool
++calltree, powered by the Valgrind runtime instrumentation framework.
++
++%prep
++%setup
++CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure \
++ \
++ $LOCALFLAGS
++%build
++# Setup for parallel builds
++numprocs=`egrep -c ^cpu[0-9]+ /proc/stat || :`
++if [ "$numprocs" = "0" ]; then
++ numprocs=1
++fi
++
++make -j$numprocs
++
++%install
++make install-strip DESTDIR=$RPM_BUILD_ROOT
++
++cd $RPM_BUILD_ROOT
++find . -type d | sed '1,2d;s,^\.,\%attr(-\,root\,root) \%dir ,' > $RPM_BUILD_DIR/file.list.kdecachegrind
++find . -type f | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.kdecachegrind
++find . -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.kdecachegrind
++
++%clean
++rm -rf $RPM_BUILD_ROOT/*
++rm -rf $RPM_BUILD_DIR/kdecachegrind
++rm -rf ../file.list.kdecachegrind
++
++
++%files -f ../file.list.kdecachegrind
+diff --git a/kdecachegrind/kdecachegrind/Doxyfile b/kdecachegrind/kdecachegrind/Doxyfile
+new file mode 100644
+index 0000000..9d5d050
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/Doxyfile
+@@ -0,0 +1,157 @@
++# Doxygen configuration generated by Doxywizard version 0.1
++#---------------------------------------------------------------------------
++# General configuration options
++#---------------------------------------------------------------------------
++PROJECT_NAME = kdecachegrind
++PROJECT_NUMBER =
++OUTPUT_DIRECTORY =
++OUTPUT_LANGUAGE = English
++EXTRACT_ALL = YES
++EXTRACT_PRIVATE = YES
++EXTRACT_STATIC = YES
++HIDE_UNDOC_MEMBERS =
++HIDE_UNDOC_CLASSES =
++BRIEF_MEMBER_DESC =
++REPEAT_BRIEF =
++ALWAYS_DETAILED_SEC =
++FULL_PATH_NAMES =
++STRIP_FROM_PATH =
++INTERNAL_DOCS =
++CLASS_DIAGRAMS =
++SOURCE_BROWSER =
++INLINE_SOURCES =
++STRIP_CODE_COMMENTS =
++CASE_SENSE_NAMES =
++SHORT_NAMES =
++HIDE_SCOPE_NAMES =
++VERBATIM_HEADERS =
++SHOW_INCLUDE_FILES =
++JAVADOC_AUTOBRIEF =
++INHERIT_DOCS =
++INLINE_INFO =
++SORT_MEMBER_DOCS =
++DISTRIBUTE_GROUP_DOC =
++TAB_SIZE =
++ENABLED_SECTIONS =
++GENERATE_TODOLIST =
++GENERATE_TESTLIST =
++GENERATE_BUGLIST =
++ALIASES =
++MAX_INITIALIZER_LINES =
++OPTIMIZE_OUTPUT_FOR_C =
++SHOW_USED_FILES =
++#---------------------------------------------------------------------------
++# configuration options related to warning and progress messages
++#---------------------------------------------------------------------------
++QUIET =
++WARNINGS =
++WARN_IF_UNDOCUMENTED =
++WARN_FORMAT = "$file:$line: $text"
++WARN_LOGFILE =
++#---------------------------------------------------------------------------
++# configuration options related to the input files
++#---------------------------------------------------------------------------
++INPUT = .
++FILE_PATTERNS = *.cpp \
++ *.h
++RECURSIVE = no
++EXCLUDE =
++EXCLUDE_PATTERNS =
++EXAMPLE_PATH =
++EXAMPLE_PATTERNS =
++IMAGE_PATH =
++INPUT_FILTER =
++FILTER_SOURCE_FILES =
++#---------------------------------------------------------------------------
++# configuration options related to the alphabetical class index
++#---------------------------------------------------------------------------
++ALPHABETICAL_INDEX =
++COLS_IN_ALPHA_INDEX =
++IGNORE_PREFIX =
++#---------------------------------------------------------------------------
++# configuration options related to the HTML output
++#---------------------------------------------------------------------------
++GENERATE_HTML =
++HTML_OUTPUT = html
++HTML_HEADER =
++HTML_FOOTER =
++HTML_STYLESHEET =
++HTML_ALIGN_MEMBERS =
++GENERATE_HTMLHELP =
++GENERATE_CHI =
++BINARY_TOC =
++TOC_EXPAND =
++DISABLE_INDEX =
++ENUM_VALUES_PER_LINE =
++GENERATE_TREEVIEW =
++TREEVIEW_WIDTH =
++#---------------------------------------------------------------------------
++# configuration options related to the LaTeX output
++#---------------------------------------------------------------------------
++GENERATE_LATEX = NO
++LATEX_OUTPUT = latex
++COMPACT_LATEX =
++PAPER_TYPE = a4wide
++EXTRA_PACKAGES =
++LATEX_HEADER =
++PDF_HYPERLINKS =
++USE_PDFLATEX =
++LATEX_BATCHMODE =
++#---------------------------------------------------------------------------
++# configuration options related to the RTF output
++#---------------------------------------------------------------------------
++GENERATE_RTF = NO
++RTF_OUTPUT = rtf
++COMPACT_RTF =
++RTF_HYPERLINKS =
++RTF_STYLESHEET_FILE =
++RTF_EXTENSIONS_FILE =
++#---------------------------------------------------------------------------
++# configuration options related to the man page output
++#---------------------------------------------------------------------------
++GENERATE_MAN = NO
++MAN_OUTPUT = man
++MAN_EXTENSION = .3
++MAN_LINKS =
++#---------------------------------------------------------------------------
++# Configuration options related to the preprocessor
++#---------------------------------------------------------------------------
++ENABLE_PREPROCESSING =
++MACRO_EXPANSION =
++EXPAND_ONLY_PREDEF =
++SEARCH_INCLUDES =
++INCLUDE_PATH =
++INCLUDE_FILE_PATTERNS =
++PREDEFINED =
++EXPAND_AS_DEFINED =
++#---------------------------------------------------------------------------
++# Configuration::addtions related to external references
++#---------------------------------------------------------------------------
++TAGFILES =
++GENERATE_TAGFILE =
++ALLEXTERNALS =
++PERL_PATH = /usr/bin/perl
++#---------------------------------------------------------------------------
++# Configuration options related to the dot tool
++#---------------------------------------------------------------------------
++HAVE_DOT =
++CLASS_GRAPH =
++COLLABORATION_GRAPH =
++INCLUDE_GRAPH =
++INCLUDED_BY_GRAPH =
++GRAPHICAL_HIERARCHY =
++DOT_PATH =
++MAX_DOT_GRAPH_WIDTH =
++MAX_DOT_GRAPH_HEIGHT =
++GENERATE_LEGEND =
++DOT_CLEANUP =
++#---------------------------------------------------------------------------
++# Configuration::addtions related to the search engine
++#---------------------------------------------------------------------------
++SEARCHENGINE =
++CGI_NAME = search.cgi
++CGI_URL =
++DOC_URL =
++DOC_ABSPATH =
++BIN_ABSPATH = /usr/local/bin/
++EXT_DOC_PATHS =
+diff --git a/kdecachegrind/kdecachegrind/Makefile.am b/kdecachegrind/kdecachegrind/Makefile.am
+new file mode 100644
+index 0000000..53cd35d
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/Makefile.am
+@@ -0,0 +1,62 @@
++bin_PROGRAMS = kdecachegrind
++
++kdecachegrind_SOURCES = \
++ functionselectionbase.ui \
++ stackselectionbase.ui \
++ partselectionbase.ui \
++ configdlgbase.ui \
++ loader.cpp cachegrindloader.cpp treemap.cpp pool.cpp \
++ main.cpp configuration.cpp \
++ functionselection.cpp coverage.cpp partgraph.cpp \
++ toplevel.cpp stackselection.cpp stackbrowser.cpp \
++ subcost.cpp tracedata.cpp partselection.cpp configdlg.cpp \
++ utils.cpp fixcost.cpp \
++ traceitemview.cpp instrview.cpp tabview.cpp \
++ sourceview.cpp callmapview.cpp callview.cpp \
++ coverageview.cpp costtypeview.cpp partview.cpp \
++ listutils.cpp costtypeitem.cpp multiview.cpp \
++ callitem.cpp coverageitem.cpp sourceitem.cpp \
++ costlistitem.cpp partlistitem.cpp functionitem.cpp \
++ instritem.cpp stackitem.cpp callgraphview.cpp
++
++kdecachegrind_COMPILE_FIRST = ../version.h
++
++kdecachegrind_LDADD = $(LIB_KIO)
++
++KDE_ICON = AUTO
++
++xdg_apps_DATA = kdecachegrind.desktop
++
++mimeapplicationdir = $(kde_mimedir)/application
++mimeapplication_DATA = x-kcachegrind.desktop
++
++EXTRA_DIST = \
++ kdecachegrind.desktop \
++ x-kcachegrind.desktop \
++ hi32-app-kcachegrind.png \
++ hi48-app-kcachegrind.png \
++ Doxyfile \
++ kdecachegrindui.rc
++
++# set the include path for X, qt and KDE
++INCLUDES= $(all_includes)
++
++METASOURCES = AUTO
++
++# the library search path.
++kdecachegrind_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_KDECORE) $(LIB_KDEUI) -lkdefx $(LIB_KIO) -lktexteditor
++
++rcdir = $(kde_datadir)/kdecachegrind
++rc_DATA = kdecachegrindui.rc
++
++tipdir = $(kde_datadir)/kdecachegrind
++tip_DATA = tips
++
++messages: rc.cpp
++ $(PREPARETIPS) > tips.txt
++ LIST=`find . -name \*.h -o -name \*.cpp -o -name \*.txt`; \
++ if test -n "$$LIST"; then \
++ $(XGETTEXT) $$LIST -o $(podir)/kdecachegrind.pot; \
++ fi
++ rm -f tips.txt
++
+diff --git a/kdecachegrind/kdecachegrind/cachegrindloader.cpp b/kdecachegrind/kdecachegrind/cachegrindloader.cpp
+new file mode 100644
+index 0000000..4fe57d3
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/cachegrindloader.cpp
+@@ -0,0 +1,1323 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#include <errno.h>
++
++#include <tqfile.h>
++#include <tqcstring.h>
++
++#include <klocale.h>
++#include <kdebug.h>
++
++#include "loader.h"
++#include "tracedata.h"
++#include "utils.h"
++#include "fixcost.h"
++
++
++#define TRACE_LOADER 0
++
++/*
++ * Loader for Callgrind Profile data (format based on Cachegrind format).
++ * See Callgrind documentation for the file format.
++ */
++
++class CachegrindLoader: public Loader
++{
++public:
++ CachegrindLoader();
++
++ bool canLoadTrace(TQFile* file);
++ bool loadTrace(TracePart*);
++ bool isPartOfTrace(TQString file, TraceData*);
++
++private:
++ bool loadTraceInternal(TracePart*);
++
++ enum lineType { SelfCost, CallCost, BoringJump, CondJump };
++
++ bool parsePosition(FixString& s, PositionSpec& newPos);
++
++ // position setters
++ void clearPosition();
++ void ensureObject();
++ void ensureFile();
++ void ensureFunction();
++ void setObject(const TQString&);
++ void setCalledObject(const TQString&);
++ void setFile(const TQString&);
++ void setCalledFile(const TQString&);
++ void setFunction(const TQString&);
++ void setCalledFunction(const TQString&);
++
++ TQString _emptyString;
++
++ // current line in file to read in
++ TQString _filename;
++ int _lineNo;
++
++ TraceSubMapping* subMapping;
++ TraceData* _data;
++ TracePart* _part;
++
++ // current position
++ lineType nextLineType;
++ bool hasLineInfo, hasAddrInfo;
++ PositionSpec currentPos;
++
++ // current function/line
++ TraceObject* currentObject;
++ TracePartObject* currentPartObject;
++ TraceFile* currentFile;
++ TracePartFile* currentPartFile;
++ TraceFunction* currentFunction;
++ TracePartFunction* currentPartFunction;
++ TraceFunctionSource* currentFunctionSource;
++ TraceInstr* currentInstr;
++ TracePartInstr* currentPartInstr;
++ TraceLine* currentLine;
++ TracePartLine* currentPartLine;
++
++ // current call
++ TraceObject* currentCalledObject;
++ TracePartObject* currentCalledPartObject;
++ TraceFile* currentCalledFile;
++ TracePartFile* currentCalledPartFile;
++ TraceFunction* currentCalledFunction;
++ TracePartFunction* currentCalledPartFunction;
++ SubCost currentCallCount;
++
++ // current jump
++ TraceFile* currentJumpToFile;
++ TraceFunction* currentJumpToFunction;
++ PositionSpec targetPos;
++ SubCost jumpsFollowed, jumpsExecuted;
++
++ /** Support for compressed string format
++ * This uses the following string compression model
++ * for objects, files, functions:
++ * If the name matches
++ * "(<Integer>) Name": this is a compression specification,
++ * mapping the integer number to Name and using Name.
++ * "(<Integer>)" : this is a compression reference.
++ * Assumes previous compression specification of the
++ * integer number to a name, uses this name.
++ * "Name" : Regular name
++ */
++ void clearCompression();
++ const TQString& checkUnknown(const TQString& n);
++ TraceObject* compressedObject(const TQString& name);
++ TraceFile* compressedFile(const TQString& name);
++ TraceFunction* compressedFunction(const TQString& name,
++ TraceFile*, TraceObject*);
++
++ TQPtrVector<TraceCostItem> _objectVector, _fileVector, _functionVector;
++};
++
++
++
++/**********************************************************
++ * Loader
++ */
++
++
++CachegrindLoader::CachegrindLoader()
++ : Loader("Callgrind",
++ i18n( "Import filter for Cachegrind/Callgrind generated profile data files") )
++{
++ _emptyString = TQString("");
++}
++
++bool CachegrindLoader::canLoadTrace(TQFile* file)
++{
++ if (!file) return false;
++
++ if (!file->isOpen()) {
++ if (!file->open( IO_ReadOnly ) ) {
++ kdDebug() << TQFile::encodeName(_filename).data() << ": "
++ << strerror( errno ) << endl;
++ return false;
++ }
++ }
++
++ /*
++ * We recognize this as cachegrind/callgrind format if in the first
++ * 2047 bytes we see the string "\nevents:"
++ */
++ char buf[2048];
++ int read = file->readBlock(buf,2047);
++ if (read < 0)
++ return false;
++ buf[read] = 0;
++
++ TQCString s;
++ s.setRawData(buf, read+1);
++ int pos = s.find("events:");
++ if (pos>0 && buf[pos-1] != '\n') pos = -1;
++ s.resetRawData(buf, read+1);
++ return (pos>=0);
++}
++
++bool CachegrindLoader::loadTrace(TracePart* p)
++{
++ /* do the loading in a new object so parallel load
++ * operations do not interfere each other.
++ */
++ CachegrindLoader l;
++
++ /* emit progress signals via the singleton loader */
++ connect(&l, TQT_SIGNAL(updateStatus(TQString, int)),
++ this, TQT_SIGNAL(updateStatus(TQString, int)));
++
++ return l.loadTraceInternal(p);
++}
++
++Loader* createCachegrindLoader()
++{
++ return new CachegrindLoader();
++}
++
++
++
++/**
++ * Return false if this is no position specification
++ */
++bool CachegrindLoader::parsePosition(FixString& line,
++ PositionSpec& newPos)
++{
++ char c;
++ uint diff;
++
++ if (hasAddrInfo) {
++
++ if (!line.first(c)) return false;
++
++ if (c == '*') {
++ // nothing changed
++ line.stripFirst(c);
++ newPos.fromAddr = currentPos.fromAddr;
++ newPos.toAddr = currentPos.toAddr;
++ }
++ else if (c == '+') {
++ line.stripFirst(c);
++ line.stripUInt(diff, false);
++ newPos.fromAddr = currentPos.fromAddr + diff;
++ newPos.toAddr = newPos.fromAddr;
++ }
++ else if (c == '-') {
++ line.stripFirst(c);
++ line.stripUInt(diff, false);
++ newPos.fromAddr = currentPos.fromAddr - diff;
++ newPos.toAddr = newPos.fromAddr;
++ }
++ else if (c >= '0') {
++ uint64 v;
++ line.stripUInt64(v, false);
++ newPos.fromAddr = Addr(v);
++ newPos.toAddr = newPos.fromAddr;
++ }
++ else return false;
++
++ // Range specification
++ if (line.first(c)) {
++ if (c == '+') {
++ line.stripFirst(c);
++ line.stripUInt(diff);
++ newPos.toAddr = newPos.fromAddr + diff;
++ }
++ else if ((c == '-') || (c == ':')) {
++ line.stripFirst(c);
++ uint64 v;
++ line.stripUInt64(v);
++ newPos.toAddr = Addr(v);
++ }
++ }
++ line.stripSpaces();
++
++#if TRACE_LOADER
++ if (newPos.fromAddr == newPos.toAddr)
++ kdDebug() << " Got Addr " << newPos.fromAddr.toString() << endl;
++ else
++ kdDebug() << " Got AddrRange " << newPos.fromAddr.toString()
++ << ":" << newPos.toAddr.toString() << endl;
++#endif
++
++ }
++
++ if (hasLineInfo) {
++
++ if (!line.first(c)) return false;
++
++ if (c > '9') return false;
++ else if (c == '*') {
++ // nothing changed
++ line.stripFirst(c);
++ newPos.fromLine = currentPos.fromLine;
++ newPos.toLine = currentPos.toLine;
++ }
++ else if (c == '+') {
++ line.stripFirst(c);
++ line.stripUInt(diff, false);
++ newPos.fromLine = currentPos.fromLine + diff;
++ newPos.toLine = newPos.fromLine;
++ }
++ else if (c == '-') {
++ line.stripFirst(c);
++ line.stripUInt(diff, false);
++ if (currentPos.fromLine < diff) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Negative line number "
++ << (int)currentPos.fromLine - (int)diff << endl;
++ diff = currentPos.fromLine;
++ }
++ newPos.fromLine = currentPos.fromLine - diff;
++ newPos.toLine = newPos.fromLine;
++ }
++ else if (c >= '0') {
++ line.stripUInt(newPos.fromLine, false);
++ newPos.toLine = newPos.fromLine;
++ }
++ else return false;
++
++ // Range specification
++ if (line.first(c)) {
++ if (c == '+') {
++ line.stripFirst(c);
++ line.stripUInt(diff);
++ newPos.toLine = newPos.fromLine + diff;
++ }
++ else if ((c == '-') || (c == ':')) {
++ line.stripFirst(c);
++ line.stripUInt(newPos.toLine);
++ }
++ }
++ line.stripSpaces();
++
++#if TRACE_LOADER
++ if (newPos.fromLine == newPos.toLine)
++ kdDebug() << " Got Line " << newPos.fromLine << endl;
++ else
++ kdDebug() << " Got LineRange " << newPos.fromLine
++ << ":" << newPos.toLine << endl;
++#endif
++
++ }
++
++ return true;
++}
++
++// Support for compressed strings
++void CachegrindLoader::clearCompression()
++{
++ // this doesn't delete previous contained objects
++ _objectVector.clear();
++ _fileVector.clear();
++ _functionVector.clear();
++
++ // reset to reasonable init size. We double lengths if needed.
++ _objectVector.resize(100);
++ _fileVector.resize(1000);
++ _functionVector.resize(10000);
++}
++
++const TQString& CachegrindLoader::checkUnknown(const TQString& n)
++{
++ if (n == "???") return _emptyString;
++ return n;
++}
++
++TraceObject* CachegrindLoader::compressedObject(const TQString& name)
++{
++ if ((name[0] != '(') || !name[1].isDigit()) return _data->object(checkUnknown(name));
++
++ // compressed format using _objectVector
++ int p = name.find(')');
++ if (p<2) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid compressed ELF object ('"
++ << name << "')" << endl;
++ return 0;
++ }
++ unsigned index = name.mid(1, p-1).toInt();
++ TraceObject* o = 0;
++ p++;
++ if ((int)name.length()>p) {
++ while(name.at(p).isSpace()) p++;
++
++ if (_objectVector.size() <= index) {
++ int newSize = index * 2;
++#if TRACE_LOADER
++ kdDebug() << " CachegrindLoader: objectVector enlarged to "
++ << newSize << endl;
++#endif
++ _objectVector.resize(newSize);
++ }
++
++ TQString realName = checkUnknown(name.mid(p));
++ o = (TraceObject*) _objectVector.at(index);
++ if (o && (o->name() != realName)) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Redefinition of compressed ELF object index " << index
++ << " (was '" << o->name()
++ << "') to '" << realName << "'" << endl;
++ }
++
++ o = _data->object(realName);
++ _objectVector.insert(index, o);
++ }
++ else {
++ if ((_objectVector.size() <= index) ||
++ ( (o=(TraceObject*)_objectVector.at(index)) == 0)) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Undefined compressed ELF object index " << index << endl;
++ return 0;
++ }
++ }
++
++ return o;
++}
++
++
++// Note: Callgrind sometimes gives different IDs for same file
++// (when references to same source file come from different ELF objects)
++TraceFile* CachegrindLoader::compressedFile(const TQString& name)
++{
++ if ((name[0] != '(') || !name[1].isDigit()) return _data->file(checkUnknown(name));
++
++ // compressed format using _fileVector
++ int p = name.find(')');
++ if (p<2) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid compressed file ('"
++ << name << "')" << endl;
++ return 0;
++ }
++ unsigned int index = name.mid(1, p-1).toUInt();
++ TraceFile* f = 0;
++ p++;
++ if ((int)name.length()>p) {
++ while(name.at(p).isSpace()) p++;
++
++ if (_fileVector.size() <= index) {
++ int newSize = index * 2;
++#if TRACE_LOADER
++ kdDebug() << " CachegrindLoader::fileVector enlarged to "
++ << newSize << endl;
++#endif
++ _fileVector.resize(newSize);
++ }
++
++ TQString realName = checkUnknown(name.mid(p));
++ f = (TraceFile*) _fileVector.at(index);
++ if (f && (f->name() != realName)) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Redefinition of compressed file index " << index
++ << " (was '" << f->name()
++ << "') to '" << realName << "'" << endl;
++ }
++
++ f = _data->file(realName);
++ _fileVector.insert(index, f);
++ }
++ else {
++ if ((_fileVector.size() <= index) ||
++ ( (f=(TraceFile*)_fileVector.at(index)) == 0)) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Undefined compressed file index " << index << endl;
++ return 0;
++ }
++ }
++
++ return f;
++}
++
++// Note: Callgrind gives different IDs even for same function
++// when parts of the function are from different source files.
++// Thus, it is no error when multiple indexes map to same function.
++TraceFunction* CachegrindLoader::compressedFunction(const TQString& name,
++ TraceFile* file,
++ TraceObject* object)
++{
++ if ((name[0] != '(') || !name[1].isDigit())
++ return _data->function(checkUnknown(name), file, object);
++
++ // compressed format using _functionVector
++ int p = name.find(')');
++ if (p<2) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid compressed function ('"
++ << name << "')" << endl;
++ return 0;
++ }
++
++
++ unsigned int index = name.mid(1, p-1).toUInt();
++ TraceFunction* f = 0;
++ p++;
++ if ((int)name.length()>p) {
++ while(name.at(p).isSpace()) p++;
++
++ if (_functionVector.size() <= index) {
++ int newSize = index * 2;
++#if TRACE_LOADER
++ kdDebug() << " CachegrindLoader::functionVector enlarged to "
++ << newSize << endl;
++#endif
++ _functionVector.resize(newSize);
++ }
++
++ TQString realName = checkUnknown(name.mid(p));
++ f = (TraceFunction*) _functionVector.at(index);
++ if (f && (f->name() != realName)) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Redefinition of compressed function index " << index
++ << " (was '" << f->name()
++ << "') to '" << realName << "'" << endl;
++ }
++
++ f = _data->function(realName, file, object);
++ _functionVector.insert(index, f);
++
++#if TRACE_LOADER
++ kdDebug() << "compressedFunction: Inserted at Index " << index
++ << "\n " << f->fullName()
++ << "\n in " << f->cls()->fullName()
++ << "\n in " << f->file()->fullName()
++ << "\n in " << f->object()->fullName() << endl;
++#endif
++ }
++ else {
++ if ((_functionVector.size() <= index) ||
++ ( (f=(TraceFunction*)_functionVector.at(index)) == 0)) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Undefined compressed function index "
++ << index << endl;
++ return 0;
++ }
++
++ // there was a check if the used function (returned from KCachegrinds
++ // model) has the same object and file as here given to us, but that was wrong:
++ // that holds only if we make this assumption on the model...
++ }
++
++ return f;
++}
++
++
++// make sure that a valid object is set, at least dummy with empty name
++void CachegrindLoader::ensureObject()
++{
++ if (currentObject) return;
++
++ currentObject = _data->object(_emptyString);
++ currentPartObject = currentObject->partObject(_part);
++}
++
++void CachegrindLoader::setObject(const TQString& name)
++{
++ currentObject = compressedObject(name);
++ if (!currentObject) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid object specification, setting to unknown" << endl;
++
++ currentObject = _data->object(_emptyString);
++ }
++
++ currentPartObject = currentObject->partObject(_part);
++ currentFunction = 0;
++ currentPartFunction = 0;
++}
++
++void CachegrindLoader::setCalledObject(const TQString& name)
++{
++ currentCalledObject = compressedObject(name);
++
++ if (!currentCalledObject) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid called specification, setting to unknown" << endl;
++
++ currentCalledObject = _data->object(_emptyString);
++ }
++
++ currentCalledPartObject = currentCalledObject->partObject(_part);
++}
++
++
++// make sure that a valid file is set, at least dummy with empty name
++void CachegrindLoader::ensureFile()
++{
++ if (currentFile) return;
++
++ currentFile = _data->file(_emptyString);
++ currentPartFile = currentFile->partFile(_part);
++}
++
++void CachegrindLoader::setFile(const TQString& name)
++{
++ currentFile = compressedFile(name);
++
++ if (!currentFile) {
++ kdWarning() << _filename << ":" << _lineNo
++ << " - Invalid file specification, setting to unknown" << endl;
++
++ currentFile = _data->file(_emptyString);
++ }
++
++ currentPartFile = currentFile->partFile(_part);
++ currentLine = 0;
++ currentPartLine = 0;
++}
++
++void CachegrindLoader::setCalledFile(const TQString& name)
++{
++ currentCalledFile = compressedFile(name);
++
++ if (!currentCalledFile) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid called file specification, setting to unknown" << endl;
++
++ currentCalledFile = _data->file(_emptyString);
++ }
++
++ currentCalledPartFile = currentCalledFile->partFile(_part);
++}
++
++// make sure that a valid function is set, at least dummy with empty name
++void CachegrindLoader::ensureFunction()
++{
++ if (currentFunction) return;
++
++ kdWarning() << _filename << ":" << _lineNo
++ << " - Function name not set" << endl;
++
++ ensureFile();
++ ensureObject();
++
++ currentFunction = _data->function(_emptyString,
++ currentFile,
++ currentObject);
++ currentPartFunction = currentFunction->partFunction(_part,
++ currentPartFile,
++ currentPartObject);
++}
++
++void CachegrindLoader::setFunction(const TQString& name)
++{
++ ensureFile();
++ ensureObject();
++
++ currentFunction = compressedFunction( name,
++ currentFile,
++ currentObject);
++
++ if (!currentFunction) {
++ kdWarning() << _filename << ":" << _lineNo
++ << " - Invalid function, setting to unknown" << endl;
++
++ currentFunction = _data->function(_emptyString,
++ currentFile,
++ currentObject);
++ }
++
++ currentPartFunction = currentFunction->partFunction(_part,
++ currentPartFile,
++ currentPartObject);
++
++ currentFunctionSource = 0;
++ currentLine = 0;
++ currentPartLine = 0;
++}
++
++void CachegrindLoader::setCalledFunction(const TQString& name)
++{
++ // if called object/file not set, use current object/file
++ if (!currentCalledObject) {
++ currentCalledObject = currentObject;
++ currentCalledPartObject = currentPartObject;
++ }
++
++ if (!currentCalledFile) {
++ // !=0 as functions needs file
++ currentCalledFile = currentFile;
++ currentCalledPartFile = currentPartFile;
++ }
++
++ currentCalledFunction = compressedFunction(name,
++ currentCalledFile,
++ currentCalledObject);
++ if (!currentCalledFunction) {
++ kdWarning() << _filename << ":" << _lineNo
++ << " - Invalid called function, setting to unknown" << endl;
++
++ currentCalledFunction = _data->function(_emptyString,
++ currentCalledFile,
++ currentCalledObject);
++ }
++
++ currentCalledPartFunction =
++ currentCalledFunction->partFunction(_part,
++ currentCalledPartFile,
++ currentCalledPartObject);
++}
++
++
++void CachegrindLoader::clearPosition()
++{
++ currentPos = PositionSpec();
++
++ // current function/line
++ currentFunction = 0;
++ currentPartFunction = 0;
++ currentFunctionSource = 0;
++ currentFile = 0;
++ currentPartFile = 0;
++ currentObject = 0;
++ currentPartObject = 0;
++ currentLine = 0;
++ currentPartLine = 0;
++ currentInstr = 0;
++ currentPartInstr = 0;
++
++ // current call
++ currentCalledObject = 0;
++ currentCalledPartObject = 0;
++ currentCalledFile = 0;
++ currentCalledPartFile = 0;
++ currentCalledFunction = 0;
++ currentCalledPartFunction = 0;
++ currentCallCount = 0;
++
++ // current jump
++ currentJumpToFile = 0;
++ currentJumpToFunction = 0;
++ targetPos = PositionSpec();
++ jumpsFollowed = 0;
++ jumpsExecuted = 0;
++
++ subMapping = 0;
++}
++
++
++/**
++ * The main import function...
++ */
++bool CachegrindLoader::loadTraceInternal(TracePart* part)
++{
++ clearCompression();
++ clearPosition();
++
++ _part = part;
++ _data = part->data();
++ TQFile* pFile = part->file();
++
++ if (!pFile) return false;
++
++ _filename = pFile->name();
++
++ FixFile file(pFile);
++ if (!file.exists()) {
++ kdError() << "File doesn't exist\n" << endl;
++ return false;
++ }
++ kdDebug() << "Loading " << _filename << " ..." << endl;
++ TQString statusMsg = i18n("Loading %1").arg(_filename);
++ int statusProgress = 0;
++ emit updateStatus(statusMsg,statusProgress);
++
++
++#if USE_FIXCOST
++ // FixCost Memory Pool
++ FixPool* pool = _data->fixPool();
++#endif
++
++ _lineNo = 0;
++ FixString line;
++ char c;
++ bool totalsSet = false;
++
++ // current position
++ nextLineType = SelfCost;
++ // default if there's no "positions:" line
++ hasLineInfo = true;
++ hasAddrInfo = false;
++
++ while (file.nextLine(line)) {
++
++ _lineNo++;
++
++#if TRACE_LOADER
++ kdDebug() << "[CachegrindLoader] " << _filename << ":" << _lineNo
++ << " - '" << TQString(line) << "'" << endl;
++#endif
++
++ // if we cannot strip a character, this was an empty line
++ if (!line.first(c)) continue;
++
++ if (c <= '9') {
++
++ if (c == '#') continue;
++
++ // parse position(s)
++ if (!parsePosition(line, currentPos)) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid position specification ('"
++ << TQString(line) << "')" << endl;
++ continue;
++ }
++
++ // go through after big switch
++ }
++ else { // if (c > '9')
++
++ line.stripFirst(c);
++
++ /* in order of probability */
++ switch(c) {
++
++ case 'f':
++
++ // fl=, fi=, fe=
++ if (line.stripPrefix("l=") ||
++ line.stripPrefix("i=") ||
++ line.stripPrefix("e=")) {
++
++ setFile(line);
++ continue;
++ }
++
++ // fn=
++ if (line.stripPrefix("n=")) {
++
++ setFunction(line);
++
++ // on a new function, update status
++ int progress = (int)(100.0 * file.current() / file.len() +.5);
++ if (progress != statusProgress) {
++ statusProgress = progress;
++
++ /* When this signal is connected, it most probably
++ * should lead to GUI update. Thus, when multiple
++ * "long operations" (like file loading) are in progress,
++ * this can temporarly switch to another operation.
++ */
++ emit updateStatus(statusMsg,statusProgress);
++ }
++
++ continue;
++ }
++
++ break;
++
++ case 'c':
++ // cob=
++ if (line.stripPrefix("ob=")) {
++ setCalledObject(line);
++ continue;
++ }
++
++ // cfi= / cfl=
++ if (line.stripPrefix("fl=") ||
++ line.stripPrefix("fi=")) {
++ setCalledFile(line);
++ continue;
++ }
++
++ // cfn=
++ if (line.stripPrefix("fn=")) {
++
++ setCalledFunction(line);
++ continue;
++ }
++
++ // calls=
++ if (line.stripPrefix("alls=")) {
++ // ignore long lines...
++ line.stripUInt64(currentCallCount);
++ nextLineType = CallCost;
++ continue;
++ }
++
++ // cmd:
++ if (line.stripPrefix("md:")) {
++ TQString command = TQString(line).stripWhiteSpace();
++ if (!_data->command().isEmpty() &&
++ _data->command() != command) {
++
++ kdWarning() << _filename << ":" << _lineNo
++ << " - Redefined command, was '"
++ << _data->command()
++ << "'" << endl;
++ }
++ _data->setCommand(command);
++ continue;
++ }
++
++ // creator:
++ if (line.stripPrefix("reator:")) {
++ // ignore ...
++ continue;
++ }
++
++ break;
++
++ case 'j':
++
++ // jcnd=
++ if (line.stripPrefix("cnd=")) {
++ bool valid;
++
++ valid = line.stripUInt64(jumpsFollowed) &&
++ line.stripPrefix("/") &&
++ line.stripUInt64(jumpsExecuted) &&
++ parsePosition(line, targetPos);
++
++ if (!valid) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid jcnd line" << endl;
++ }
++ else
++ nextLineType = CondJump;
++ continue;
++ }
++
++ if (line.stripPrefix("ump=")) {
++ bool valid;
++
++ valid = line.stripUInt64(jumpsExecuted) &&
++ parsePosition(line, targetPos);
++
++ if (!valid) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid jump line" << endl;
++ }
++ else
++ nextLineType = BoringJump;
++ continue;
++ }
++
++ // jfi=
++ if (line.stripPrefix("fi=")) {
++ currentJumpToFile = compressedFile(line);
++ continue;
++ }
++
++ // jfn=
++ if (line.stripPrefix("fn=")) {
++
++ if (!currentJumpToFile) {
++ // !=0 as functions needs file
++ currentJumpToFile = currentFile;
++ }
++
++ currentJumpToFunction =
++ compressedFunction(line,
++ currentJumpToFile,
++ currentObject);
++ continue;
++ }
++
++ break;
++
++ case 'o':
++
++ // ob=
++ if (line.stripPrefix("b=")) {
++ setObject(line);
++ continue;
++ }
++
++ break;
++
++ case '#':
++ continue;
++
++ case 't':
++
++ // totals:
++ if (line.stripPrefix("otals:")) continue;
++
++ // thread:
++ if (line.stripPrefix("hread:")) {
++ part->setThreadID(TQString(line).toInt());
++ continue;
++ }
++
++ // timeframe (BB):
++ if (line.stripPrefix("imeframe (BB):")) {
++ part->setTimeframe(line);
++ continue;
++ }
++
++ break;
++
++ case 'd':
++
++ // desc:
++ if (line.stripPrefix("esc:")) {
++
++ line.stripSurroundingSpaces();
++
++ // desc: Trigger:
++ if (line.stripPrefix("Trigger:")) {
++ part->setTrigger(line);
++ }
++
++ continue;
++ }
++ break;
++
++ case 'e':
++
++ // events:
++ if (line.stripPrefix("vents:")) {
++ subMapping = _data->mapping()->subMapping(line);
++ part->setFixSubMapping(subMapping);
++ continue;
++ }
++
++ // event:<name>[=<formula>][:<long name>]
++ if (line.stripPrefix("vent:")) {
++ line.stripSurroundingSpaces();
++
++ FixString e, f, l;
++ if (!line.stripName(e)) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid event" << endl;
++ continue;
++ }
++ line.stripSpaces();
++ if (!line.stripFirst(c)) continue;
++
++ if (c=='=') f = line.stripUntil(':');
++ line.stripSpaces();
++
++ // add to known cost types
++ if (line.isEmpty()) line = e;
++ TraceCostType::add(new TraceCostType(e,line,f));
++ continue;
++ }
++ break;
++
++ case 'p':
++
++ // part:
++ if (line.stripPrefix("art:")) {
++ part->setPartNumber(TQString(line).toInt());
++ continue;
++ }
++
++ // pid:
++ if (line.stripPrefix("id:")) {
++ part->setProcessID(TQString(line).toInt());
++ continue;
++ }
++
++ // positions:
++ if (line.stripPrefix("ositions:")) {
++ TQString positions(line);
++ hasLineInfo = (positions.find("line")>=0);
++ hasAddrInfo = (positions.find("instr")>=0);
++ continue;
++ }
++ break;
++
++ case 'v':
++
++ // version:
++ if (line.stripPrefix("ersion:")) {
++ part->setVersion(line);
++ continue;
++ }
++ break;
++
++ case 's':
++
++ // summary:
++ if (line.stripPrefix("ummary:")) {
++ if (!subMapping) {
++ kdError() << "No event line found. Skipping '" << _filename << endl;
++ return false;
++ }
++
++ part->totals()->set(subMapping, line);
++ continue;
++ }
++
++ case 'r':
++
++ // rcalls= (deprecated)
++ if (line.stripPrefix("calls=")) {
++ // handle like normal calls: we need the sum of call count
++ // recursive cost is discarded in cycle detection
++ line.stripUInt64(currentCallCount);
++ nextLineType = CallCost;
++
++ kdDebug() << "WARNING: This trace dump was generated by an old "
++ "version\n of the call-tree skin. Use a new one!" << endl;
++
++ continue;
++ }
++ break;
++
++ default:
++ break;
++ }
++
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid line '" << c << TQString(line) << "'" << endl;
++ continue;
++ }
++
++ if (!subMapping) {
++ kdError() << "No event line found. Skipping '" << _filename << "'" << endl;
++ return false;
++ }
++
++ // for a cost line, we always need a current function
++ ensureFunction();
++
++
++#if USE_FIXCOST
++ if (!currentFunctionSource ||
++ (currentFunctionSource->file() != currentFile))
++ currentFunctionSource = currentFunction->sourceFile(currentFile,
++ true);
++#else
++ if (hasAddrInfo) {
++ if (!currentInstr ||
++ (currentInstr->addr() != currentPos.fromAddr)) {
++ currentInstr = currentFunction->instr(currentPos.fromAddr,
++ true);
++
++ if (!currentInstr) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Invalid address "
++ << currentPos.fromAddr.toString() << endl;
++
++ continue;
++ }
++
++ currentPartInstr = currentInstr->partInstr(part,
++ currentPartFunction);
++ }
++ }
++
++ if (hasLineInfo) {
++ if (!currentLine ||
++ (currentLine->lineno() != currentPos.fromLine)) {
++
++ currentLine = currentFunction->line(currentFile,
++ currentPos.fromLine,
++ true);
++ currentPartLine = currentLine->partLine(part,
++ currentPartFunction);
++ }
++ if (hasAddrInfo && currentInstr)
++ currentInstr->setLine(currentLine);
++ }
++#endif
++
++#if TRACE_LOADER
++ kdDebug() << _filename << ":" << _lineNo
++ << endl << " currentInstr "
++ << (currentInstr ? currentInstr->toString().ascii() : ".")
++ << endl << " currentLine "
++ << (currentLine ? currentLine->toString().ascii() : ".")
++ << "( file " << currentFile->name() << ")"
++ << endl << " currentFunction "
++ << currentFunction->prettyName().ascii()
++ << endl << " currentCalled "
++ << (currentCalledFunction ? currentCalledFunction->prettyName().ascii() : ".")
++ << endl;
++#endif
++
++ // create cost item
++
++ if (nextLineType == SelfCost) {
++
++#if USE_FIXCOST
++ new (pool) FixCost(part, pool,
++ currentFunctionSource,
++ currentPos,
++ currentPartFunction,
++ line);
++#else
++ if (hasAddrInfo) {
++ TracePartInstr* partInstr;
++ partInstr = currentInstr->partInstr(part, currentPartFunction);
++
++ if (hasLineInfo) {
++ // we need to set <line> back after reading for the line
++ int l = line.len();
++ const char* s = line.ascii();
++
++ partInstr->addCost(subMapping, line);
++ line.set(s,l);
++ }
++ else
++ partInstr->addCost(subMapping, line);
++ }
++
++ if (hasLineInfo) {
++ TracePartLine* partLine;
++ partLine = currentLine->partLine(part, currentPartFunction);
++ partLine->addCost(subMapping, line);
++ }
++#endif
++
++ if (!line.isEmpty()) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Garbage at end of cost line ('"
++ << TQString(line) << "')" << endl;
++ }
++ }
++ else if (nextLineType == CallCost) {
++ nextLineType = SelfCost;
++
++ TraceCall* calling = currentFunction->calling(currentCalledFunction);
++ TracePartCall* partCalling =
++ calling->partCall(part, currentPartFunction,
++ currentCalledPartFunction);
++
++#if USE_FIXCOST
++ FixCallCost* fcc;
++ fcc = new (pool) FixCallCost(part, pool,
++ currentFunctionSource,
++ hasLineInfo ? currentPos.fromLine : 0,
++ hasAddrInfo ? currentPos.fromAddr : Addr(0),
++ partCalling,
++ currentCallCount, line);
++ fcc->setMax(_data->callMax());
++#else
++ if (hasAddrInfo) {
++ TraceInstrCall* instrCall;
++ TracePartInstrCall* partInstrCall;
++
++ instrCall = calling->instrCall(currentInstr);
++ partInstrCall = instrCall->partInstrCall(part, partCalling);
++ partInstrCall->addCallCount(currentCallCount);
++
++ if (hasLineInfo) {
++ // we need to set <line> back after reading for the line
++ int l = line.len();
++ const char* s = line.ascii();
++
++ partInstrCall->addCost(subMapping, line);
++ line.set(s,l);
++ }
++ else
++ partInstrCall->addCost(subMapping, line);
++
++ // update maximum of call cost
++ _data->callMax()->maxCost(partInstrCall);
++ }
++
++ if (hasLineInfo) {
++ TraceLineCall* lineCall;
++ TracePartLineCall* partLineCall;
++
++ lineCall = calling->lineCall(currentLine);
++ partLineCall = lineCall->partLineCall(part, partCalling);
++
++ partLineCall->addCallCount(currentCallCount);
++ partLineCall->addCost(subMapping, line);
++
++ // update maximum of call cost
++ _data->callMax()->maxCost(partLineCall);
++ }
++#endif
++ currentCalledFile = 0;
++ currentCalledPartFile = 0;
++ currentCalledObject = 0;
++ currentCalledPartObject = 0;
++ currentCallCount = 0;
++
++ if (!line.isEmpty()) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Garbage at end of call cost line ('"
++ << TQString(line) << "')" << endl;
++ }
++ }
++ else { // (nextLineType == BoringJump || nextLineType == CondJump)
++
++ TraceFunctionSource* targetSource;
++
++ if (!currentJumpToFunction)
++ currentJumpToFunction = currentFunction;
++
++ targetSource = (currentJumpToFile) ?
++ currentJumpToFunction->sourceFile(currentJumpToFile, true) :
++ currentFunctionSource;
++
++#if USE_FIXCOST
++ new (pool) FixJump(part, pool,
++ /* source */
++ hasLineInfo ? currentPos.fromLine : 0,
++ hasAddrInfo ? currentPos.fromAddr : 0,
++ currentPartFunction,
++ currentFunctionSource,
++ /* target */
++ hasLineInfo ? targetPos.fromLine : 0,
++ hasAddrInfo ? targetPos.fromAddr : Addr(0),
++ currentJumpToFunction,
++ targetSource,
++ (nextLineType == CondJump),
++ jumpsExecuted, jumpsFollowed);
++#endif
++
++ if (0) {
++ kdDebug() << _filename << ":" << _lineNo
++ << " - jump from 0x" << currentPos.fromAddr.toString()
++ << " (line " << currentPos.fromLine
++ << ") to 0x" << targetPos.fromAddr.toString()
++ << " (line " << targetPos.fromLine << ")" << endl;
++
++ if (nextLineType == BoringJump)
++ kdDebug() << " Boring Jump, count " << jumpsExecuted.pretty() << endl;
++ else
++ kdDebug() << " Cond. Jump, followed " << jumpsFollowed.pretty()
++ << ", executed " << jumpsExecuted.pretty() << endl;
++ }
++
++ nextLineType = SelfCost;
++ currentJumpToFunction = 0;
++ currentJumpToFile = 0;
++
++ if (!line.isEmpty()) {
++ kdError() << _filename << ":" << _lineNo
++ << " - Garbage at end of jump cost line ('"
++ << TQString(line) << "')" << endl;
++ }
++
++ }
++ }
++
++
++ emit updateStatus(statusMsg,100);
++
++ _part->invalidate();
++ if (!totalsSet) {
++ _part->totals()->clear();
++ _part->totals()->addCost(_part);
++ }
++
++ pFile->close();
++
++ return true;
++}
++
+diff --git a/kdecachegrind/kdecachegrind/callgraphview.cpp b/kdecachegrind/kdecachegrind/callgraphview.cpp
+new file mode 100644
+index 0000000..bc01da8
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/callgraphview.cpp
+@@ -0,0 +1,2734 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Callgraph View
++ */
++
++#include <stdlib.h>
++#include <math.h>
++
++#include <tqtooltip.h>
++#include <tqfile.h>
++#include <tqtextstream.h>
++#include <tqwhatsthis.h>
++#include <tqcanvas.h>
++#include <tqwmatrix.h>
++#include <tqpair.h>
++#include <tqpainter.h>
++#include <tqpopupmenu.h>
++#include <tqstyle.h>
++#include <tqprocess.h>
++
++#include <kdebug.h>
++#include <klocale.h>
++#include <kconfig.h>
++#include <ktempfile.h>
++#include <kapplication.h>
++#include <kiconloader.h>
++#include <kfiledialog.h>
++
++#include "configuration.h"
++#include "callgraphview.h"
++#include "toplevel.h"
++#include "listutils.h"
++
++
++/*
++ * TODO:
++ * - Zooming option for work canvas? (e.g. 1:1 - 1:3)
++ */
++
++#define DEBUG_GRAPH 0
++
++// CallGraphView defaults
++
++#define DEFAULT_FUNCLIMIT .05
++#define DEFAULT_CALLLIMIT .05
++#define DEFAULT_MAXCALLER 2
++#define DEFAULT_MAXCALLING -1
++#define DEFAULT_SHOWSKIPPED false
++#define DEFAULT_EXPANDCYCLES false
++#define DEFAULT_CLUSTERGROUPS false
++#define DEFAULT_DETAILLEVEL 1
++#define DEFAULT_LAYOUT GraphOptions::TopDown
++#define DEFAULT_ZOOMPOS Auto
++
++
++//
++// GraphEdgeList
++//
++
++GraphEdgeList::GraphEdgeList()
++ : _sortCallerPos(true)
++{}
++
++int GraphEdgeList::compareItems(Item item1, Item item2)
++{
++ CanvasEdge* e1 = ((GraphEdge*)item1)->canvasEdge();
++ CanvasEdge* e2 = ((GraphEdge*)item2)->canvasEdge();
++
++ // edges without arrow visualisations are sorted as low
++ if (!e1) return -1;
++ if (!e2) return 1;
++
++ int dx1, dy1, dx2, dy2;
++ int x, y;
++ if (_sortCallerPos) {
++ e1->controlPoints().point(0,&x,&y);
++ e2->controlPoints().point(0,&dx1,&dy1);
++ dx1 -= x; dy1 -= y;
++ }
++ else {
++ TQPointArray a1 = e1->controlPoints();
++ TQPointArray a2 = e2->controlPoints();
++ a1.point(a1.count()-2,&x,&y);
++ a2.point(a2.count()-1,&dx2,&dy2);
++ dx2 -= x; dy2 -= y;
++ }
++ double at1 = atan2(double(dx1), double(dy1));
++ double at2 = atan2(double(dx2), double(dy2));
++
++ return (at1 < at2) ? 1:-1;
++}
++
++
++
++
++//
++// GraphNode
++//
++
++GraphNode::GraphNode()
++{
++ _f=0;
++ self = incl = 0;
++ _cn = 0;
++
++ _visible = false;
++ _lastCallerIndex = _lastCallingIndex = -1;
++
++ callers.setSortCallerPos(false);
++ callings.setSortCallerPos(true);
++ _lastFromCaller = true;
++}
++
++TraceCall* GraphNode::visibleCaller()
++{
++ if (0) qDebug("GraphNode::visibleCaller %s: last %d, count %d",
++ _f->prettyName().ascii(), _lastCallerIndex, callers.count());
++
++ GraphEdge* e = callers.at(_lastCallerIndex);
++ if (e && !e->isVisible()) e = 0;
++ if (!e) {
++ double maxCost = 0.0;
++ GraphEdge* maxEdge = 0;
++ int idx = 0;
++ for(e = callers.first();e; e=callers.next(),idx++)
++ if (e->isVisible() && (e->cost > maxCost)) {
++ maxCost = e->cost;
++ maxEdge = e;
++ _lastCallerIndex = idx;
++ }
++ e = maxEdge;
++ }
++ return e ? e->call() : 0;
++}
++
++TraceCall* GraphNode::visibleCalling()
++{
++ if (0) qDebug("GraphNode::visibleCalling %s: last %d, count %d",
++ _f->prettyName().ascii(), _lastCallingIndex, callings.count());
++
++ GraphEdge* e = callings.at(_lastCallingIndex);
++ if (e && !e->isVisible()) e = 0;
++ if (!e) {
++ double maxCost = 0.0;
++ GraphEdge* maxEdge = 0;
++ int idx = 0;
++ for(e = callings.first();e; e=callings.next(),idx++)
++ if (e->isVisible() && (e->cost > maxCost)) {
++ maxCost = e->cost;
++ maxEdge = e;
++ _lastCallingIndex = idx;
++ }
++ e = maxEdge;
++ }
++ return e ? e->call() : 0;
++}
++
++void GraphNode::setCalling(GraphEdge* e)
++{
++ _lastCallingIndex = callings.findRef(e);
++ _lastFromCaller = false;
++}
++
++void GraphNode::setCaller(GraphEdge* e)
++{
++ _lastCallerIndex = callers.findRef(e);
++ _lastFromCaller = true;
++}
++
++TraceFunction* GraphNode::nextVisible()
++{
++ TraceCall* c;
++ if (_lastFromCaller) {
++ c = nextVisibleCaller(callers.at(_lastCallerIndex));
++ if (c) return c->called(true);
++ c = nextVisibleCalling(callings.at(_lastCallingIndex));
++ if (c) return c->caller(true);
++ }
++ else {
++ c = nextVisibleCalling(callings.at(_lastCallingIndex));
++ if (c) return c->caller(true);
++ c = nextVisibleCaller(callers.at(_lastCallerIndex));
++ if (c) return c->called(true);
++ }
++ return 0;
++}
++
++TraceFunction* GraphNode::priorVisible()
++{
++ TraceCall* c;
++ if (_lastFromCaller) {
++ c = priorVisibleCaller(callers.at(_lastCallerIndex));
++ if (c) return c->called(true);
++ c = priorVisibleCalling(callings.at(_lastCallingIndex));
++ if (c) return c->caller(true);
++ }
++ else {
++ c = priorVisibleCalling(callings.at(_lastCallingIndex));
++ if (c) return c->caller(true);
++ c = priorVisibleCaller(callers.at(_lastCallerIndex));
++ if (c) return c->called(true);
++ }
++ return 0;
++}
++
++TraceCall* GraphNode::nextVisibleCaller(GraphEdge* last)
++{
++ GraphEdge* e;
++ bool found = false;
++ int idx = 0;
++ for(e = callers.first();e; e=callers.next(),idx++) {
++ if (found && e->isVisible()) {
++ _lastCallerIndex = idx;
++ return e->call();
++ }
++ if (e == last) found = true;
++ }
++ return 0;
++}
++
++TraceCall* GraphNode::nextVisibleCalling(GraphEdge* last)
++{
++ GraphEdge* e;
++ bool found = false;
++ int idx = 0;
++ for(e = callings.first();e; e=callings.next(),idx++) {
++ if (found && e->isVisible()) {
++ _lastCallingIndex = idx;
++ return e->call();
++ }
++ if (e == last) found = true;
++ }
++ return 0;
++}
++
++TraceCall* GraphNode::priorVisibleCaller(GraphEdge* last)
++{
++ GraphEdge *e, *prev = 0;
++ int prevIdx = -1, idx = 0;
++ for(e = callers.first(); e; e=callers.next(),idx++) {
++ if (e == last) {
++ _lastCallerIndex = prevIdx;
++ return prev ? prev->call() : 0;
++ }
++ if (e->isVisible()) {
++ prev = e;
++ prevIdx = idx;
++ }
++ }
++ return 0;
++}
++
++TraceCall* GraphNode::priorVisibleCalling(GraphEdge* last)
++{
++ GraphEdge *e, *prev = 0;
++ int prevIdx = -1, idx = 0;
++ for(e = callings.first(); e; e=callings.next(),idx++) {
++ if (e == last) {
++ _lastCallingIndex = prevIdx;
++ return prev ? prev->call() : 0;
++ }
++ if (e->isVisible()) {
++ prev = e;
++ prevIdx = idx;
++ }
++ }
++ return 0;
++}
++
++//
++// GraphEdge
++//
++
++GraphEdge::GraphEdge()
++{
++ _c=0;
++ _from = _to = 0;
++ _fromNode = _toNode = 0;
++ cost = count = 0;
++ _ce = 0;
++
++ _visible = false;
++ _lastFromCaller = true;
++}
++
++TQString GraphEdge::prettyName()
++{
++ if (_c) return _c->prettyName();
++ if (_from) return i18n("Call(s) from %1").arg(_from->prettyName());
++ if (_to) return i18n("Call(s) to %1").arg(_to->prettyName());
++ return i18n("(unknown call)");
++}
++
++
++TraceFunction* GraphEdge::visibleCaller()
++{
++ if (_from) {
++ _lastFromCaller = true;
++ if (_fromNode) _fromNode->setCalling(this);
++ return _from;
++ }
++ return 0;
++}
++
++TraceFunction* GraphEdge::visibleCalling()
++{
++ if (_to) {
++ _lastFromCaller = false;
++ if (_toNode) _toNode->setCaller(this);
++ return _to;
++ }
++ return 0;
++}
++
++TraceCall* GraphEdge::nextVisible()
++{
++ TraceCall* res = 0;
++
++ if (_lastFromCaller && _fromNode) {
++ res = _fromNode->nextVisibleCalling(this);
++ if (!res && _toNode)
++ res = _toNode->nextVisibleCaller(this);
++ }
++ else if (_toNode) {
++ res = _toNode->nextVisibleCaller(this);
++ if (!res && _fromNode)
++ res = _fromNode->nextVisibleCalling(this);
++ }
++ return res;
++}
++
++TraceCall* GraphEdge::priorVisible()
++{
++ TraceCall* res = 0;
++
++ if (_lastFromCaller && _fromNode) {
++ res = _fromNode->priorVisibleCalling(this);
++ if (!res && _toNode)
++ res = _toNode->priorVisibleCaller(this);
++ }
++ else if (_toNode) {
++ res = _toNode->priorVisibleCaller(this);
++ if (!res && _fromNode)
++ res = _fromNode->priorVisibleCalling(this);
++ }
++ return res;
++}
++
++
++
++//
++// GraphOptions
++//
++
++TQString GraphOptions::layoutString(Layout l)
++{
++ if (l == Circular) return TQString("Circular");
++ if (l == LeftRight) return TQString("LeftRight");
++ return TQString("TopDown");
++}
++
++GraphOptions::Layout GraphOptions::layout(TQString s)
++{
++ if (s == TQString("Circular")) return Circular;
++ if (s == TQString("LeftRight")) return LeftRight;
++ return TopDown;
++}
++
++
++//
++// StorableGraphOptions
++//
++
++StorableGraphOptions::StorableGraphOptions()
++{
++ // default options
++ _funcLimit = DEFAULT_FUNCLIMIT;
++ _callLimit = DEFAULT_CALLLIMIT;
++ _maxCallerDepth = DEFAULT_MAXCALLER;
++ _maxCallingDepth = DEFAULT_MAXCALLING;
++ _showSkipped = DEFAULT_SHOWSKIPPED;
++ _expandCycles = DEFAULT_EXPANDCYCLES;
++ _detailLevel = DEFAULT_DETAILLEVEL;
++ _layout = DEFAULT_LAYOUT;
++}
++
++
++
++
++//
++// GraphExporter
++//
++
++GraphExporter::GraphExporter()
++{
++ _go = this;
++ _tmpFile = 0;
++ _item = 0;
++ reset(0, 0, 0, TraceItem::NoCostType, TQString());
++}
++
++
++GraphExporter::GraphExporter(TraceData* d, TraceFunction* f, TraceCostType* ct,
++ TraceItem::CostType gt, TQString filename)
++{
++ _go = this;
++ _tmpFile = 0;
++ _item = 0;
++ reset(d, f, ct, gt, filename);
++}
++
++
++GraphExporter::~GraphExporter()
++{
++ if (_item && _tmpFile) {
++#if DEBUG_GRAPH
++ _tmpFile->unlink();
++#endif
++ delete _tmpFile;
++ }
++}
++
++
++void GraphExporter::reset(TraceData*, TraceItem* i, TraceCostType* ct,
++ TraceItem::CostType gt, TQString filename)
++{
++ _graphCreated = false;
++ _nodeMap.clear();
++ _edgeMap.clear();
++
++ if (_item && _tmpFile) {
++ _tmpFile->unlink();
++ delete _tmpFile;
++ }
++
++ if (i) {
++ switch(i->type()) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ case TraceItem::Call:
++ break;
++ default:
++ i = 0;
++ }
++ }
++
++ _item = i;
++ _costType = ct;
++ _groupType = gt;
++ if (!i) return;
++
++ if (filename.isEmpty()) {
++ _tmpFile = new KTempFile(TQString(), ".dot");
++ _dotName = _tmpFile->name();
++ _useBox = true;
++ }
++ else {
++ _tmpFile = 0;
++ _dotName = filename;
++ _useBox = false;
++ }
++}
++
++
++
++void GraphExporter::setGraphOptions(GraphOptions* go)
++{
++ if (go == 0) go = this;
++ _go = go;
++}
++
++void GraphExporter::createGraph()
++{
++ if (!_item) return;
++ if (_graphCreated) return;
++ _graphCreated = true;
++
++ if ((_item->type() == TraceItem::Function) ||
++ (_item->type() == TraceItem::FunctionCycle)) {
++ TraceFunction* f = (TraceFunction*) _item;
++
++ double incl = f->inclusive()->subCost(_costType);
++ _realFuncLimit = incl * _go->funcLimit();
++ _realCallLimit = incl * _go->callLimit();
++
++ buildGraph(f, 0, true, 1.0); // down to callings
++
++ // set costs of function back to 0, as it will be added again
++ GraphNode& n = _nodeMap[f];
++ n.self = n.incl = 0.0;
++
++ buildGraph(f, 0, false, 1.0); // up to callers
++ }
++ else {
++ TraceCall* c = (TraceCall*) _item;
++
++ double incl = c->subCost(_costType);
++ _realFuncLimit = incl * _go->funcLimit();
++ _realCallLimit = incl * _go->callLimit();
++
++ // create edge
++ TraceFunction *caller, *called;
++ caller = c->caller(false);
++ called = c->called(false);
++ TQPair<TraceFunction*,TraceFunction*> p(caller, called);
++ GraphEdge& e = _edgeMap[p];
++ e.setCall(c);
++ e.setCaller(p.first);
++ e.setCalling(p.second);
++ e.cost = c->subCost(_costType);
++ e.count = c->callCount();
++
++ SubCost s = called->inclusive()->subCost(_costType);
++ buildGraph(called, 0, true, e.cost / s); // down to callings
++ s = caller->inclusive()->subCost(_costType);
++ buildGraph(caller, 0, false, e.cost / s); // up to callers
++ }
++}
++
++void GraphExporter::writeDot()
++{
++ if (!_item) return;
++
++ TQFile* file = 0;
++ TQTextStream* stream = 0;
++
++ if (_tmpFile)
++ stream = _tmpFile->textStream();
++ else {
++ file = new TQFile(_dotName);
++ if ( !file->open( IO_WriteOnly ) ) {
++ kdError() << "Can't write dot file '" << _dotName << "'" << endl;
++ return;
++ }
++ stream = new TQTextStream(file);
++ }
++
++ if (!_graphCreated) createGraph();
++
++ /* Generate dot format...
++ * When used for the CallGraphView (in contrast to "Export Callgraph..."),
++ * the labels are only dummy placeholders to reserve space for our own
++ * drawings.
++ */
++
++ *stream << "digraph \"callgraph\" {\n";
++
++ if (_go->layout() == LeftRight) {
++ *stream << TQString(" rankdir=LR;\n");
++ }
++ else if (_go->layout() == Circular) {
++ TraceFunction *f = 0;
++ switch(_item->type()) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ f = (TraceFunction*) _item;
++ break;
++ case TraceItem::Call:
++ f = ((TraceCall*)_item)->caller(true);
++ break;
++ default:
++ break;
++ }
++ if (f)
++ *stream << TQString(" center=F%1;\n").arg((long)f, 0, 16);
++ *stream << TQString(" overlap=false;\n splines=true;\n");
++ }
++
++ // for clustering
++ TQMap<TraceCostItem*,TQPtrList<GraphNode> > nLists;
++
++ GraphNodeMap::Iterator nit;
++ for ( nit = _nodeMap.begin();
++ nit != _nodeMap.end(); ++nit ) {
++ GraphNode& n = *nit;
++
++ if (n.incl <= _realFuncLimit) continue;
++
++ // for clustering: get cost item group of function
++ TraceCostItem* g;
++ TraceFunction* f = n.function();
++ switch(_groupType) {
++ case TraceItem::Object: g = f->object(); break;
++ case TraceItem::Class: g = f->cls(); break;
++ case TraceItem::File: g = f->file(); break;
++ case TraceItem::FunctionCycle: g = f->cycle(); break;
++ default: g = 0; break;
++ }
++ nLists[g].append(&n);
++ }
++
++ TQMap<TraceCostItem*,TQPtrList<GraphNode> >::Iterator lit;
++ int cluster = 0;
++ for ( lit = nLists.begin();
++ lit != nLists.end(); ++lit, cluster++ ) {
++ TQPtrList<GraphNode>& l = lit.data();
++ TraceCostItem* i = lit.key();
++
++ if (_go->clusterGroups() && i) {
++ TQString iabr = i->prettyName();
++ if ((int)iabr.length() > Configuration::maxSymbolLength())
++ iabr = iabr.left(Configuration::maxSymbolLength()) + "...";
++
++ *stream << TQString("subgraph \"cluster%1\" { label=\"%2\";\n")
++ .arg(cluster).arg(iabr);
++ }
++
++ GraphNode* np;
++ for(np = l.first(); np; np = l.next() ) {
++ TraceFunction* f = np->function();
++
++ TQString abr = f->prettyName();
++ if ((int)abr.length() > Configuration::maxSymbolLength())
++ abr = abr.left(Configuration::maxSymbolLength()) + "...";
++
++ *stream << TQString(" F%1 [").arg((long)f, 0, 16);
++ if (_useBox) {
++ // make label 3 lines for CallGraphView
++ *stream << TQString("shape=box,label=\"** %1 **\\n**\\n%2\"];\n")
++ .arg(abr)
++ .arg(SubCost(np->incl).pretty());
++ }
++ else
++ *stream << TQString("label=\"%1\\n%2\"];\n")
++ .arg(abr)
++ .arg(SubCost(np->incl).pretty());
++ }
++
++ if (_go->clusterGroups() && i)
++ *stream << TQString("}\n");
++ }
++
++ GraphEdgeMap::Iterator eit;
++ for ( eit = _edgeMap.begin();
++ eit != _edgeMap.end(); ++eit ) {
++ GraphEdge& e = *eit;
++
++ if (e.cost < _realCallLimit) continue;
++ if (!_go->expandCycles()) {
++ // don't show inner cycle calls
++ if (e.call()->inCycle()>0) continue;
++ }
++
++
++ GraphNode& from = _nodeMap[e.from()];
++ GraphNode& to = _nodeMap[e.to()];
++
++ e.setCallerNode(&from);
++ e.setCallingNode(&to);
++
++ if ((from.incl <= _realFuncLimit) ||
++ (to.incl <= _realFuncLimit)) continue;
++
++ // remove dumped edges from n.callers/n.callings
++ from.callings.removeRef(&e);
++ to.callers.removeRef(&e);
++ from.callingSet.remove(&e);
++ to.callerSet.remove(&e);
++
++ *stream << TQString(" F%1 -> F%2 [weight=%3")
++ .arg((long)e.from(), 0, 16)
++ .arg((long)e.to(), 0, 16)
++ .arg((long)log(log(e.cost)));
++
++ if (_go->detailLevel() ==1)
++ *stream << TQString(",label=\"%1\"")
++ .arg(SubCost(e.cost).pretty());
++ else if (_go->detailLevel() ==2)
++ *stream << TQString(",label=\"%3\\n%4 x\"")
++ .arg(SubCost(e.cost).pretty())
++ .arg(SubCost(e.count).pretty());
++
++ *stream << TQString("];\n");
++ }
++
++ if (_go->showSkipped()) {
++
++ // Create sum-edges for skipped edges
++ GraphEdge* e;
++ double costSum, countSum;
++ for ( nit = _nodeMap.begin();
++ nit != _nodeMap.end(); ++nit ) {
++ GraphNode& n = *nit;
++ if (n.incl <= _realFuncLimit) continue;
++
++ costSum = countSum = 0.0;
++ for (e=n.callers.first();e;e=n.callers.next()) {
++ costSum += e->cost;
++ countSum += e->count;
++ }
++ if (costSum > _realCallLimit) {
++
++ TQPair<TraceFunction*,TraceFunction*> p(0, n.function());
++ e = &(_edgeMap[p]);
++ e->setCalling(p.second);
++ e->cost = costSum;
++ e->count = countSum;
++
++ *stream << TQString(" R%1 [shape=point,label=\"\"];\n")
++ .arg((long)n.function(), 0, 16);
++ *stream << TQString(" R%1 -> F%2 [label=\"%3\\n%4 x\",weight=%5];\n")
++ .arg((long)n.function(), 0, 16)
++ .arg((long)n.function(), 0, 16)
++ .arg(SubCost(costSum).pretty())
++ .arg(SubCost(countSum).pretty())
++ .arg((int)log(costSum));
++ }
++
++ costSum = countSum = 0.0;
++ for (e=n.callings.first();e;e=n.callings.next()) {
++ costSum += e->cost;
++ countSum += e->count;
++ }
++ if (costSum > _realCallLimit) {
++
++ TQPair<TraceFunction*,TraceFunction*> p(n.function(), 0);
++ e = &(_edgeMap[p]);
++ e->setCaller(p.first);
++ e->cost = costSum;
++ e->count = countSum;
++
++ *stream << TQString(" S%1 [shape=point,label=\"\"];\n")
++ .arg((long)n.function(), 0, 16);
++ *stream << TQString(" F%1 -> S%2 [label=\"%3\\n%4 x\",weight=%5];\n")
++ .arg((long)n.function(), 0, 16)
++ .arg((long)n.function(), 0, 16)
++ .arg(SubCost(costSum).pretty())
++ .arg(SubCost(countSum).pretty())
++ .arg((int)log(costSum));
++ }
++ }
++ }
++
++ // clear edges here completely.
++ // Visible edges are inserted again on parsing in CallGraphView::refresh
++ for ( nit = _nodeMap.begin();
++ nit != _nodeMap.end(); ++nit ) {
++ GraphNode& n = *nit;
++ n.callers.clear();
++ n.callings.clear();
++ n.callerSet.clear();
++ n.callingSet.clear();
++ }
++
++ *stream << "}\n";
++
++ if (_tmpFile) {
++ _tmpFile->close();
++ }
++ else {
++ file->close();
++ delete file;
++ delete stream;
++ }
++}
++
++void GraphExporter::sortEdges()
++{
++ GraphNodeMap::Iterator nit;
++ for ( nit = _nodeMap.begin();
++ nit != _nodeMap.end(); ++nit ) {
++ GraphNode& n = *nit;
++
++ n.callers.sort();
++ n.callings.sort();
++ }
++}
++
++TraceFunction* GraphExporter::toFunc(TQString s)
++{
++ if (s[0] != 'F') return 0;
++ bool ok;
++ TraceFunction* f = (TraceFunction*) s.mid(1).toULong(&ok, 16);
++ if (!ok) return 0;
++
++ return f;
++}
++
++GraphNode* GraphExporter::node(TraceFunction* f)
++{
++ if (!f) return 0;
++
++ GraphNodeMap::Iterator it = _nodeMap.find(f);
++ if (it == _nodeMap.end()) return 0;
++
++ return &(*it);
++}
++
++GraphEdge* GraphExporter::edge(TraceFunction* f1, TraceFunction* f2)
++{
++ GraphEdgeMap::Iterator it = _edgeMap.find(tqMakePair(f1, f2));
++ if (it == _edgeMap.end()) return 0;
++
++ return &(*it);
++}
++
++
++/**
++ * We do a DFS and don't stop on already visited nodes/edges,
++ * but add up costs. We only stop if limits/max depth is reached.
++ *
++ * For a node/edge, it can happen that the first time visited the
++ * cost will below the limit, so the search is stopped.
++ * If on a further visit of the node/edge the limit is reached,
++ * we use the whole node/edge cost and continue search.
++ */
++void GraphExporter::buildGraph(TraceFunction* f, int d,
++ bool toCallings, double factor)
++{
++#if DEBUG_GRAPH
++ kdDebug() << "buildGraph(" << f->prettyName() << "," << d << "," << factor
++ << ") [to " << (toCallings ? "Callings":"Callers") << "]" << endl;
++#endif
++
++ double oldIncl = 0.0;
++ GraphNode& n = _nodeMap[f];
++ if (n.function() == 0) {
++ n.setFunction(f);
++ }
++ else
++ oldIncl = n.incl;
++
++ double incl = f->inclusive()->subCost(_costType) * factor;
++ n.incl += incl;
++ n.self += f->subCost(_costType) * factor;
++ if (0) qDebug(" Added Incl. %f, now %f", incl, n.incl);
++
++ // A negative depth limit means "unlimited"
++ int maxDepth = toCallings ? _go->maxCallingDepth() : _go->maxCallerDepth();
++ if ((maxDepth>=0) && (d >= maxDepth)) {
++ if (0) qDebug(" Cutoff, max depth reached");
++ return;
++ }
++
++ // if we just reached the limit by summing, do a DFS
++ // from here with full incl. cost because of previous cutoffs
++ if ((n.incl >= _realFuncLimit) && (oldIncl < _realFuncLimit)) incl = n.incl;
++
++ if (f->cycle()) {
++ // for cycles members, we never stop on first visit, but always on 2nd
++ // note: a 2nd visit never should happen, as we don't follow inner-cycle
++ // calls
++ if (oldIncl > 0.0) {
++ if (0) qDebug(" Cutoff, 2nd visit to Cycle Member");
++ // and takeback cost addition, as it's added twice
++ n.incl = oldIncl;
++ n.self -= f->subCost(_costType) * factor;
++ return;
++ }
++ }
++ else if (incl <= _realFuncLimit) {
++ if (0) qDebug(" Cutoff, below limit");
++ return;
++ }
++
++ TraceCall* call;
++ TraceFunction* f2;
++
++
++ // on entering a cycle, only go the FunctionCycle
++ TraceCallList l = toCallings ?
++ f->callings(false) : f->callers(false);
++
++ for (call=l.first();call;call=l.next()) {
++
++ f2 = toCallings ? call->called(false) : call->caller(false);
++
++ double count = call->callCount() * factor;
++ double cost = call->subCost(_costType) * factor;
++
++ // ignore function calls with absolute cost < 3 per call
++ // No: This would skip a lot of functions e.g. with L2 cache misses
++ // if (count>0.0 && (cost/count < 3)) continue;
++
++ double oldCost = 0.0;
++ TQPair<TraceFunction*,TraceFunction*> p(toCallings ? f:f2,
++ toCallings ? f2:f);
++ GraphEdge& e = _edgeMap[p];
++ if (e.call() == 0) {
++ e.setCall(call);
++ e.setCaller(p.first);
++ e.setCalling(p.second);
++ }
++ else
++ oldCost = e.cost;
++
++ e.cost += cost;
++ e.count += count;
++ if (0) qDebug(" Edge to %s, added cost %f, now %f",
++ f2->prettyName().ascii(), cost, e.cost);
++
++ // if this call goes into a FunctionCycle, we also show the real call
++ if (f2->cycle() == f2) {
++ TraceFunction* realF;
++ realF = toCallings ? call->called(true) : call->caller(true);
++ TQPair<TraceFunction*,TraceFunction*> realP(toCallings ? f:realF,
++ toCallings ? realF:f);
++ GraphEdge& e = _edgeMap[realP];
++ if (e.call() == 0) {
++ e.setCall(call);
++ e.setCaller(realP.first);
++ e.setCalling(realP.second);
++ }
++ e.cost += cost;
++ e.count += count;
++ }
++
++ // - don't do a DFS on calls in recursion/cycle
++ if (call->inCycle()>0) continue;
++ if (call->isRecursion()) continue;
++
++ if (toCallings) {
++ GraphEdgeSet::Iterator it = n.callingSet.find(&e);
++ if (it == n.callingSet.end()) {
++ n.callings.append(&e);
++ n.callingSet.insert(&e, 1 );
++ }
++ }
++ else {
++ GraphEdgeSet::Iterator it = n.callerSet.find(&e);
++ if (it == n.callerSet.end()) {
++ n.callers.append(&e);
++ n.callerSet.insert(&e, 1 );
++ }
++ }
++
++ // if we just reached the call limit (=func limit by summing, do a DFS
++ // from here with full incl. cost because of previous cutoffs
++ if ((e.cost >= _realCallLimit) && (oldCost < _realCallLimit)) cost = e.cost;
++ if (cost < _realCallLimit) {
++ if (0) qDebug(" Edge Cutoff, limit not reached");
++ continue;
++ }
++
++ SubCost s;
++ if (call->inCycle())
++ s = f2->cycle()->inclusive()->subCost(_costType);
++ else
++ s = f2->inclusive()->subCost(_costType);
++ SubCost v = call->subCost(_costType);
++ buildGraph(f2, d+1, toCallings, factor * v / s);
++ }
++}
++
++
++//
++// PannerView
++//
++PannerView::PannerView(TQWidget * parent, const char * name)
++ : TQCanvasView(parent, name, WNoAutoErase | WStaticContents)
++{
++ _movingZoomRect = false;
++
++ // why doesn't this avoid flicker ?
++ viewport()->setBackgroundMode(TQt::NoBackground);
++ setBackgroundMode(TQt::NoBackground);
++}
++
++void PannerView::setZoomRect(TQRect r)
++{
++ TQRect oldRect = _zoomRect;
++ _zoomRect = r;
++ updateContents(oldRect);
++ updateContents(_zoomRect);
++}
++
++void PannerView::drawContents(TQPainter * p, int clipx, int clipy, int clipw, int cliph)
++{
++ // save/restore around TQCanvasView::drawContents seems to be needed
++ // for QT 3.0 to get the red rectangle drawn correct
++ p->save();
++ TQCanvasView::drawContents(p,clipx,clipy,clipw,cliph);
++ p->restore();
++ if (_zoomRect.isValid()) {
++ p->setPen(red.dark());
++ p->drawRect(_zoomRect);
++ p->setPen(red);
++ p->drawRect(TQRect(_zoomRect.x()+1, _zoomRect.y()+1,
++ _zoomRect.width()-2, _zoomRect.height()-2));
++ }
++}
++
++void PannerView::contentsMousePressEvent(TQMouseEvent* e)
++{
++ if (_zoomRect.isValid()) {
++ if (!_zoomRect.contains(e->pos()))
++ emit zoomRectMoved(e->pos().x() - _zoomRect.center().x(),
++ e->pos().y() - _zoomRect.center().y());
++
++ _movingZoomRect = true;
++ _lastPos = e->pos();
++ }
++}
++
++void PannerView::contentsMouseMoveEvent(TQMouseEvent* e)
++{
++ if (_movingZoomRect) {
++ emit zoomRectMoved(e->pos().x() - _lastPos.x(), e->pos().y() - _lastPos.y());
++ _lastPos = e->pos();
++ }
++}
++
++void PannerView::contentsMouseReleaseEvent(TQMouseEvent*)
++{
++ _movingZoomRect = false;
++ emit zoomRectMoveFinished();
++}
++
++
++
++
++
++//
++// CanvasNode
++//
++
++CanvasNode::CanvasNode(CallGraphView* v, GraphNode* n,
++ int x, int y, int w, int h, TQCanvas* c)
++ : TQCanvasRectangle(x, y, w, h, c), _node(n), _view(v)
++{
++ setPosition(0, DrawParams::TopCenter);
++ setPosition(1, DrawParams::BottomCenter);
++
++ updateGroup();
++
++ if (!_node || !_view) return;
++
++ if (_node->function())
++ setText(0, _node->function()->prettyName());
++
++ TraceCost* totalCost;
++ if (_view->topLevel()->showExpanded()) {
++ if (_view->activeFunction()) {
++ if (_view->activeFunction()->cycle())
++ totalCost = _view->activeFunction()->cycle()->inclusive();
++ else
++ totalCost = _view->activeFunction()->inclusive();
++ }
++ else
++ totalCost = (TraceCost*) _view->activeItem();
++ }
++ else
++ totalCost = _view->TraceItemView::data();
++ double total = totalCost->subCost(_view->costType());
++ double inclP = 100.0 * n->incl / total;
++ if (_view->topLevel()->showPercentage())
++ setText(1, TQString("%1 %")
++ .arg(inclP, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(1, SubCost(n->incl).pretty());
++ setPixmap(1, percentagePixmap(25,10,(int)(inclP+.5), TQt::blue, true));
++}
++
++void CanvasNode::setSelected(bool s)
++{
++ StoredDrawParams::setSelected(s);
++ update();
++}
++
++void CanvasNode::updateGroup()
++{
++ if (!_view || !_node) return;
++
++ TQColor c = Configuration::functionColor(_view->groupType(),
++ _node->function());
++ setBackColor(c);
++ update();
++}
++
++void CanvasNode::drawShape(TQPainter& p)
++{
++ TQRect r = rect(), origRect = r;
++
++ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2);
++
++ RectDrawing d(r);
++ d.drawBack(&p, this);
++ r.setRect(r.x()+2, r.y()+2, r.width()-4, r.height()-4);
++
++ if (StoredDrawParams::selected() && _view->hasFocus()) {
++ _view->style().tqdrawPrimitive( TQStyle::PE_FocusRect, &p, r,
++ _view->colorGroup());
++ }
++
++ // draw afterwards to always get a frame even when zoomed
++ p.setPen(StoredDrawParams::selected() ? red : black);
++ p.drawRect(origRect);
++
++ d.setRect(r);
++ d.drawField(&p, 0, this);
++ d.drawField(&p, 1, this);
++}
++
++
++//
++// CanvasEdgeLabel
++//
++
++CanvasEdgeLabel::CanvasEdgeLabel(CallGraphView* v, CanvasEdge* ce,
++ int x, int y, int w, int h, TQCanvas* c)
++ : TQCanvasRectangle(x, y, w, h, c), _ce(ce), _view(v)
++{
++ GraphEdge* e = ce->edge();
++ if (!e) return;
++
++ setPosition(1, DrawParams::TopCenter);
++ setText(1, TQString("%1 x").arg(SubCost(e->count).pretty()));
++
++ setPosition(0, DrawParams::BottomCenter);
++
++ TraceCost* totalCost;
++ if (_view->topLevel()->showExpanded()) {
++ if (_view->activeFunction()) {
++ if (_view->activeFunction()->cycle())
++ totalCost = _view->activeFunction()->cycle()->inclusive();
++ else
++ totalCost = _view->activeFunction()->inclusive();
++ }
++ else
++ totalCost = (TraceCost*) _view->activeItem();
++ }
++ else
++ totalCost = _view->TraceItemView::data();
++ double total = totalCost->subCost(_view->costType());
++ double inclP = 100.0 * e->cost / total;
++ if (_view->topLevel()->showPercentage())
++ setText(0, TQString("%1 %")
++ .arg(inclP, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(0, SubCost(e->cost).pretty());
++ setPixmap(0, percentagePixmap(25,10,(int)(inclP+.5), TQt::blue, true));
++
++ if (e->call() && (e->call()->isRecursion() || e->call()->inCycle())) {
++ TQString icon = "undo";
++ KIconLoader* loader = KApplication::kApplication()->iconLoader();
++ TQPixmap p= loader->loadIcon(icon, KIcon::Small, 0,
++ KIcon::DefaultState, 0, true);
++ setPixmap(0, p);
++ }
++}
++
++void CanvasEdgeLabel::drawShape(TQPainter& p)
++{
++ TQRect r = rect();
++ //p.setPen(blue);
++ //p.drawRect(r);
++ RectDrawing d(r);
++ d.drawField(&p, 0, this);
++ d.drawField(&p, 1, this);
++}
++
++//
++// CanvasEdgeArrow
++
++CanvasEdgeArrow::CanvasEdgeArrow(CanvasEdge* ce, TQCanvas* c)
++ : TQCanvasPolygon(c), _ce(ce)
++{}
++
++void CanvasEdgeArrow::drawShape(TQPainter& p)
++{
++ if (_ce->isSelected()) p.setBrush(TQt::red);
++
++ TQCanvasPolygon::drawShape(p);
++}
++
++//
++// CanvasEdge
++//
++
++CanvasEdge::CanvasEdge(GraphEdge* e, TQCanvas* c)
++ : TQCanvasSpline(c), _edge(e)
++{
++ _label = 0;
++ _arrow = 0;
++}
++
++void CanvasEdge::setSelected(bool s)
++{
++ TQCanvasItem::setSelected(s);
++ update();
++ if (_arrow) _arrow->setSelected(s);
++}
++
++TQPointArray CanvasEdge::areaPoints() const
++{
++ int minX = poly[0].x(), minY = poly[0].y();
++ int maxX = minX, maxY = minY;
++ int i;
++
++ if (0) qDebug("CanvasEdge::areaPoints\n P 0: %d/%d", minX, minY);
++ int len = poly.count();
++ for (i=1;i<len;i++) {
++ if (poly[i].x() < minX) minX = poly[i].x();
++ if (poly[i].y() < minY) minY = poly[i].y();
++ if (poly[i].x() > maxX) maxX = poly[i].x();
++ if (poly[i].y() > maxY) maxY = poly[i].y();
++ if (0) qDebug(" P %d: %d/%d", i, poly[i].x(), poly[i].y());
++ }
++ TQPointArray a = poly.copy(), b = poly.copy();
++ if (minX == maxX) {
++ a.translate(-2, 0);
++ b.translate(2, 0);
++ }
++ else {
++ a.translate(0, -2);
++ b.translate(0, 2);
++ }
++ a.resize(2*len);
++ for (i=0;i<len;i++)
++ a[2 * len - 1 -i] = b[i];
++
++ if (0) {
++ qDebug(" Result:");
++ for (i=0;i<2*len;i++)
++ qDebug(" P %d: %d/%d", i, a[i].x(), a[i].y());
++ }
++
++ return a;
++}
++
++void CanvasEdge::drawShape(TQPainter& p)
++{
++ if (isSelected()) p.setPen(TQt::red);
++
++ p.drawPolyline(poly);
++}
++
++
++//
++// CanvasFrame
++//
++
++TQPixmap* CanvasFrame::_p = 0;
++
++CanvasFrame::CanvasFrame(CanvasNode* n, TQCanvas* c)
++ : TQCanvasRectangle(c)
++{
++ if (!_p) {
++
++ int d = 5;
++ float v1 = 130.0, v2 = 10.0, v = v1, f = 1.03;
++
++ // calculate pix size
++ TQRect r(0, 0, 30, 30);
++ while (v>v2) {
++ r.setRect(r.x()-d, r.y()-d, r.width()+2*d, r.height()+2*d);
++ v /= f;
++ }
++
++ _p = new TQPixmap(r.size());
++ _p->fill(TQt::white);
++ TQPainter p(_p);
++ p.setPen(TQt::NoPen);
++
++ r.moveBy(-r.x(), -r.y());
++
++ while (v<v1) {
++ v *= f;
++ p.setBrush(TQColor(265-(int)v, 265-(int)v, 265-(int)v));
++
++ p.drawRect(TQRect(r.x(), r.y(), r.width(), d));
++ p.drawRect(TQRect(r.x(), r.bottom()-d, r.width(), d));
++ p.drawRect(TQRect(r.x(), r.y()+d, d, r.height()-2*d));
++ p.drawRect(TQRect(r.right()-d, r.y()+d, d, r.height()-2*d));
++
++ r.setRect(r.x()+d, r.y()+d, r.width()-2*d, r.height()-2*d);
++ }
++ }
++
++ setSize(_p->width(), _p->height());
++ move(n->rect().center().x()-_p->width()/2,
++ n->rect().center().y()-_p->height()/2);
++}
++
++
++void CanvasFrame::drawShape(TQPainter& p)
++{
++ p.drawPixmap( int(x()), int(y()), *_p );
++}
++
++
++
++
++//
++// Tooltips for CallGraphView
++//
++
++class CallGraphTip: public TQToolTip
++{
++public:
++ CallGraphTip( TQWidget* p ):TQToolTip(p) {}
++
++protected:
++ void maybeTip( const TQPoint & );
++};
++
++void CallGraphTip::maybeTip( const TQPoint& pos )
++{
++ if (!parentWidget()->inherits( "CallGraphView" )) return;
++ CallGraphView* cgv = (CallGraphView*)parentWidget();
++
++ TQPoint cPos = cgv->viewportToContents(pos);
++
++ if (0) qDebug("CallGraphTip for (%d/%d) -> (%d/%d) ?",
++ pos.x(), pos.y(), cPos.x(), cPos.y());
++
++ TQCanvasItemList l = cgv->canvas()->collisions(cPos);
++ if (l.count() == 0) return;
++ TQCanvasItem* i = l.first();
++
++ if (i->rtti() == CANVAS_NODE) {
++ CanvasNode* cn = (CanvasNode*)i;
++ GraphNode* n = cn->node();
++ if (0) qDebug("CallGraphTip: Mouse on Node '%s'",
++ n->function()->prettyName().ascii());
++
++ TQString tipStr = TQString("%1 (%2)").arg(cn->text(0)).arg(cn->text(1));
++ TQPoint vPosTL = cgv->contentsToViewport(i->boundingRect().topLeft());
++ TQPoint vPosBR = cgv->contentsToViewport(i->boundingRect().bottomRight());
++ tip(TQRect(vPosTL, vPosBR), tipStr);
++
++ return;
++ }
++
++ // redirect from label / arrow to edge
++ if (i->rtti() == CANVAS_EDGELABEL)
++ i = ((CanvasEdgeLabel*)i)->canvasEdge();
++ if (i->rtti() == CANVAS_EDGEARROW)
++ i = ((CanvasEdgeArrow*)i)->canvasEdge();
++
++ if (i->rtti() == CANVAS_EDGE) {
++ CanvasEdge* ce = (CanvasEdge*)i;
++ GraphEdge* e = ce->edge();
++ if (0) qDebug("CallGraphTip: Mouse on Edge '%s'",
++ e->prettyName().ascii());
++
++ TQString tipStr;
++ if (!ce->label())
++ tipStr = e->prettyName();
++ else
++ tipStr = TQString("%1 (%2)")
++ .arg(ce->label()->text(0)).arg(ce->label()->text(1));
++ tip(TQRect(pos.x()-5,pos.y()-5,pos.x()+5,pos.y()+5), tipStr);
++ }
++}
++
++
++
++
++//
++// CallGraphView
++//
++CallGraphView::CallGraphView(TraceItemView* parentView,
++ TQWidget* parent, const char* name)
++ : TQCanvasView(parent, name), TraceItemView(parentView)
++{
++ _zoomPosition = DEFAULT_ZOOMPOS;
++ _lastAutoPosition = TopLeft;
++
++ _canvas = 0;
++ _xMargin = _yMargin = 0;
++ _completeView = new PannerView(this);
++ _cvZoom = 1;
++ _selectedNode = 0;
++ _selectedEdge = 0;
++
++ _exporter.setGraphOptions(this);
++
++ _completeView->setVScrollBarMode(TQScrollView::AlwaysOff);
++ _completeView->setHScrollBarMode(TQScrollView::AlwaysOff);
++ _completeView->raise();
++ _completeView->hide();
++
++ setFocusPolicy(TQ_StrongFocus);
++ setBackgroundMode(TQt::NoBackground);
++
++ connect(this, TQT_SIGNAL(contentsMoving(int,int)),
++ this, TQT_SLOT(contentsMovingSlot(int,int)));
++ connect(_completeView, TQT_SIGNAL(zoomRectMoved(int,int)),
++ this, TQT_SLOT(zoomRectMoved(int,int)));
++ connect(_completeView, TQT_SIGNAL(zoomRectMoveFinished()),
++ this, TQT_SLOT(zoomRectMoveFinished()));
++
++ TQWhatsThis::add( this, whatsThis() );
++
++ // tooltips...
++ _tip = new CallGraphTip(this);
++
++ _renderProcess = 0;
++ _prevSelectedNode = 0;
++ connect(&_renderTimer, TQT_SIGNAL(timeout()),
++ this, TQT_SLOT(showRenderWarning()));
++}
++
++CallGraphView::~CallGraphView()
++{
++ delete _completeView;
++ delete _tip;
++
++ if (_canvas) {
++ setCanvas(0);
++ delete _canvas;
++ }
++}
++
++TQString CallGraphView::whatsThis() const
++{
++ return i18n( "<b>Call Graph around active Function</b>"
++ "<p>Depending on configuration, this view shows "
++ "the call graph environment of the active function. "
++ "Note: the shown cost is <b>only</b> the cost which is "
++ "spent while the active function was actually running; "
++ "i.e. the cost shown for main() - if it's visible - should "
++ "be the same as the cost of the active function, as that's "
++ "the part of inclusive cost of main() spent while the active "
++ "function was running.</p>"
++ "<p>For cycles, blue call arrows indicate that this is an "
++ "artificial call added for correct drawing which "
++ "actually never happened.</p>"
++ "<p>If the graph is larger than the widget area, an overview "
++ "panner is shown in one edge. "
++ "There are similar visualization options to the "
++ "Call Treemap; the selected function is highlighted.<p>");
++}
++
++void CallGraphView::updateSizes(TQSize s)
++{
++ if (!_canvas) return;
++
++ if (s == TQSize(0,0)) s = size();
++
++ // the part of the canvas that should be visible
++ int cWidth = _canvas->width() - 2*_xMargin + 100;
++ int cHeight = _canvas->height() - 2*_yMargin + 100;
++
++ // hide birds eye view if no overview needed
++ if (!_data || !_activeItem ||
++ ((cWidth < s.width()) && cHeight < s.height())) {
++ _completeView->hide();
++ return;
++ }
++ _completeView->show();
++
++ // first, assume use of 1/3 of width/height (possible larger)
++ double zoom = .33 * s.width() / cWidth;
++ if (zoom * cHeight < .33 * s.height()) zoom = .33 * s.height() / cHeight;
++
++ // fit to widget size
++ if (cWidth * zoom > s.width()) zoom = s.width() / (double)cWidth;
++ if (cHeight * zoom > s.height()) zoom = s.height() / (double)cHeight;
++
++ // scale to never use full height/width
++ zoom = zoom * 3/4;
++
++ // at most a zoom of 1/3
++ if (zoom > .33) zoom = .33;
++
++ if (zoom != _cvZoom) {
++ _cvZoom = zoom;
++ if (0) qDebug("Canvas Size: %dx%d, Visible: %dx%d, Zoom: %f",
++ _canvas->width(), _canvas->height(),
++ cWidth, cHeight, zoom);
++
++ TQWMatrix wm;
++ wm.scale( zoom, zoom );
++ _completeView->setWorldMatrix(wm);
++
++ // make it a little bigger to compensate for widget frame
++ _completeView->resize(int(cWidth * zoom) + 4,
++ int(cHeight * zoom) + 4);
++
++ // update ZoomRect in completeView
++ contentsMovingSlot(contentsX(), contentsY());
++ }
++
++ _completeView->setContentsPos(int(zoom*(_xMargin-50)),
++ int(zoom*(_yMargin-50)));
++
++ int cvW = _completeView->width();
++ int cvH = _completeView->height();
++ int x = width()- cvW - verticalScrollBar()->width() -2;
++ int y = height()-cvH - horizontalScrollBar()->height() -2;
++ TQPoint oldZoomPos = _completeView->pos();
++ TQPoint newZoomPos = TQPoint(0,0);
++ ZoomPosition zp = _zoomPosition;
++ if (zp == Auto) {
++ TQPoint tl1Pos = viewportToContents(TQPoint(0,0));
++ TQPoint tl2Pos = viewportToContents(TQPoint(cvW,cvH));
++ TQPoint tr1Pos = viewportToContents(TQPoint(x,0));
++ TQPoint tr2Pos = viewportToContents(TQPoint(x+cvW,cvH));
++ TQPoint bl1Pos = viewportToContents(TQPoint(0,y));
++ TQPoint bl2Pos = viewportToContents(TQPoint(cvW,y+cvH));
++ TQPoint br1Pos = viewportToContents(TQPoint(x,y));
++ TQPoint br2Pos = viewportToContents(TQPoint(x+cvW,y+cvH));
++ int tlCols = _canvas->collisions(TQRect(tl1Pos,tl2Pos)).count();
++ int trCols = _canvas->collisions(TQRect(tr1Pos,tr2Pos)).count();
++ int blCols = _canvas->collisions(TQRect(bl1Pos,bl2Pos)).count();
++ int brCols = _canvas->collisions(TQRect(br1Pos,br2Pos)).count();
++ int minCols = tlCols;
++ zp = _lastAutoPosition;
++ switch(zp) {
++ case TopRight: minCols = trCols; break;
++ case BottomLeft: minCols = blCols; break;
++ case BottomRight: minCols = brCols; break;
++ default:
++ case TopLeft: minCols = tlCols; break;
++ }
++ if (minCols > tlCols) { minCols = tlCols; zp = TopLeft; }
++ if (minCols > trCols) { minCols = trCols; zp = TopRight; }
++ if (minCols > blCols) { minCols = blCols; zp = BottomLeft; }
++ if (minCols > brCols) { minCols = brCols; zp = BottomRight; }
++
++ _lastAutoPosition = zp;
++ }
++
++ switch(zp) {
++ case TopRight:
++ newZoomPos = TQPoint(x,0);
++ break;
++ case BottomLeft:
++ newZoomPos = TQPoint(0,y);
++ break;
++ case BottomRight:
++ newZoomPos = TQPoint(x,y);
++ break;
++ default:
++ break;
++ }
++ if (newZoomPos != oldZoomPos) _completeView->move(newZoomPos);
++}
++
++void CallGraphView::focusInEvent(TQFocusEvent*)
++{
++ if (!_canvas) return;
++
++ if (_selectedNode && _selectedNode->canvasNode()) {
++ _selectedNode->canvasNode()->setSelected(true); // requests item update
++ _canvas->update();
++ }
++}
++
++void CallGraphView::focusOutEvent(TQFocusEvent* e)
++{
++ // trigger updates as in focusInEvent
++ focusInEvent(e);
++}
++
++void CallGraphView::keyPressEvent(TQKeyEvent* e)
++{
++ if (!_canvas) {
++ e->ignore();
++ return;
++ }
++
++ if ((e->key() == Key_Return) ||
++ (e->key() == Key_Space)) {
++ if (_selectedNode)
++ activated(_selectedNode->function());
++ else if (_selectedEdge && _selectedEdge->call())
++ activated(_selectedEdge->call());
++ return;
++ }
++
++ // move selected node/edge
++ if (!(e->state() & (ShiftButton | ControlButton)) &&
++ (_selectedNode || _selectedEdge) &&
++ ((e->key() == Key_Up) ||
++ (e->key() == Key_Down) ||
++ (e->key() == Key_Left) ||
++ (e->key() == Key_Right))) {
++
++ TraceFunction* f = 0;
++ TraceCall* c = 0;
++
++ // rotate arrow key meaning for LeftRight layout
++ int key = e->key();
++ if (_layout == LeftRight) {
++ switch(key) {
++ case Key_Up: key = Key_Left; break;
++ case Key_Down: key = Key_Right; break;
++ case Key_Left: key = Key_Up; break;
++ case Key_Right: key = Key_Down; break;
++ default: break;
++ }
++ }
++
++ if (_selectedNode) {
++ if (key == Key_Up) c = _selectedNode->visibleCaller();
++ if (key == Key_Down) c = _selectedNode->visibleCalling();
++ if (key == Key_Right) f = _selectedNode->nextVisible();
++ if (key == Key_Left) f = _selectedNode->priorVisible();
++ }
++ else if (_selectedEdge) {
++ if (key == Key_Up) f = _selectedEdge->visibleCaller();
++ if (key == Key_Down) f = _selectedEdge->visibleCalling();
++ if (key == Key_Right) c = _selectedEdge->nextVisible();
++ if (key == Key_Left) c = _selectedEdge->priorVisible();
++ }
++
++ if (c) selected(c);
++ if (f) selected(f);
++ return;
++ }
++
++ // move canvas...
++ if (e->key() == Key_Home)
++ scrollBy(-_canvas->width(),0);
++ else if (e->key() == Key_End)
++ scrollBy(_canvas->width(),0);
++ else if (e->key() == Key_Prior)
++ scrollBy(0,-visibleHeight()/2);
++ else if (e->key() == Key_Next)
++ scrollBy(0,visibleHeight()/2);
++ else if (e->key() == Key_Left)
++ scrollBy(-visibleWidth()/10,0);
++ else if (e->key() == Key_Right)
++ scrollBy(visibleWidth()/10,0);
++ else if (e->key() == Key_Down)
++ scrollBy(0,visibleHeight()/10);
++ else if (e->key() == Key_Up)
++ scrollBy(0,-visibleHeight()/10);
++ else e->ignore();
++}
++
++void CallGraphView::resizeEvent(TQResizeEvent* e)
++{
++ TQCanvasView::resizeEvent(e);
++ if (_canvas) updateSizes(e->size());
++}
++
++TraceItem* CallGraphView::canShow(TraceItem* i)
++{
++ if (i) {
++ switch(i->type()) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ case TraceItem::Call:
++ return i;
++ default:
++ break;
++ }
++ }
++ return 0;
++}
++
++void CallGraphView::doUpdate(int changeType)
++{
++ // Special case ?
++ if (changeType == costType2Changed) return;
++
++ if (changeType == selectedItemChanged) {
++ if (!_canvas) return;
++
++ if (!_selectedItem) return;
++
++ GraphNode* n = 0;
++ GraphEdge* e = 0;
++ if ((_selectedItem->type() == TraceItem::Function) ||
++ (_selectedItem->type() == TraceItem::FunctionCycle)) {
++ n = _exporter.node((TraceFunction*)_selectedItem);
++ if (n == _selectedNode) return;
++ }
++ else if (_selectedItem->type() == TraceItem::Call) {
++ TraceCall* c = (TraceCall*)_selectedItem;
++ e = _exporter.edge(c->caller(false), c->called(false));
++ if (e == _selectedEdge) return;
++ }
++
++ // unselected any selected item
++ if (_selectedNode && _selectedNode->canvasNode()) {
++ _selectedNode->canvasNode()->setSelected(false);
++ }
++ _selectedNode = 0;
++ if (_selectedEdge && _selectedEdge->canvasEdge()) {
++ _selectedEdge->canvasEdge()->setSelected(false);
++ }
++ _selectedEdge = 0;
++
++ // select
++ CanvasNode* sNode = 0;
++ if (n && n->canvasNode()) {
++ _selectedNode = n;
++ _selectedNode->canvasNode()->setSelected(true);
++
++ if (!_isMoving) sNode = _selectedNode->canvasNode();
++ }
++ if (e && e->canvasEdge()) {
++ _selectedEdge = e;
++ _selectedEdge->canvasEdge()->setSelected(true);
++
++#if 0 // don't change position when selecting edge
++ if (!_isMoving) {
++ if (_selectedEdge->fromNode())
++ sNode = _selectedEdge->fromNode()->canvasNode();
++ if (!sNode && _selectedEdge->toNode())
++ sNode = _selectedEdge->toNode()->canvasNode();
++ }
++#endif
++ }
++ if (sNode) {
++ double x = sNode->x() + sNode->width()/2;
++ double y = sNode->y() + sNode->height()/2;
++
++ ensureVisible(int(x),int(y),
++ sNode->width()/2+50, sNode->height()/2+50);
++ }
++
++ _canvas->update();
++ return;
++ }
++
++ if (changeType == groupTypeChanged) {
++ if (!_canvas) return;
++
++ if (_clusterGroups) {
++ refresh();
++ return;
++ }
++
++ TQCanvasItemList l = _canvas->allItems();
++ TQCanvasItemList::iterator it;
++ for (it = l.begin();it != l.end(); ++it)
++ if ((*it)->rtti() == CANVAS_NODE)
++ ((CanvasNode*) (*it))->updateGroup();
++
++ _canvas->update();
++ return;
++ }
++
++ if (changeType & dataChanged) {
++ // invalidate old selection and graph part
++ _exporter.reset(_data, _activeItem, _costType, _groupType);
++ _selectedNode = 0;
++ _selectedEdge = 0;
++ }
++
++ refresh();
++}
++
++void CallGraphView::clear()
++{
++ if (!_canvas) return;
++
++ delete _canvas;
++ _canvas = 0;
++ _completeView->setCanvas(0);
++ setCanvas(0);
++}
++
++void CallGraphView::showText(TQString s)
++{
++ clear();
++ _renderTimer.stop();
++
++ _canvas = new TQCanvas(TQApplication::desktop()->width(),
++ TQApplication::desktop()->height());
++
++ TQCanvasText* t = new TQCanvasText(s, _canvas);
++ t->move(5, 5);
++ t->show();
++ center(0,0);
++ setCanvas(_canvas);
++ _canvas->update();
++ _completeView->hide();
++}
++
++void CallGraphView::showRenderWarning()
++{
++ TQString s;
++
++ if (_renderProcess)
++ s =i18n("Warning: a long lasting graph layouting is in progress.\n"
++ "Reduce node/edge limits for speedup.\n");
++ else
++ s = i18n("Layouting stopped.\n");
++
++ s.append(i18n("The call graph has %1 nodes and %2 edges.\n")
++ .arg(_exporter.nodeCount())
++ .arg(_exporter.edgeCount()));
++
++ showText(s);
++}
++
++void CallGraphView::stopRendering()
++{
++ if (!_renderProcess) return;
++
++ _renderProcess->kill();
++ delete _renderProcess;
++ _renderProcess = 0;
++ _unparsedOutput = TQString();
++
++ _renderTimer.start(200, true);
++}
++
++void CallGraphView::refresh()
++{
++ // trigger start of background rendering
++ if (_renderProcess) stopRendering();
++
++ // we want to keep a selected node item at the same global position
++ _prevSelectedNode = _selectedNode;
++ _prevSelectedPos = TQPoint(-1,-1);
++ if (_selectedNode) {
++ TQPoint center = _selectedNode->canvasNode()->boundingRect().center();
++ _prevSelectedPos = contentsToViewport(center);
++ }
++
++ if (!_data || !_activeItem) {
++ showText(i18n("No item activated for which to draw the call graph."));
++ return;
++ }
++
++ TraceItem::CostType t = _activeItem->type();
++ switch(t) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ case TraceItem::Call:
++ break;
++ default:
++ showText(i18n("No call graph can be drawn for the active item."));
++ return;
++ }
++
++ if (1) kdDebug() << "CallGraphView::refresh" << endl;
++
++ _selectedNode = 0;
++ _selectedEdge = 0;
++ _exporter.reset(_data, _activeItem, _costType, _groupType);
++ _exporter.writeDot();
++
++ _renderProcess = new TQProcess(TQT_TQOBJECT(this));
++ if (_layout == GraphOptions::Circular)
++ _renderProcess->addArgument( "twopi" );
++ else
++ _renderProcess->addArgument( "dot" );
++ _renderProcess->addArgument(_exporter.filename());
++ _renderProcess->addArgument( "-Tplain" );
++
++ connect( _renderProcess, TQT_SIGNAL(readyReadStdout()),
++ this, TQT_SLOT(readDotOutput()) );
++ connect( _renderProcess, TQT_SIGNAL(processExited()),
++ this, TQT_SLOT(dotExited()) );
++
++ if (1) kdDebug() << "Running '"
++ << _renderProcess->arguments().join(" ")
++ << "'..." << endl;
++
++ if ( !_renderProcess->start() ) {
++ TQString e = i18n("No call graph is available because the following\n"
++ "command cannot be run:\n'%1'\n")
++ .arg(_renderProcess->arguments().join(" "));
++ e += i18n("Please check that 'dot' is installed (package GraphViz).");
++ showText(e);
++
++ delete _renderProcess;
++ _renderProcess = 0;
++
++ return;
++ }
++
++ _unparsedOutput = TQString();
++
++ // layouting of more than seconds is dubious
++ _renderTimer.start(1000, true);
++}
++
++void CallGraphView::readDotOutput()
++{
++ _unparsedOutput.append( _renderProcess->readStdout() );
++}
++
++void CallGraphView::dotExited()
++{
++ TQString line, cmd;
++ CanvasNode *rItem;
++ TQCanvasEllipse* eItem;
++ CanvasEdge* sItem;
++ CanvasEdgeLabel* lItem;
++ TQTextStream* dotStream;
++ double scale = 1.0, scaleX = 1.0, scaleY = 1.0;
++ double dotWidth, dotHeight;
++ GraphNode* activeNode = 0;
++ GraphEdge* activeEdge = 0;
++
++ _renderTimer.stop();
++ viewport()->setUpdatesEnabled(false);
++ clear();
++ dotStream = new TQTextStream(_unparsedOutput, IO_ReadOnly);
++
++ int lineno = 0;
++ while (1) {
++ line = dotStream->readLine();
++ if (line.isNull()) break;
++ lineno++;
++ if (line.isEmpty()) continue;
++
++ TQTextStream lineStream(line, IO_ReadOnly);
++ lineStream >> cmd;
++
++ if (0) qDebug("%s:%d - line '%s', cmd '%s'",
++ _exporter.filename().ascii(), lineno,
++ line.ascii(), cmd.ascii());
++
++ if (cmd == "stop") break;
++
++ if (cmd == "graph") {
++ TQString dotWidthString, dotHeightString;
++ lineStream >> scale >> dotWidthString >> dotHeightString;
++ dotWidth = dotWidthString.toDouble();
++ dotHeight = dotHeightString.toDouble();
++
++ if (_detailLevel == 0) { scaleX = scale * 70; scaleY = scale * 40; }
++ else if (_detailLevel == 1) { scaleX = scale * 80; scaleY = scale * 70; }
++ else { scaleX = scale * 60; scaleY = scale * 100; }
++
++ if (!_canvas) {
++ int w = (int)(scaleX * dotWidth);
++ int h = (int)(scaleY * dotHeight);
++
++ // We use as minimum canvas size the desktop size.
++ // Otherwise, the canvas would have to be resized on widget resize.
++ _xMargin = 50;
++ if (w < TQApplication::desktop()->width())
++ _xMargin += (TQApplication::desktop()->width()-w)/2;
++
++ _yMargin = 50;
++ if (h < TQApplication::desktop()->height())
++ _yMargin += (TQApplication::desktop()->height()-h)/2;
++
++ _canvas = new TQCanvas(int(w+2*_xMargin), int(h+2*_yMargin));
++
++#if DEBUG_GRAPH
++ kdDebug() << _exporter.filename().ascii() << ":" << lineno
++ << " - graph (" << dotWidth << " x " << dotHeight
++ << ") => (" << w << " x " << h << ")" << endl;
++#endif
++ }
++ else
++ kdWarning() << "Ignoring 2nd 'graph' from dot ("
++ << _exporter.filename() << ":" << lineno << ")" << endl;
++ continue;
++ }
++
++ if ((cmd != "node") && (cmd != "edge")) {
++ kdWarning() << "Ignoring unknown command '" << cmd << "' from dot ("
++ << _exporter.filename() << ":" << lineno << ")" << endl;
++ continue;
++ }
++
++ if (_canvas == 0) {
++ kdWarning() << "Ignoring '" << cmd << "' without 'graph' from dot ("
++ << _exporter.filename() << ":" << lineno << ")" << endl;
++ continue;
++ }
++
++ if (cmd == "node") {
++ // x, y are centered in node
++ TQString nodeName, label, nodeX, nodeY, nodeWidth, nodeHeight;
++ double x, y, width, height;
++ lineStream >> nodeName >> nodeX >> nodeY >> nodeWidth >> nodeHeight;
++ x = nodeX.toDouble();
++ y = nodeY.toDouble();
++ width = nodeWidth.toDouble();
++ height = nodeHeight.toDouble();
++
++ GraphNode* n = _exporter.node(_exporter.toFunc(nodeName));
++
++ int xx = (int)(scaleX * x + _xMargin);
++ int yy = (int)(scaleY * (dotHeight - y) + _yMargin);
++ int w = (int)(scaleX * width);
++ int h = (int)(scaleY * height);
++
++#if DEBUG_GRAPH
++ kdDebug() << _exporter.filename() << ":" << lineno
++ << " - node '" << nodeName << "' ( "
++ << x << "/" << y << " - "
++ << width << "x" << height << " ) => ("
++ << xx-w/2 << "/" << yy-h/2 << " - "
++ << w << "x" << h << ")" << endl;
++#endif
++
++
++ // Unnamed nodes with collapsed edges (with 'R' and 'S')
++ if (nodeName[0] == 'R' || nodeName[0] == 'S') {
++ w = 10, h = 10;
++ eItem = new TQCanvasEllipse(w, h, _canvas);
++ eItem->move(xx, yy);
++ eItem->setBrush(TQt::gray);
++ eItem->setZ(1.0);
++ eItem->show();
++ continue;
++ }
++
++ if (!n) {
++ qDebug("Warning: Unknown function '%s' ?!", nodeName.ascii());
++ continue;
++ }
++ n->setVisible(true);
++
++ rItem = new CanvasNode(this, n, xx-w/2, yy-h/2, w, h, _canvas);
++ n->setCanvasNode(rItem);
++
++ if (n) {
++ if (n->function() == activeItem()) activeNode = n;
++ if (n->function() == selectedItem()) _selectedNode = n;
++ rItem->setSelected(n == _selectedNode);
++ }
++
++ rItem->setZ(1.0);
++ rItem->show();
++
++ continue;
++ }
++
++ // edge
++
++ TQString node1Name, node2Name, label, edgeX, edgeY;
++ double x, y;
++ TQPointArray pa;
++ int points, i;
++ lineStream >> node1Name >> node2Name >> points;
++
++ GraphEdge* e = _exporter.edge(_exporter.toFunc(node1Name),
++ _exporter.toFunc(node2Name));
++ if (!e) {
++ kdWarning() << "Unknown edge '" << node1Name << "'-'"
++ << node2Name << "' from dot ("
++ << _exporter.filename() << ":" << lineno << ")" << endl;
++ continue;
++ }
++ e->setVisible(true);
++ if (e->fromNode()) e->fromNode()->callings.append(e);
++ if (e->toNode()) e->toNode()->callers.append(e);
++
++ if (0) qDebug(" Edge with %d points:", points);
++
++ pa.resize(points);
++ for (i=0;i<points;i++) {
++ if (lineStream.atEnd()) break;
++ lineStream >> edgeX >> edgeY;
++ x = edgeX.toDouble();
++ y = edgeY.toDouble();
++
++ int xx = (int)(scaleX * x + _xMargin);
++ int yy = (int)(scaleY * (dotHeight - y) + _yMargin);
++
++ if (0) qDebug(" P %d: ( %f / %f ) => ( %d / %d)",
++ i, x, y, xx, yy);
++
++ pa.setPoint(i, xx, yy);
++ }
++ if (i < points) {
++ qDebug("CallGraphView: Can't read %d spline points (%s:%d)",
++ points, _exporter.filename().ascii(), lineno);
++ continue;
++ }
++
++ // calls into/out of cycles are special: make them blue
++ TQColor arrowColor = TQt::black;
++ TraceFunction* caller = e->fromNode() ? e->fromNode()->function() : 0;
++ TraceFunction* called = e->toNode() ? e->toNode()->function() : 0;
++ if ( (caller && (caller->cycle() == caller)) ||
++ (called && (called->cycle() == called)) ) arrowColor = TQt::blue;
++
++ sItem = new CanvasEdge(e, _canvas);
++ e->setCanvasEdge(sItem);
++ sItem->setControlPoints(pa, false);
++ sItem->setPen(TQPen(arrowColor, 1 /*(int)log(log(e->cost))*/ ));
++ sItem->setZ(0.5);
++ sItem->show();
++
++ if (e->call() == selectedItem()) _selectedEdge = e;
++ if (e->call() == activeItem()) activeEdge = e;
++ sItem->setSelected(e == _selectedEdge);
++
++ // Arrow head
++ TQPoint arrowDir;
++ int indexHead = -1;
++
++ // check if head is at start of spline...
++ // this is needed because dot always gives points from top to bottom
++ CanvasNode* fromNode = e->fromNode() ? e->fromNode()->canvasNode() : 0;
++ if (fromNode) {
++ TQPoint toCenter = fromNode->rect().center();
++ int dx0 = pa.point(0).x() - toCenter.x();
++ int dy0 = pa.point(0).y() - toCenter.y();
++ int dx1 = pa.point(points-1).x() - toCenter.x();
++ int dy1 = pa.point(points-1).y() - toCenter.y();
++ if (dx0*dx0+dy0*dy0 > dx1*dx1+dy1*dy1) {
++ // start of spline is nearer to call target node
++ indexHead=-1;
++ while(arrowDir.isNull() && (indexHead<points-2)) {
++ indexHead++;
++ arrowDir = pa.point(indexHead) - pa.point(indexHead+1);
++ }
++ }
++ }
++
++ if (arrowDir.isNull()) {
++ indexHead = points;
++ // sometimes the last spline points from dot are the same...
++ while(arrowDir.isNull() && (indexHead>1)) {
++ indexHead--;
++ arrowDir = pa.point(indexHead) - pa.point(indexHead-1);
++ }
++ }
++
++ if (!arrowDir.isNull()) {
++ // arrow around pa.point(indexHead) with direction arrowDir
++ arrowDir *= 10.0/sqrt(double(arrowDir.x()*arrowDir.x() +
++ arrowDir.y()*arrowDir.y()));
++ TQPointArray a(3);
++ a.setPoint(0, pa.point(indexHead) + arrowDir);
++ a.setPoint(1, pa.point(indexHead) + TQPoint(arrowDir.y()/2,
++ -arrowDir.x()/2));
++ a.setPoint(2, pa.point(indexHead) + TQPoint(-arrowDir.y()/2,
++ arrowDir.x()/2));
++
++ if (0) qDebug(" Arrow: ( %d/%d, %d/%d, %d/%d)",
++ a.point(0).x(), a.point(0).y(),
++ a.point(1).x(), a.point(1).y(),
++ a.point(2).x(), a.point(2).y());
++
++ CanvasEdgeArrow* aItem = new CanvasEdgeArrow(sItem,_canvas);
++ aItem->setPoints(a);
++ aItem->setBrush(arrowColor);
++ aItem->setZ(1.5);
++ aItem->show();
++
++ sItem->setArrow(aItem);
++ }
++
++ if (lineStream.atEnd()) continue;
++
++ // parse quoted label
++ TQChar c;
++ lineStream >> c;
++ while (c.isSpace()) lineStream >> c;
++ if (c != '\"') {
++ lineStream >> label;
++ label = c + label;
++ }
++ else {
++ lineStream >> c;
++ while(!c.isNull() && (c != '\"')) {
++ //if (c == '\\') lineStream >> c;
++
++ label += c;
++ lineStream >> c;
++ }
++ }
++ lineStream >> edgeX >> edgeY;
++ x = edgeX.toDouble();
++ y = edgeY.toDouble();
++
++ int xx = (int)(scaleX * x + _xMargin);
++ int yy = (int)(scaleY * (dotHeight - y) + _yMargin);
++
++ if (0) qDebug(" Label '%s': ( %f / %f ) => ( %d / %d)",
++ label.ascii(), x, y, xx, yy);
++
++ // Fixed Dimensions for Label: 100 x 40
++ int w = 100;
++ int h = _detailLevel * 20;
++ lItem = new CanvasEdgeLabel(this, sItem, xx-w/2, yy-h/2, w, h, _canvas);
++ // edge labels above nodes
++ lItem->setZ(1.5);
++ sItem->setLabel(lItem);
++ if (h>0) lItem->show();
++
++ }
++ delete dotStream;
++
++ // for keyboard navigation
++ // TODO: Edge sorting. Better keep left-to-right edge order from dot now
++ // _exporter.sortEdges();
++
++ if (!_canvas) {
++ _canvas = new TQCanvas(size().width(),size().height());
++ TQString s = i18n("Error running the graph layouting tool.\n");
++ s += i18n("Please check that 'dot' is installed (package GraphViz).");
++ TQCanvasText* t = new TQCanvasText(s, _canvas);
++ t->move(5, 5);
++ t->show();
++ center(0,0);
++ }
++ else if (!activeNode && !activeEdge) {
++ TQString s = i18n("There is no call graph available for function\n"
++ "\t'%1'\n"
++ "because it has no cost of the selected event type.");
++ TQCanvasText* t = new TQCanvasText(s.arg(_activeItem->name()), _canvas);
++ // t->setTextFlags(TQt::AlignHCenter | TQt::AlignVCenter);
++ t->move(5,5);
++ t->show();
++ center(0,0);
++ }
++
++ _completeView->setCanvas(_canvas);
++ setCanvas(_canvas);
++
++ // if we don't have a selection, or the old selection is not
++ // in visible graph, make active function selected for this view
++ if ((!_selectedNode || !_selectedNode->canvasNode()) &&
++ (!_selectedEdge || !_selectedEdge->canvasEdge())) {
++ if (activeNode) {
++ _selectedNode = activeNode;
++ _selectedNode->canvasNode()->setSelected(true);
++ }
++ else if (activeEdge) {
++ _selectedEdge = activeEdge;
++ _selectedEdge->canvasEdge()->setSelected(true);
++ }
++ }
++
++ CanvasNode* sNode = 0;
++ if (_selectedNode)
++ sNode = _selectedNode->canvasNode();
++ else if (_selectedEdge) {
++ if (_selectedEdge->fromNode())
++ sNode = _selectedEdge->fromNode()->canvasNode();
++ if (!sNode && _selectedEdge->toNode())
++ sNode = _selectedEdge->toNode()->canvasNode();
++ }
++ if (sNode) {
++ int x = int(sNode->x() + sNode->width()/2);
++ int y = int(sNode->y() + sNode->height()/2);
++
++ if (_prevSelectedNode) {
++ if (rect().contains(_prevSelectedPos))
++ setContentsPos(x-_prevSelectedPos.x(),
++ y-_prevSelectedPos.y());
++ else
++ ensureVisible(x,y,
++ sNode->width()/2+50, sNode->height()/2+50);
++ }
++ else center(x,y);
++ }
++
++ if (activeNode) {
++ CanvasNode* cn = activeNode->canvasNode();
++ CanvasFrame* f = new CanvasFrame(cn, _canvas);
++ f->setZ(-1);
++ f->show();
++ }
++
++ _cvZoom = 0;
++ updateSizes();
++
++ _canvas->update();
++ viewport()->setUpdatesEnabled(true);
++
++ delete _renderProcess;
++ _renderProcess = 0;
++}
++
++void CallGraphView::contentsMovingSlot(int x, int y)
++{
++ TQRect z(int(x * _cvZoom), int(y * _cvZoom),
++ int(visibleWidth() * _cvZoom)-1, int(visibleHeight() * _cvZoom)-1);
++ if (0) qDebug("moving: (%d,%d) => (%d/%d - %dx%d)",
++ x, y, z.x(), z.y(), z.width(), z.height());
++ _completeView->setZoomRect(z);
++}
++
++void CallGraphView::zoomRectMoved(int dx, int dy)
++{
++ if (leftMargin()>0) dx = 0;
++ if (topMargin()>0) dy = 0;
++ scrollBy(int(dx/_cvZoom),int(dy/_cvZoom));
++}
++
++void CallGraphView::zoomRectMoveFinished()
++{
++ if (_zoomPosition == Auto) updateSizes();
++}
++
++void CallGraphView::contentsMousePressEvent(TQMouseEvent* e)
++{
++ // clicking on the viewport sets focus
++ setFocus();
++
++ _isMoving = true;
++
++ TQCanvasItemList l = canvas()->collisions(e->pos());
++ if (l.count()>0) {
++ TQCanvasItem* i = l.first();
++
++ if (i->rtti() == CANVAS_NODE) {
++ GraphNode* n = ((CanvasNode*)i)->node();
++ if (0) qDebug("CallGraphView: Got Node '%s'",
++ n->function()->prettyName().ascii());
++
++ selected(n->function());
++ }
++
++ // redirect from label / arrow to edge
++ if (i->rtti() == CANVAS_EDGELABEL)
++ i = ((CanvasEdgeLabel*)i)->canvasEdge();
++ if (i->rtti() == CANVAS_EDGEARROW)
++ i = ((CanvasEdgeArrow*)i)->canvasEdge();
++
++ if (i->rtti() == CANVAS_EDGE) {
++ GraphEdge* e = ((CanvasEdge*)i)->edge();
++ if (0) qDebug("CallGraphView: Got Edge '%s'",
++ e->prettyName().ascii());
++
++ if (e->call()) selected(e->call());
++ }
++ }
++ _lastPos = e->globalPos();
++}
++
++void CallGraphView::contentsMouseMoveEvent(TQMouseEvent* e)
++{
++ if (_isMoving) {
++ int dx = e->globalPos().x() - _lastPos.x();
++ int dy = e->globalPos().y() - _lastPos.y();
++ scrollBy(-dx, -dy);
++ _lastPos = e->globalPos();
++ }
++}
++
++void CallGraphView::contentsMouseReleaseEvent(TQMouseEvent*)
++{
++ _isMoving = false;
++ if (_zoomPosition == Auto) updateSizes();
++}
++
++void CallGraphView::contentsMouseDoubleClickEvent(TQMouseEvent* e)
++{
++ TQCanvasItemList l = canvas()->collisions(e->pos());
++ if (l.count() == 0) return;
++ TQCanvasItem* i = l.first();
++
++ if (i->rtti() == CANVAS_NODE) {
++ GraphNode* n = ((CanvasNode*)i)->node();
++ if (0) qDebug("CallGraphView: Double Clicked on Node '%s'",
++ n->function()->prettyName().ascii());
++
++ activated(n->function());
++ }
++
++ // redirect from label / arrow to edge
++ if (i->rtti() == CANVAS_EDGELABEL)
++ i = ((CanvasEdgeLabel*)i)->canvasEdge();
++ if (i->rtti() == CANVAS_EDGEARROW)
++ i = ((CanvasEdgeArrow*)i)->canvasEdge();
++
++ if (i->rtti() == CANVAS_EDGE) {
++ GraphEdge* e = ((CanvasEdge*)i)->edge();
++ if (e->call()) {
++ if (0) qDebug("CallGraphView: Double Clicked On Edge '%s'",
++ e->call()->prettyName().ascii());
++
++ activated(e->call());
++ }
++ }
++}
++
++void CallGraphView::contentsContextMenuEvent(TQContextMenuEvent* e)
++{
++ TQCanvasItemList l = canvas()->collisions(e->pos());
++ TQCanvasItem* i = (l.count() == 0) ? 0 : l.first();
++
++ TQPopupMenu popup;
++ TraceFunction *f = 0, *cycle = 0;
++ TraceCall* c = 0;
++
++ if (i) {
++ if (i->rtti() == CANVAS_NODE) {
++ GraphNode* n = ((CanvasNode*)i)->node();
++ if (0) qDebug("CallGraphView: Menu on Node '%s'",
++ n->function()->prettyName().ascii());
++ f = n->function();
++ cycle = f->cycle();
++
++ TQString name = f->prettyName();
++ popup.insertItem(i18n("Go to '%1'")
++ .arg(Configuration::shortenSymbol(name)), 93);
++ if (cycle && (cycle != f)) {
++ name = Configuration::shortenSymbol(cycle->prettyName());
++ popup.insertItem(i18n("Go to '%1'").arg(name), 94);
++ }
++ popup.insertSeparator();
++ }
++
++ // redirect from label / arrow to edge
++ if (i->rtti() == CANVAS_EDGELABEL)
++ i = ((CanvasEdgeLabel*)i)->canvasEdge();
++ if (i->rtti() == CANVAS_EDGEARROW)
++ i = ((CanvasEdgeArrow*)i)->canvasEdge();
++
++ if (i->rtti() == CANVAS_EDGE) {
++ GraphEdge* e = ((CanvasEdge*)i)->edge();
++ if (0) qDebug("CallGraphView: Menu on Edge '%s'",
++ e->prettyName().ascii());
++ c = e->call();
++ if (c) {
++ TQString name = c->prettyName();
++ popup.insertItem(i18n("Go to '%1'")
++ .arg(Configuration::shortenSymbol(name)), 95);
++
++ popup.insertSeparator();
++ }
++ }
++ }
++
++ if (_renderProcess) {
++ popup.insertItem(i18n("Stop Layouting"), 999);
++ popup.insertSeparator();
++ }
++
++ addGoMenu(&popup);
++ popup.insertSeparator();
++
++ TQPopupMenu epopup;
++ epopup.insertItem(i18n("As PostScript"), 201);
++ epopup.insertItem(i18n("As Image ..."), 202);
++
++ popup.insertItem(i18n("Export Graph"), &epopup, 200);
++ popup.insertSeparator();
++
++ TQPopupMenu gpopup1;
++ gpopup1.setCheckable(true);
++ gpopup1.insertItem(i18n("Unlimited"), 100);
++ gpopup1.setItemEnabled(100, (_funcLimit>0.005));
++ gpopup1.insertSeparator();
++ gpopup1.insertItem(i18n("None"), 101);
++ gpopup1.insertItem(i18n("max. 2"), 102);
++ gpopup1.insertItem(i18n("max. 5"), 103);
++ gpopup1.insertItem(i18n("max. 10"), 104);
++ gpopup1.insertItem(i18n("max. 15"), 105);
++ if (_maxCallerDepth<-1) _maxCallerDepth=-1;
++ switch(_maxCallerDepth) {
++ case -1: gpopup1.setItemChecked(100,true); break;
++ case 0: gpopup1.setItemChecked(101,true); break;
++ case 2: gpopup1.setItemChecked(102,true); break;
++ case 5: gpopup1.setItemChecked(103,true); break;
++ case 10: gpopup1.setItemChecked(104,true); break;
++ case 15: gpopup1.setItemChecked(105,true); break;
++ default:
++ gpopup1.insertItem(i18n("< %1").arg(_maxCallerDepth), 106);
++ gpopup1.setItemChecked(106,true); break;
++ }
++
++ TQPopupMenu gpopup2;
++ gpopup2.setCheckable(true);
++ gpopup2.insertItem(i18n("Unlimited"), 110);
++ gpopup2.setItemEnabled(110, (_funcLimit>0.005));
++ gpopup2.insertSeparator();
++ gpopup2.insertItem(i18n("None"), 111);
++ gpopup2.insertItem(i18n("max. 2"), 112);
++ gpopup2.insertItem(i18n("max. 5"), 113);
++ gpopup2.insertItem(i18n("max. 10"), 114);
++ gpopup2.insertItem(i18n("max. 15"), 115);
++ if (_maxCallingDepth<-1) _maxCallingDepth=-1;
++ switch(_maxCallingDepth) {
++ case -1: gpopup2.setItemChecked(110,true); break;
++ case 0: gpopup2.setItemChecked(111,true); break;
++ case 2: gpopup2.setItemChecked(112,true); break;
++ case 5: gpopup2.setItemChecked(113,true); break;
++ case 10: gpopup2.setItemChecked(114,true); break;
++ case 15: gpopup2.setItemChecked(115,true); break;
++ default:
++ gpopup2.insertItem(i18n("< %1").arg(_maxCallingDepth), 116);
++ gpopup2.setItemChecked(116,true); break;
++ }
++
++ TQPopupMenu gpopup3;
++ gpopup3.setCheckable(true);
++ gpopup3.insertItem(i18n("No Minimum"), 120);
++ gpopup3.setItemEnabled(120,
++ (_maxCallerDepth>=0) && (_maxCallingDepth>=0));
++ gpopup3.insertSeparator();
++ gpopup3.insertItem(i18n("50 %"), 121);
++ gpopup3.insertItem(i18n("20 %"), 122);
++ gpopup3.insertItem(i18n("10 %"), 123);
++ gpopup3.insertItem(i18n("5 %"), 124);
++ gpopup3.insertItem(i18n("3 %"), 125);
++ gpopup3.insertItem(i18n("2 %"), 126);
++ gpopup3.insertItem(i18n("1.5 %"), 127);
++ gpopup3.insertItem(i18n("1 %"), 128);
++ if (_funcLimit<0) _funcLimit = DEFAULT_FUNCLIMIT;
++ if (_funcLimit>.5) _funcLimit = .5;
++ if (_funcLimit == 0.0) gpopup3.setItemChecked(120,true);
++ else if (_funcLimit >= 0.5) gpopup3.setItemChecked(121,true);
++ else if (_funcLimit >= 0.2) gpopup3.setItemChecked(122,true);
++ else if (_funcLimit >= 0.1) gpopup3.setItemChecked(123,true);
++ else if (_funcLimit >= 0.05) gpopup3.setItemChecked(124,true);
++ else if (_funcLimit >= 0.03) gpopup3.setItemChecked(125,true);
++ else if (_funcLimit >= 0.02) gpopup3.setItemChecked(126,true);
++ else if (_funcLimit >= 0.015) gpopup3.setItemChecked(127,true);
++ else gpopup3.setItemChecked(128,true);
++ double oldFuncLimit = _funcLimit;
++
++ TQPopupMenu gpopup4;
++ gpopup4.setCheckable(true);
++ gpopup4.insertItem(i18n("Same as Node"), 160);
++ gpopup4.insertItem(i18n("50 % of Node"), 161);
++ gpopup4.insertItem(i18n("20 % of Node"), 162);
++ gpopup4.insertItem(i18n("10 % of Node"), 163);
++ if (_callLimit<0) _callLimit = DEFAULT_CALLLIMIT;
++ if (_callLimit >= _funcLimit) _callLimit = _funcLimit;
++ if (_callLimit == _funcLimit) gpopup4.setItemChecked(160,true);
++ else if (_callLimit >= 0.5 * _funcLimit) gpopup4.setItemChecked(161,true);
++ else if (_callLimit >= 0.2 * _funcLimit) gpopup4.setItemChecked(162,true);
++ else gpopup4.setItemChecked(163,true);
++
++ TQPopupMenu gpopup;
++ gpopup.setCheckable(true);
++ gpopup.insertItem(i18n("Caller Depth"), &gpopup1, 80);
++ gpopup.insertItem(i18n("Callee Depth"), &gpopup2, 81);
++ gpopup.insertItem(i18n("Min. Node Cost"), &gpopup3, 82);
++ gpopup.insertItem(i18n("Min. Call Cost"), &gpopup4, 83);
++ gpopup.insertSeparator();
++ gpopup.insertItem(i18n("Arrows for Skipped Calls"), 130);
++ gpopup.setItemChecked(130,_showSkipped);
++ gpopup.insertItem(i18n("Inner-cycle Calls"), 131);
++ gpopup.setItemChecked(131,_expandCycles);
++ gpopup.insertItem(i18n("Cluster Groups"), 132);
++ gpopup.setItemChecked(132,_clusterGroups);
++
++ TQPopupMenu vpopup;
++ vpopup.setCheckable(true);
++ vpopup.insertItem(i18n("Compact"), 140);
++ vpopup.insertItem(i18n("Normal"), 141);
++ vpopup.insertItem(i18n("Tall"), 142);
++ vpopup.setItemChecked(140,_detailLevel == 0);
++ vpopup.setItemChecked(141,_detailLevel == 1);
++ vpopup.setItemChecked(142,_detailLevel == 2);
++ vpopup.insertSeparator();
++ vpopup.insertItem(i18n("Top to Down"), 150);
++ vpopup.insertItem(i18n("Left to Right"), 151);
++ vpopup.insertItem(i18n("Circular"), 152);
++ vpopup.setItemChecked(150,_layout == TopDown);
++ vpopup.setItemChecked(151,_layout == LeftRight);
++ vpopup.setItemChecked(152,_layout == Circular);
++
++ TQPopupMenu opopup;
++ opopup.insertItem(i18n("TopLeft"), 170);
++ opopup.insertItem(i18n("TopRight"), 171);
++ opopup.insertItem(i18n("BottomLeft"), 172);
++ opopup.insertItem(i18n("BottomRight"), 173);
++ opopup.insertItem(i18n("Automatic"), 174);
++ opopup.setItemChecked(170,_zoomPosition == TopLeft);
++ opopup.setItemChecked(171,_zoomPosition == TopRight);
++ opopup.setItemChecked(172,_zoomPosition == BottomLeft);
++ opopup.setItemChecked(173,_zoomPosition == BottomRight);
++ opopup.setItemChecked(174,_zoomPosition == Auto);
++
++ popup.insertItem(i18n("Graph"), &gpopup, 70);
++ popup.insertItem(i18n("Visualization"), &vpopup, 71);
++ popup.insertItem(i18n("Birds-eye View"), &opopup, 72);
++
++ int r = popup.exec(e->globalPos());
++
++ switch(r) {
++ case 93: activated(f); break;
++ case 94: activated(cycle); break;
++ case 95: activated(c); break;
++
++ case 999: stopRendering(); break;
++
++ case 201:
++ {
++ TraceFunction* f = activeFunction();
++ if (!f) break;
++
++ GraphExporter ge(TraceItemView::data(), f, costType(), groupType(),
++ TQString("callgraph.dot"));
++ ge.setGraphOptions(this);
++ ge.writeDot();
++
++ system("(dot callgraph.dot -Tps > callgraph.ps; kghostview callgraph.ps)&");
++ }
++ break;
++
++ case 202:
++ // write current content of canvas as image to file
++ {
++ if (!_canvas) return;
++
++ TQString fn = KFileDialog::getSaveFileName(":","*.png");
++
++ if (!fn.isEmpty()) {
++ TQPixmap pix(_canvas->size());
++ TQPainter p(&pix);
++ _canvas->drawArea( _canvas->rect(), &p );
++ pix.save(fn,"PNG");
++ }
++ }
++ break;
++
++ case 100: _maxCallerDepth = -1; break;
++ case 101: _maxCallerDepth = 0; break;
++ case 102: _maxCallerDepth = 2; break;
++ case 103: _maxCallerDepth = 5; break;
++ case 104: _maxCallerDepth = 10; break;
++ case 105: _maxCallerDepth = 15; break;
++
++ case 110: _maxCallingDepth = -1; break;
++ case 111: _maxCallingDepth = 0; break;
++ case 112: _maxCallingDepth = 2; break;
++ case 113: _maxCallingDepth = 5; break;
++ case 114: _maxCallingDepth = 10; break;
++ case 115: _maxCallingDepth = 15; break;
++
++ case 120: _funcLimit = 0; break;
++ case 121: _funcLimit = 0.5; break;
++ case 122: _funcLimit = 0.2; break;
++ case 123: _funcLimit = 0.1; break;
++ case 124: _funcLimit = 0.05; break;
++ case 125: _funcLimit = 0.03; break;
++ case 126: _funcLimit = 0.02; break;
++ case 127: _funcLimit = 0.015; break;
++ case 128: _funcLimit = 0.01; break;
++
++ case 130: _showSkipped = !_showSkipped; break;
++ case 131: _expandCycles = !_expandCycles; break;
++ case 132: _clusterGroups = !_clusterGroups; break;
++
++ case 140: _detailLevel = 0; break;
++ case 141: _detailLevel = 1; break;
++ case 142: _detailLevel = 2; break;
++
++ case 150: _layout = TopDown; break;
++ case 151: _layout = LeftRight; break;
++ case 152: _layout = Circular; break;
++
++ case 160: _callLimit = _funcLimit; break;
++ case 161: _callLimit = .5 * _funcLimit; break;
++ case 162: _callLimit = .2 * _funcLimit; break;
++ case 163: _callLimit = .1 * _funcLimit; break;
++
++ case 170: _zoomPosition = TopLeft; break;
++ case 171: _zoomPosition = TopRight; break;
++ case 172: _zoomPosition = BottomLeft; break;
++ case 173: _zoomPosition = BottomRight; break;
++ case 174: _zoomPosition = Auto; break;
++
++ default: break;
++ }
++ if (r>=120 && r<130) _callLimit *= _funcLimit / oldFuncLimit;
++
++ if (r>99 && r<170) refresh();
++ if (r>169 && r<180) updateSizes();
++}
++
++CallGraphView::ZoomPosition CallGraphView::zoomPos(TQString s)
++{
++ if (s == TQString("TopLeft")) return TopLeft;
++ if (s == TQString("TopRight")) return TopRight;
++ if (s == TQString("BottomLeft")) return BottomLeft;
++ if (s == TQString("BottomRight")) return BottomRight;
++ if (s == TQString("Automatic")) return Auto;
++
++ return DEFAULT_ZOOMPOS;
++}
++
++TQString CallGraphView::zoomPosString(ZoomPosition p)
++{
++ if (p == TopRight) return TQString("TopRight");
++ if (p == BottomLeft) return TQString("BottomLeft");
++ if (p == BottomRight) return TQString("BottomRight");
++ if (p == Auto) return TQString("Automatic");
++
++ return TQString("TopLeft");
++}
++
++void CallGraphView::readViewConfig(KConfig* c,
++ TQString prefix, TQString postfix, bool)
++{
++ KConfigGroup* g = configGroup(c, prefix, postfix);
++
++ if (0) qDebug("CallGraphView::readViewConfig");
++
++ _maxCallerDepth = g->readNumEntry("MaxCaller", DEFAULT_MAXCALLER);
++ _maxCallingDepth = g->readNumEntry("MaxCalling", DEFAULT_MAXCALLING);
++ _funcLimit = g->readDoubleNumEntry("FuncLimit", DEFAULT_FUNCLIMIT);
++ _callLimit = g->readDoubleNumEntry("CallLimit", DEFAULT_CALLLIMIT);
++ _showSkipped = g->readBoolEntry("ShowSkipped", DEFAULT_SHOWSKIPPED);
++ _expandCycles = g->readBoolEntry("ExpandCycles", DEFAULT_EXPANDCYCLES);
++ _clusterGroups = g->readBoolEntry("ClusterGroups",
++ DEFAULT_CLUSTERGROUPS);
++ _detailLevel = g->readNumEntry("DetailLevel", DEFAULT_DETAILLEVEL);
++ _layout = GraphOptions::layout(g->readEntry("Layout",
++ layoutString(DEFAULT_LAYOUT)));
++ _zoomPosition = zoomPos(g->readEntry("ZoomPosition",
++ zoomPosString(DEFAULT_ZOOMPOS)));
++
++ delete g;
++}
++
++void CallGraphView::saveViewConfig(KConfig* c,
++ TQString prefix, TQString postfix, bool)
++{
++ KConfigGroup g(c, (prefix+postfix).ascii());
++
++ writeConfigEntry(&g, "MaxCaller", _maxCallerDepth, DEFAULT_MAXCALLER);
++ writeConfigEntry(&g, "MaxCalling", _maxCallingDepth, DEFAULT_MAXCALLING);
++ writeConfigEntry(&g, "FuncLimit", _funcLimit, DEFAULT_FUNCLIMIT);
++ writeConfigEntry(&g, "CallLimit", _callLimit, DEFAULT_CALLLIMIT);
++ writeConfigEntry(&g, "ShowSkipped", _showSkipped, DEFAULT_SHOWSKIPPED);
++ writeConfigEntry(&g, "ExpandCycles", _expandCycles, DEFAULT_EXPANDCYCLES);
++ writeConfigEntry(&g, "ClusterGroups", _clusterGroups,
++ DEFAULT_CLUSTERGROUPS);
++ writeConfigEntry(&g, "DetailLevel", _detailLevel, DEFAULT_DETAILLEVEL);
++ writeConfigEntry(&g, "Layout",
++ layoutString(_layout), layoutString(DEFAULT_LAYOUT).utf8().data());
++ writeConfigEntry(&g, "ZoomPosition",
++ zoomPosString(_zoomPosition),
++ zoomPosString(DEFAULT_ZOOMPOS).utf8().data());
++}
++
++#include "callgraphview.moc"
++
+diff --git a/kdecachegrind/kdecachegrind/callgraphview.h b/kdecachegrind/kdecachegrind/callgraphview.h
+new file mode 100644
+index 0000000..4db619d
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/callgraphview.h
+@@ -0,0 +1,501 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Callgraph View
++ */
++
++#ifndef CALLGRAPHVIEW_H
++#define CALLGRAPHVIEW_H
++
++#include <tqcanvas.h>
++#include <tqwidget.h>
++#include <tqmap.h>
++#include <tqtimer.h>
++
++#include "treemap.h" // for DrawParams
++#include "tracedata.h"
++#include "traceitemview.h"
++
++class TQProcess;
++
++class KTempFile;
++class CanvasNode;
++class CanvasEdge;
++class GraphEdge;
++class CallGraphView;
++
++// sorts according start/end position of a call arc
++// this depends on attached CanvasEdge's !
++class GraphEdgeList: public TQPtrList<GraphEdge>
++{
++ public:
++ GraphEdgeList();
++ void setSortCallerPos(bool b) { _sortCallerPos = b; }
++
++ protected:
++ int compareItems ( Item item1, Item item2 );
++
++ private:
++ bool _sortCallerPos;
++};
++
++
++typedef TQMap<GraphEdge*, int> GraphEdgeSet;
++
++// temporary parts of call graph to be shown
++class GraphNode
++{
++public:
++ GraphNode();
++
++ TraceFunction* function() { return _f; }
++ void setFunction(TraceFunction* f) { _f = f; }
++
++ CanvasNode* canvasNode() { return _cn; }
++ void setCanvasNode(CanvasNode* cn) { _cn = cn; }
++
++ bool isVisible() { return _visible; }
++ void setVisible(bool v) { _visible = v; }
++
++ // keyboard navigation
++ TraceCall* visibleCaller();
++ TraceCall* visibleCalling();
++ void setCalling(GraphEdge*);
++ void setCaller(GraphEdge*);
++ TraceFunction* nextVisible();
++ TraceFunction* priorVisible();
++ TraceCall* nextVisibleCaller(GraphEdge*);
++ TraceCall* nextVisibleCalling(GraphEdge*);
++ TraceCall* priorVisibleCaller(GraphEdge*);
++ TraceCall* priorVisibleCalling(GraphEdge*);
++
++ double self, incl;
++ GraphEdgeList callers, callings;
++ // for fast unique insertion of GraphEdges in above lists
++ GraphEdgeSet callerSet, callingSet;
++
++ private:
++ TraceFunction* _f;
++ CanvasNode* _cn;
++ bool _visible;
++
++ // for keyboard navigation
++ int _lastCallerIndex, _lastCallingIndex;
++ bool _lastFromCaller;
++};
++
++class GraphEdge
++{
++public:
++ GraphEdge();
++
++ CanvasEdge* canvasEdge() { return _ce; }
++ void setCanvasEdge(CanvasEdge* ce) { _ce = ce; }
++
++ TraceCall* call() { return _c; }
++ void setCall(TraceCall* c) { _c = c; }
++
++ bool isVisible() { return _visible; }
++ void setVisible(bool v) { _visible = v; }
++
++ GraphNode* fromNode() { return _fromNode; }
++ GraphNode* toNode() { return _toNode; }
++ TraceFunction* from() { return _from; }
++ TraceFunction* to() { return _to; }
++
++ // has special cases for collapsed edges
++ TQString prettyName();
++
++ void setCaller(TraceFunction* f) { _from = f; }
++ void setCalling(TraceFunction* f) { _to = f; }
++ void setCallerNode(GraphNode* n) { _fromNode = n; }
++ void setCallingNode(GraphNode* n) { _toNode = n; }
++
++ // keyboard navigation
++ TraceFunction* visibleCaller();
++ TraceFunction* visibleCalling();
++ TraceCall* nextVisible();
++ TraceCall* priorVisible();
++
++ double cost, count;
++
++ private:
++ // we have a _c *and* _from/_to because for collapsed edges,
++ // only _to or _from will be unequal NULL
++ TraceCall* _c;
++ TraceFunction * _from, * _to;
++ GraphNode *_fromNode, *_toNode;
++ CanvasEdge* _ce;
++ bool _visible;
++ // for keyboard navigation: have we last reached this edge via a caller?
++ bool _lastFromCaller;
++
++};
++
++
++typedef TQMap<TraceFunction*, GraphNode> GraphNodeMap;
++typedef TQMap<TQPair<TraceFunction*, TraceFunction*>, GraphEdge> GraphEdgeMap;
++
++
++/* Abstract Interface for graph options */
++class GraphOptions
++{
++ public:
++ enum Layout { TopDown, LeftRight, Circular};
++
++ virtual double funcLimit() = 0;
++ virtual double callLimit() = 0;
++ virtual int maxCallerDepth() = 0;
++ virtual int maxCallingDepth() = 0;
++ virtual bool showSkipped() = 0;
++ virtual bool expandCycles() = 0;
++ virtual bool clusterGroups() = 0;
++ virtual int detailLevel() = 0;
++ virtual Layout layout() = 0;
++
++ static TQString layoutString(Layout);
++ static Layout layout(TQString);
++};
++
++/* Graph Options Storage */
++class StorableGraphOptions: public GraphOptions
++{
++ public:
++ StorableGraphOptions();
++
++ // implementation of getters
++ virtual double funcLimit() { return _funcLimit; }
++ virtual double callLimit() { return _callLimit; }
++ virtual int maxCallerDepth() { return _maxCallerDepth; }
++ virtual int maxCallingDepth() { return _maxCallingDepth; }
++ virtual bool showSkipped() { return _showSkipped; }
++ virtual bool expandCycles() { return _expandCycles; }
++ virtual bool clusterGroups() { return _clusterGroups; }
++ virtual int detailLevel() { return _detailLevel; }
++ virtual Layout layout() { return _layout; }
++
++ // setters
++ void setMaxCallerDepth(int d) { _maxCallerDepth = d; }
++ void setMaxCallingDepth(int d) { _maxCallingDepth = d; }
++ void setFuncLimit(double l) { _funcLimit = l; }
++ void setCallLimit(double l) { _callLimit = l; }
++ void setShowSkipped(bool b) { _showSkipped = b; }
++ void setExpandCycles(bool b) { _expandCycles = b; }
++ void setClusterGroups(bool b) { _clusterGroups = b; }
++ void setDetailLevel(int l) { _detailLevel = l; }
++ void setLayout(Layout l) { _layout = l; }
++
++ protected:
++ double _funcLimit, _callLimit;
++ int _maxCallerDepth, _maxCallingDepth;
++ bool _showSkipped, _expandCycles, _clusterGroups;
++ int _detailLevel;
++ Layout _layout;
++};
++
++/**
++ * GraphExporter
++ *
++ * Generates a graph file for "dot"
++ * Create an instance and
++ */
++class GraphExporter: public StorableGraphOptions
++{
++public:
++ GraphExporter();
++ GraphExporter(TraceData*, TraceFunction*, TraceCostType*,
++ TraceItem::CostType, TQString filename = TQString());
++ virtual ~GraphExporter();
++
++ void reset(TraceData*, TraceItem*, TraceCostType*,
++ TraceItem::CostType, TQString filename = TQString());
++
++ TQString filename() { return _dotName; }
++ int edgeCount() { return _edgeMap.count(); }
++ int nodeCount() { return _nodeMap.count(); }
++
++ // Set the object from which to get graph options for creation.
++ // Default is this object itself (supply 0 for default)
++ void setGraphOptions(GraphOptions* go = 0);
++
++ // Create a subgraph with given limits/maxDepths
++ void createGraph();
++
++ // calls createGraph before dumping of not already created
++ void writeDot();
++
++ // to map back to structures when parsing a layouted graph
++
++ /* <toFunc> is a helper for node() and edge().
++ * Don't use the returned pointer directly, but only with
++ * node() or edge(), because it could be a dangling pointer.
++ */
++ TraceFunction* toFunc(TQString);
++ GraphNode* node(TraceFunction*);
++ GraphEdge* edge(TraceFunction*, TraceFunction*);
++
++ /* After CanvasEdges are attached to GraphEdges, we can
++ * sort the incoming and outgoing edges of all nodes
++ * regarding start/end points for keyboard navigation
++ */
++ void sortEdges();
++
++private:
++ void buildGraph(TraceFunction*, int, bool, double);
++
++ TQString _dotName;
++ TraceItem* _item;
++ TraceCostType* _costType;
++ TraceItem::CostType _groupType;
++ KTempFile* _tmpFile;
++ double _realFuncLimit, _realCallLimit;
++ int _maxDepth;
++ bool _graphCreated;
++
++ GraphOptions* _go;
++
++ // optional graph attributes
++ bool _useBox;
++
++ // graph parts written to file
++ GraphNodeMap _nodeMap;
++ GraphEdgeMap _edgeMap;
++};
++
++/**
++ * A panner layed over a TQCanvas
++ */
++class PannerView: public TQCanvasView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ PannerView(TQWidget * parent = 0, const char * name = 0);
++
++ void setZoomRect(TQRect r);
++
++signals:
++ void zoomRectMoved(int dx, int dy);
++ void zoomRectMoveFinished();
++
++protected:
++ void contentsMousePressEvent(TQMouseEvent*);
++ void contentsMouseMoveEvent(TQMouseEvent*);
++ void contentsMouseReleaseEvent(TQMouseEvent*);
++ void drawContents(TQPainter * p, int clipx, int clipy, int clipw, int cliph);
++
++ TQRect _zoomRect;
++ bool _movingZoomRect;
++ TQPoint _lastPos;
++};
++
++
++/*
++ * Canvas Items:
++ * - CanvasNode (Rectangular Area)
++ * - CanvasEdge (Spline curve)
++ * - CanvasEdgeLabel (Label for edges)
++ * - CanvasEdgeArrow (Arrows at the end of the edge spline)
++ * - CanvasFrame (Grey background blending to show active node)
++ */
++
++enum {
++ CANVAS_NODE = 1122,
++ CANVAS_EDGE, CANVAS_EDGELABEL, CANVAS_EDGEARROW,
++ CANVAS_FRAME
++};
++
++class CanvasNode: public TQCanvasRectangle, public StoredDrawParams
++{
++public:
++ CanvasNode(CallGraphView*,GraphNode*, int, int, int, int, TQCanvas*);
++
++ void updateGroup();
++ void setSelected(bool);
++ void drawShape(TQPainter&);
++
++ GraphNode* node() { return _node; }
++ int rtti() const { return CANVAS_NODE; }
++
++private:
++ GraphNode* _node;
++ CallGraphView* _view;
++};
++
++class CanvasEdgeLabel: public TQCanvasRectangle, public StoredDrawParams
++{
++public:
++ CanvasEdgeLabel(CallGraphView*, CanvasEdge*, int, int, int, int, TQCanvas*);
++
++ void drawShape(TQPainter&);
++
++ CanvasEdge* canvasEdge() { return _ce; }
++ int rtti() const { return CANVAS_EDGELABEL; }
++
++private:
++ CanvasEdge* _ce;
++ CallGraphView* _view;
++};
++
++class CanvasEdgeArrow: public TQCanvasPolygon
++{
++public:
++ CanvasEdgeArrow(CanvasEdge*, TQCanvas*);
++
++ void drawShape(TQPainter&);
++
++ CanvasEdge* canvasEdge() { return _ce; }
++ int rtti() const { return CANVAS_EDGEARROW; }
++
++private:
++ CanvasEdge* _ce;
++};
++
++
++class CanvasEdge: public TQCanvasSpline
++{
++public:
++ CanvasEdge(GraphEdge*, TQCanvas*);
++
++ void setSelected(bool);
++ void drawShape(TQPainter&);
++ TQPointArray areaPoints() const;
++
++ CanvasEdgeLabel* label() { return _label; }
++ void setLabel(CanvasEdgeLabel* l) { _label = l; }
++ CanvasEdgeArrow* arrow() { return _arrow; }
++ void setArrow(CanvasEdgeArrow* a) { _arrow = a; }
++
++ GraphEdge* edge() { return _edge; }
++ int rtti() const { return CANVAS_EDGE; }
++
++private:
++ GraphEdge* _edge;
++ CanvasEdgeLabel* _label;
++ CanvasEdgeArrow* _arrow;
++};
++
++
++class CanvasFrame: public TQCanvasRectangle
++{
++public:
++ CanvasFrame( CanvasNode*, TQCanvas *canvas );
++ int rtti () const { return CANVAS_FRAME; }
++ bool hit( const TQPoint&) const { return false; }
++protected:
++ void drawShape( TQPainter & );
++private:
++ static TQPixmap* _p;
++};
++
++
++class CallGraphTip;
++
++/**
++ * A CanvasView showing a part of the call graph
++ * and another zoomed out CanvasView in a border acting as
++ * a panner to select to visible part (only if needed)
++ */
++class CallGraphView: public TQCanvasView, public TraceItemView,
++ public StorableGraphOptions
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ enum ZoomPosition { TopLeft, TopRight, BottomLeft, BottomRight, Auto };
++
++ CallGraphView(TraceItemView* parentView,
++ TQWidget* parent=0, const char* name=0);
++ ~CallGraphView();
++
++ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++
++ TQWidget* widget() { return this; }
++ TQString whatsThis() const;
++
++ ZoomPosition zoomPos() const { return _zoomPosition; }
++ static ZoomPosition zoomPos(TQString);
++ static TQString zoomPosString(ZoomPosition);
++
++public slots:
++ void contentsMovingSlot(int,int);
++ void zoomRectMoved(int,int);
++ void zoomRectMoveFinished();
++
++ void showRenderWarning();
++ void stopRendering();
++ void readDotOutput();
++ void dotExited();
++
++protected:
++ void resizeEvent(TQResizeEvent*);
++ void contentsMousePressEvent(TQMouseEvent*);
++ void contentsMouseMoveEvent(TQMouseEvent*);
++ void contentsMouseReleaseEvent(TQMouseEvent*);
++ void contentsMouseDoubleClickEvent(TQMouseEvent*);
++ void contentsContextMenuEvent(TQContextMenuEvent*);
++ void keyPressEvent(TQKeyEvent*);
++ void focusInEvent(TQFocusEvent*);
++ void focusOutEvent(TQFocusEvent*);
++
++private:
++ void updateSizes(TQSize s = TQSize(0,0));
++ TraceItem* canShow(TraceItem*);
++ void doUpdate(int);
++ void refresh();
++ void makeFrame(CanvasNode*, bool active);
++ void clear();
++ void showText(TQString);
++
++ TQCanvas *_canvas;
++ int _xMargin, _yMargin;
++ PannerView *_completeView;
++ double _cvZoom;
++
++ CallGraphTip* _tip;
++
++ bool _isMoving;
++ TQPoint _lastPos;
++
++ GraphExporter _exporter;
++
++ GraphNode* _selectedNode;
++ GraphEdge* _selectedEdge;
++
++ // widget options
++ ZoomPosition _zoomPosition, _lastAutoPosition;
++
++ // background rendering
++ TQProcess* _renderProcess;
++ TQTimer _renderTimer;
++ GraphNode* _prevSelectedNode;
++ TQPoint _prevSelectedPos;
++ TQString _unparsedOutput;
++};
++
++
++
++
++#endif
++
++
++
+diff --git a/kdecachegrind/kdecachegrind/callitem.cpp b/kdecachegrind/kdecachegrind/callitem.cpp
+new file mode 100644
+index 0000000..ebca490
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/callitem.cpp
+@@ -0,0 +1,185 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items for caller/callee view.
++ */
++
++#include <tqpixmap.h>
++#include <klocale.h>
++#include <kapplication.h>
++#include <kiconloader.h>
++
++#include "configuration.h"
++#include "listutils.h"
++#include "callitem.h"
++#include "callview.h"
++#include "toplevel.h"
++
++// CallItem
++
++
++CallItem::CallItem(CallView* view, TQListView* parent, TraceCall* c)
++ : TQListViewItem(parent)
++{
++ _call = c;
++ _view = view;
++
++ _active = _view->activeFunction();
++ bool baseIsCycle = (_active && (_active == _active->cycle()));
++
++ TQString fName;
++ if (_view->showCallers()) {
++ _shown = _call->caller(true);
++ fName = c->callerName(!baseIsCycle);
++ }
++ else {
++ _shown = _call->called(true);
++ fName = c->calledName(!baseIsCycle);
++ }
++
++ _shown->addPrettyLocation(fName);
++
++ setText(3, fName);
++ updateGroup();
++ updateCost();
++}
++
++void CallItem::updateGroup()
++{
++ TQColor c = Configuration::functionColor(_view->groupType(), _shown);
++ setPixmap(3, colorPixmap(10, 10, c));
++}
++
++void CallItem::updateCost()
++{
++ bool sameCycle = _shown->cycle() && (_active->cycle() == _shown->cycle());
++ bool shownIsCycle = (_shown == _shown->cycle());
++ bool selectedIsCycle = (_active == _active->cycle());
++ if (_call->isRecursion()) sameCycle=true;
++
++ TQString cStr;
++ if ((selectedIsCycle || shownIsCycle) && sameCycle)
++ cStr = "-";
++ else {
++ _cc = _call->callCount();
++ if (_cc == 0)
++ cStr = i18n("(active)");
++ else
++ cStr = _call->prettyCallCount();
++ }
++ setText(2, cStr);
++
++ TraceCost* totalCost;
++ if (_view->topLevel()->showExpanded()) {
++ if (_active->cycle())
++ totalCost = _active->cycle()->inclusive();
++ else
++ totalCost = _active->inclusive();
++ }
++ else
++ totalCost = _active->data();
++
++ TraceCostType* ct = _view->costType();
++ _sum = _call->subCost(ct);
++ double total = totalCost->subCost(ct);
++
++ if (total == 0.0) {
++ TQString str = "-";
++
++ setText(0, str);
++ setPixmap(0, TQPixmap());
++ }
++ else {
++ double sum = 100.0 * _sum / total;
++
++ if (_view->topLevel()->showPercentage())
++ setText(0, TQString("%1")
++ .arg(sum, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(0, _call->prettySubCost(ct));
++
++ setPixmap(0, costPixmap(ct, _call, total, false));
++ }
++
++ // Cost Type 2
++ TraceCostType* ct2 = _view->costType2();
++ if (ct2) {
++ _sum2 = _call->subCost(ct2);
++ double total = totalCost->subCost(ct2);
++
++ if (total == 0.0) {
++ TQString str = "-";
++
++ setText(1, str);
++ setPixmap(1, TQPixmap());
++ }
++ else {
++ double sum = 100.0 * _sum2 / total;
++
++ if (_view->topLevel()->showPercentage())
++ setText(1, TQString("%1")
++ .arg(sum, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(1, _call->prettySubCost(ct2));
++
++ setPixmap(1, costPixmap(ct2, _call, total, false));
++ }
++ }
++
++ TQPixmap p;
++ if (sameCycle && !selectedIsCycle && !shownIsCycle) {
++
++ TQString icon = "undo";
++ KIconLoader* loader = KApplication::kApplication()->iconLoader();
++ p= loader->loadIcon(icon, KIcon::Small, 0,
++ KIcon::DefaultState, 0, true);
++ }
++ setPixmap(2, p);
++}
++
++
++int CallItem::compare(TQListViewItem * i, int col, bool ascending ) const
++{
++ const CallItem* ci1 = this;
++ const CallItem* ci2 = (CallItem*) i;
++
++ // we always want descending order
++ if (ascending) {
++ ci1 = ci2;
++ ci2 = this;
++ }
++
++ if (col==0) {
++ if (ci1->_sum < ci2->_sum) return -1;
++ if (ci1->_sum > ci2->_sum) return 1;
++ return 0;
++ }
++ if (col==1) {
++ if (ci1->_sum2 < ci2->_sum2) return -1;
++ if (ci1->_sum2 > ci2->_sum2) return 1;
++ return 0;
++ }
++ if (col==2) {
++ if (ci1->_cc < ci2->_cc) return -1;
++ if (ci1->_cc > ci2->_cc) return 1;
++ return 0;
++ }
++ return TQListViewItem::compare(i, col, ascending);
++}
++
+diff --git a/kdecachegrind/kdecachegrind/callitem.h b/kdecachegrind/kdecachegrind/callitem.h
+new file mode 100644
+index 0000000..94191b8
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/callitem.h
+@@ -0,0 +1,50 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of call view.
++ */
++
++#ifndef CALLITEM_H
++#define CALLITEM_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++
++class CallView;
++
++class CallItem: public TQListViewItem
++{
++public:
++ CallItem(CallView*, TQListView*, TraceCall* c);
++
++ int compare(TQListViewItem * i, int col, bool ascending ) const;
++ TraceCall* call() { return _call; }
++ CallView* view() { return _view; }
++ void updateCost();
++ void updateGroup();
++
++private:
++ SubCost _sum, _sum2;
++ SubCost _cc;
++ TraceCall* _call;
++ CallView* _view;
++ TraceFunction *_active, *_shown;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/callmapview.cpp b/kdecachegrind/kdecachegrind/callmapview.cpp
+new file mode 100644
+index 0000000..0e4d5e3
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/callmapview.cpp
+@@ -0,0 +1,999 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Call Map View
++ */
++
++#include <tqwhatsthis.h>
++#include <tqpopupmenu.h>
++
++#include <klocale.h>
++#include <kiconloader.h>
++#include <kapplication.h>
++#include <kconfig.h>
++
++#include "callmapview.h"
++#include "configuration.h"
++#include "listutils.h"
++#include "toplevel.h"
++
++//
++// CallMapView
++//
++
++
++// defaults
++#define DEFAULT_SPLITMODE "Rows"
++#define DEFAULT_DRAWNAME true
++#define DEFAULT_DRAWCOST true
++#define DEFAULT_DRAWLOCATION false
++#define DEFAULT_DRAWCALLS false
++#define DEFAULT_FORCESTRINGS false
++#define DEFAULT_ROTATION true
++#define DEFAULT_SHADING true
++#define DEFAULT_MAXAREA 100
++
++
++CallMapView::CallMapView(bool showCallers, TraceItemView* parentView,
++ TQWidget* parent, const char* name)
++ : TreeMapWidget(new CallMapBaseItem(), parent, name), TraceItemView(parentView)
++{
++ _showCallers = showCallers;
++
++ setFieldType(0, i18n( "Name" ));
++ setFieldType(1, i18n( "Cost" ));
++ setFieldType(2, i18n( "Location" ));
++ setFieldPosition(2, TreeMapItem::TopLeft);
++ setFieldType(3, i18n( "Calls" ));
++ setFieldPosition(3, TreeMapItem::TopRight);
++
++ setSplitMode(DEFAULT_SPLITMODE);
++ setFieldVisible(0, DEFAULT_DRAWNAME);
++ setFieldVisible(1, DEFAULT_DRAWCOST);
++ setFieldVisible(2, DEFAULT_DRAWLOCATION);
++ setFieldVisible(3, DEFAULT_DRAWCALLS);
++ setFieldForced(0, DEFAULT_FORCESTRINGS);
++ setFieldForced(1, DEFAULT_FORCESTRINGS);
++ setFieldForced(2, DEFAULT_FORCESTRINGS);
++ setFieldForced(3, DEFAULT_FORCESTRINGS);
++ setAllowRotation(DEFAULT_ROTATION);
++ setShadingEnabled(DEFAULT_SHADING);
++ setMinimalArea(DEFAULT_MAXAREA);
++
++ connect(this,
++ TQT_SIGNAL(doubleClicked(TreeMapItem*)),
++ TQT_SLOT(activatedSlot(TreeMapItem*)));
++ connect(this,
++ TQT_SIGNAL(returnPressed(TreeMapItem*)),
++ TQT_SLOT(activatedSlot(TreeMapItem*)));
++ connect(this,
++ TQT_SIGNAL(currentChanged(TreeMapItem*, bool)),
++ TQT_SLOT(selectedSlot(TreeMapItem*, bool)));
++ connect(this,
++ TQT_SIGNAL(contextMenuRequested(TreeMapItem*,const TQPoint &)),
++ TQT_SLOT(context(TreeMapItem*,const TQPoint &)));
++
++ TQWhatsThis::add( this, whatsThis());
++}
++
++TQString CallMapView::whatsThis() const
++{
++ TQString s = _showCallers ?
++ i18n( "<b>Caller Map</b>"
++ "<p>This graph shows the nested hierarchy of "
++ "all callers of the current activated function. "
++ "Each colored rectangle represents a function; "
++ "its size tries to be proportional to the cost spent "
++ "therein while the active function is running "
++ "(however, there are drawing constrains).</p>") :
++ i18n("<b>Call Map</b>"
++ "<p>This graph shows the nested hierarchy of "
++ "all callees of the current activated function. "
++ "Each colored rectangle represents a function; "
++ "its size tries to be proportional to the cost spent "
++ "therein while the active function is running "
++ "(however, there are drawing constrains).</p>");
++
++ s += i18n( "<p>Appearance options can be found in the "
++ "in the context menu. To get exact size proportions, "
++ "choose 'Hide incorrect borders'. As this mode can be "
++ "<em>very</em> time consuming, you may want to limit "
++ "the maximum drawn nesting level before. "
++ "'Best' determinates the split direction for children "
++ "from the aspect ratio of the parent. "
++ "'Always Best' decides on remaining space for each "
++ "sibling. "
++ "'Ignore Proportions' takes space for function name "
++ "drawing <em>before</em> drawing children. Note that "
++ "size proportions can get <em>heavily</em> wrong.</p>"
++
++ "<p>This is a <em>TreeMap</em> widget. "
++ "Keyboard navigation is available with the left/right arrow "
++ "keys for traversing siblings, and up/down arrow keys "
++ "to go a nesting level up/down. "
++ "<em>Return</em> activates the current item.</p>");
++
++ return s;
++}
++
++void CallMapView::setData(TraceData* d)
++{
++ TraceItemView::setData(d);
++
++ ((CallMapBaseItem*)base())->setFunction(0);
++}
++
++void CallMapView::context(TreeMapItem* i,const TQPoint & p)
++{
++ if (!i) return;
++
++ TQPopupMenu popup;
++ TQPopupMenu fpopup; // select function subpopup
++ TQPopupMenu vpopup; // visualisation subpopup
++ TQPopupMenu dpopup; // split direction
++ TQPopupMenu bpopup; // border subpopup
++ TQPopupMenu l1popup; // depth limit subpopup
++ TQPopupMenu l2popup; // function limit subpopup
++ TQPopupMenu l3popup; // area limit subpopup
++
++ TreeMapItem* item = i;
++ int count;
++
++ TQString shortCurrentName;
++ if (i) {
++ shortCurrentName = i->text(0);
++ if ((int)shortCurrentName.length() > Configuration::maxSymbolLength())
++ shortCurrentName =
++ shortCurrentName.left(Configuration::maxSymbolLength()) + "...";
++ }
++
++ if (item) {
++ popup.insertItem(i18n("Go To"), &fpopup, 100);
++ count = 0;
++ while (count<Configuration::maxSymbolCount() && item) {
++ TQString name = item->text(0);
++ if ((int)name.length()>Configuration::maxSymbolLength())
++ name = name.left(Configuration::maxSymbolLength()) + "...";
++ fpopup.insertItem(name, 101+count);
++ item = item->parent();
++ count++;
++ }
++ popup.insertSeparator();
++ }
++
++ addGoMenu(&popup);
++ popup.insertSeparator();
++
++ l1popup.setCheckable(true);
++ popup.insertItem(i18n("Stop at Depth"), &l1popup, 12);
++
++ int maxDepth = maxDrawingDepth();
++ l1popup.insertItem(i18n("No Depth Limit"), 50);
++ l1popup.setItemChecked(50, maxDepth==-1);
++ l1popup.insertSeparator();
++ l1popup.insertItem(i18n("Depth 10"), 51);
++ l1popup.setItemChecked(51, maxDepth==10);
++ l1popup.insertItem(i18n("Depth 15"), 52);
++ l1popup.setItemChecked(52, maxDepth==15);
++ l1popup.insertItem(i18n("Depth 20"), 53);
++ l1popup.setItemChecked(53, maxDepth==20);
++ if (i) {
++ l1popup.insertSeparator();
++ l1popup.insertItem(i18n("Depth of '%1' (%2)")
++ .arg(shortCurrentName).arg(i->depth()), 55);
++ l1popup.setItemChecked(55, maxDepth == i->depth());
++ }
++ if (maxDepth>0) {
++ l1popup.insertSeparator();
++ l1popup.insertItem(i18n("Decrement Depth (to %1)").arg(maxDepth-1), 56);
++ l1popup.insertItem(i18n("Increment Depth (to %1)").arg(maxDepth+1), 57);
++ }
++
++ l2popup.setCheckable(true);
++ popup.insertItem(i18n("Stop at Function"), &l2popup, 13);
++ l2popup.insertItem(i18n("No Function Limit"), 200);
++ l2popup.setItemChecked(200, fieldStop(0).isEmpty());
++ bool foundStopName = false;
++ item = i;
++ if (i) {
++ l2popup.insertSeparator();
++ count = 0;
++ while (count<Configuration::maxSymbolCount() && item) {
++ TQString name = item->text(0);
++ if ((int)name.length()>Configuration::maxSymbolLength())
++ name = name.left(Configuration::maxSymbolLength()) + "...";
++ l2popup.insertItem(name, 201+count);
++ if (item->text(0) == fieldStop(0)) {
++ l2popup.setItemChecked(201+count, true);
++ foundStopName = true;
++ }
++ item = item->parent();
++ count++;
++ }
++ }
++ if (!foundStopName && !fieldStop(0).isEmpty()) {
++ l2popup.insertSeparator();
++ TQString name = fieldStop(0);
++ if ((int)name.length()>Configuration::maxSymbolLength())
++ name = name.left(Configuration::maxSymbolLength()) + "...";
++ l2popup.insertItem(name, 199);
++ l2popup.setItemChecked(199, true);
++ }
++
++ l3popup.setCheckable(true);
++ popup.insertItem(i18n("Stop at Area"), &l3popup, 14);
++
++ int mArea = minimalArea();
++ l3popup.insertItem(i18n("No Area Limit"), 60);
++ l3popup.setItemChecked(60, mArea ==-1);
++ l3popup.insertSeparator();
++ l3popup.insertItem(i18n("50 Pixels"), 63);
++ l3popup.setItemChecked(63, mArea==50);
++ l3popup.insertItem(i18n("100 Pixels"), 64);
++ l3popup.setItemChecked(64, mArea==100);
++ l3popup.insertItem(i18n("200 Pixels"), 65);
++ l3popup.setItemChecked(65, mArea==200);
++ l3popup.insertItem(i18n("500 Pixels"), 66);
++ l3popup.setItemChecked(66, mArea==500);
++ int currentArea = 0;
++ if (i) {
++ currentArea = i->width() * i->height();
++ l3popup.insertSeparator();
++ l3popup.insertItem(i18n("Area of '%1' (%2)")
++ .arg(shortCurrentName).arg(currentArea), 67);
++ l3popup.setItemChecked(67, mArea == currentArea);
++ }
++ if (mArea>0) {
++ l3popup.insertSeparator();
++ l3popup.insertItem(i18n("Double Area Limit (to %1)")
++ .arg(mArea*2), 68);
++ l3popup.insertItem(i18n("Half Area Limit (to %1)")
++ .arg(mArea/2), 69);
++ }
++
++ popup.insertSeparator();
++
++ vpopup.setCheckable(true);
++ popup.insertItem(i18n("Visualisation"), &vpopup, 10);
++
++ TQPopupMenu splitpopup;
++ addSplitDirectionItems(&splitpopup, 1001);
++ vpopup.insertItem(i18n("Split Direction"), &splitpopup, 1000);
++
++ vpopup.insertItem(i18n("Skip Incorrect Borders"), 40);
++ vpopup.setItemEnabled(40, !_showCallers);
++ vpopup.setItemChecked(40, skipIncorrectBorder());
++
++ bpopup.setCheckable(true);
++ vpopup.insertItem(i18n("Border Width"), &bpopup, 41);
++ bpopup.insertItem(i18n("Border 0"), 42);
++ bpopup.setItemEnabled(42, !_showCallers);
++ bpopup.setItemChecked(42, borderWidth()==0);
++ bpopup.insertItem(i18n("Border 1"), 43);
++ bpopup.setItemChecked(43, borderWidth()==1);
++ bpopup.insertItem(i18n("Border 2"), 44);
++ bpopup.setItemChecked(44, borderWidth()==2);
++ bpopup.insertItem(i18n("Border 3"), 45);
++ bpopup.setItemChecked(45, borderWidth()==3);
++
++ vpopup.insertSeparator();
++
++ vpopup.insertItem(i18n("Draw Symbol Names"), 20);
++ vpopup.insertItem(i18n("Draw Cost"), 21);
++ vpopup.insertItem(i18n("Draw Location"), 22);
++ vpopup.insertItem(i18n("Draw Calls"), 23);
++ vpopup.insertSeparator();
++
++ vpopup.insertItem(i18n("Ignore Proportions"), 24);
++ vpopup.insertItem(i18n("Allow Rotation"), 25);
++ if (!fieldVisible(0) &&
++ !fieldVisible(1) &&
++ !fieldVisible(2) &&
++ !fieldVisible(3)) {
++ vpopup.setItemEnabled(24, false);
++ vpopup.setItemEnabled(25, false);
++ }
++ else {
++ vpopup.setItemChecked(20,fieldVisible(0));
++ vpopup.setItemChecked(21,fieldVisible(1));
++ vpopup.setItemChecked(22,fieldVisible(2));
++ vpopup.setItemChecked(23,fieldVisible(3));
++ vpopup.setItemChecked(24,fieldForced(0));
++ vpopup.setItemChecked(25,allowRotation());
++ }
++
++ vpopup.insertItem(i18n("Shading"), 26);
++ vpopup.setItemChecked(26,isShadingEnabled());
++
++ int r = popup.exec(mapToGlobal(p));
++
++ if (r>100 && r<150) {
++ r -= 100;
++ while (i && (r>1)) {
++ i=i->parent();
++ r--;
++ }
++ activatedSlot(i);
++ return;
++ }
++
++ if (r>200 && r<250) {
++ r -= 200;
++ while (i && (r>1)) {
++ i=i->parent();
++ r--;
++ }
++ if (i)
++ setFieldStop(0, i->text(0));
++
++ return;
++ }
++
++ switch(r) {
++ case 20:
++ setFieldVisible(0, !vpopup.isItemChecked(20));
++ break;
++
++ case 21:
++ setFieldVisible(1, !vpopup.isItemChecked(21));
++ break;
++
++ case 22:
++ setFieldVisible(2, !vpopup.isItemChecked(22));
++ break;
++
++ case 23:
++ setFieldVisible(3, !vpopup.isItemChecked(23));
++ break;
++
++ case 24:
++ setFieldForced(0, !vpopup.isItemChecked(24));
++ setFieldForced(1, !vpopup.isItemChecked(24));
++ setFieldForced(2, !vpopup.isItemChecked(24));
++ setFieldForced(3, !vpopup.isItemChecked(24));
++ break;
++
++ case 25: setAllowRotation(!vpopup.isItemChecked(25)); break;
++ case 26: setShadingEnabled(!vpopup.isItemChecked(26)); break;
++
++ case 40:
++ setSkipIncorrectBorder(!vpopup.isItemChecked(40));
++ break;
++
++ case 42: setBorderWidth(0); break;
++ case 43: setBorderWidth(1); break;
++ case 44: setBorderWidth(2); break;
++ case 45: setBorderWidth(3); break;
++
++ case 50: setMaxDrawingDepth(-1); break;
++ case 51: setMaxDrawingDepth(10); break;
++ case 52: setMaxDrawingDepth(15); break;
++ case 53: setMaxDrawingDepth(20); break;
++ case 55: setMaxDrawingDepth(i->depth()); break;
++ case 56: setMaxDrawingDepth(maxDepth-1); break;
++ case 57: setMaxDrawingDepth(maxDepth+1); break;
++
++ case 200: setFieldStop(0, TQString()); break;
++
++ case 60: setMinimalArea(-1); break;
++ case 61: setMinimalArea(10); break;
++ case 62: setMinimalArea(20); break;
++ case 63: setMinimalArea(50); break;
++ case 64: setMinimalArea(100); break;
++ case 65: setMinimalArea(200); break;
++ case 66: setMinimalArea(500); break;
++ case 67: setMinimalArea(currentArea); break;
++ case 68: setMinimalArea(mArea*2); break;
++ case 69: setMinimalArea(mArea/2); break;
++ }
++}
++
++void CallMapView::activatedSlot(TreeMapItem* item)
++{
++ if (!item) return;
++
++ if (item->rtti() == 1) {
++ CallMapBaseItem* bi = (CallMapBaseItem*)item;
++ activated(bi->function());
++ }
++ else if (item->rtti() == 2) {
++ CallMapCallingItem* ci = (CallMapCallingItem*)item;
++ activated(ci->function());
++ }
++ else if (item->rtti() == 3) {
++ CallMapCallerItem* ci = (CallMapCallerItem*)item;
++ activated(ci->function());
++ }
++}
++
++void CallMapView::selectedSlot(TreeMapItem* item, bool kbd)
++{
++ if (!item) return;
++ if (item->text(0).isEmpty()) return;
++
++ if (kbd) {
++ TQString msg = i18n("Call Map: Current is '%1'").arg(item->text(0));
++ if (_topLevel)
++ _topLevel->showMessage(msg, 5000);
++ }
++
++ TraceFunction* f = 0;
++
++ if (item->rtti() == 1) {
++ CallMapBaseItem* bi = (CallMapBaseItem*)item;
++ f = bi->function();
++ }
++ else if (item->rtti() == 2) {
++ CallMapCallingItem* ci = (CallMapCallingItem*)item;
++ f = ci->function();
++ }
++ else if (item->rtti() == 3) {
++ CallMapCallerItem* ci = (CallMapCallerItem*)item;
++ f = ci->function();
++ }
++ if (f) {
++ // this avoids marking
++ _selectedItem = f;
++ selected(f);
++ }
++}
++
++TraceItem* CallMapView::canShow(TraceItem* i)
++{
++ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType;
++
++ switch(t) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ return i;
++ default:
++ break;
++ }
++ return 0;
++}
++
++void CallMapView::doUpdate(int changeType)
++{
++ if (changeType == costType2Changed) return;
++
++ // if there is a selected item, always draw marking...
++ if (changeType & selectedItemChanged) {
++ TraceFunction* f = 0;
++
++ if (_selectedItem) {
++ switch(_selectedItem->type()) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ f = (TraceFunction*)_selectedItem;
++ break;
++ default:
++ break;
++ }
++ }
++ // if this is the only change...
++ if (changeType == selectedItemChanged) {
++ setMarked(f ? 1:0, true);
++ return;
++ }
++ setMarked(f ? 1:0, false);
++ }
++
++
++ if (changeType & activeItemChanged) {
++ TraceFunction* f = 0;
++
++ if (_activeItem) {
++ switch(_activeItem->type()) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ f = (TraceFunction*)_activeItem;
++ break;
++ default:
++ break;
++ }
++ }
++ ((CallMapBaseItem*)base())->setFunction(f);
++ }
++ else if ( ((changeType & partsChanged) && Configuration::showCycles()) ||
++ (changeType & dataChanged) ||
++ (changeType & configChanged)) {
++ /* regenerates the treemap because traceitems were added/removed */
++ base()->refresh();
++ }
++ else if ((changeType & partsChanged) ||
++ (changeType & costTypeChanged)) {
++ /* we need to do the draw order sorting again as the values change */
++ resort();
++ redraw();
++ }
++ else
++ redraw();
++}
++
++
++
++TQColor CallMapView::groupColor(TraceFunction* f) const
++{
++ if (!f)
++ return colorGroup().button();
++
++ return Configuration::functionColor(_groupType, f);
++}
++
++
++TQString CallMapView::tipString(TreeMapItem* i) const
++{
++ TQString tip, itemTip;
++ int count = 0;
++
++ //qDebug("CallMapView::tipString for '%s'", i->text(0).ascii());
++
++ // first, SubPartItem's
++ while (i && count<Configuration::maxSymbolCount()) {
++ itemTip = i->text(0);
++ if ((int)itemTip.length()>Configuration::maxSymbolLength())
++ itemTip = itemTip.left(Configuration::maxSymbolLength()) + "...";
++
++ if (!i->text(1).isEmpty())
++ itemTip += " (" + i->text(1) + ")";
++
++ if (!tip.isEmpty()) tip += "\n";
++
++ tip += itemTip;
++ i = i->parent();
++ count++;
++ }
++ if (count == Configuration::maxSymbolCount()) tip += "\n...";
++
++ return tip;
++}
++
++
++TraceCost* CallMapView::totalCost()
++{
++ TraceFunction* f = ((CallMapBaseItem*)base())->function();
++ if (!f) return 0;
++
++ return Configuration::showExpanded() ? f->inclusive() : f->data();
++}
++
++
++
++
++// CallMapBaseItem
++
++CallMapBaseItem::CallMapBaseItem()
++{
++ _f = 0;
++}
++
++void CallMapBaseItem::setFunction(TraceFunction* f)
++{
++ if (f == _f) return;
++
++ _f = f;
++ refresh();
++}
++
++
++TQString CallMapBaseItem::text(int textNo) const
++{
++ if (textNo == 0) {
++ if (!_f)
++ return i18n("(no function)");
++
++ return _f->prettyName();
++ }
++
++ if (!_f) return TQString();
++
++ if (textNo == 2) return _f->prettyLocation();
++ if (textNo == 3) return _f->calledCount().pretty();
++ if (textNo != 1) return TQString();
++
++ TraceCostType* ct = ((CallMapView*)widget())->costType();
++ TraceCost* t = ((CallMapView*)widget())->totalCost();
++
++ if (Configuration::showPercentage()) {
++ double sum, total = t->subCost(ct);
++ if (total == 0.0)
++ sum = 100.0;
++ else
++ sum = 100.0 * _f->inclusive()->subCost(ct) / total;
++
++ return TQString("%1 %")
++ .arg(sum, 0, 'f', Configuration::percentPrecision());
++ }
++ return _f->inclusive()->prettySubCost(ct);
++}
++
++TQPixmap CallMapBaseItem::pixmap(int i) const
++{
++ if ((i != 1) || !_f) return TQPixmap();
++
++ TraceCostType* ct = ((CallMapView*)widget())->costType();
++ TraceCost* t = ((CallMapView*)widget())->totalCost();
++
++ // colored level meter with frame
++ return costPixmap( ct, _f->inclusive(), (double) (t->subCost(ct)), true);
++}
++
++
++double CallMapBaseItem::value() const
++{
++ if (!_f) return 0.0;
++
++ TraceCostType* ct;
++ ct = ((CallMapView*)widget())->costType();
++ return (double) _f->inclusive()->subCost(ct);
++}
++
++
++double CallMapBaseItem::sum() const
++{
++ if (!_f) return 0.0;
++
++ CallMapView* w = (CallMapView*)widget();
++
++ if (w->showCallers())
++ return 0.0;
++ else
++ return (double) _f->inclusive()->subCost(w->costType());
++}
++
++
++bool CallMapBaseItem::isMarked(int) const
++{
++ return ((CallMapView*)widget())->selectedItem() == _f;
++}
++
++TreeMapItemList* CallMapBaseItem::children()
++{
++ if (_f && !initialized()) {
++ CallMapView* w = (CallMapView*)widget();
++
++ if (0) qDebug("Create Function %s (%s)",
++ w->showCallers() ? "Callers":"Callees",
++ text(0).ascii());
++
++ TraceCall* call;
++
++ setSorting(-1);
++ if (w->showCallers()) {
++ TraceCallList l = _f->callers();
++ for (call=l.first();call;call=l.next()) {
++
++ // don't show calls inside of a cycle
++ if (call->inCycle()>0) continue;
++ if (call->isRecursion()) continue;
++
++ addItem(new CallMapCallerItem(1.0, call));
++ }
++
++ setSum(0);
++ }
++ else {
++ TraceCallList l = _f->callings();
++ for (call=l.first();call;call=l.next()) {
++
++ // don't show calls inside of a cycle
++ if (call->inCycle()>0) continue;
++ if (call->isRecursion()) continue;
++
++ CallMapCallingItem* i = new CallMapCallingItem(1.0, call);
++ i->init();
++ addItem(i);
++ }
++
++ setSum(_f->inclusive()->subCost(w->costType()));
++ }
++ setSorting(-2, false);
++ }
++
++ return _children;
++}
++
++TQColor CallMapBaseItem::backColor() const
++{
++ return ((CallMapView*)widget())->groupColor(_f);
++}
++
++
++
++// CallMapCallingItems
++
++CallMapCallingItem::CallMapCallingItem(double factor, TraceCall* c)
++{
++ _factor = factor;
++ _c = c;
++}
++
++void CallMapCallingItem::init()
++{
++#if 0
++ // create assoziation: if not possible, i.e. an ass. already exists
++ // for the function, we need to draw the recursive version
++ _recursive = !setFunction(_c->called());
++ _valid = true;
++#endif
++}
++
++TQString CallMapCallingItem::text(int textNo) const
++{
++ if (textNo == 0) {
++ if (!_c)
++ return i18n("(no call)");
++
++ return _c->calledName();
++ }
++
++ if (textNo == 2) return _c->called()->prettyLocation();
++ if (textNo == 3) return SubCost(_factor * _c->callCount()).pretty();
++ if (textNo != 1) return TQString();
++
++ TraceCostType* ct;
++ ct = ((CallMapView*)widget())->costType();
++
++ SubCost val = SubCost(_factor * _c->subCost(ct));
++ if (Configuration::showPercentage()) {
++ // percentage relative to function cost
++ TraceCost* t = ((CallMapView*)widget())->totalCost();
++ double p = 100.0 * _factor * _c->subCost(ct) / t->subCost(ct);
++ return TQString("%1 %")
++ .arg(p, 0, 'f', Configuration::percentPrecision());
++ }
++ return val.pretty();
++}
++
++TQPixmap CallMapCallingItem::pixmap(int i) const
++{
++ if (i != 1) return TQPixmap();
++
++ // Cost pixmap
++ TraceCostType* ct = ((CallMapView*)widget())->costType();
++ TraceCost* t = ((CallMapView*)widget())->totalCost();
++
++ // colored level meter with frame
++ return costPixmap( ct, _c, t->subCost(ct) / _factor, true);
++}
++
++
++double CallMapCallingItem::value() const
++{
++ TraceCostType* ct;
++ ct = ((CallMapView*)widget())->costType();
++ return _factor * _c->subCost(ct);
++}
++
++double CallMapCallingItem::sum() const
++{
++ return value();
++}
++
++bool CallMapCallingItem::isMarked(int) const
++{
++ return ((CallMapView*)widget())->selectedItem() == _c->called();
++}
++
++
++TreeMapItemList* CallMapCallingItem::children()
++{
++ if (!initialized()) {
++ if (0) qDebug("Create Calling subitems (%s)", path(0).join("/").ascii());
++
++ TraceCostType* ct;
++ ct = ((CallMapView*)widget())->costType();
++
++ // same as sum()
++ SubCost s = _c->called()->inclusive()->subCost(ct);
++ SubCost v = _c->subCost(ct);
++ if (v>s) {
++ qDebug("Warning: CallingItem subVal %u > Sum %u (%s)",
++ (unsigned)v, (unsigned)s, _c->called()->prettyName().ascii());
++ v = s;
++ }
++ double newFactor = _factor * v / s;
++
++#if 0
++ qDebug("CallingItem: Subitems of %s => %s, factor %f * %d/%d => %f",
++ _c->caller()->prettyName().ascii(),
++ _c->called()->prettyName().ascii(),
++ _factor, v, s, newFactor);
++#endif
++ setSorting(-1);
++ TraceCall* call;
++ TraceCallList l = _c->called()->callings();
++ for (call=l.first();call;call=l.next()) {
++
++ // don't show calls inside of a cycle
++ if (call->inCycle()>0) continue;
++ if (call->isRecursion()) continue;
++
++ CallMapCallingItem* i = new CallMapCallingItem(newFactor, call);
++ i->init();
++ addItem(i);
++ }
++ setSorting(-2, false);
++ }
++
++ return _children;
++}
++
++
++TQColor CallMapCallingItem::backColor() const
++{
++ CallMapView* w = (CallMapView*)widget();
++ return w->groupColor(_c->called());
++}
++
++
++// CallMapCallerItem
++
++CallMapCallerItem::CallMapCallerItem(double factor, TraceCall* c)
++{
++ _factor = factor;
++ _c = c;
++}
++
++TQString CallMapCallerItem::text(int textNo) const
++{
++ if (textNo == 0) {
++ if (!_c)
++ return i18n("(no call)");
++
++ return _c->callerName();
++ }
++
++ if (textNo == 2) return _c->caller()->prettyLocation();
++ if (textNo == 3) return SubCost(_factor * _c->callCount()).pretty();
++ if (textNo != 1) return TQString();
++
++ TraceCostType* ct;
++ ct = ((CallMapView*)widget())->costType();
++
++ SubCost val = SubCost(_factor * _c->subCost(ct));
++ if (Configuration::showPercentage()) {
++ TraceCost* t = ((CallMapView*)widget())->totalCost();
++ double p = 100.0 * _factor * _c->subCost(ct) / t->subCost(ct);
++ return TQString("%1 %")
++ .arg(p, 0, 'f', Configuration::percentPrecision());
++ }
++ return val.pretty();
++}
++
++
++TQPixmap CallMapCallerItem::pixmap(int i) const
++{
++ if (i != 1) return TQPixmap();
++
++ // Cost pixmap
++ TraceCostType* ct = ((CallMapView*)widget())->costType();
++ TraceCost* t = ((CallMapView*)widget())->totalCost();
++
++ // colored level meter with frame
++ return costPixmap( ct, _c, t->subCost(ct) / _factor, true );
++}
++
++
++double CallMapCallerItem::value() const
++{
++ TraceCostType* ct;
++ ct = ((CallMapView*)widget())->costType();
++ return (double) _c->subCost(ct);
++}
++
++bool CallMapCallerItem::isMarked(int) const
++{
++ return ((CallMapView*)widget())->selectedItem() == _c->caller();
++}
++
++
++TreeMapItemList* CallMapCallerItem::children()
++{
++ if (!initialized()) {
++ //qDebug("Create Caller subitems (%s)", name().ascii());
++
++ TraceCostType* ct;
++ ct = ((CallMapView*)widget())->costType();
++
++ SubCost s = _c->caller()->inclusive()->subCost(ct);
++ SubCost v = _c->subCost(ct);
++ double newFactor = _factor * v / s;
++
++
++#if 0
++ qDebug("CallerItem: Subitems of %s => %s, factor %f * %d/%d => %f",
++ _c->caller()->prettyName().ascii(),
++ _c->called()->prettyName().ascii(),
++ _factor, v, s, newFactor);
++#endif
++ setSorting(-1);
++
++ TraceCall* call;
++ TraceCallList l = _c->caller()->callers();
++ for (call=l.first();call;call=l.next()) {
++
++ // don't show calls inside of a cycle
++ if (call->inCycle()>0) continue;
++ if (call->isRecursion()) continue;
++
++ TreeMapItem* i = new CallMapCallerItem(newFactor, call);
++ addItem(i);
++ }
++ setSorting(-2, false);
++ }
++
++ return _children;
++}
++
++TQColor CallMapCallerItem::backColor() const
++{
++ CallMapView* w = (CallMapView*)widget();
++ return w->groupColor(_c->caller());
++}
++
++void CallMapView::readViewConfig(KConfig* c,
++ TQString prefix, TQString postfix, bool)
++{
++ KConfigGroup* g = configGroup(c, prefix, postfix);
++
++ setSplitMode(g->readEntry("SplitMode", DEFAULT_SPLITMODE));
++
++ setFieldVisible(0, g->readBoolEntry("DrawName", DEFAULT_DRAWNAME));
++ setFieldVisible(1, g->readBoolEntry("DrawCost", DEFAULT_DRAWCOST));
++ setFieldVisible(2, g->readBoolEntry("DrawLocation", DEFAULT_DRAWLOCATION));
++ setFieldVisible(3, g->readBoolEntry("DrawCalls", DEFAULT_DRAWCALLS));
++
++ bool enable = g->readBoolEntry("ForceStrings", DEFAULT_FORCESTRINGS);
++ setFieldForced(0, enable);
++ setFieldForced(1, enable);
++ setFieldForced(2, enable);
++ setFieldForced(3, enable);
++
++ setAllowRotation(g->readBoolEntry("AllowRotation", DEFAULT_ROTATION));
++ setShadingEnabled(g->readBoolEntry("Shading", DEFAULT_SHADING));
++ setFieldStop(0, g->readEntry("StopName"));
++ setMaxDrawingDepth(g->readNumEntry("MaxDepth", -1));
++ setMinimalArea(g->readNumEntry("MaxArea", DEFAULT_MAXAREA));
++
++ delete g;
++}
++
++void CallMapView::saveViewConfig(KConfig* c,
++ TQString prefix, TQString postfix, bool)
++{
++ KConfigGroup g(c, (prefix+postfix).ascii());
++
++ writeConfigEntry(&g, "SplitMode", splitModeString(), DEFAULT_SPLITMODE);
++ writeConfigEntry(&g, "DrawName", fieldVisible(0), DEFAULT_DRAWNAME);
++ writeConfigEntry(&g, "DrawCost", fieldVisible(1), DEFAULT_DRAWCOST);
++ writeConfigEntry(&g, "DrawLocation", fieldVisible(2), DEFAULT_DRAWLOCATION);
++ writeConfigEntry(&g, "DrawCalls", fieldVisible(3), DEFAULT_DRAWCALLS);
++ // when option for all text (0-3)
++ writeConfigEntry(&g, "ForceStrings", fieldForced(0), DEFAULT_FORCESTRINGS);
++
++ writeConfigEntry(&g, "AllowRotation", allowRotation(), DEFAULT_ROTATION);
++ writeConfigEntry(&g, "Shading", isShadingEnabled(), DEFAULT_SHADING);
++
++ writeConfigEntry(&g, "StopName", fieldStop(0), "");
++ writeConfigEntry(&g, "MaxDepth", maxDrawingDepth(), -1);
++ writeConfigEntry(&g, "MaxArea", minimalArea(), DEFAULT_MAXAREA);
++}
++
++#include "callmapview.moc"
+diff --git a/kdecachegrind/kdecachegrind/callmapview.h b/kdecachegrind/kdecachegrind/callmapview.h
+new file mode 100644
+index 0000000..860743f
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/callmapview.h
+@@ -0,0 +1,130 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Call Map View
++ */
++
++#ifndef CALLMAPVIEW_H
++#define CALLMAPVIEW_H
++
++#include "treemap.h"
++#include "tracedata.h"
++#include "traceitemview.h"
++
++class CallMapView: public TreeMapWidget, public TraceItemView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++
++ CallMapView(bool showCallers, TraceItemView* parentView,
++ TQWidget* parent=0, const char* name=0);
++
++ TQWidget* widget() { return this; }
++ TQString whatsThis() const;
++ void setData(TraceData*);
++
++ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++
++ bool showCallers() const { return _showCallers; }
++ TraceCost* totalCost();
++ TQString tipString(TreeMapItem*) const;
++ TQColor groupColor(TraceFunction*) const;
++
++private slots:
++ void context(TreeMapItem*,const TQPoint &);
++ void selectedSlot(TreeMapItem*, bool);
++ void activatedSlot(TreeMapItem*);
++
++private:
++ TraceItem* canShow(TraceItem*);
++ void doUpdate(int);
++
++ bool _showCallers;
++};
++
++
++
++// Subitems of CallMap
++
++class CallMapBaseItem: public TreeMapItem
++{
++public:
++ CallMapBaseItem();
++
++ void setFunction(TraceFunction* f);
++ TraceFunction* function() { return _f; }
++ int rtti() const { return 1; }
++ double sum() const;
++ double value() const ;
++ bool isMarked(int) const;
++ TQString text(int) const;
++ TQPixmap pixmap(int) const;
++ TreeMapItemList* children();
++ TQColor backColor() const;
++
++private:
++ TraceFunction* _f;
++};
++
++
++class CallMapCallingItem: public TreeMapItem
++{
++public:
++ CallMapCallingItem(double factor, TraceCall* c);
++ void init();
++ int rtti() const { return 2; }
++ int borderWidth() const { return widget()->borderWidth(); }
++ TraceFunction* function() { return _c->called(); }
++ double value() const;
++ double sum() const;
++ bool isMarked(int) const;
++ TQString text(int) const;
++ TQPixmap pixmap(int) const;
++ TreeMapItemList* children();
++ TQColor backColor() const;
++
++private:
++ TraceCall* _c;
++ double _factor;
++};
++
++class CallMapCallerItem: public TreeMapItem
++{
++public:
++ CallMapCallerItem(double factor, TraceCall* c);
++ int rtti() const { return 3; }
++ int borderWidth() const { return widget()->borderWidth(); }
++ TraceFunction* function() { return _c->caller(); }
++ double value() const;
++ bool isMarked(int) const;
++ TQString text(int) const;
++ TQPixmap pixmap(int) const;
++ TreeMapItemList* children();
++ TQColor backColor() const;
++
++private:
++ TraceCall* _c;
++ double _factor;
++};
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/callview.cpp b/kdecachegrind/kdecachegrind/callview.cpp
+new file mode 100644
+index 0000000..317d137
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/callview.cpp
+@@ -0,0 +1,256 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Call Views
++ */
++
++#include <tqwhatsthis.h>
++#include <tqpopupmenu.h>
++#include <klocale.h>
++
++#include "configuration.h"
++#include "callitem.h"
++#include "callview.h"
++
++
++
++//
++// CallView
++//
++
++
++CallView::CallView(bool showCallers, TraceItemView* parentView,
++ TQWidget* parent, const char* name)
++ : TQListView(parent, name), TraceItemView(parentView)
++{
++ _showCallers = showCallers;
++
++ addColumn( i18n( "Cost" ) );
++ addColumn( i18n( "Cost 2" ) );
++ if (_showCallers) {
++ addColumn( i18n( "Count" ) );
++ addColumn( i18n( "Caller" ) );
++ }
++ else {
++ addColumn( i18n( "Count" ) );
++ addColumn( i18n( "Callee" ) );
++ }
++
++ setSorting(0,false);
++ setColumnAlignment(0, TQt::AlignRight);
++ setColumnAlignment(1, TQt::AlignRight);
++ setColumnAlignment(2, TQt::AlignRight);
++ setAllColumnsShowFocus(true);
++ setResizeMode(TQListView::LastColumn);
++ setMinimumHeight(50);
++
++ connect( this,
++ TQT_SIGNAL( selectionChanged(TQListViewItem*) ),
++ TQT_SLOT( selectedSlot(TQListViewItem*) ) );
++
++ connect( this,
++ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
++ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int)));
++
++ connect(this,
++ TQT_SIGNAL(doubleClicked(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ connect(this,
++ TQT_SIGNAL(returnPressed(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ TQWhatsThis::add( this, whatsThis() );
++}
++
++TQString CallView::whatsThis() const
++{
++ return _showCallers ?
++ i18n( "<b>List of direct Callers</b>"
++ "<p>This list shows all functions calling the "
++ "current selected one directly, together with "
++ "a call count and the cost spent in the current "
++ "selected function while being called from the "
++ "function from the list.</p>"
++ "<p>An icon instead of an inclusive cost specifies "
++ "that this is a call inside of a recursive cycle. "
++ "An inclusive cost makes no sense here.</p>"
++ "<p>Selecting a function makes it the current selected "
++ "one of this information panel. "
++ "If there are two panels (Split mode), the "
++ "function of the other panel is changed instead.</p>") :
++ i18n( "<b>List of direct Callees</b>"
++ "<p>This list shows all functions called by the "
++ "current selected one directly, together with "
++ "a call count and the cost spent in this function "
++ "while being called from the selected function.</p>"
++ "<p>Selecting a function makes it the current selected "
++ "one of this information panel. "
++ "If there are two panels (Split mode), the "
++ "function of the other panel is changed instead.</p>");
++}
++
++
++void CallView::context(TQListViewItem* i, const TQPoint & p, int col)
++{
++ TQPopupMenu popup;
++
++ // Menu entry:
++ TraceCall* c = i ? ((CallItem*) i)->call() : 0;
++ TraceFunction *f = 0, *cycle = 0;
++
++ if (c) {
++ TQString name = _showCallers ? c->callerName(true) : c->calledName(true);
++ f = _showCallers ? c->caller(true) : c->called(true);
++ cycle = f->cycle();
++
++ popup.insertItem(i18n("Go to '%1'")
++ .arg(Configuration::shortenSymbol(name)), 93);
++
++ if (cycle) {
++ name = Configuration::shortenSymbol(cycle->prettyName());
++ popup.insertItem(i18n("Go to '%1'").arg(name), 94);
++ }
++
++ popup.insertSeparator();
++ }
++
++ if ((col == 0) || (col == 1)) {
++ addCostMenu(&popup);
++ popup.insertSeparator();
++ }
++ addGoMenu(&popup);
++
++ int r = popup.exec(p);
++ if (r == 93) activated(f);
++ else if (r == 94) activated(cycle);
++}
++
++void CallView::selectedSlot(TQListViewItem * i)
++{
++ if (!i) return;
++ TraceCall* c = ((CallItem*) i)->call();
++ // Should we skip cycles here?
++ TraceItem* f = _showCallers ? c->caller(false) : c->called(false);
++
++ _selectedItem = f;
++ selected(f);
++}
++
++void CallView::activatedSlot(TQListViewItem * i)
++{
++ if (!i) return;
++ TraceCall* c = ((CallItem*) i)->call();
++ // skip cycles: use the context menu to get to the cycle...
++ TraceItem* f = _showCallers ? c->caller(true) : c->called(true);
++
++ activated(f);
++}
++
++TraceItem* CallView::canShow(TraceItem* i)
++{
++ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType;
++
++ switch(t) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ return i;
++ default:
++ break;
++ }
++ return 0;
++}
++
++void CallView::doUpdate(int changeType)
++{
++ // Special case ?
++ if (changeType == selectedItemChanged) {
++
++ if (!_selectedItem) {
++ clearSelection();
++ return;
++ }
++
++ CallItem* ci = (CallItem*) TQListView::selectedItem();
++ TraceCall* c;
++ TraceItem* ti;
++ if (ci) {
++ c = ci->call();
++ ti = _showCallers ? c->caller() : c->called();
++ if (ti == _selectedItem) return;
++ }
++
++ TQListViewItem *item;
++ for (item = firstChild();item;item = item->nextSibling()) {
++ c = ((CallItem*) item)->call();
++ ti = _showCallers ? c->caller() : c->called();
++ if (ti == _selectedItem) {
++ ensureItemVisible(item);
++ setSelected(item, true);
++ break;
++ }
++ }
++ if (!item && ci) clearSelection();
++ return;
++ }
++
++ if (changeType == groupTypeChanged) {
++ TQListViewItem *item;
++ for (item = firstChild();item;item = item->nextSibling())
++ ((CallItem*)item)->updateGroup();
++ return;
++ }
++
++ refresh();
++}
++
++void CallView::refresh()
++{
++ clear();
++ setColumnWidth(0, 50);
++ setColumnWidth(1, _costType2 ? 50:0);
++ setColumnWidth(2, 50);
++ if (_costType)
++ setColumnText(0, _costType->name());
++ if (_costType2)
++ setColumnText(1, _costType2->name());
++
++ if (!_data || !_activeItem) return;
++
++ TraceFunction* f = activeFunction();
++ if (!f) return;
++
++ TraceCall* call;
++ // In the call lists, we skip cycles to show the real call relations
++ TraceCallList l = _showCallers ? f->callers(true) : f->callings(true);
++
++ // Allow resizing of column 1
++ setColumnWidthMode(1, TQListView::Maximum);
++
++ for (call=l.first();call;call=l.next())
++ if (call->subCost(_costType)>0)
++ new CallItem(this, this, call);
++
++ if (!_costType2) {
++ setColumnWidthMode(1, TQListView::Manual);
++ setColumnWidth(1, 0);
++ }
++}
++
++#include "callview.moc"
+diff --git a/kdecachegrind/kdecachegrind/callview.h b/kdecachegrind/kdecachegrind/callview.h
+new file mode 100644
+index 0000000..be644f9
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/callview.h
+@@ -0,0 +1,56 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Call Views
++ */
++
++#ifndef CALLVIEW_H
++#define CALLVIEW_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++#include "traceitemview.h"
++
++class CallView: public TQListView, public TraceItemView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ CallView(bool showCallers, TraceItemView* parentView,
++ TQWidget* parent=0, const char* name=0);
++
++ virtual TQWidget* widget() { return this; }
++ TQString whatsThis() const;
++ bool showCallers() const { return _showCallers; }
++
++private slots:
++ void context(TQListViewItem*,const TQPoint &, int);
++ void selectedSlot(TQListViewItem*);
++ void activatedSlot(TQListViewItem*);
++
++private:
++ TraceItem* canShow(TraceItem*);
++ void doUpdate(int);
++ void refresh();
++
++ bool _showCallers;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/configdlg.cpp b/kdecachegrind/kdecachegrind/configdlg.cpp
+new file mode 100644
+index 0000000..e0b4547
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/configdlg.cpp
+@@ -0,0 +1,398 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Configuration Dialog for KCachegrind
++ */
++
++#include <tqcombobox.h>
++#include <tqcheckbox.h>
++#include <tqlineedit.h>
++#include <tqlistview.h>
++#include <tqdict.h>
++#include <tqmessagebox.h>
++
++#include <kcolorbutton.h>
++#include <kfiledialog.h>
++#include <klocale.h>
++#include <knumvalidator.h>
++
++#include "configdlg.h"
++#include "tracedata.h"
++#include "configuration.h"
++
++
++ConfigDlg::ConfigDlg(Configuration* c, TraceData* data,
++ TQWidget* parent, const char* name)
++ :ConfigDlgBase(parent, name)
++{
++ _config = c;
++ _data = data;
++ _objectCS = 0;
++ _classCS = 0;
++ _fileCS = 0;
++ KIntValidator * numValidator = new KIntValidator( this );
++ maxListEdit->setValidator(numValidator );
++ symbolCount->setValidator(numValidator );
++ symbolLength->setValidator(numValidator );
++ precisionEdit->setValidator(numValidator );
++ contextEdit->setValidator(numValidator );
++
++#if 0
++ TQListViewItem *oItem, *fItem, *cItem, *fnItem;
++ oItem = new(colorList, i18n("ELF Objects"));
++
++ fItem = new(colorList, i18n("Source Files"));
++ cItem = new(colorList, i18n("C++ Classes"));
++ fnItem = new(colorList, i18n("Function (no Grouping)"));
++#endif
++
++ connect(objectCombo, TQT_SIGNAL(activated(const TQString &)),
++ this, TQT_SLOT(objectActivated(const TQString &)));
++ connect(objectCombo, TQT_SIGNAL(textChanged(const TQString &)),
++ this, TQT_SLOT(objectActivated(const TQString &)));
++ connect(objectCheck, TQT_SIGNAL(toggled(bool)),
++ this, TQT_SLOT(objectCheckChanged(bool)));
++ connect(objectColor, TQT_SIGNAL(changed(const TQColor &)),
++ this, TQT_SLOT(objectColorChanged(const TQColor &)));
++
++ connect(classCombo, TQT_SIGNAL(activated(const TQString &)),
++ this, TQT_SLOT(classActivated(const TQString &)));
++ connect(classCombo, TQT_SIGNAL(textChanged(const TQString &)),
++ this, TQT_SLOT(classActivated(const TQString &)));
++ connect(classCheck, TQT_SIGNAL(toggled(bool)),
++ this, TQT_SLOT(classCheckChanged(bool)));
++ connect(classColor, TQT_SIGNAL(changed(const TQColor &)),
++ this, TQT_SLOT(classColorChanged(const TQColor &)));
++
++ connect(fileCombo, TQT_SIGNAL(activated(const TQString &)),
++ this, TQT_SLOT(fileActivated(const TQString &)));
++ connect(fileCombo, TQT_SIGNAL(textChanged(const TQString &)),
++ this, TQT_SLOT(fileActivated(const TQString &)));
++ connect(fileCheck, TQT_SIGNAL(toggled(bool)),
++ this, TQT_SLOT(fileCheckChanged(bool)));
++ connect(fileColor, TQT_SIGNAL(changed(const TQColor &)),
++ this, TQT_SLOT(fileColorChanged(const TQColor &)));
++
++ TQString objectPrefix = TraceCost::typeName(TraceCost::Object);
++ TQString classPrefix = TraceCost::typeName(TraceCost::Class);
++ TQString filePrefix = TraceCost::typeName(TraceCost::File);
++
++ objectCombo->setDuplicatesEnabled(false);
++ classCombo->setDuplicatesEnabled(false);
++ fileCombo->setDuplicatesEnabled(false);
++ objectCombo->setAutoCompletion(true);
++ classCombo->setAutoCompletion(true);
++ fileCombo->setAutoCompletion(true);
++
++ // first unspecified cost items from data
++ TraceObjectMap::Iterator oit;
++ TQStringList oList;
++ for ( oit = data->objectMap().begin();
++ oit != data->objectMap().end(); ++oit )
++ oList.append((*oit).prettyName());
++
++ TraceClassMap::Iterator cit;
++ TQStringList cList;
++ for ( cit = data->classMap().begin();
++ cit != data->classMap().end(); ++cit )
++ cList.append((*cit).prettyName());
++
++ TraceFileMap::Iterator fit;
++ TQStringList fList;
++ for ( fit = data->fileMap().begin();
++ fit != data->fileMap().end(); ++fit )
++ fList.append((*fit).prettyName());
++
++ // then already defined colors (have to check for duplicates!)
++ TQDictIterator<Configuration::ColorSetting> it( c->_colors );
++ for( ; it.current(); ++it ) {
++ if ((*it)->automatic) continue;
++
++ TQString n = it.currentKey();
++ if (n.startsWith(objectPrefix)) {
++ n = n.remove(0, objectPrefix.length()+1);
++ if (oList.findIndex(n) == -1) oList.append(n);
++ }
++ else if (n.startsWith(classPrefix)) {
++ n = n.remove(0, classPrefix.length()+1);
++ if (cList.findIndex(n) == -1) cList.append(n);
++ }
++ else if (n.startsWith(filePrefix)) {
++ n = n.remove(0, filePrefix.length()+1);
++ if (fList.findIndex(n) == -1) fList.append(n);
++ }
++ }
++
++ oList.sort();
++ cList.sort();
++ fList.sort();
++ objectCombo->insertStringList(oList);
++ classCombo->insertStringList(cList);
++ fileCombo->insertStringList(fList);
++
++ objectActivated(objectCombo->currentText());
++ classActivated(classCombo->currentText());
++ fileActivated(fileCombo->currentText());
++
++ maxListEdit->setText(TQString::number(c->_maxListCount));
++
++ _dirItem = 0;
++
++ TQListViewItem* i = new TQListViewItem(dirList, i18n("(always)"));
++ i->setOpen(true);
++ TQStringList::Iterator sit = c->_generalSourceDirs.begin();
++ for(; sit != c->_generalSourceDirs.end(); ++sit ) {
++ TQString d = (*sit);
++ if (d.isEmpty()) d = "/";
++ new TQListViewItem(i, d);
++ }
++ for ( oit = data->objectMap().begin();
++ oit != data->objectMap().end(); ++oit ) {
++ TQString n = (*oit).name();
++ i = new TQListViewItem(dirList, n);
++ i->setOpen(true);
++ TQStringList* dirs = c->_objectSourceDirs[n];
++ if (!dirs) continue;
++
++ sit = dirs->begin();
++ for(; sit != dirs->end(); ++sit ) {
++ TQString d = (*sit);
++ if (d.isEmpty()) d = "/";
++ new TQListViewItem(i, d);
++ }
++ }
++
++ connect(dirList, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
++ this, TQT_SLOT(dirsItemChanged(TQListViewItem*)));
++ connect(addDirButton, TQT_SIGNAL(clicked()),
++ this, TQT_SLOT(dirsAddPressed()));
++ connect(deleteDirButton, TQT_SIGNAL(clicked()),
++ this, TQT_SLOT(dirsDeletePressed()));
++ dirList->setSelected(dirList->firstChild(), true);
++
++ symbolCount->setText(TQString::number(c->_maxSymbolCount));
++ symbolLength->setText(TQString::number(c->_maxSymbolLength));
++ precisionEdit->setText(TQString::number(c->_percentPrecision));
++ contextEdit->setText(TQString::number(c->_context));
++}
++
++ConfigDlg::~ConfigDlg()
++{
++}
++
++bool ConfigDlg::configure(Configuration* c, TraceData* d, TQWidget* p)
++{
++ ConfigDlg dlg(c, d, p);
++
++ if (dlg.exec()) {
++
++ bool ok;
++ int newValue = dlg.maxListEdit->text().toUInt(&ok);
++ if (ok && newValue < 500)
++ c->_maxListCount = newValue;
++ else
++ TQMessageBox::warning(p, i18n("KCachegrind Configuration"),
++ i18n("The Maximum Number of List Items should be below 500."
++ "The previous set value (%1) will still be used.")
++ .arg(TQString::number(c->_maxListCount)),
++ TQMessageBox::Ok, 0);
++
++ c->_maxSymbolCount = dlg.symbolCount->text().toInt();
++ c->_maxSymbolLength = dlg.symbolLength->text().toInt();
++ c->_percentPrecision = dlg.precisionEdit->text().toInt();
++ c->_context = dlg.contextEdit->text().toInt();
++ return true;
++ }
++ return false;
++}
++
++void ConfigDlg::objectActivated(const TQString & s)
++{
++// qDebug("objectActivated: %s", s.ascii());
++
++ if (s.isEmpty()) { _objectCS=0; return; }
++
++ TQString n = TraceCost::typeName(TraceCost::Object) + "-" + s;
++
++ Configuration* c = Configuration::config();
++ Configuration::ColorSetting* cs = c->_colors[n];
++ if (!cs)
++ cs = Configuration::color(n);
++// else
++// qDebug("found color %s", n.ascii());
++
++ _objectCS = cs;
++
++ objectCheck->setChecked(cs->automatic);
++ objectColor->setColor(cs->color);
++
++ /*
++ qDebug("Found Color %s, automatic to %s",
++ _objectCS->name.ascii(),
++ _objectCS->automatic ? "true":"false");
++ */
++}
++
++
++void ConfigDlg::objectCheckChanged(bool b)
++{
++ if (_objectCS) {
++ _objectCS->automatic = b;
++ /*
++ qDebug("Set Color %s automatic to %s",
++ _objectCS->name.ascii(),
++ _objectCS->automatic ? "true":"false");
++ */
++ }
++}
++
++void ConfigDlg::objectColorChanged(const TQColor & c)
++{
++ if (_objectCS) _objectCS->color = c;
++}
++
++void ConfigDlg::classActivated(const TQString & s)
++{
++// qDebug("classActivated: %s", s.ascii());
++
++ if (s.isEmpty()) { _classCS=0; return; }
++
++ TQString n = TraceCost::typeName(TraceCost::Class) + "-" + s;
++
++ Configuration* c = Configuration::config();
++ Configuration::ColorSetting* cs = c->_colors[n];
++ if (!cs)
++ cs = Configuration::color(n);
++
++ _classCS = cs;
++
++ classCheck->setChecked(cs->automatic);
++ classColor->setColor(cs->color);
++
++}
++
++
++void ConfigDlg::classCheckChanged(bool b)
++{
++ if (_classCS) _classCS->automatic = b;
++}
++
++void ConfigDlg::classColorChanged(const TQColor & c)
++{
++ if (_classCS) _classCS->color = c;
++}
++
++
++void ConfigDlg::fileActivated(const TQString & s)
++{
++// qDebug("fileActivated: %s", s.ascii());
++
++ if (s.isEmpty()) { _fileCS=0; return; }
++
++ TQString n = TraceCost::typeName(TraceCost::File) + "-" + s;
++
++ Configuration* c = Configuration::config();
++ Configuration::ColorSetting* cs = c->_colors[n];
++ if (!cs)
++ cs = Configuration::color(n);
++
++ _fileCS = cs;
++
++ fileCheck->setChecked(cs->automatic);
++ fileColor->setColor(cs->color);
++}
++
++
++void ConfigDlg::fileCheckChanged(bool b)
++{
++ if (_fileCS) _fileCS->automatic = b;
++}
++
++void ConfigDlg::fileColorChanged(const TQColor & c)
++{
++ if (_fileCS) _fileCS->color = c;
++}
++
++
++void ConfigDlg::dirsItemChanged(TQListViewItem* i)
++{
++ _dirItem = i;
++ deleteDirButton->setEnabled(i->depth() == 1);
++ addDirButton->setEnabled(i->depth() == 0);
++}
++
++void ConfigDlg::dirsDeletePressed()
++{
++ if (!_dirItem || (_dirItem->depth() == 0)) return;
++ TQListViewItem* p = _dirItem->parent();
++ if (!p) return;
++
++ Configuration* c = Configuration::config();
++ TQString objName = p->text(0);
++
++ TQStringList* dirs;
++ if (objName == i18n("(always)"))
++ dirs = &(c->_generalSourceDirs);
++ else
++ dirs = c->_objectSourceDirs[objName];
++ if (!dirs) return;
++
++ dirs->remove(_dirItem->text(0));
++ delete _dirItem;
++ _dirItem = 0;
++
++ deleteDirButton->setEnabled(false);
++}
++
++void ConfigDlg::dirsAddPressed()
++{
++ if (!_dirItem || (_dirItem->depth() >0)) return;
++
++ Configuration* c = Configuration::config();
++ TQString objName = _dirItem->text(0);
++
++ TQStringList* dirs;
++ if (objName == i18n("(always)"))
++ dirs = &(c->_generalSourceDirs);
++ else {
++ dirs = c->_objectSourceDirs[objName];
++ if (!dirs) {
++ dirs = new TQStringList;
++ c->_objectSourceDirs.insert(objName, dirs);
++ }
++ }
++
++ TQString newDir;
++ newDir = KFileDialog::getExistingDirectory(TQString(),
++ this,
++ i18n("Choose Source Folder"));
++ if (newDir.isEmpty()) return;
++
++ // even for "/", we strip the tailing slash
++ if (newDir.endsWith("/"))
++ newDir = newDir.left(newDir.length()-1);
++
++ if (dirs->findIndex(newDir)>=0) return;
++
++ dirs->append(newDir);
++ if (newDir.isEmpty()) newDir = TQString("/");
++ new TQListViewItem(_dirItem, newDir);
++}
++
++#include "configdlg.moc"
+diff --git a/kdecachegrind/kdecachegrind/configdlg.h b/kdecachegrind/kdecachegrind/configdlg.h
+new file mode 100644
+index 0000000..5ef6bab
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/configdlg.h
+@@ -0,0 +1,65 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Configuration Dialog for KCachegrind
++ */
++
++#ifndef CONFIGDLG_H
++#define CONFIGDLG_H
++
++#include "configdlgbase.h"
++#include "configuration.h"
++
++class TraceData;
++
++class ConfigDlg : public ConfigDlgBase
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ ConfigDlg(Configuration*, TraceData*,
++ TQWidget* parent = 0, const char* name = 0);
++ ~ConfigDlg();
++
++ static bool configure(Configuration*, TraceData*, TQWidget*);
++
++protected slots:
++ void objectActivated(const TQString &);
++ void objectCheckChanged(bool);
++ void objectColorChanged(const TQColor &);
++ void classActivated(const TQString &);
++ void classCheckChanged(bool);
++ void classColorChanged(const TQColor &);
++ void fileActivated(const TQString &);
++ void fileCheckChanged(bool);
++ void fileColorChanged(const TQColor &);
++ void dirsItemChanged(TQListViewItem*);
++ void dirsDeletePressed();
++ void dirsAddPressed();
++
++private:
++ Configuration* _config;
++ TraceData* _data;
++
++ Configuration::ColorSetting *_objectCS, *_classCS, *_fileCS;
++ TQListViewItem* _dirItem;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/configdlgbase.ui b/kdecachegrind/kdecachegrind/configdlgbase.ui
+new file mode 100644
+index 0000000..dc0ee9e
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/configdlgbase.ui
+@@ -0,0 +1,653 @@
++<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
++<class>ConfigDlgBase</class>
++<widget class="TQDialog">
++ <property name="name">
++ <cstring>configDlgBase</cstring>
++ </property>
++ <property name="geometry">
++ <rect>
++ <x>0</x>
++ <y>0</y>
++ <width>447</width>
++ <height>378</height>
++ </rect>
++ </property>
++ <property name="caption">
++ <string>Configuration</string>
++ </property>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <property name="margin">
++ <number>11</number>
++ </property>
++ <property name="spacing">
++ <number>6</number>
++ </property>
++ <widget class="TQTabWidget">
++ <property name="name">
++ <cstring>tabWidget2</cstring>
++ </property>
++ <widget class="TQWidget">
++ <property name="name">
++ <cstring>tab</cstring>
++ </property>
++ <attribute name="title">
++ <string>General</string>
++ </attribute>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout10</cstring>
++ </property>
++ <grid>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQLineEdit" row="3" column="2" rowspan="1" colspan="2">
++ <property name="name">
++ <cstring>precisionEdit</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>7</hsizetype>
++ <vsizetype>0</vsizetype>
++ <horstretch>2</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ </widget>
++ <widget class="TQLabel" row="2" column="1">
++ <property name="name">
++ <cstring>TextLabel2</cstring>
++ </property>
++ <property name="text">
++ <string>Truncated when more/longer than:</string>
++ </property>
++ </widget>
++ <widget class="TQLabel" row="3" column="0" rowspan="1" colspan="2">
++ <property name="name">
++ <cstring>TextLabel4_3</cstring>
++ </property>
++ <property name="text">
++ <string>Precision of percentage values:</string>
++ </property>
++ </widget>
++ <widget class="TQLabel" row="1" column="0" rowspan="1" colspan="3">
++ <property name="name">
++ <cstring>TextLabel3</cstring>
++ </property>
++ <property name="text">
++ <string>Symbols in tooltips and context menus</string>
++ </property>
++ </widget>
++ <widget class="TQLineEdit" row="2" column="3">
++ <property name="name">
++ <cstring>symbolLength</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>4</hsizetype>
++ <vsizetype>0</vsizetype>
++ <horstretch>0</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ </widget>
++ <spacer row="2" column="0">
++ <property name="name">
++ <cstring>Spacer6_2_2_2</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Horizontal</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Fixed</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>16</width>
++ <height>20</height>
++ </size>
++ </property>
++ </spacer>
++ <widget class="TQLineEdit" row="0" column="2" rowspan="1" colspan="2">
++ <property name="name">
++ <cstring>maxListEdit</cstring>
++ </property>
++ </widget>
++ <widget class="TQLineEdit" row="2" column="2">
++ <property name="name">
++ <cstring>symbolCount</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>4</hsizetype>
++ <vsizetype>0</vsizetype>
++ <horstretch>0</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ </widget>
++ <widget class="TQLabel" row="0" column="0" rowspan="1" colspan="2">
++ <property name="name">
++ <cstring>TextLabel5</cstring>
++ </property>
++ <property name="text">
++ <string>Maximum number of items in lists:</string>
++ </property>
++ </widget>
++ </grid>
++ </widget>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>TextLabel1</cstring>
++ </property>
++ <property name="font">
++ <font>
++ <bold>1</bold>
++ </font>
++ </property>
++ <property name="frameShape">
++ <enum>NoFrame</enum>
++ </property>
++ <property name="frameShadow">
++ <enum>Plain</enum>
++ </property>
++ <property name="text">
++ <string>Cost Item Colors</string>
++ </property>
++ </widget>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>Layout9</cstring>
++ </property>
++ <grid>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <property name="margin">
++ <number>0</number>
++ </property>
++ <property name="spacing">
++ <number>6</number>
++ </property>
++ <spacer row="1" column="1">
++ <property name="name">
++ <cstring>Spacer9</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Vertical</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Fixed</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>20</width>
++ <height>16</height>
++ </size>
++ </property>
++ </spacer>
++ <spacer row="0" column="0">
++ <property name="name">
++ <cstring>Spacer6</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Horizontal</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Fixed</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>16</width>
++ <height>20</height>
++ </size>
++ </property>
++ </spacer>
++ <widget class="TQLayoutWidget" row="0" column="1">
++ <property name="name">
++ <cstring>Layout9</cstring>
++ </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="TQComboBox" row="1" column="1">
++ <property name="name">
++ <cstring>classCombo</cstring>
++ </property>
++ <property name="maximumSize">
++ <size>
++ <width>300</width>
++ <height>32767</height>
++ </size>
++ </property>
++ <property name="editable">
++ <bool>true</bool>
++ </property>
++ </widget>
++ <widget class="TQCheckBox" row="2" column="2">
++ <property name="name">
++ <cstring>fileCheck</cstring>
++ </property>
++ <property name="text">
++ <string>Automatic</string>
++ </property>
++ </widget>
++ <widget class="TQLabel" row="0" column="0">
++ <property name="name">
++ <cstring>TextLabel4</cstring>
++ </property>
++ <property name="text">
++ <string>Object:</string>
++ </property>
++ </widget>
++ <widget class="TQLabel" row="1" column="0">
++ <property name="name">
++ <cstring>TextLabel4_2_2</cstring>
++ </property>
++ <property name="text">
++ <string>Class:</string>
++ </property>
++ </widget>
++ <widget class="KColorButton" row="2" column="3">
++ <property name="name">
++ <cstring>fileColor</cstring>
++ </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>
++ </widget>
++ <widget class="TQCheckBox" row="1" column="2">
++ <property name="name">
++ <cstring>classCheck</cstring>
++ </property>
++ <property name="text">
++ <string>Automatic</string>
++ </property>
++ </widget>
++ <widget class="KColorButton" row="0" column="3">
++ <property name="name">
++ <cstring>objectColor</cstring>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ </widget>
++ <widget class="TQCheckBox" row="0" column="2">
++ <property name="name">
++ <cstring>objectCheck</cstring>
++ </property>
++ <property name="text">
++ <string>Automatic</string>
++ </property>
++ </widget>
++ <widget class="TQLabel" row="2" column="0">
++ <property name="name">
++ <cstring>TextLabel4_2</cstring>
++ </property>
++ <property name="text">
++ <string>File:</string>
++ </property>
++ </widget>
++ <widget class="KColorButton" row="1" column="3">
++ <property name="name">
++ <cstring>classColor</cstring>
++ </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>
++ </widget>
++ <widget class="TQComboBox" row="2" column="1">
++ <property name="name">
++ <cstring>fileCombo</cstring>
++ </property>
++ <property name="maximumSize">
++ <size>
++ <width>300</width>
++ <height>32767</height>
++ </size>
++ </property>
++ <property name="editable">
++ <bool>true</bool>
++ </property>
++ </widget>
++ <widget class="TQComboBox" row="0" column="1">
++ <property name="name">
++ <cstring>objectCombo</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>3</hsizetype>
++ <vsizetype>0</vsizetype>
++ <horstretch>0</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ <property name="maximumSize">
++ <size>
++ <width>300</width>
++ <height>32767</height>
++ </size>
++ </property>
++ <property name="editable">
++ <bool>true</bool>
++ </property>
++ </widget>
++ </grid>
++ </widget>
++ </grid>
++ </widget>
++ </vbox>
++ </widget>
++ <widget class="TQWidget">
++ <property name="name">
++ <cstring>tab</cstring>
++ </property>
++ <attribute name="title">
++ <string>Annotations</string>
++ </attribute>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout8</cstring>
++ </property>
++ <hbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>TextLabel4_3_2</cstring>
++ </property>
++ <property name="text">
++ <string>Context lines in annotations:</string>
++ </property>
++ </widget>
++ <widget class="TQLineEdit">
++ <property name="name">
++ <cstring>contextEdit</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>7</hsizetype>
++ <vsizetype>0</vsizetype>
++ <horstretch>2</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ </widget>
++ </hbox>
++ </widget>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>TextLabel1_2</cstring>
++ </property>
++ <property name="font">
++ <font>
++ <bold>1</bold>
++ </font>
++ </property>
++ <property name="text">
++ <string>Source Folders</string>
++ </property>
++ </widget>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout11</cstring>
++ </property>
++ <grid>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <spacer row="0" column="0">
++ <property name="name">
++ <cstring>Spacer6_2</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Horizontal</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Fixed</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>16</width>
++ <height>20</height>
++ </size>
++ </property>
++ </spacer>
++ <widget class="TQListView" row="0" column="1">
++ <column>
++ <property name="text">
++ <string>Object / Related Source Base</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <property name="name">
++ <cstring>dirList</cstring>
++ </property>
++ <property name="rootIsDecorated">
++ <bool>true</bool>
++ </property>
++ </widget>
++ <widget class="TQLayoutWidget" row="0" column="2">
++ <property name="name">
++ <cstring>layout10</cstring>
++ </property>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>addDirButton</cstring>
++ </property>
++ <property name="text">
++ <string>Add...</string>
++ </property>
++ </widget>
++ <spacer>
++ <property name="name">
++ <cstring>Spacer5</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Vertical</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Expanding</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>16</width>
++ <height>49</height>
++ </size>
++ </property>
++ </spacer>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>deleteDirButton</cstring>
++ </property>
++ <property name="text">
++ <string>Delete</string>
++ </property>
++ </widget>
++ </vbox>
++ </widget>
++ <spacer row="1" column="1">
++ <property name="name">
++ <cstring>Spacer9_2</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Vertical</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Fixed</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>20</width>
++ <height>16</height>
++ </size>
++ </property>
++ </spacer>
++ </grid>
++ </widget>
++ </vbox>
++ </widget>
++ </widget>
++ <widget class="Line">
++ <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="TQLayoutWidget">
++ <property name="name">
++ <cstring>Layout4</cstring>
++ </property>
++ <hbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <property name="margin">
++ <number>0</number>
++ </property>
++ <property name="spacing">
++ <number>6</number>
++ </property>
++ <spacer>
++ <property name="name">
++ <cstring>Spacer2</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Horizontal</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Expanding</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>210</width>
++ <height>0</height>
++ </size>
++ </property>
++ </spacer>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>PushButton2</cstring>
++ </property>
++ <property name="text">
++ <string>&amp;OK</string>
++ </property>
++ <property name="default">
++ <bool>true</bool>
++ </property>
++ </widget>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>PushButton1</cstring>
++ </property>
++ <property name="text">
++ <string>&amp;Cancel</string>
++ </property>
++ </widget>
++ </hbox>
++ </widget>
++ </vbox>
++</widget>
++<connections>
++ <connection>
++ <sender>PushButton2</sender>
++ <signal>clicked()</signal>
++ <receiver>configDlgBase</receiver>
++ <slot>accept()</slot>
++ </connection>
++ <connection>
++ <sender>PushButton1</sender>
++ <signal>clicked()</signal>
++ <receiver>configDlgBase</receiver>
++ <slot>reject()</slot>
++ </connection>
++ <connection>
++ <sender>classCheck</sender>
++ <signal>toggled(bool)</signal>
++ <receiver>classColor</receiver>
++ <slot>setDisabled(bool)</slot>
++ </connection>
++ <connection>
++ <sender>fileCheck</sender>
++ <signal>toggled(bool)</signal>
++ <receiver>fileColor</receiver>
++ <slot>setDisabled(bool)</slot>
++ </connection>
++ <connection>
++ <sender>objectCheck</sender>
++ <signal>toggled(bool)</signal>
++ <receiver>objectColor</receiver>
++ <slot>setDisabled(bool)</slot>
++ </connection>
++</connections>
++<tabstops>
++ <tabstop>objectCombo</tabstop>
++ <tabstop>objectCheck</tabstop>
++ <tabstop>classCombo</tabstop>
++ <tabstop>classCheck</tabstop>
++ <tabstop>classColor</tabstop>
++ <tabstop>fileCombo</tabstop>
++ <tabstop>fileCheck</tabstop>
++ <tabstop>fileColor</tabstop>
++ <tabstop>maxListEdit</tabstop>
++ <tabstop>PushButton1</tabstop>
++ <tabstop>PushButton2</tabstop>
++</tabstops>
++<includes>
++ <include location="global" impldecl="in implementation">kcolorbutton.h</include>
++</includes>
++<pixmapinproject/>
++<layoutdefaults spacing="6" margin="11"/>
++</UI>
+diff --git a/kdecachegrind/kdecachegrind/configuration.cpp b/kdecachegrind/kdecachegrind/configuration.cpp
+new file mode 100644
+index 0000000..02d5c09
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/configuration.cpp
+@@ -0,0 +1,490 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Configuration for KCachegrind
++ */
++
++#include <kconfig.h>
++#include <klocale.h>
++#include <kdebug.h>
++
++#include "configuration.h"
++#include "tracedata.h"
++#include "configdlgbase.h"
++
++#include "traceitemview.h"
++
++//
++// Some predefined cost types...
++//
++
++static TQStringList knownTypes()
++{
++ TQStringList l;
++
++ l << "Ir" << "Dr" << "Dw"
++ << "I1mr" << "D1mr" << "D1mw"
++ << "I2mr" << "D2mr" << "D2mw"
++
++ << "Smp" << "Sys" << "User"
++ << "L1m" << "L2m" << "CEst";
++
++ return l;
++}
++
++
++static TQString knownFormula(TQString name)
++{
++ if (name =="L1m") return TQString("I1mr + D1mr + D1mw");
++ if (name =="L2m") return TQString("I2mr + D2mr + D2mw");
++ if (name =="CEst") return TQString("Ir + 10 L1m + 100 L2m");
++
++ return TQString();
++}
++
++static TQString knownLongName(TQString name)
++{
++ if (name == "Ir") return i18n("Instruction Fetch");
++ if (name =="Dr") return i18n("Data Read Access");
++ if (name =="Dw") return i18n("Data Write Access");
++ if (name =="I1mr") return i18n("L1 Instr. Fetch Miss");
++ if (name =="D1mr") return i18n("L1 Data Read Miss");
++ if (name =="D1mw") return i18n("L1 Data Write Miss");
++ if (name =="I2mr") return i18n("L2 Instr. Fetch Miss");
++ if (name =="D2mr") return i18n("L2 Data Read Miss");
++ if (name =="D2mw") return i18n("L2 Data Write Miss");
++ if (name =="Smp") return i18n("Samples");
++ if (name =="Sys") return i18n("System Time");
++ if (name =="User") return i18n("User Time");
++ if (name =="L1m") return i18n("L1 Miss Sum");
++ if (name =="L2m") return i18n("L2 Miss Sum");
++ if (name =="CEst") return i18n("Cycle Estimation");
++
++ return TQString();
++}
++
++
++
++
++//
++// Configuration
++//
++
++Configuration* Configuration::_config = 0;
++
++Configuration::Configuration()
++ :_colors(517)
++{
++ _config = 0;
++
++ _colors.setAutoDelete(true);
++ _objectSourceDirs.setAutoDelete(true);
++
++ // defaults
++ _showPercentage = true;
++ _showExpanded = false;
++ _showCycles = true;
++ _cycleCut = 0.0;
++ _percentPrecision = 2;
++
++ // max symbol count/length in tooltip/popup
++ _maxSymbolLength = 30;
++ _maxSymbolCount = 10;
++ _maxListCount = 100;
++
++ // annotation behaviour
++ _context = 3;
++ _noCostInside = 20;
++}
++
++Configuration* Configuration::config()
++{
++ if (!_config)
++ _config = new Configuration();
++
++ return _config;
++}
++
++
++void Configuration::saveOptions(KConfig* kconfig)
++{
++ Configuration* c = config();
++
++ // color options
++ KConfigGroup colorConfig(kconfig, TQCString("CostColors"));
++ TQDictIterator<ColorSetting> it( c->_colors );
++ int count = 1;
++ for( ; it.current(); ++it ) {
++ if ( !(*it)->automatic ) {
++ colorConfig.writeEntry( TQString("Name%1").arg(count),
++ it.currentKey());
++ colorConfig.writeEntry( TQString("Color%1").arg(count),
++ (*it)->color);
++ //qDebug("Written Color %s (%d)", it.currentKey().ascii(), count);
++
++ count++;
++ }
++ }
++ colorConfig.writeEntry( "Count", count-1);
++
++ // source options
++ KConfigGroup sourceConfig(kconfig, TQCString("Source"));
++ sourceConfig.writeEntry("Dirs", c->_generalSourceDirs, ':');
++ TQDictIterator<TQStringList> it2( c->_objectSourceDirs );
++ count = 1;
++ for( ; it2.current(); ++it2 ) {
++ sourceConfig.writeEntry( TQString("Object%1").arg(count),
++ it2.currentKey());
++ sourceConfig.writeEntry( TQString("Dirs%1").arg(count),
++ *(*it2), ':');
++ count++;
++ }
++ sourceConfig.writeEntry( "Count", count-1);
++
++ // general options
++ KConfigGroup generalConfig(kconfig, TQCString("General"));
++ generalConfig.writeEntry("ShowPercentage", c->_showPercentage);
++ generalConfig.writeEntry("ShowExpanded", c->_showExpanded);
++ generalConfig.writeEntry("ShowCycles", c->_showCycles);
++ generalConfig.writeEntry("CycleCut", c->_cycleCut);
++ generalConfig.writeEntry("MaxSymbolCount", c->_maxSymbolCount);
++ generalConfig.writeEntry("MaxListCount", c->_maxListCount);
++ generalConfig.writeEntry("MaxSymbolLength", c->_maxSymbolLength);
++ generalConfig.writeEntry("PercentPrecision", c->_percentPrecision);
++
++ generalConfig.writeEntry("Context", c->_context);
++ generalConfig.writeEntry("NoCostInside", c->_noCostInside);
++
++ KConfigGroup ctConfig(kconfig, TQCString("CostTypes"));
++ int ctCount = TraceCostType::knownTypeCount();
++ ctConfig.writeEntry( "Count", ctCount);
++ for (int i=0; i<ctCount; i++) {
++ TraceCostType* t = TraceCostType::knownType(i);
++ ctConfig.writeEntry( TQString("Name%1").arg(i+1), t->name());
++
++ // Use localized key
++ TraceItemView::writeConfigEntry(&ctConfig,
++ TQString("Longname%1").arg(i+1).ascii(),
++ t->longName(),
++ knownLongName(t->name()).utf8().data() /*, true */ );
++ TraceItemView::writeConfigEntry(&ctConfig,
++ TQString("Formula%1").arg(i+1).ascii(),
++ t->formula(), knownFormula(t->name()).utf8().data());
++ }
++}
++
++
++
++
++void Configuration::readOptions(KConfig* kconfig)
++{
++ int i, count;
++ Configuration* c = config();
++
++ // color options
++ c->_colors.clear();
++
++ // colors for default cost types:
++ // red for L2 misses, green for L1 misses, blue for normal accesses
++ c->color("CostType-I2mr")->color = TQColor(240, 0, 0);
++ c->color("CostType-D2mr")->color = TQColor(180,40,40);
++ c->color("CostType-D2mw")->color = TQColor(120,80,80);
++
++ c->color("CostType-I1mr")->color = TQColor(0, 240, 0);
++ c->color("CostType-D1mr")->color = TQColor(40,180,40);
++ c->color("CostType-D1mw")->color = TQColor(80,120,80);
++
++ c->color("CostType-Ir")->color = TQColor(0, 0, 240);
++ c->color("CostType-Dr")->color = TQColor(40,40,180);
++ c->color("CostType-Dw")->color = TQColor(80,80,120);
++
++ KConfigGroup colorConfig(kconfig, TQCString("CostColors"));
++ count = colorConfig.readNumEntry("Count", 0);
++ for (i=1;i<=count;i++) {
++ TQString n = colorConfig.readEntry(TQString("Name%1").arg(i));
++ TQColor color = colorConfig.readColorEntry(TQString("Color%1").arg(i));
++
++ if (n.isEmpty()) continue;
++
++ ColorSetting* cs = new ColorSetting;
++ cs->name = n;
++ cs->automatic = false;
++ cs->color = color;
++
++ c->_colors.insert(n, cs);
++
++ //qDebug("Read Color %s", n.ascii());
++ }
++
++ // source options
++ KConfigGroup sourceConfig(kconfig, TQCString("Source"));
++ TQStringList dirs;
++ dirs = sourceConfig.readListEntry("Dirs", ':');
++ if (dirs.count()>0) c->_generalSourceDirs = dirs;
++ count = sourceConfig.readNumEntry("Count", 0);
++ c->_objectSourceDirs.clear();
++ if (count>17) c->_objectSourceDirs.resize(count);
++ for (i=1;i<=count;i++) {
++ TQString n = sourceConfig.readEntry(TQString("Object%1").arg(i));
++ dirs = sourceConfig.readListEntry(TQString("Dirs%1").arg(i), ':');
++
++ if (n.isEmpty() || (dirs.count()==0)) continue;
++
++ c->_objectSourceDirs.insert(n, new TQStringList(dirs));
++ }
++
++
++ // general options
++ KConfigGroup generalConfig(kconfig, TQCString("General"));
++ c->_showPercentage = generalConfig.readBoolEntry("ShowPercentage", true);
++ c->_showExpanded = generalConfig.readBoolEntry("ShowExpanded", false);
++ c->_showCycles = generalConfig.readBoolEntry("ShowCycles", true);
++ c->_cycleCut = generalConfig.readDoubleNumEntry("CycleCut", 0.0);
++ c->_maxSymbolCount = generalConfig.readNumEntry("MaxSymbolCount", 10);
++ c->_maxListCount = generalConfig.readNumEntry("MaxListCount", 100);
++ c->_maxSymbolLength = generalConfig.readNumEntry("MaxSymbolLength", 30);
++ c->_percentPrecision = generalConfig.readNumEntry("PercentPrecision", 2);
++
++ c->_context = generalConfig.readNumEntry("Context", 3);
++ c->_noCostInside = generalConfig.readNumEntry("NoCostInside", 20);
++
++ // known cost types
++ if (TraceCostType::knownTypeCount()==0) {
++
++ KConfigGroup ctConfig(kconfig, TQCString("CostTypes"));
++ int ctCount = ctConfig.readNumEntry("Count", 0);
++ if (ctCount>0) {
++ for (int i=1;i<=ctCount;i++) {
++ TQString n = ctConfig.readEntry(TQString("Name%1").arg(i));
++ TQString l = ctConfig.readEntry(TQString("Longname%1").arg(i));
++ if (l.isEmpty()) l = knownLongName(n);
++ TQString f = ctConfig.readEntry(TQString("Formula%1").arg(i));
++ if (f.isEmpty()) f = knownFormula(n);
++
++ TraceCostType::add(new TraceCostType(n, l, f));
++ }
++ }
++ else {
++ // add default types
++
++ TQString longName, formula;
++ TraceCostType* ct;
++ TQStringList l = knownTypes();
++ for ( TQStringList::Iterator it = l.begin();
++ it != l.end(); ++it ) {
++ longName = knownLongName(*it);
++ formula = knownFormula(*it);
++ ct = new TraceCostType(*it, longName, formula);
++ TraceCostType::add(ct);
++ }
++ }
++ }
++}
++
++TQColor Configuration::groupColor(TraceItem* cost)
++{
++ TQString n;
++
++ if (!cost)
++ n = TQString("default");
++ else
++ n = TraceCost::typeName(cost->type()) + "-" + cost->prettyName();
++
++ return color(n)->color;
++}
++
++TQColor Configuration::costTypeColor(TraceCostType* t)
++{
++ TQString n;
++
++ if (!t)
++ n = TQString("CostType-default");
++ else
++ n = TQString("CostType-%1").arg(t->name());
++
++ return color(n)->color;
++}
++
++TQColor Configuration::functionColor(TraceCost::CostType gt,
++ TraceFunction* f)
++{
++ TraceCost* group = f;
++ TQString n;
++
++ switch(gt) {
++ case TraceCost::Object: group = f->object(); break;
++ case TraceCost::Class: group = f->cls(); break;
++ case TraceCost::File: group = f->file(); break;
++ default:
++ break;
++ }
++
++ if (group != f) {
++ // first look for manual color of a function in a group
++ n = TraceCost::typeName(group->type()) +
++ "-" + group->prettyName() +
++ "-" + f->prettyName();
++
++ ColorSetting* cs = color(n, false);
++ if (cs) return cs->color;
++ }
++ return groupColor(group);
++}
++
++Configuration::ColorSetting* Configuration::color(TQString n, bool createNew)
++{
++// qDebug("Color for %s", n.latin1());
++
++ // predefined ?
++ Configuration* c = config();
++ ColorSetting* cs = c->_colors[n];
++ if (cs || !createNew) return cs;
++
++ // automatic colors...
++ int h = 0, s = 100;
++ const char* str = n.ascii();
++ while (*str) {
++ h = (h * 37 + s* (unsigned)*str) % 256;
++ s = (s * 17 + h* (unsigned)*str) % 192;
++ str++;
++ }
++
++ //qDebug("New color for %s: H %d, S %d", n.ascii(), h, 64+s);
++ TQColor color = TQColor(h, 64+s, 192, TQColor::Hsv);
++
++ cs = new ColorSetting;
++ cs->name = n;
++ cs->automatic = true;
++ cs->color = color;
++ c->_colors.insert(n, cs);
++
++ //qDebug("new Color %s", n.ascii());
++
++ return cs;
++}
++
++/* Gives back a list of all Source Base Directories of Objects in
++ * current trace. If a special object is given in 2nd argument,
++ * put its Source Base in front.
++ */
++TQStringList Configuration::sourceDirs(TraceData* data, TraceObject* o)
++{
++ TQStringList l = config()->_generalSourceDirs, *ol, *ol2 = 0;
++ TraceObjectMap::Iterator oit;
++ for ( oit = data->objectMap().begin();
++ oit != data->objectMap().end(); ++oit ) {
++ ol = config()->_objectSourceDirs[(*oit).name()];
++ if (&(*oit) == o) {
++ ol2 = ol;
++ continue;
++ }
++ if (!ol) continue;
++
++ for(unsigned int i=0;i<ol->count();i++)
++ l.prepend( (*ol)[i] );
++ }
++ if (ol2) {
++ for(unsigned int i=0;i<ol2->count();i++)
++ l.prepend( (*ol2)[i] );
++ }
++ if (0) kdDebug() << "Configuration::sourceDirs: " << l.join(":") << endl;
++
++ return l;
++}
++
++bool Configuration::showPercentage()
++{
++ return config()->_showPercentage;
++}
++
++bool Configuration::showExpanded()
++{
++ return config()->_showExpanded;
++}
++
++bool Configuration::showCycles()
++{
++ return config()->_showCycles;
++}
++
++void Configuration::setShowPercentage(bool s)
++{
++ Configuration* c = config();
++ if (c->_showPercentage == s) return;
++
++ c->_showPercentage = s;
++}
++
++void Configuration::setShowExpanded(bool s)
++{
++ Configuration* c = config();
++ if (c->_showExpanded == s) return;
++
++ c->_showExpanded = s;
++}
++
++void Configuration::setShowCycles(bool s)
++{
++ Configuration* c = config();
++ if (c->_showCycles == s) return;
++
++ c->_showCycles = s;
++}
++
++double Configuration::cycleCut()
++{
++ return config()->_cycleCut;
++}
++
++int Configuration::percentPrecision()
++{
++ return config()->_percentPrecision;
++}
++
++int Configuration::maxSymbolLength()
++{
++ return config()->_maxSymbolLength;
++}
++
++TQString Configuration::shortenSymbol(TQString s)
++{
++ if ((int)s.length() > maxSymbolLength())
++ s = s.left(maxSymbolLength()) + "...";
++ return s;
++}
++
++int Configuration::maxListCount()
++{
++ return config()->_maxListCount;
++}
++
++int Configuration::maxSymbolCount()
++{
++ return config()->_maxSymbolCount;
++}
++
++int Configuration::context()
++{
++ return config()->_context;
++}
++
++int Configuration::noCostInside()
++{
++ return config()->_noCostInside;
++}
+diff --git a/kdecachegrind/kdecachegrind/configuration.h b/kdecachegrind/kdecachegrind/configuration.h
+new file mode 100644
+index 0000000..478f617
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/configuration.h
+@@ -0,0 +1,101 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Configuration for KCachegrind
++ */
++
++#ifndef CONFIGURATION_H
++#define CONFIGURATION_H
++
++#include <tqcolor.h>
++#include <tqstringlist.h>
++#include <tqdict.h>
++
++#include "tracedata.h"
++
++class KConfig;
++
++class Configuration
++{
++ friend class ConfigDlg;
++
++public:
++ Configuration();
++
++ static Configuration* config();
++
++ static void saveOptions(KConfig*);
++ static void readOptions(KConfig*);
++
++ // color for visualisation of an object
++ static TQColor functionColor(TraceItem::CostType gt, TraceFunction*);
++ static TQColor groupColor(TraceItem*);
++ static TQColor costTypeColor(TraceCostType*);
++ static TQStringList sourceDirs(TraceData*, TraceObject* o = 0);
++ static bool showPercentage();
++ static bool showExpanded();
++ static bool showCycles();
++
++ // lower percentage limit of cost items filled into lists
++ static int percentPrecision();
++ // max symbol lengths/count in tooltip/popup
++ static int maxSymbolLength();
++ // strip a symbol name according to <maxSymbolLength>
++ static TQString shortenSymbol(TQString);
++ static int maxSymbolCount();
++ // max. number of items in lists
++ static int maxListCount();
++
++ // how many lines of context to show before/after annotated source/assembler
++ static int context();
++ // how many lines without cost are still regarded as inside a function
++ static int noCostInside();
++
++ static void setShowPercentage(bool);
++ static void setShowExpanded(bool);
++
++ static void setShowCycles(bool);
++ // upper limit for cutting of a call in cycle detection
++ static double cycleCut();
++
++private:
++ struct ColorSetting {
++ TQString name;
++ TQColor color;
++ bool automatic;
++ };
++
++ static ColorSetting* color(TQString, bool createNew = true);
++
++ TQDict<ColorSetting> _colors;
++
++ TQStringList _generalSourceDirs;
++ TQDict<TQStringList> _objectSourceDirs;
++
++ bool _showPercentage, _showExpanded, _showCycles;
++ double _cycleCut;
++ int _percentPrecision;
++ int _maxSymbolLength, _maxSymbolCount, _maxListCount;
++ int _context, _noCostInside;
++
++ static Configuration* _config;
++};
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/costlistitem.cpp b/kdecachegrind/kdecachegrind/costlistitem.cpp
+new file mode 100644
+index 0000000..1e777b0
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/costlistitem.cpp
+@@ -0,0 +1,136 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#include <math.h>
++
++#include <tqpainter.h>
++#include <tqregexp.h>
++
++#include <klocale.h>
++#include <kiconloader.h>
++#include <kapplication.h>
++
++#include "listutils.h"
++#include "costlistitem.h"
++#include "coverage.h"
++#include "configuration.h"
++
++// CostListItem
++
++
++CostListItem::CostListItem(TQListView* parent, TraceCostItem* costItem,
++ TraceCostType* ct, int size)
++ :TQListViewItem(parent)
++{
++ _groupSize = size;
++ _skipped = 0;
++ _costItem = costItem;
++ setCostType(ct);
++
++ if (costItem) {
++ updateName();
++ setPixmap(1, colorPixmap(10, 10,
++ Configuration::groupColor(_costItem)));
++ }
++}
++
++CostListItem::CostListItem(TQListView* parent, int skipped,
++ TraceCostItem* costItem, TraceCostType* ct)
++ :TQListViewItem(parent)
++{
++ _skipped = skipped;
++ _costItem = costItem;
++ setCostType(ct);
++
++ setText(1, i18n("(%n item skipped)", "(%n items skipped)", _skipped));
++}
++
++void CostListItem::setCostType(TraceCostType* ct)
++{
++ _costType = ct;
++ update();
++}
++
++void CostListItem::updateName()
++{
++ if (!_costItem) return;
++
++ TQString n = _costItem->prettyName();
++ if (_groupSize>=0) n += TQString(" (%1)").arg(_groupSize);
++
++ setText(1, n);
++}
++
++void CostListItem::setSize(int s)
++{
++ _groupSize = s;
++ updateName();
++}
++
++void CostListItem::update()
++{
++ if (!_costItem) return;
++ TraceData* d = _costItem->data();
++
++ double total = d->subCost(_costType);
++ if (total == 0.0) {
++ setText(0, TQString("---"));
++ setPixmap(0, TQPixmap());
++ return;
++ }
++
++ _pure = _costItem->subCost(_costType);
++ double pure = 100.0 * _pure / total;
++ TQString str;
++ if (Configuration::showPercentage())
++ str = TQString("%1").arg(pure, 0, 'f', Configuration::percentPrecision());
++ else
++ str = _costItem->prettySubCost(_costType);
++
++ if (_skipped) {
++ // special handling for skip entries...
++ setText(0, TQString("< %1").arg(str));
++ return;
++ }
++
++ setText(0, str);
++ setPixmap(0, costPixmap(_costType, _costItem, total, false));
++}
++
++int CostListItem::compare(TQListViewItem * i, int col, bool ascending ) const
++{
++ const CostListItem* fi1 = this;
++ const CostListItem* fi2 = (CostListItem*) i;
++
++ // we always want descending order
++ if (ascending) {
++ fi1 = fi2;
++ fi2 = this;
++ }
++
++ // a skip entry is always sorted last
++ if (fi1->_skipped) return -1;
++ if (fi2->_skipped) return 1;
++
++ if (col==0) {
++ if (fi1->_pure < fi2->_pure) return -1;
++ if (fi1->_pure > fi2->_pure) return 1;
++ return 0;
++ }
++ return TQListViewItem::compare(i, col, ascending);
++}
+diff --git a/kdecachegrind/kdecachegrind/costlistitem.h b/kdecachegrind/kdecachegrind/costlistitem.h
+new file mode 100644
+index 0000000..99f654e
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/costlistitem.h
+@@ -0,0 +1,52 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#ifndef COSTLISTITEM_H
++#define COSTLISTITEM_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++
++class CostListItem: public TQListViewItem
++{
++public:
++ CostListItem(TQListView* parent, TraceCostItem* cost,
++ TraceCostType* ct, int size = -1);
++ // entry with multiple skipped items
++ CostListItem(TQListView* parent, int skipped, TraceCostItem* cost,
++ TraceCostType* ct);
++
++ int compare(TQListViewItem * i, int col, bool ascending ) const;
++ TraceCostItem* costItem() { return (_skipped) ? 0 : _costItem; }
++ void setCostType(TraceCostType* ct);
++ void update();
++ void setSize(int s);
++
++private:
++ void updateName();
++
++ SubCost _pure;
++ TraceCostType* _costType;
++ TraceCostItem* _costItem;
++ // >0 only for last item in list, if items are skipped
++ int _skipped;
++ // number of items in group, is put in parenthesis after name
++ int _groupSize;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/costtypeitem.cpp b/kdecachegrind/kdecachegrind/costtypeitem.cpp
+new file mode 100644
+index 0000000..dc35cb2
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/costtypeitem.cpp
+@@ -0,0 +1,149 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of cost type view.
++ */
++
++#include <tqpixmap.h>
++#include <klocale.h>
++
++#include "configuration.h"
++#include "listutils.h"
++#include "costtypeitem.h"
++
++
++// CostTypeItem
++
++
++CostTypeItem::CostTypeItem(TQListView* parent, TraceCostItem* costItem,
++ TraceCostType* ct, TraceCost::CostType gt)
++ :TQListViewItem(parent)
++{
++ _costItem = costItem;
++ _costType = ct;
++ _groupType = gt;
++
++ if (ct) {
++ setText(0, ct->longName());
++ setText(3, ct->name());
++ TQString formula = ct->formula();
++ setText(5, formula);
++ if (!formula.isEmpty()) {
++ setText(4, "=");
++ // we have a virtual type: allow editing
++ setRenameEnabled(0, true);
++ setRenameEnabled(3, true);
++ setRenameEnabled(5, true);
++ }
++ }
++ else {
++ setText(0, i18n("Unknown Type"));
++ }
++ update();
++}
++
++void CostTypeItem::setGroupType(TraceCost::CostType gt)
++{
++ if (_groupType == gt) return;
++
++ _groupType = gt;
++ update();
++}
++
++void CostTypeItem::update()
++{
++ TraceData* d = _costItem ? _costItem->data() : 0;
++ double total = d ? ((double)d->subCost(_costType)) : 0.0;
++
++ if (total == 0.0) {
++ setText(1, "-");
++ setPixmap(1, TQPixmap());
++ setText(2, "-");
++ setPixmap(2, TQPixmap());
++ return;
++ }
++
++ TraceFunction* f = (_costItem->type()==TraceCost::Function) ?
++ (TraceFunction*)_costItem : 0;
++
++ TraceCost* selfTotalCost = f ? f->data() : d;
++ if (f && Configuration::showExpanded()) {
++ switch(_groupType) {
++ case TraceCost::Object: selfTotalCost = f->object(); break;
++ case TraceCost::Class: selfTotalCost = f->cls(); break;
++ case TraceCost::File: selfTotalCost = f->file(); break;
++ case TraceCost::FunctionCycle: selfTotalCost = f->cycle(); break;
++ default: break;
++ }
++ }
++ if (_costItem->type()==TraceCost::FunctionCycle) {
++ f = (TraceFunction*)_costItem;
++ selfTotalCost = f->data();
++ }
++
++ double selfTotal = selfTotalCost->subCost(_costType);
++
++ // for all cost items there's a self cost
++ _pure = _costItem ? _costItem->subCost(_costType) : SubCost(0);
++ double pure = 100.0 * _pure / selfTotal;
++ if (Configuration::showPercentage()) {
++ setText(2, TQString("%1")
++ .arg(pure, 0, 'f', Configuration::percentPrecision()));
++ }
++ else
++ setText(2, _costItem->prettySubCost(_costType));
++
++ setPixmap(2, costPixmap(_costType, _costItem, selfTotal, false));
++
++ if (!f) {
++ setText(1, "-");
++ setPixmap(1, TQPixmap());
++ return;
++ }
++
++ _sum = f->inclusive()->subCost(_costType);
++ double sum = 100.0 * _sum / total;
++ if (Configuration::showPercentage()) {
++ setText(1, TQString("%1")
++ .arg(sum, 0, 'f', Configuration::percentPrecision()));
++ }
++ else
++ setText(1, _sum.pretty());
++
++ setPixmap(1, costPixmap(_costType, f->inclusive(), total, false));
++}
++
++
++int CostTypeItem::compare(TQListViewItem * i, int col, bool ascending ) const
++{
++ CostTypeItem* fi = (CostTypeItem*) i;
++ if (col==0) {
++ if (_sum < fi->_sum) return -1;
++ if (_sum > fi->_sum) return 1;
++ return 0;
++ }
++ if (col==1) {
++ if (_pure < fi->_pure) return -1;
++ if (_pure > fi->_pure) return 1;
++ return 0;
++ }
++ return TQListViewItem::compare(i, col, ascending);
++}
++
++
+diff --git a/kdecachegrind/kdecachegrind/costtypeitem.h b/kdecachegrind/kdecachegrind/costtypeitem.h
+new file mode 100644
+index 0000000..d34973d
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/costtypeitem.h
+@@ -0,0 +1,50 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of cost type view.
++ */
++
++#ifndef COSTTYEPITEM_H
++#define COSTTYEPITEM_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++
++
++class CostTypeItem: public TQListViewItem
++{
++public:
++ CostTypeItem(TQListView* parent, TraceCostItem* costItem,
++ TraceCostType* ct, TraceCost::CostType gt);
++
++ int compare(TQListViewItem * i, int col, bool ascending ) const;
++ void setGroupType(TraceCost::CostType);
++ TraceCostItem* costItem() { return _costItem; }
++ TraceCostType* costType() { return _costType; }
++ void update();
++
++private:
++ SubCost _sum, _pure;
++ TraceCostType* _costType;
++ TraceCostItem* _costItem;
++ TraceCost::CostType _groupType;
++};
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/costtypeview.cpp b/kdecachegrind/kdecachegrind/costtypeview.cpp
+new file mode 100644
+index 0000000..3f5417e
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/costtypeview.cpp
+@@ -0,0 +1,310 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Cost Type View
++ */
++
++#include <tqwhatsthis.h>
++#include <tqpopupmenu.h>
++#include <klocale.h>
++
++#include "configuration.h"
++#include "costtypeitem.h"
++#include "costtypeview.h"
++#include "toplevel.h"
++
++
++//
++// CostTypeView
++//
++
++
++CostTypeView::CostTypeView(TraceItemView* parentView,
++ TQWidget* parent, const char* name)
++ : TQListView(parent, name), TraceItemView(parentView)
++{
++ addColumn( i18n( "Event Type" ) );
++ addColumn( i18n( "Incl." ) );
++ addColumn( i18n( "Self" ) );
++ addColumn( i18n( "Short" ) );
++ addColumn( TQString() );
++ addColumn( i18n( "Formula" ) );
++
++ setSorting(-1);
++ setAllColumnsShowFocus(true);
++ setColumnAlignment(1, TQt::AlignRight);
++ setColumnAlignment(2, TQt::AlignRight);
++ setColumnAlignment(3, TQt::AlignRight);
++ setMinimumHeight(50);
++
++ connect( this,
++ TQT_SIGNAL( selectionChanged(TQListViewItem*) ),
++ TQT_SLOT( selectedSlot(TQListViewItem*) ) );
++
++ connect( this,
++ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
++ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int)));
++
++ connect(this,
++ TQT_SIGNAL(doubleClicked(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ connect(this,
++ TQT_SIGNAL(returnPressed(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ connect(this,
++ TQT_SIGNAL(itemRenamed(TQListViewItem*,int,const TQString&)),
++ TQT_SLOT(renamedSlot(TQListViewItem*,int,const TQString&)));
++
++ TQWhatsThis::add( this, whatsThis() );
++}
++
++TQString CostTypeView::whatsThis() const
++{
++ return i18n( "<b>Cost Types List</b>"
++ "<p>This list shows all cost types available "
++ "and what the self/inclusive cost of the "
++ "current selected function is for that cost type.</p>"
++ "<p>By choosing a cost type from the list, "
++ "you change the cost type of costs shown "
++ "all over KCachegrind to be the selected one.</p>");
++}
++
++
++void CostTypeView::context(TQListViewItem* i, const TQPoint & p, int)
++{
++ TQPopupMenu popup;
++
++ TraceCostType* ct = i ? ((CostTypeItem*) i)->costType() : 0;
++
++ if (ct)
++ popup.insertItem(i18n("Set Secondary Event Type"), 99);
++ if (_costType2)
++ popup.insertItem(i18n("Remove Secondary Event Type"), 98);
++ if (popup.count()>0)
++ popup.insertSeparator();
++
++ if (ct && !ct->isReal()) {
++ popup.insertItem(i18n("Edit Long Name"), 93);
++ popup.insertItem(i18n("Edit Short Name"), 94);
++ popup.insertItem(i18n("Edit Formula"), 95);
++ popup.insertItem(i18n("Remove"), 96);
++ popup.insertSeparator();
++ }
++
++ addGoMenu(&popup);
++
++ popup.insertSeparator();
++ popup.insertItem(i18n("New Cost Type ..."), 97);
++
++ int r = popup.exec(p);
++ if (r == 98) selectedCostType2(0);
++ else if (r == 99) selectedCostType2(ct);
++ else if (r == 93) i->startRename(0);
++ else if (r == 94) i->startRename(3);
++ else if (r == 95) i->startRename(5);
++ else if (r == 96) {
++
++ // search for a previous type
++ TraceCostType* prev = 0, *ct = 0;
++ TraceCostMapping* m = _data->mapping();
++ for (int i=0;i<m->realCount();i++) {
++ ct = m->realType(i);
++ if (ct) prev = ct;
++ }
++ for (int i=0;i<m->virtualCount();i++) {
++ ct = m->virtualType(i);
++ if (ct == _costType) break;
++ if (ct) prev = ct;
++ }
++
++ if (_data->mapping()->remove(ct)) {
++ // select previous cost type
++ selectedCostType(prev);
++ if (_costType2 == ct)
++ selectedCostType2(prev);
++ refresh();
++ }
++ }
++ else if (r == 97) {
++ int i = 1;
++ while(1) {
++ if (!TraceCostType::knownVirtualType(i18n("New%1").arg(i)))
++ break;
++ i++;
++ }
++ // add same new cost type to this mapping and to known types
++ TQString shortName = i18n("New%1").arg(i);
++ TQString longName = i18n("New Cost Type %1").arg(i);
++ TraceCostType::add(new TraceCostType(shortName, longName, "0"));
++ _data->mapping()->add(new TraceCostType(shortName, longName, "0"));
++ refresh();
++ }
++}
++
++void CostTypeView::selectedSlot(TQListViewItem * i)
++{
++ TraceCostType* ct = i ? ((CostTypeItem*) i)->costType() : 0;
++ if (ct)
++ selectedCostType(ct);
++}
++
++void CostTypeView::activatedSlot(TQListViewItem * i)
++{
++ TraceCostType* ct = i ? ((CostTypeItem*) i)->costType() : 0;
++ if (ct)
++ selectedCostType2(ct);
++}
++
++TraceItem* CostTypeView::canShow(TraceItem* i)
++{
++ if (!i) return 0;
++
++ switch(i->type()) {
++ case TraceCost::Object:
++ case TraceCost::Class:
++ case TraceCost::File:
++ case TraceCost::Call:
++ case TraceCost::FunctionCycle:
++ case TraceCost::Function:
++ break;
++ default:
++ return 0;
++ }
++ return i;
++}
++
++void CostTypeView::doUpdate(int changeType)
++{
++ // Special case ?
++ if (changeType == selectedItemChanged) return;
++
++ if (changeType == costType2Changed) return;
++
++ if (changeType == groupTypeChanged) {
++ TQListViewItem *item;
++ for (item = firstChild();item;item = item->nextSibling())
++ ((CostTypeItem*)item)->setGroupType(_groupType);
++
++ return;
++ }
++
++ if (changeType == costTypeChanged) {
++ TQListViewItem *item;
++ for (item = firstChild();item;item = item->nextSibling())
++ if ( ((CostTypeItem*)item)->costType() == _costType) {
++ setSelected(item, true);
++ ensureItemVisible(item);
++ break;
++ }
++
++ return;
++ }
++
++ if (changeType == partsChanged) {
++ TQListViewItem *item;
++ for (item = firstChild();item;item = item->nextSibling())
++ ((CostTypeItem*)item)->update();
++
++ return;
++ }
++
++
++ refresh();
++}
++
++void CostTypeView::refresh()
++{
++ clear();
++ setColumnWidth(1, 50);
++ setColumnWidth(2, 50);
++
++ if (!_data || !_activeItem) return;
++ switch(_activeItem->type()) {
++ case TraceCost::Object:
++ case TraceCost::Class:
++ case TraceCost::File:
++ case TraceCost::FunctionCycle:
++ case TraceCost::Function:
++ break;
++ default:
++ return;
++ }
++ TraceCostItem* c = (TraceCostItem*) _activeItem;
++
++ TraceCostType* ct =0 ;
++ TQListViewItem* item = 0;
++ TQString sumStr, pureStr;
++ TQListViewItem* costItem=0;
++
++ TraceCostMapping* m = _data->mapping();
++ for (int i=m->virtualCount()-1;i>=0;i--) {
++ ct = m->virtualType(i);
++ if (!ct) continue;
++ item = new CostTypeItem(this, c, ct, _groupType);
++ if (ct == _costType) costItem = item;
++ }
++ for (int i=m->realCount()-1;i>=0;i--) {
++ ct = m->realType(i);
++ item = new CostTypeItem(this, c, ct, _groupType);
++ if (ct == _costType) costItem = item;
++ }
++
++ if (costItem) {
++ setSelected(costItem, true);
++ ensureItemVisible(costItem);
++ }
++
++ if (item) setMinimumHeight(3*item->height());
++}
++
++
++void CostTypeView::renamedSlot(TQListViewItem* item,int c,const TQString& t)
++{
++ TraceCostType* ct = item ? ((CostTypeItem*) item)->costType() : 0;
++ if (!ct || ct->isReal()) return;
++
++ // search for matching known Type
++ int knownCount = TraceCostType::knownTypeCount();
++ TraceCostType* known = 0;
++ for (int i=0; i<knownCount; i++) {
++ known = TraceCostType::knownType(i);
++ if (known->name() == ct->name()) break;
++ }
++
++ if (c == 0) {
++ ct->setLongName(t);
++ if (known) known->setLongName(t);
++ }
++ else if (c == 3) {
++ ct->setName(t);
++ if (known) known->setName(t);
++ }
++ else if (c == 5) {
++ ct->setFormula(t);
++ if (known) known->setFormula(t);
++ }
++ else return;
++
++ if (_topLevel) _topLevel->configChanged();
++ refresh();
++}
++
++#include "costtypeview.moc"
+diff --git a/kdecachegrind/kdecachegrind/costtypeview.h b/kdecachegrind/kdecachegrind/costtypeview.h
+new file mode 100644
+index 0000000..ee9963e
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/costtypeview.h
+@@ -0,0 +1,54 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Cost Type View
++ */
++
++#ifndef COSTTYPEVIEW_H
++#define COSTTYPEVIEW_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++#include "traceitemview.h"
++
++class CostTypeView: public TQListView, public TraceItemView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ CostTypeView(TraceItemView* parentView,
++ TQWidget* parent=0, const char* name=0);
++
++ virtual TQWidget* widget() { return this; }
++ TQString whatsThis() const;
++
++private slots:
++ void context(TQListViewItem*,const TQPoint &, int);
++ void selectedSlot(TQListViewItem*);
++ void activatedSlot(TQListViewItem*);
++ void renamedSlot(TQListViewItem*,int,const TQString&);
++
++private:
++ TraceItem* canShow(TraceItem*);
++ void doUpdate(int);
++ void refresh();
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/coverage.cpp b/kdecachegrind/kdecachegrind/coverage.cpp
+new file mode 100644
+index 0000000..86e6f7f
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/coverage.cpp
+@@ -0,0 +1,329 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Function Coverage Analysis
++ */
++
++#include "coverage.h"
++
++//#define DEBUG_COVERAGE 1
++
++TraceCostType* Coverage::_costType;
++
++const int Coverage::maxHistogramDepth = maxHistogramDepthValue;
++const int Coverage::Rtti = 1;
++
++Coverage::Coverage()
++{
++}
++
++void Coverage::init()
++{
++ _self = 0.0;
++ _incl = 0.0;
++ _callCount = 0.0;
++ // should always be overwritten before usage
++ _firstPercentage = 1.0;
++ _minDistance = 9999;
++ _maxDistance = 0;
++ _active = false;
++ _inRecursion = false;
++ for (int i = 0;i<maxHistogramDepth;i++) {
++ _selfHisto[i] = 0.0;
++ _inclHisto[i] = 0.0;
++ }
++
++ _valid = true;
++}
++
++int Coverage::inclusiveMedian()
++{
++ double maxP = _inclHisto[0];
++ int medD = 0;
++ for (int i = 1;i<maxHistogramDepth;i++)
++ if (_inclHisto[i]>maxP) {
++ maxP = _inclHisto[i];
++ medD = i;
++ }
++
++ return medD;
++}
++
++int Coverage::selfMedian()
++{
++ double maxP = _selfHisto[0];
++ int medD = 0;
++ for (int i = 1;i<maxHistogramDepth;i++)
++ if (_selfHisto[i]>maxP) {
++ maxP = _selfHisto[i];
++ medD = i;
++ }
++
++ return medD;
++}
++
++TraceFunctionList Coverage::coverage(TraceFunction* f, CoverageMode m,
++ TraceCostType* ct)
++{
++ invalidate(f->data(), Coverage::Rtti);
++
++ _costType = ct;
++
++ // function f takes ownership over c!
++ Coverage* c = new Coverage();
++ c->setFunction(f);
++ c->init();
++
++ TraceFunctionList l;
++
++ if (m == Caller)
++ c->addCallerCoverage(l, 1.0, 0);
++ else
++ c->addCallingCoverage(l, 1.0, 1.0, 0);
++
++ return l;
++}
++
++void Coverage::addCallerCoverage(TraceFunctionList& fList,
++ double pBack, int d)
++{
++ TraceCallList cList;
++ TraceCall* call;
++ Coverage* c;
++
++ if (_inRecursion) return;
++
++ double incl;
++ incl = (double) (_function->inclusive()->subCost(_costType));
++
++ if (_active) {
++#ifdef DEBUG_COVERAGE
++ qDebug("CallerCov: D %d, %s (was active, incl %f, self %f): newP %f", d,
++ _function->prettyName().ascii(), _incl, _self, pBack);
++#endif
++ _inRecursion = true;
++ }
++ else {
++ _active = true;
++
++ // only add cost if this is no recursion
++
++ _incl += pBack;
++ _firstPercentage = pBack;
++
++ if (_minDistance > d) _minDistance = d;
++ if (_maxDistance < d) _maxDistance = d;
++ if (d<maxHistogramDepth) {
++ _inclHisto[d] += pBack;
++ }
++ else {
++ _inclHisto[maxHistogramDepth-1] += pBack;
++ }
++
++#ifdef DEBUG_COVERAGE
++ qDebug("CallerCov: D %d, %s (now active, new incl %f): newP %f",
++ d, _function->prettyName().ascii(), _incl, pBack);
++#endif
++ }
++
++ double callVal, pBackNew;
++
++ cList = _function->callers();
++ for (call=cList.first();call;call=cList.next()) {
++ if (call->inCycle()>0) continue;
++ if (call->isRecursion()) continue;
++
++ if (call->subCost(_costType)>0) {
++ TraceFunction* caller = call->caller();
++
++ c = (Coverage*) caller->assoziation(rtti());
++ if (!c) {
++ c = new Coverage();
++ c->setFunction(caller);
++ }
++ if (!c->isValid()) {
++ c->init();
++ fList.append(caller);
++ }
++
++ if (c->isActive()) continue;
++ if (c->inRecursion()) continue;
++
++ callVal = (double) call->subCost(_costType);
++ pBackNew = pBack * (callVal / incl);
++
++ // FIXME ?!?
++
++ if (!c->isActive()) {
++ if (d>=0)
++ c->callCount() += (double)call->callCount();
++ else
++ c->callCount() += _callCount;
++ }
++ else {
++ // adjust pNew by sum of geometric series of recursion factor.
++ // Thus we can avoid endless recursion here
++ pBackNew *= 1.0 / (1.0 - pBackNew / c->firstPercentage());
++ }
++
++ // Limit depth
++ if (pBackNew > 0.0001)
++ c->addCallerCoverage(fList, pBackNew, d+1);
++ }
++ }
++
++ if (_inRecursion)
++ _inRecursion = false;
++ else if (_active)
++ _active = false;
++}
++
++/**
++ * pForward is time on percent used,
++ * pBack is given to allow for calculation of call counts
++ */
++void Coverage::addCallingCoverage(TraceFunctionList& fList,
++ double pForward, double pBack, int d)
++{
++ TraceCallList cList;
++ TraceCall* call;
++ Coverage* c;
++
++ if (_inRecursion) return;
++
++#ifdef DEBUG_COVERAGE
++ static const char* spaces = " ";
++#endif
++
++ double self, incl;
++ incl = (double) (_function->inclusive()->subCost(_costType));
++
++#ifdef DEBUG_COVERAGE
++ qDebug("CngCov:%s - %s (incl %f, self %f): forward %f, back %f",
++ spaces+strlen(spaces)-d,
++ _function->prettyName().ascii(), _incl, _self, pForward, pBack);
++#endif
++
++
++ if (_active) {
++ _inRecursion = true;
++
++#ifdef DEBUG_COVERAGE
++ qDebug("CngCov:%s < %s: STOP (is active)",
++ spaces+strlen(spaces)-d,
++ _function->prettyName().ascii());
++#endif
++
++ }
++ else {
++ _active = true;
++
++ // only add cost if this is no recursion
++ self = pForward * (_function->subCost(_costType)) / incl;
++ _incl += pForward;
++ _self += self;
++ _firstPercentage = pForward;
++
++ if (_minDistance > d) _minDistance = d;
++ if (_maxDistance < d) _maxDistance = d;
++ if (d<maxHistogramDepth) {
++ _inclHisto[d] += pForward;
++ _selfHisto[d] += self;
++ }
++ else {
++ _inclHisto[maxHistogramDepth-1] += pForward;
++ _selfHisto[maxHistogramDepth-1] += self;
++ }
++
++#ifdef DEBUG_COVERAGE
++ qDebug("CngCov:%s < %s (incl %f, self %f)",
++ spaces+strlen(spaces)-d,
++ _function->prettyName().ascii(), _incl, _self);
++#endif
++ }
++
++ double callVal, pForwardNew, pBackNew;
++
++ cList = _function->callings();
++ for (call=cList.first();call;call=cList.next()) {
++ if (call->inCycle()>0) continue;
++ if (call->isRecursion()) continue;
++
++ if (call->subCost(_costType)>0) {
++ TraceFunction* calling = call->called();
++
++ c = (Coverage*) calling->assoziation(rtti());
++ if (!c) {
++ c = new Coverage();
++ c->setFunction(calling);
++ }
++ if (!c->isValid()) {
++ c->init();
++ fList.append(calling);
++ }
++
++ if (c->isActive()) continue;
++ if (c->inRecursion()) continue;
++
++ callVal = (double) call->subCost(_costType);
++ pForwardNew = pForward * (callVal / incl);
++ pBackNew = pBack * (callVal /
++ calling->inclusive()->subCost(_costType));
++
++ if (!c->isActive()) {
++ c->callCount() += pBack * call->callCount();
++
++#ifdef DEBUG_COVERAGE
++ qDebug("CngCov:%s > %s: forward %f, back %f, calls %f -> %f, now %f",
++ spaces+strlen(spaces)-d,
++ calling->prettyName().ascii(),
++ pForwardNew, pBackNew,
++ (double)call->callCount(),
++ pBack * call->callCount(),
++ c->callCount());
++#endif
++ }
++ else {
++ // adjust pNew by sum of geometric series of recursion factor.
++ // Thus we can avoid endless recursion here
++ double fFactor = 1.0 / (1.0 - pForwardNew / c->firstPercentage());
++ double bFactor = 1.0 / (1.0 - pBackNew);
++#ifdef DEBUG_COVERAGE
++ qDebug("CngCov:%s Recursion - origP %f, actP %f => factor %f, newP %f",
++ spaces+strlen(spaces)-d,
++ c->firstPercentage(), pForwardNew,
++ fFactor, pForwardNew * fFactor);
++#endif
++ pForwardNew *= fFactor;
++ pBackNew *= bFactor;
++
++ }
++
++ // Limit depth
++ if (pForwardNew > 0.0001)
++ c->addCallingCoverage(fList, pForwardNew, pBackNew, d+1);
++ }
++ }
++
++ if (_inRecursion)
++ _inRecursion = false;
++ else if (_active)
++ _active = false;
++}
++
+diff --git a/kdecachegrind/kdecachegrind/coverage.h b/kdecachegrind/kdecachegrind/coverage.h
+new file mode 100644
+index 0000000..50c5936
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/coverage.h
+@@ -0,0 +1,102 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Function Coverage Analysis
++ */
++
++#ifndef COVERAGE_H
++#define COVERAGE_H
++
++#include "tracedata.h"
++
++/**
++ * Coverage of a function.
++ * When analysis is done, every function involved will have a
++ * pointer to an object of this class.
++ *
++ * This function also holds the main routine for coverage analysis,
++ * Coverage::coverage(), as static method.
++ */
++class Coverage : public TraceAssoziation
++{
++public:
++ /* Direction of coverage analysis */
++ enum CoverageMode { Caller, Called };
++
++ // max depth for distance histogram
++#define maxHistogramDepthValue 40
++ static const int maxHistogramDepth;
++
++ static const int Rtti;
++
++ Coverage();
++
++ virtual int rtti() { return Rtti; }
++ void init();
++
++ TraceFunction* function() { return _function; }
++ double self() { return _self; }
++ double inclusive() { return _incl; }
++ double firstPercentage() { return _firstPercentage; }
++ double& callCount() { return _callCount; }
++ int minDistance() { return _minDistance; }
++ int maxDistance() { return _maxDistance; }
++ int inclusiveMedian();
++ int selfMedian();
++ double* selfHistogram() { return _selfHisto; }
++ double* inclusiveHistogram() { return _inclHisto; }
++ bool isActive() { return _active; }
++ bool inRecursion() { return _inRecursion; }
++
++ void setSelf(float p) { _self = p; }
++ void setInclusive(float p) { _incl = p; }
++ void setCallCount(float cc) { _callCount = cc; }
++ void setActive(bool a) { _active = a; }
++ void setInRecursion(bool r) { _inRecursion = r; }
++
++ /**
++ * Calculate coverage of all functions based on function f.
++ * If mode is Called, the coverage of functions called by
++ * f is calculated, otherwise that of functions calling f.
++ * SubCost type ct is used for the analysis.
++ * Self values are undefined for Caller mode.
++ *
++ * Returns list of functions covered.
++ * Coverage degree of returned functions can be get
++ * with function->coverage()->percentage()
++ */
++ static TraceFunctionList coverage(TraceFunction* f, CoverageMode m,
++ TraceCostType* ct);
++
++private:
++ void addCallerCoverage(TraceFunctionList& l, double, int d);
++ void addCallingCoverage(TraceFunctionList& l, double, double, int d);
++
++ double _self, _incl, _firstPercentage, _callCount;
++ int _minDistance, _maxDistance;
++ bool _active, _inRecursion;
++ double _selfHisto[maxHistogramDepthValue];
++ double _inclHisto[maxHistogramDepthValue];
++
++ // temporary set for one coverage analysis
++ static TraceCostType* _costType;
++};
++
++#endif
++
+diff --git a/kdecachegrind/kdecachegrind/coverageitem.cpp b/kdecachegrind/kdecachegrind/coverageitem.cpp
+new file mode 100644
+index 0000000..26e5b36
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/coverageitem.cpp
+@@ -0,0 +1,343 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of coverage view.
++ */
++
++#include <tqpixmap.h>
++#include <klocale.h>
++
++#include "configuration.h"
++#include "listutils.h"
++#include "coverage.h"
++#include "coverageitem.h"
++
++
++// CallerCoverageItem
++
++
++CallerCoverageItem::CallerCoverageItem(TQListView* parent, Coverage* c,
++ TraceFunction* base,
++ TraceCostType* ct,
++ TraceCost::CostType gt)
++ : TQListViewItem(parent)
++{
++ _skipped = 0;
++ _coverage = c;
++ _function = c ? c->function() : 0;
++ _base = base;
++ _groupType = TraceCost::NoCostType;
++
++ setText(3, _function->prettyNameWithLocation());
++
++ setCostType(ct);
++ setGroupType(gt);
++}
++
++CallerCoverageItem::CallerCoverageItem(TQListView* parent, int skipped, Coverage* c,
++ TraceFunction* base,
++ TraceCostType* ct,
++ TraceCost::CostType gt)
++ : TQListViewItem(parent)
++{
++ _skipped = skipped;
++ _coverage = c;
++ _function = c ? c->function() : 0;
++ _base = base;
++ _groupType = TraceCost::NoCostType;
++
++ setText(3, i18n("(%n function skipped)", "(%n functions skipped)", _skipped));
++
++ setCostType(ct);
++ setGroupType(gt);
++}
++
++void CallerCoverageItem::setGroupType(TraceCost::CostType gt)
++{
++ if (_skipped) return;
++ if (_groupType == gt) return;
++ _groupType = gt;
++
++ TQColor c = Configuration::functionColor(_groupType, _function);
++ setPixmap(3, colorPixmap(10, 10, c));
++}
++
++void CallerCoverageItem::setCostType(TraceCostType* ct)
++{
++ _costType = ct;
++ update();
++}
++
++void CallerCoverageItem::update()
++{
++ if (!_coverage) {
++ setText(0, TQString());
++ setText(1, TQString());
++ return;
++ }
++
++ _pSum = 100.0 * _coverage->inclusive();
++ SubCost realSum = _base->inclusive()->subCost(_costType);
++ _sum = SubCost(realSum * _coverage->inclusive());
++ TQString str;
++ if (Configuration::showPercentage())
++ str = TQString("%1").arg(_pSum, 0, 'f', Configuration::percentPrecision());
++ else
++ str = _sum.pretty();
++
++ if (_skipped) {
++ setText(0, TQString("< %1").arg(str));
++ return;
++ }
++
++ setText(0, str);
++ setPixmap(0, partitionPixmap(25, 10, _coverage->inclusiveHistogram(), 0,
++ Coverage::maxHistogramDepth, false));
++
++ // call count
++ _cc = SubCost(_coverage->callCount());
++ setText(2, _cc ? _cc.pretty() : TQString("(0)"));
++
++ // distance (min/max/median)
++ _distance = _coverage->inclusiveMedian();
++ TQString distString;
++ if (_coverage->minDistance() == _coverage->maxDistance())
++ distString = TQString::number(_distance);
++ else
++ distString = TQString("%1-%2 (%3)")
++ .arg(_coverage->minDistance())
++ .arg(_coverage->maxDistance())
++ .arg(_distance);
++ setText(1, distString);
++}
++
++
++int CallerCoverageItem::compare(TQListViewItem * i,
++ int col, bool ascending ) const
++{
++ const CallerCoverageItem* ci1 = this;
++ const CallerCoverageItem* ci2 = (CallerCoverageItem*) i;
++
++ // we always want descending order
++ if (ascending) {
++ ci1 = ci2;
++ ci2 = this;
++ }
++
++ // a skip entry is always sorted last
++ if (ci1->_skipped) return -1;
++ if (ci2->_skipped) return 1;
++
++ if (col==0) {
++ if (ci1->_pSum < ci2->_pSum) return -1;
++ if (ci1->_pSum > ci2->_pSum) return 1;
++
++ // for same percentage (e.g. all 100%), use distance info
++ if (ci1->_distance < ci2->_distance) return -1;
++ if (ci1->_distance > ci2->_distance) return 1;
++ return 0;
++ }
++
++ if (col==1) {
++ if (ci1->_distance < ci2->_distance) return -1;
++ if (ci1->_distance > ci2->_distance) return 1;
++ return 0;
++ }
++
++ if (col==2) {
++ if (ci1->_cc < ci2->_cc) return -1;
++ if (ci1->_cc > ci2->_cc) return 1;
++ return 0;
++ }
++ return TQListViewItem::compare(i, col, ascending);
++}
++
++
++// CalleeCoverageItem
++
++
++CalleeCoverageItem::CalleeCoverageItem(TQListView* parent, Coverage* c,
++ TraceFunction* base,
++ TraceCostType* ct,
++ TraceCost::CostType gt)
++ : TQListViewItem(parent)
++{
++ _skipped = 0;
++ _coverage = c;
++ _function = c ? c->function() : 0;
++ _base = base;
++ _groupType = TraceCost::NoCostType;
++
++ setText(4, _function->prettyNameWithLocation());
++
++ setCostType(ct);
++ setGroupType(gt);
++}
++
++CalleeCoverageItem::CalleeCoverageItem(TQListView* parent, int skipped, Coverage* c,
++ TraceFunction* base,
++ TraceCostType* ct,
++ TraceCost::CostType gt)
++ : TQListViewItem(parent)
++{
++ _skipped = skipped;
++ _coverage = c;
++ _function = c ? c->function() : 0;
++ _base = base;
++ _groupType = TraceCost::NoCostType;
++
++ setText(4, i18n("(%n function skipped)", "(%n functions skipped)", _skipped));
++
++ setCostType(ct);
++ setGroupType(gt);
++}
++
++void CalleeCoverageItem::setGroupType(TraceCost::CostType gt)
++{
++ if (_skipped) return;
++ if (_groupType == gt) return;
++ _groupType = gt;
++
++ TQColor c = Configuration::functionColor(_groupType, _function);
++ setPixmap(4, colorPixmap(10, 10, c));
++}
++
++void CalleeCoverageItem::setCostType(TraceCostType* ct)
++{
++ _costType = ct;
++ update();
++}
++
++void CalleeCoverageItem::update()
++{
++ if (!_coverage) {
++ setText(0, TQString());
++ setText(1, TQString());
++ setText(2, TQString());
++ return;
++ }
++
++ _pSum = 100.0 * _coverage->inclusive();
++
++ // pSum/pSelf are percentages of inclusive cost of base
++ SubCost realSum = _base->inclusive()->subCost(_costType);
++ _sum = SubCost(realSum * _coverage->inclusive());
++
++
++ TQString str;
++ if (Configuration::showPercentage())
++ str = TQString("%1").arg(_pSum, 0, 'f', Configuration::percentPrecision());
++ else
++ str = _sum.pretty();
++
++ if (_skipped) {
++ str = TQString("< %1").arg(str);
++ setText(0, str);
++ setText(1, str);
++ return;
++ }
++ setText(0, str);
++
++ _pSelf = 100.0 * _coverage->self();
++ _self = SubCost(realSum * _coverage->self());
++
++ if (Configuration::showPercentage()) {
++ setText(1, TQString("%1")
++ .arg(_pSelf, 0, 'f', Configuration::percentPrecision()));
++ }
++ else {
++ setText(1, _self.pretty());
++ }
++
++ setPixmap(0, partitionPixmap(25, 10, _coverage->inclusiveHistogram(), 0,
++ Coverage::maxHistogramDepth, false));
++ setPixmap(1, partitionPixmap(25, 10, _coverage->selfHistogram(), 0,
++ Coverage::maxHistogramDepth, false));
++
++
++ _cc = SubCost(_coverage->callCount());
++ setText(3, _cc ? _cc.pretty() : TQString("(0)"));
++
++ // for comparations
++ _distance = _coverage->inclusiveMedian();
++ TQString distString;
++ if (_coverage->minDistance() == _coverage->maxDistance())
++ distString = TQString::number(_distance);
++ else {
++ int sMed = _coverage->selfMedian();
++ TQString med;
++ if (_distance == sMed)
++ med = TQString::number(_distance);
++ else
++ med = TQString("%1/%2").arg(_distance).arg(sMed);
++
++ distString = TQString("%1-%2 (%3)")
++ .arg(_coverage->minDistance())
++ .arg(_coverage->maxDistance())
++ .arg(med);
++ }
++ setText(2, distString);
++}
++
++
++int CalleeCoverageItem::compare(TQListViewItem * i,
++ int col, bool ascending ) const
++{
++ CalleeCoverageItem* ci = (CalleeCoverageItem*) i;
++
++ // a skip entry is always sorted last
++ if (_skipped) return -1;
++ if (ci->_skipped) return 1;
++
++ if (col==0) {
++ if (_pSum < ci->_pSum) return -1;
++ if (_pSum > ci->_pSum) return 1;
++
++ // for same percentage (e.g. all 100%), use distance info
++ if (_distance < ci->_distance) return -1;
++ if (_distance > ci->_distance) return 1;
++ return 0;
++ }
++
++ if (col==1) {
++ if (_pSelf < ci->_pSelf) return -1;
++ if (_pSelf > ci->_pSelf) return 1;
++
++ // for same percentage (e.g. all 100%), use distance info
++ if (_distance < ci->_distance) return -1;
++ if (_distance > ci->_distance) return 1;
++ return 0;
++ }
++
++ if (col==2) {
++ // we want to sort the distance in contra direction to costs
++ if (_distance < ci->_distance) return 1;
++ if (_distance > ci->_distance) return -1;
++ return 0;
++ }
++
++ if (col==3) {
++ if (_cc < ci->_cc) return -1;
++ if (_cc > ci->_cc) return 1;
++ return 0;
++ }
++ return TQListViewItem::compare(i, col, ascending);
++}
++
++
+diff --git a/kdecachegrind/kdecachegrind/coverageitem.h b/kdecachegrind/kdecachegrind/coverageitem.h
+new file mode 100644
+index 0000000..ba442aa
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/coverageitem.h
+@@ -0,0 +1,82 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of coverage view.
++ */
++
++#ifndef COVERAGEITEM_H
++#define COVERAGEITEM_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++
++class Coverage;
++
++class CallerCoverageItem: public TQListViewItem
++{
++public:
++ CallerCoverageItem(TQListView* parent, Coverage* c, TraceFunction* base,
++ TraceCostType* ct, TraceCost::CostType gt);
++ CallerCoverageItem(TQListView* parent, int skipped, Coverage* c, TraceFunction* base,
++ TraceCostType* ct, TraceCost::CostType gt);
++
++ int compare(TQListViewItem * i, int col, bool ascending ) const;
++ TraceFunction* function() { return (_skipped) ? 0 : _function; }
++ void setCostType(TraceCostType* ct);
++ void setGroupType(TraceCost::CostType);
++ void update();
++
++private:
++ float _pSum;
++ SubCost _sum;
++ TraceCostType* _costType;
++ TraceCost::CostType _groupType;
++ SubCost _cc;
++ int _distance, _skipped;
++ TraceFunction *_function, *_base;
++ Coverage* _coverage;
++};
++
++
++class CalleeCoverageItem: public TQListViewItem
++{
++public:
++ CalleeCoverageItem(TQListView* parent, Coverage* c, TraceFunction* base,
++ TraceCostType* ct, TraceCost::CostType gt);
++ CalleeCoverageItem(TQListView* parent, int skipped, Coverage* c, TraceFunction* base,
++ TraceCostType* ct, TraceCost::CostType gt);
++
++ int compare(TQListViewItem * i, int col, bool ascending ) const;
++ TraceFunction* function() { return (_skipped) ? 0 : _function; }
++ void setCostType(TraceCostType* ct);
++ void setGroupType(TraceCost::CostType);
++ void update();
++
++private:
++ float _pSum, _pSelf;
++ SubCost _sum, _self;
++ TraceCostType* _costType;
++ TraceCost::CostType _groupType;
++ SubCost _cc;
++ int _distance, _skipped;
++ TraceFunction *_function, *_base;
++ Coverage* _coverage;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/coverageview.cpp b/kdecachegrind/kdecachegrind/coverageview.cpp
+new file mode 100644
+index 0000000..6657e92
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/coverageview.cpp
+@@ -0,0 +1,321 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Coverage Views
++ */
++
++#include <tqwhatsthis.h>
++#include <tqpopupmenu.h>
++#include <klocale.h>
++
++#include "configuration.h"
++#include "coverageitem.h"
++#include "coverage.h"
++#include "coverageview.h"
++
++
++
++//
++// CoverageView
++//
++
++
++CoverageView::CoverageView(bool showCallers, TraceItemView* parentView,
++ TQWidget* parent, const char* name)
++ : TQListView(parent, name), TraceItemView(parentView)
++{
++ _showCallers = showCallers;
++
++
++ addColumn( i18n( "Incl." ) );
++ if (_showCallers) {
++ addColumn( i18n( "Distance" ) );
++ addColumn( i18n( "Called" ) );
++ addColumn( i18n( "Caller" ) );
++ }
++ else {
++ addColumn( i18n( "Self" ) );
++ addColumn( i18n( "Distance" ) );
++ addColumn( i18n( "Calling" ) );
++ addColumn( i18n( "Callee" ) );
++ setColumnAlignment(3, TQt::AlignRight);
++ }
++
++ setSorting(0,false);
++ setColumnAlignment(0, TQt::AlignRight);
++ setColumnAlignment(1, TQt::AlignRight);
++ setColumnAlignment(2, TQt::AlignRight);
++ setAllColumnsShowFocus(true);
++ setResizeMode(TQListView::LastColumn);
++ setMinimumHeight(50);
++
++ connect( this,
++ TQT_SIGNAL( selectionChanged(TQListViewItem*) ),
++ TQT_SLOT( selectedSlot(TQListViewItem*) ) );
++
++ connect( this,
++ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
++ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int)));
++
++ connect(this,
++ TQT_SIGNAL(doubleClicked(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ connect(this,
++ TQT_SIGNAL(returnPressed(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ TQWhatsThis::add( this, whatsThis() );
++}
++
++TQString CoverageView::whatsThis() const
++{
++ return _showCallers ?
++ i18n( "<b>List of all Callers</b>"
++ "<p>This list shows all functions calling the "
++ "current selected one, either directly or with "
++ "several functions in-between on the stack; the "
++ "number of functions in-between plus one "
++ "is called the <em>Distance</em> (e.g. "
++ "for function A,B,C there exists a call from "
++ "A to C when A calls B and B calls C, i.e. "
++ "A => B => C. The distance here is 2).</p>"
++
++ "<p>Absolute cost shown is the cost spent in the "
++ "selected function while a listed function is active; "
++ "relative cost is the percentage of all cost spent in "
++ "the selected function while the listed one is "
++ "active. The cost graphic shows logarithmic "
++ "percentage with a different color for each "
++ "distance.</p>"
++
++ "<p>As there can be many calls from the same function, "
++ "the distance column sometimes shows "
++ "the range of distances for all "
++ "calls happening; then, in parentheses, there is the "
++ "medium distance, i.e. the distance where most of the "
++ "call costs happened.</p>"
++
++ "<p>Selecting a function makes it the current selected "
++ "one of this information panel. "
++ "If there are two panels (Split mode), the "
++ "function of the other panel is changed instead.</p>") :
++
++ i18n( "<b>List of all Callees</b>"
++ "<p>This list shows all functions called by the "
++ "current selected one, either directly or with "
++ "several function in-between on the stack; the "
++ "number of function in-between plus one "
++ "is called the <em>Distance</em> (e.g. "
++ "for function A,B,C there exists a call from "
++ "A to C when A calls B and B calls C, i.e. "
++ "A => B => C. The distance here is 2).</p>"
++
++ "<p>Absolute cost shown is the cost spent in the "
++ "listed function while the selected is active; "
++ "relative cost is the percentage of all cost spent in "
++ "the listed function while the selected one is active. "
++ "The cost graphic always shows logarithmic "
++ "percentage with a different color for each "
++ "distance.</p>"
++
++ "<p>As there can be many calls to the same function, "
++ "the distance column sometimes shows "
++ "the range of distances for all "
++ "calls happening; then, in parentheses, there is the "
++ "medium distance, i.e. the distance where most of the "
++ "call costs happened.</p>"
++
++ "<p>Selecting a function makes it the current selected "
++ "one of this information panel. "
++ "If there are two panels (Split mode), the "
++ "function of the other panel is changed instead.</p>");
++}
++
++void CoverageView::context(TQListViewItem* i, const TQPoint & p, int c)
++{
++ TQPopupMenu popup;
++
++ TraceFunction* f = 0;
++ if (i) {
++ f = _showCallers ?
++ ((CallerCoverageItem*)i)->function() :
++ ((CalleeCoverageItem*)i)->function();
++ }
++
++ if (f) {
++ TQString name = f->name();
++ if ((int)name.length()>Configuration::maxSymbolLength())
++ name = name.left(Configuration::maxSymbolLength()) + "...";
++ popup.insertItem(i18n("Go to '%1'").arg(name), 93);
++ popup.insertSeparator();
++ }
++
++ if ((c == 0) || (!_showCallers && c == 1)) {
++ addCostMenu(&popup, false);
++ popup.insertSeparator();
++ }
++ addGoMenu(&popup);
++
++ int r = popup.exec(p);
++ if (r == 93) activated(f);
++}
++
++void CoverageView::selectedSlot(TQListViewItem * i)
++{
++ TraceFunction* f = 0;
++ if (i) {
++ f = _showCallers ?
++ ((CallerCoverageItem*)i)->function() :
++ ((CalleeCoverageItem*)i)->function();
++ }
++
++ if (f) {
++ _selectedItem = f;
++ selected(f);
++ }
++}
++
++void CoverageView::activatedSlot(TQListViewItem * i)
++{
++ TraceFunction* f = 0;
++ if (i) {
++ f = _showCallers ?
++ ((CallerCoverageItem*)i)->function() :
++ ((CalleeCoverageItem*)i)->function();
++ }
++
++ if (f) activated(f);
++}
++
++TraceItem* CoverageView::canShow(TraceItem* i)
++{
++ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType;
++
++ switch(t) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ return i;
++ default:
++ break;
++ }
++ return 0;
++}
++
++void CoverageView::doUpdate(int changeType)
++{
++ // Special case ?
++ if (changeType == selectedItemChanged) {
++
++ if (!_selectedItem) {
++ clearSelection();
++ return;
++ }
++
++ TraceFunction* f = 0;
++ TQListViewItem* i = TQListView::selectedItem();
++ if (i) {
++ f = _showCallers ?
++ ((CallerCoverageItem*)i)->function() :
++ ((CalleeCoverageItem*)i)->function();
++ }
++ if (f == _selectedItem) return;
++
++ TQListViewItem *item;
++ for (item = firstChild();item;item = item->nextSibling()) {
++ f = _showCallers ?
++ ((CallerCoverageItem*)item)->function() :
++ ((CalleeCoverageItem*)item)->function();
++ if (f == _selectedItem) {
++ ensureItemVisible(item);
++ setCurrentItem(item);
++ break;
++ }
++ }
++ return;
++ }
++
++ if (changeType == groupTypeChanged) {
++ TQListViewItem *item;
++ for (item = firstChild();item;item = item->nextSibling()) {
++ if (_showCallers)
++ ((CallerCoverageItem*)item)->setGroupType(_groupType);
++ else
++ ((CalleeCoverageItem*)item)->setGroupType(_groupType);
++ }
++ return;
++ }
++
++ refresh();
++}
++
++void CoverageView::refresh()
++{
++ clear();
++ setColumnWidth(0, 50);
++ if (!_showCallers)
++ setColumnWidth(1, 50);
++
++ if (!_data || !_activeItem) return;
++
++ TraceItem::CostType t = _activeItem->type();
++ TraceFunction* f = 0;
++ if (t == TraceItem::Function) f = (TraceFunction*) _activeItem;
++ if (t == TraceItem::FunctionCycle) f = (TraceFunction*) _activeItem;
++ if (!f) return;
++
++ TraceFunction* ff;
++ TraceFunctionList l;
++
++ _hc.clear(Configuration::maxListCount());
++ SubCost realSum = f->inclusive()->subCost(_costType);
++
++ if (_showCallers)
++ l = Coverage::coverage(f, Coverage::Caller, _costType);
++ else
++ l = Coverage::coverage(f, Coverage::Called, _costType);
++
++ for (ff=l.first();ff;ff=l.next()) {
++ Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti);
++ if (c && (c->inclusive()>0.0))
++ _hc.addCost(ff, SubCost(realSum * c->inclusive()));
++ }
++
++ for(int i=0;i<_hc.realCount();i++) {
++ ff = (TraceFunction*) _hc[i];
++ Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti);
++ if (_showCallers)
++ new CallerCoverageItem(this, c, f, _costType, _groupType);
++ else
++ new CalleeCoverageItem(this, c, f, _costType, _groupType);
++ }
++ if (_hc.hasMore()) {
++ // a placeholder for all the functions skipped ...
++ ff = (TraceFunction*) _hc[_hc.maxSize()-1];
++ Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti);
++ if (_showCallers)
++ new CallerCoverageItem(this, _hc.count() - _hc.maxSize(),
++ c, f, _costType, _groupType);
++ else
++ new CalleeCoverageItem(this, _hc.count() - _hc.maxSize(),
++ c, f, _costType, _groupType);
++ }
++}
++
++#include "coverageview.moc"
+diff --git a/kdecachegrind/kdecachegrind/coverageview.h b/kdecachegrind/kdecachegrind/coverageview.h
+new file mode 100644
+index 0000000..09c5de0
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/coverageview.h
+@@ -0,0 +1,57 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Coverage Views
++ */
++
++#ifndef COVERAGEVIEW_H
++#define COVERAGEVIEW_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++#include "traceitemview.h"
++#include "listutils.h"
++
++class CoverageView: public TQListView, public TraceItemView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ CoverageView(bool showCallers, TraceItemView* parentView,
++ TQWidget* parent=0, const char* name=0);
++
++ virtual TQWidget* widget() { return this; }
++ TQString whatsThis() const;
++
++private slots:
++ void context(TQListViewItem*,const TQPoint &, int);
++ void selectedSlot(TQListViewItem*);
++ void activatedSlot(TQListViewItem*);
++
++private:
++ TraceItem* canShow(TraceItem*);
++ void doUpdate(int);
++ void refresh();
++
++ HighestCostList _hc;
++ bool _showCallers;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/dumpmanager.cpp b/kdecachegrind/kdecachegrind/dumpmanager.cpp
+new file mode 100644
+index 0000000..2f0891a
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/dumpmanager.cpp
+@@ -0,0 +1,50 @@
++/**
++ * DumpManager
++ * Part of KCachegrind
++ * 2003, Josef Weidendorfer (GPL V2)
++ */
++
++#include "dumpmanager.h"
++
++
++//
++// Dump
++//
++
++Dump::Dump(TQString file)
++{
++ _filename = file;
++}
++
++
++//
++// DumpManager
++//
++
++DumpManager* DumpManager::_self = 0;
++
++
++DumpManager::DumpManager()
++{
++}
++
++DumpManager* DumpManager::self()
++{
++ if (!_self)
++ _self = new DumpManager();
++
++ return _self;
++}
++
++
++DumpList DumpManager::loadableDumps()
++{
++ DumpList res;
++
++ return res;
++}
++
++TraceData* DumpManager::load(Dump*)
++{
++ return 0;
++}
+diff --git a/kdecachegrind/kdecachegrind/dumpmanager.h b/kdecachegrind/kdecachegrind/dumpmanager.h
+new file mode 100644
+index 0000000..4925819
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/dumpmanager.h
+@@ -0,0 +1,59 @@
++/**
++ * DumpManager
++ * Part of KCachegrind
++ * 2003, Josef Weidendorfer (GPL V2)
++ *
++ * DumpManager is a Singleton.
++ * - Has List of current loaded dumps / loadable dumps
++ * - Does "communication" with current running profiles
++ * for dump selection dockable
++ */
++
++#ifndef DUMPMANAGER_H
++#define DUMPMANAGER_H
++
++#include <tqstring.h>
++#include <tqptrlist.h>
++
++class Dump;
++class TraceData;
++
++typedef TQPtrList<Dump> DumpList;
++
++
++/**
++ * A loadable profile Dump
++ */
++class Dump
++{
++public:
++ Dump(TQString);
++
++ TQString filename() { return _filename; }
++
++private:
++ TQString _filename;
++};
++
++
++/*
++ * TODO:
++ * - Everything
++ *
++ */
++
++class DumpManager
++{
++public:
++ DumpManager();
++
++ DumpManager* self();
++
++ DumpList loadableDumps();
++ TraceData* load(Dump*);
++
++private:
++ static DumpManager* _self;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/dumpselection.cpp b/kdecachegrind/kdecachegrind/dumpselection.cpp
+new file mode 100644
+index 0000000..4d812ef
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/dumpselection.cpp
+@@ -0,0 +1,33 @@
++/**
++ * DumpSelection Dockable
++ * Part of KCachegrind
++ * 2003, Josef Weidendorfer (GPL V2)
++ *
++ * - Fast Selection of dumps to load/activate/use for comparing
++ * - Start a profile run from GUI (current supported: Callgrind)
++ * - View state of running profile runs.
++ *
++ */
++
++#include "dumpselection.h"
++
++/*
++ * TODO:
++ * - Everything !!
++ * - Request State info on current function..
++ *
++ */
++
++
++DumpSelection::DumpSelection( TopLevel* top,
++ TQWidget* parent, const char* name)
++ : DumpSelectionBase(parent, name), TraceItemView(0, top)
++{
++}
++
++DumpSelection::~DumpSelection()
++{}
++
++
++#include "dumpselection.moc"
++
+diff --git a/kdecachegrind/kdecachegrind/dumpselection.h b/kdecachegrind/kdecachegrind/dumpselection.h
+new file mode 100644
+index 0000000..49ca532
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/dumpselection.h
+@@ -0,0 +1,30 @@
++/**
++ * DumpSelection Dockable
++ * Part of KCachegrind
++ * 2003, Josef Weidendorfer (GPL V2)
++ *
++ * - Fast Selection of dumps to load/activate/use for comparing
++ * - Start a profile run from GUI (current supported: Callgrind)
++ * - View state of running profile runs.
++ *
++ */
++
++#ifndef DUMPSELECTION_H
++#define DUMPSELECTION_H
++
++#include "dumpselectionbase.h"
++#include "traceitemview.h"
++
++class DumpSelection : public DumpSelectionBase, public TraceItemView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ DumpSelection( TopLevel*, TQWidget* parent = 0, const char* name = 0);
++ virtual ~DumpSelection();
++
++ TQWidget* widget() { return this; }
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/dumpselectionbase.ui b/kdecachegrind/kdecachegrind/dumpselectionbase.ui
+new file mode 100644
+index 0000000..b8ad1b0
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/dumpselectionbase.ui
+@@ -0,0 +1,1082 @@
++<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
++<class>DumpSelectionBase</class>
++<widget class="TQWidget">
++ <property name="name">
++ <cstring>DumpSelectionBase</cstring>
++ </property>
++ <property name="geometry">
++ <rect>
++ <x>0</x>
++ <y>0</y>
++ <width>349</width>
++ <height>832</height>
++ </rect>
++ </property>
++ <property name="caption">
++ <string>Profile Dumps</string>
++ </property>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQSplitter">
++ <property name="name">
++ <cstring>splitter1</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Vertical</enum>
++ </property>
++ <widget class="TQListView">
++ <column>
++ <property name="text">
++ <string>Target</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Time</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Path</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <property name="name">
++ <cstring>listView1</cstring>
++ </property>
++ </widget>
++ <widget class="TQTabWidget">
++ <property name="name">
++ <cstring>tabWidget2</cstring>
++ </property>
++ <widget class="TQWidget">
++ <property name="name">
++ <cstring>tab</cstring>
++ </property>
++ <attribute name="title">
++ <string>Options</string>
++ </attribute>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>textLabel1</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>5</hsizetype>
++ <vsizetype>5</vsizetype>
++ <horstretch>1</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ <property name="text">
++ <string>Target command:</string>
++ </property>
++ </widget>
++ <widget class="TQLineEdit">
++ <property name="name">
++ <cstring>lineEdit1</cstring>
++ </property>
++ </widget>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>textLabel2</cstring>
++ </property>
++ <property name="text">
++ <string>Profiler options:</string>
++ </property>
++ </widget>
++ <widget class="TQListView">
++ <column>
++ <property name="text">
++ <string>Option</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Value</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <item>
++ <property name="text">
++ <string>Trace</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>Jumps</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Instructions</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <item>
++ <property name="text">
++ <string>Events</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>Full Cache</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Custom</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <item>
++ <property name="text">
++ <string>Collect</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>At Startup</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>While In</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <item>
++ <property name="text">
++ <string>Skip</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>PLT</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Function</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <item>
++ <property name="text">
++ <string>Dump Profile</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>Every BBs</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>On Entering</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>On Leaving</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <item>
++ <property name="text">
++ <string>Zero Events</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>On Entering</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <item>
++ <property name="text">
++ <string>Separate</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>Threads</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Recursions</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Call Chain</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <property name="name">
++ <cstring>listView3</cstring>
++ </property>
++ </widget>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>textLabel1_2</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>5</hsizetype>
++ <vsizetype>5</vsizetype>
++ <horstretch>1</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ <property name="text">
++ <string>Custom profiler options:</string>
++ </property>
++ </widget>
++ <widget class="TQLineEdit">
++ <property name="name">
++ <cstring>lineEdit1_2</cstring>
++ </property>
++ </widget>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout3</cstring>
++ </property>
++ <hbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <spacer>
++ <property name="name">
++ <cstring>spacer1</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Horizontal</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Expanding</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>21</width>
++ <height>20</height>
++ </size>
++ </property>
++ </spacer>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>pushButton2</cstring>
++ </property>
++ <property name="text">
++ <string>Run New Profile</string>
++ </property>
++ </widget>
++ </hbox>
++ </widget>
++ </vbox>
++ </widget>
++ <widget class="TQWidget">
++ <property name="name">
++ <cstring>tab</cstring>
++ </property>
++ <attribute name="title">
++ <string>Info</string>
++ </attribute>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>textLabel8</cstring>
++ </property>
++ <property name="text">
++ <string>Dump reason:</string>
++ </property>
++ </widget>
++ <widget class="TQLineEdit">
++ <property name="name">
++ <cstring>lineEdit3</cstring>
++ </property>
++ </widget>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>textLabel6</cstring>
++ </property>
++ <property name="text">
++ <string>Event summary:</string>
++ </property>
++ </widget>
++ <widget class="TQListView">
++ <column>
++ <property name="text">
++ <string>Name</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Sum</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <property name="name">
++ <cstring>listView4</cstring>
++ </property>
++ </widget>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>textLabel7</cstring>
++ </property>
++ <property name="text">
++ <string>Miscellaneous:</string>
++ </property>
++ </widget>
++ <widget class="TQTextEdit">
++ <property name="name">
++ <cstring>textEdit2</cstring>
++ </property>
++ </widget>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout7</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>50</width>
++ <height>20</height>
++ </size>
++ </property>
++ </spacer>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>pushButton6</cstring>
++ </property>
++ <property name="text">
++ <string>Show</string>
++ </property>
++ </widget>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>pushButton5</cstring>
++ </property>
++ <property name="text">
++ <string>Compare</string>
++ </property>
++ </widget>
++ </hbox>
++ </widget>
++ </vbox>
++ </widget>
++ <widget class="TQWidget">
++ <property name="name">
++ <cstring>tab</cstring>
++ </property>
++ <attribute name="title">
++ <string>State</string>
++ </attribute>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout2</cstring>
++ </property>
++ <hbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>pushButton1</cstring>
++ </property>
++ <property name="text">
++ <string>Update</string>
++ </property>
++ </widget>
++ <widget class="TQCheckBox">
++ <property name="name">
++ <cstring>checkBox1</cstring>
++ </property>
++ <property name="text">
++ <string>Every [s]:</string>
++ </property>
++ </widget>
++ <widget class="TQLineEdit">
++ <property name="name">
++ <cstring>lineEdit3_2</cstring>
++ </property>
++ </widget>
++ </hbox>
++ </widget>
++ <widget class="TQListView">
++ <column>
++ <property name="text">
++ <string>Counter</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Value</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <item>
++ <property name="text">
++ <string>Dumps Done</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Is Collecting</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Executed</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>Basic Blocks</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Calls</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Jumps</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <item>
++ <property name="text">
++ <string>Events</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>Ir</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <item>
++ <property name="text">
++ <string>Distinct</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <item>
++ <property name="text">
++ <string>ELF Objects</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Functions</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ <item>
++ <property name="text">
++ <string>Contexts</string>
++ </property>
++ <property name="text">
++ <string></string>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ <property name="pixmap">
++ <pixmap></pixmap>
++ </property>
++ </item>
++ </item>
++ <property name="name">
++ <cstring>listView4_3</cstring>
++ </property>
++ </widget>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout4</cstring>
++ </property>
++ <hbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>textLabel4</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>5</hsizetype>
++ <vsizetype>5</vsizetype>
++ <horstretch>1</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ <property name="text">
++ <string>Stack trace:</string>
++ </property>
++ </widget>
++ <widget class="TQCheckBox">
++ <property name="name">
++ <cstring>checkBox2</cstring>
++ </property>
++ <property name="text">
++ <string>Sync.</string>
++ </property>
++ </widget>
++ </hbox>
++ </widget>
++ <widget class="TQListView">
++ <column>
++ <property name="text">
++ <string>#</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Incl.</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Called</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Function</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Location</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <property name="name">
++ <cstring>listView7</cstring>
++ </property>
++ </widget>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout6</cstring>
++ </property>
++ <hbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>pushButton7</cstring>
++ </property>
++ <property name="text">
++ <string>Start</string>
++ </property>
++ </widget>
++ <spacer>
++ <property name="name">
++ <cstring>spacer2</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Horizontal</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Expanding</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>20</width>
++ <height>20</height>
++ </size>
++ </property>
++ </spacer>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>pushButton6_2</cstring>
++ </property>
++ <property name="text">
++ <string>Zero</string>
++ </property>
++ </widget>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>pushButton4</cstring>
++ </property>
++ <property name="text">
++ <string>Dump</string>
++ </property>
++ </widget>
++ </hbox>
++ </widget>
++ </vbox>
++ </widget>
++ <widget class="TQWidget">
++ <property name="name">
++ <cstring>tab</cstring>
++ </property>
++ <attribute name="title">
++ <string>Messages</string>
++ </attribute>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQTextEdit">
++ <property name="name">
++ <cstring>textEdit2_2</cstring>
++ </property>
++ </widget>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout6</cstring>
++ </property>
++ <hbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>pushButton9</cstring>
++ </property>
++ <property name="text">
++ <string>Kill Run</string>
++ </property>
++ </widget>
++ <spacer>
++ <property name="name">
++ <cstring>spacer4</cstring>
++ </property>
++ <property name="orientation">
++ <enum>Horizontal</enum>
++ </property>
++ <property name="sizeType">
++ <enum>Expanding</enum>
++ </property>
++ <property name="sizeHint">
++ <size>
++ <width>21</width>
++ <height>20</height>
++ </size>
++ </property>
++ </spacer>
++ <widget class="TQPushButton">
++ <property name="name">
++ <cstring>pushButton8</cstring>
++ </property>
++ <property name="text">
++ <string>Clear</string>
++ </property>
++ </widget>
++ </hbox>
++ </widget>
++ </vbox>
++ </widget>
++ </widget>
++ </widget>
++ </vbox>
++</widget>
++<layoutdefaults spacing="6" margin="11"/>
++</UI>
+diff --git a/kdecachegrind/kdecachegrind/fixcost.cpp b/kdecachegrind/kdecachegrind/fixcost.cpp
+new file mode 100644
+index 0000000..4102926
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/fixcost.cpp
+@@ -0,0 +1,174 @@
++/*
++ * Part of KCacheGrind
++ *
++ * 2003, Josef Weidendorfer
++ */
++
++#include "fixcost.h"
++#include "utils.h"
++
++
++// FixCost
++
++FixCost::FixCost(TracePart* part, FixPool* pool,
++ TraceFunctionSource* functionSource,
++ PositionSpec& pos,
++ TracePartFunction* partFunction,
++ FixString& s)
++{
++ int maxCount = part->fixSubMapping()->count();
++
++ _part = part;
++ _functionSource = functionSource;
++ _pos = pos;
++
++ _cost = (SubCost*) pool->reserve(sizeof(SubCost) * maxCount);
++ s.stripSpaces();
++ int i = 0;
++ while(i<maxCount) {
++ if (!s.stripUInt64(_cost[i])) break;
++ i++;
++ }
++ _count = i;
++
++ if (!pool->allocateReserved(sizeof(SubCost) * _count))
++ _count = 0;
++
++ _nextCostOfPartFunction = partFunction ?
++ partFunction->setFirstFixCost(this) : 0;
++}
++
++void* FixCost::operator new(size_t size, FixPool* pool)
++{
++ return pool->allocate(size);
++}
++
++void FixCost::addTo(TraceCost* c)
++{
++ TraceSubMapping* sm = _part->fixSubMapping();
++
++ int i, realIndex;
++
++ for(i=0; i<_count; i++) {
++ realIndex = sm->realIndex(i);
++ c->addCost(realIndex, _cost[i]);
++ }
++}
++
++
++
++// FixCallCost
++
++FixCallCost::FixCallCost(TracePart* part, FixPool* pool,
++ TraceFunctionSource* functionSource,
++ unsigned int line, Addr addr,
++ TracePartCall* partCall,
++ SubCost callCount, FixString& s)
++{
++ if (0) qDebug("Got FixCallCost (addr 0x%s, line %d): calls %s",
++ addr.toString().ascii(), line,
++ callCount.pretty().ascii());
++
++ int maxCount = part->fixSubMapping()->count();
++
++ _part = part;
++ _functionSource = functionSource;
++ _line = line;
++ _addr = addr;
++
++ _cost = (SubCost*) pool->reserve(sizeof(SubCost) * (maxCount+1));
++ s.stripSpaces();
++ int i = 0;
++ while(i<maxCount) {
++ if (!s.stripUInt64(_cost[i])) break;
++ i++;
++ }
++ _count = i;
++
++ if (!pool->allocateReserved(sizeof(SubCost) * (_count+1) ))
++ _count = 0;
++ else
++ _cost[_count] = callCount;
++
++ _nextCostOfPartCall = partCall ? partCall->setFirstFixCallCost(this) : 0;
++}
++
++void* FixCallCost::operator new(size_t size, FixPool* pool)
++{
++ return pool->allocate(size);
++}
++
++void FixCallCost::addTo(TraceCallCost* c)
++{
++ TraceSubMapping* sm = _part->fixSubMapping();
++
++ int i, realIndex;
++
++ for(i=0; i<_count; i++) {
++ realIndex = sm->realIndex(i);
++ c->addCost(realIndex, _cost[i]);
++ }
++ c->addCallCount(_cost[_count]);
++
++ if (0) qDebug("Adding from (addr 0x%s, ln %d): calls %s",
++ _addr.toString().ascii(), _line,
++ _cost[_count].pretty().ascii());
++}
++
++void FixCallCost::setMax(TraceCost* c)
++{
++ TraceSubMapping* sm = _part->fixSubMapping();
++
++ int i, realIndex;
++
++ for(i=0; i<_count; i++) {
++ realIndex = sm->realIndex(i);
++ c->maxCost(realIndex, _cost[i]);
++ }
++}
++
++
++// FixJump
++
++FixJump::FixJump(TracePart* part, FixPool* pool,
++ unsigned int line, Addr addr,
++ TracePartFunction* partFunction,
++ TraceFunctionSource* source,
++ unsigned int targetLine, Addr targetAddr,
++ TraceFunction* targetFunction,
++ TraceFunctionSource* targetSource,
++ bool isCondJump,
++ SubCost executed, SubCost followed)
++{
++ _part = part;
++ _source = source;
++ _line = line;
++ _addr = addr;
++
++ _targetFunction = targetFunction;
++ _targetSource = targetSource;
++ _targetLine = targetLine;
++ _targetAddr = targetAddr;
++
++ _isCondJump = isCondJump;
++
++ int size = (isCondJump ? 2 : 1) * sizeof(SubCost);
++ _cost = (SubCost*) pool->allocate(size);
++ _cost[0] = executed;
++ if (isCondJump) _cost[1] = followed;
++
++ _nextJumpOfPartFunction = partFunction ?
++ partFunction->setFirstFixJump(this) : 0;
++}
++
++void* FixJump::operator new(size_t size, FixPool* pool)
++{
++ return pool->allocate(size);
++}
++
++void FixJump::addTo(TraceJumpCost* jc)
++{
++ jc->addExecutedCount(_cost[0]);
++ if (_isCondJump)
++ jc->addFollowedCount(_cost[1]);
++}
+diff --git a/kdecachegrind/kdecachegrind/fixcost.h b/kdecachegrind/kdecachegrind/fixcost.h
+new file mode 100644
+index 0000000..7e90fb4
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/fixcost.h
+@@ -0,0 +1,171 @@
++/*
++ * Part of KCacheGrind
++ *
++ * 2003, Josef Weidendorfer
++ */
++
++#ifndef FIXCOST_H
++#define FIXCOST_H
++
++/**
++ * Setting USE_FIXCOST to 1 enables a memory space hack:
++ * For some data, build up internal data model lazy by using
++ * the Fix*Cost classes, which are simple copies from input data.
++ */
++#define USE_FIXCOST 1
++
++#include "tracedata.h"
++#include "pool.h"
++
++class PositionSpec
++{
++ public:
++ PositionSpec()
++ { fromLine = 0, toLine = 0, fromAddr = 0, toAddr = 0; }
++ PositionSpec(uint l1, uint l2, Addr a1, Addr a2)
++ { fromLine = l1, toLine = l2, fromAddr = a1, toAddr = a2; }
++
++ bool isLineRegion() const { return (fromLine != toLine); }
++ bool isAddrRegion() const { return (fromAddr != toAddr); }
++
++ uint fromLine, toLine;
++ Addr fromAddr, toAddr;
++};
++
++/**
++ * A class holding an unchangable cost item of an input file.
++ *
++ * As there can be a lot of such cost items, we use our own
++ * allocator which uses FixPool
++ */
++class FixCost
++{
++
++ public:
++ FixCost(TracePart*, FixPool*,
++ TraceFunctionSource*,
++ PositionSpec&,
++ TracePartFunction*,
++ FixString&);
++
++ void *operator new(size_t size, FixPool*);
++
++ void addTo(TraceCost*);
++
++ TracePart* part() const { return _part; }
++ bool isLineRegion() const { return _pos.isLineRegion(); }
++ bool isAddrRegion() const { return _pos.isAddrRegion(); }
++ uint fromLine() const { return _pos.fromLine; }
++ uint line() const { return _pos.fromLine; }
++ uint toLine() const { return _pos.toLine; }
++ Addr fromAddr() const { return _pos.fromAddr; }
++ Addr addr() const { return _pos.fromAddr; }
++ Addr toAddr() const { return _pos.toAddr; }
++ TraceFunctionSource* functionSource() const { return _functionSource; }
++
++ FixCost* nextCostOfPartFunction() const
++ { return _nextCostOfPartFunction; }
++
++ private:
++ int _count;
++ SubCost* _cost;
++ PositionSpec _pos;
++
++ TracePart* _part;
++ TraceFunctionSource* _functionSource;
++ FixCost *_nextCostOfPartFunction;
++};
++
++/**
++ * A FixCallCost will be inserted into a
++ * - TracePartCall to keep source/target function info
++ * - TraceFunctionSourceFile to keep file info of call source
++ */
++class FixCallCost
++{
++
++ public:
++ FixCallCost(TracePart*, FixPool*,
++ TraceFunctionSource*,
++ unsigned int line,
++ Addr addr,
++ TracePartCall*,
++ SubCost, FixString&);
++
++ void *operator new(size_t size, FixPool*);
++
++ void addTo(TraceCallCost*);
++ void setMax(TraceCost*);
++
++ TracePart* part() const { return _part; }
++ unsigned int line() const { return _line; }
++ Addr addr() const { return _addr; }
++ SubCost callCount() const { return _cost[_count]; }
++ TraceFunctionSource* functionSource() const { return _functionSource; }
++ FixCallCost* nextCostOfPartCall() const
++ { return _nextCostOfPartCall; }
++
++ private:
++ // we use 1 SubCost more than _count: _cost[_count] is the call count
++ int _count;
++ SubCost* _cost;
++ unsigned int _line;
++ Addr _addr;
++
++ TracePart* _part;
++ TraceFunctionSource* _functionSource;
++ FixCallCost* _nextCostOfPartCall;
++};
++
++/**
++ * A class holding a jump (mostly) inside of a function
++ */
++class FixJump
++{
++
++ public:
++ FixJump(TracePart*, FixPool*,
++ /* source position */
++ unsigned int line, Addr addr,
++ TracePartFunction*, TraceFunctionSource*,
++ /* target position */
++ unsigned int targetLine, Addr targetAddr,
++ TraceFunction*, TraceFunctionSource*,
++ bool isCondJump,
++ SubCost, SubCost);
++
++ void *operator new(size_t size, FixPool*);
++
++ void addTo(TraceJumpCost*);
++
++ TracePart* part() const { return _part; }
++ unsigned int line() const { return _line; }
++ Addr addr() const { return _addr; }
++ TraceFunctionSource* source() const { return _source; }
++ TraceFunction* targetFunction() const { return _targetFunction; }
++ unsigned int targetLine() const { return _targetLine; }
++ Addr targetAddr() const { return _targetAddr; }
++ TraceFunctionSource* targetSource() const { return _targetSource; }
++ bool isCondJump() { return _isCondJump; }
++ SubCost executedCount() const { return _cost[0]; }
++ SubCost followedCount() const
++ { return _isCondJump ? _cost[1] : SubCost(0); }
++
++ FixJump* nextJumpOfPartFunction() const
++ { return _nextJumpOfPartFunction; }
++
++ private:
++ bool _isCondJump;
++ SubCost* _cost;
++ unsigned int _line, _targetLine;
++ Addr _addr, _targetAddr;
++
++ TracePart* _part;
++ TraceFunctionSource *_source, *_targetSource;
++ TraceFunction* _targetFunction;
++ FixJump *_nextJumpOfPartFunction;
++};
++
++#endif
++
++
+diff --git a/kdecachegrind/kdecachegrind/functionitem.cpp b/kdecachegrind/kdecachegrind/functionitem.cpp
+new file mode 100644
+index 0000000..3b694dd
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/functionitem.cpp
+@@ -0,0 +1,236 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * List Item for the FunctionSelection list
++ */
++
++
++//#include <math.h>
++
++//#include <tqpainter.h>
++//#include <tqregexp.h>
++
++#include <klocale.h>
++#include <kiconloader.h>
++#include <kapplication.h>
++
++#include "listutils.h"
++#include "functionitem.h"
++#include "configuration.h"
++
++
++// FunctionItem
++
++FunctionItem::FunctionItem(TQListView* parent, TraceFunction* f,
++ TraceCostType* ct, TraceCost::CostType gt)
++ :TQListViewItem(parent)
++{
++#if 0
++ _costPixValid = false;
++ _groupPixValid = false;
++#endif
++
++ _function = f;
++ _skipped = 0;
++ _groupType = TraceCost::NoCostType;
++ setGroupType(gt);
++ setCostType(ct);
++
++ setText(3, f->prettyName());
++ setText(4, f->prettyLocation());
++}
++
++FunctionItem::FunctionItem(TQListView* parent, int skipped,
++ TraceFunction* f, TraceCostType* ct)
++ :TQListViewItem(parent)
++{
++#if 0
++ _costPixValid = false;
++ _groupPixValid = false;
++#endif
++ _skipped = skipped;
++ _function = f;
++ _groupType = TraceCost::NoCostType;
++ setCostType(ct);
++
++ setText(3, i18n("(%n function skipped)", "(%n functions skipped)", skipped));
++}
++
++#if 0
++const TQPixmap* FunctionItem::pixmap(int column) const
++{
++ if (column == 3) {
++ if (!_groupPixValid) {
++ TQColor c = Configuration::functionColor(_groupType, _function);
++ _groupPix = colorPixmap(10, 10, c);
++ _groupPixValid = true;
++ }
++ return &_groupPix;
++ }
++ if (column == 1) {
++ if (!_costPixValid) {
++ _costPix = colorPixmap(10, 10, c);
++ _costPixValid = true;
++ }
++ return &_costPix;
++ }
++ return 0;
++}
++#endif
++
++void FunctionItem::setGroupType(TraceCost::CostType gt)
++{
++ if (_skipped) return;
++ if (_groupType == gt) return;
++ _groupType = gt;
++
++
++#if 0
++ _groupPixValid = false;
++ viewList()->repaint();
++#else
++ TQColor c = Configuration::functionColor(_groupType, _function);
++ setPixmap(3, colorPixmap(10, 10, c));
++#endif
++}
++
++void FunctionItem::setCostType(TraceCostType* c)
++{
++ _costType = c;
++ update();
++}
++
++void FunctionItem::update()
++{
++ double inclTotal = _function->data()->subCost(_costType);
++ TQString str;
++
++ TraceCost* selfCost = _function->data();
++ if (Configuration::showExpanded()) {
++ switch(_groupType) {
++ case TraceCost::Object: selfCost = _function->object(); break;
++ case TraceCost::Class: selfCost = _function->cls(); break;
++ case TraceCost::File: selfCost = _function->file(); break;
++ default: break;
++ }
++ }
++ double selfTotal = selfCost->subCost(_costType);
++
++ if (_skipped) {
++ // special handling for skip entries...
++
++ // only text updates of incl./self
++
++ // for all skipped functions, cost is below the given function
++ _sum = _function->inclusive()->subCost(_costType);
++ double incl = 100.0 * _sum / inclTotal;
++ if (Configuration::showPercentage())
++ str = TQString("%1").arg(incl, 0, 'f', Configuration::percentPrecision());
++ else
++ str = _function->inclusive()->prettySubCost(_costType);
++ str = "< " + str;
++ setText(0, str);
++ setText(1, str);
++ return;
++ }
++
++ // Call count...
++ if (_function->calledCount() >0)
++ str = _function->prettyCalledCount();
++ else {
++ if (_function == _function->cycle())
++ str = TQString("-");
++ else
++ str = TQString("(0)");
++ }
++ setText(2, str);
++
++ // Incl. cost
++ _sum = _function->inclusive()->subCost(_costType);
++ if (inclTotal == 0.0) {
++ setPixmap(0, TQPixmap());
++ setText(0, "-");
++ }
++ else {
++ double incl = 100.0 * _sum / inclTotal;
++ if (Configuration::showPercentage())
++ setText(0, TQString("%1")
++ .arg(incl, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(0, _function->inclusive()->prettySubCost(_costType));
++
++ setPixmap(0, costPixmap(_costType, _function->inclusive(), inclTotal, false));
++ }
++
++ // self
++ _pure = _function->subCost(_costType);
++ if (selfTotal == 0.0) {
++ setPixmap(1, TQPixmap());
++ setText(1, "-");
++ }
++ else {
++ double self = 100.0 * _pure / selfTotal;
++
++ if (Configuration::showPercentage())
++ setText(1, TQString("%1")
++ .arg(self, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(1, _function->prettySubCost(_costType));
++
++ setPixmap(1, costPixmap(_costType, _function, selfTotal, false));
++ }
++}
++
++
++int FunctionItem::compare(TQListViewItem * i, int col, bool ascending ) const
++{
++ const FunctionItem* fi1 = this;
++ const FunctionItem* fi2 = (FunctionItem*) i;
++
++ // we always want descending order
++ if (ascending) {
++ fi1 = fi2;
++ fi2 = this;
++ }
++
++ // a skip entry is always sorted last
++ if (fi1->_skipped) return -1;
++ if (fi2->_skipped) return 1;
++
++ if (col==0) {
++ if (fi1->_sum < fi2->_sum) return -1;
++ if (fi1->_sum > fi2->_sum) return 1;
++ return 0;
++ }
++ if (col==1) {
++ if (fi1->_pure < fi2->_pure) return -1;
++ if (fi1->_pure > fi2->_pure) return 1;
++ return 0;
++ }
++ if (col==2) {
++ if (fi1->_function->calledCount() <
++ fi2->_function->calledCount()) return -1;
++ if (fi1->_function->calledCount() >
++ fi2->_function->calledCount()) return 1;
++ return 0;
++ }
++
++ return TQListViewItem::compare(i, col, ascending);
++}
++
+diff --git a/kdecachegrind/kdecachegrind/functionitem.h b/kdecachegrind/kdecachegrind/functionitem.h
+new file mode 100644
+index 0000000..d8f98f4
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/functionitem.h
+@@ -0,0 +1,58 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * List Item for the FunctionSelection list
++ */
++
++#ifndef FUNCTIONITEM_H
++#define FUNCTIONITEM_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++
++class FunctionItem: public TQListViewItem
++{
++public:
++ FunctionItem(TQListView* parent, TraceFunction* function,
++ TraceCostType* ct, TraceCost::CostType gt);
++ // constructor for a "Skipped ... " entry
++ FunctionItem(TQListView* parent, int skipped,
++ TraceFunction* function, TraceCostType* ct);
++
++ int compare(TQListViewItem * i, int col, bool ascending ) const;
++ TraceFunction* function() { return (_skipped) ? 0 : _function; }
++ void setCostType(TraceCostType* ct);
++ void setGroupType(TraceCost::CostType);
++ void update();
++
++#if 0
++ const TQPixmap* pixmap (int column) const;
++ bool _costPixValid, _groupPixValid;
++ TQPixMap _costPix, _groupPix;
++#endif
++
++private:
++ SubCost _sum, _pure;
++ TraceCostType* _costType;
++ TraceCost::CostType _groupType;
++ TraceFunction* _function;
++ int _skipped;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/functionselection.cpp b/kdecachegrind/kdecachegrind/functionselection.cpp
+new file mode 100644
+index 0000000..c5646dd
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/functionselection.cpp
+@@ -0,0 +1,871 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * For function selection, to be put into a TQDockWindow
++ */
++
++#include <tqtimer.h>
++#include <tqlistview.h>
++#include <tqlabel.h>
++#include <tqpushbutton.h>
++#include <tqcombobox.h>
++#include <tqlineedit.h>
++#include <tqregexp.h>
++#include <tqpopupmenu.h>
++
++#include <klocale.h>
++
++#include "traceitemview.h"
++#include "stackbrowser.h"
++#include "functionselection.h"
++#include "partgraph.h"
++#include "functionitem.h"
++#include "costlistitem.h"
++#include "configuration.h"
++#include "toplevel.h"
++
++FunctionSelection::FunctionSelection( TopLevel* top,
++ TQWidget* parent, const char* name)
++ : FunctionSelectionBase(parent, name), TraceItemView(0, top)
++{
++ _group = 0;
++ _inSetGroup = false;
++ _inSetFunction = false;
++
++ TQStringList args;
++ args << i18n("(No Grouping)")
++ << TraceCost::i18nTypeName(TraceItem::Object)
++ << TraceCost::i18nTypeName(TraceItem::File)
++ << TraceCost::i18nTypeName(TraceItem::Class)
++ << TraceCost::i18nTypeName(TraceItem::FunctionCycle);
++
++ groupBox->insertStringList(args);
++ // this needs same order of grouptype actionlist!
++ connect(groupBox, TQT_SIGNAL(activated(int)),
++ top, TQT_SLOT(groupTypeSelected(int)));
++
++ // search while typing...
++ connect(searchEdit, TQT_SIGNAL(textChanged(const TQString&)),
++ this, TQT_SLOT(searchChanged(const TQString&)));
++ connect(&_searchTimer, TQT_SIGNAL(timeout()),
++ this, TQT_SLOT(queryDelayed()));
++ // select first matching group/function on return
++ connect(searchEdit, TQT_SIGNAL(returnPressed()),
++ this, TQT_SLOT(searchReturnPressed()));
++ searchEdit->setMinimumWidth(50);
++
++ // we start with desending cost sorting
++ functionList->setSorting(0,false);
++ functionList->setColumnAlignment(0, TQt::AlignRight);
++ functionList->setColumnAlignment(1, TQt::AlignRight);
++ functionList->setColumnAlignment(2, TQt::AlignRight);
++ functionList->setAllColumnsShowFocus(true);
++ // functionList->setShowSortIndicator(true);
++ // we can have very long function and location names
++ functionList->setColumnWidthMode(3, TQListView::Manual);
++ functionList->setColumnWidth(3, 200);
++ functionList->setColumnWidthMode(4, TQListView::Manual);
++ functionList->setColumnWidth(4, 200);
++
++ groupList->setSorting(0,false);
++ groupList->setColumnAlignment(0, TQt::AlignRight);
++ groupList->setAllColumnsShowFocus(true);
++ // groupList->setShowSortIndicator(true);
++ groupList->setResizeMode(TQListView::LastColumn);
++
++#if 0
++ // single click press activation
++ connect(functionList, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
++ this, TQT_SLOT(functionActivated(TQListViewItem*)));
++ connect(functionList,
++ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
++ this, TQT_SLOT(functionContext(TQListViewItem*, const TQPoint &, int)));
++#else
++ // single click release activation
++ connect(functionList, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
++ this, TQT_SLOT(functionSelected(TQListViewItem*)));
++ connect(functionList, TQT_SIGNAL(clicked(TQListViewItem*)),
++ this, TQT_SLOT(functionActivated(TQListViewItem*)));
++ connect(functionList, TQT_SIGNAL(returnPressed(TQListViewItem*)),
++ this, TQT_SLOT(functionActivated(TQListViewItem*)));
++ connect(functionList,
++ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
++ this, TQT_SLOT(functionContext(TQListViewItem*, const TQPoint &, int)));
++#endif
++
++ connect(groupList, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
++ this, TQT_SLOT(groupSelected(TQListViewItem*)));
++ connect(groupList, TQT_SIGNAL(doubleClicked(TQListViewItem*)),
++ this, TQT_SLOT(groupDoubleClicked(TQListViewItem*)));
++ connect(groupList, TQT_SIGNAL(returnPressed(TQListViewItem*)),
++ this, TQT_SLOT(groupDoubleClicked(TQListViewItem*)));
++ connect(groupList,
++ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
++ this, TQT_SLOT(groupContext(TQListViewItem*, const TQPoint &, int)));
++
++ // start hidden
++ groupList->hide();
++}
++
++FunctionSelection::~FunctionSelection()
++{
++}
++
++void FunctionSelection::searchReturnPressed()
++{
++ query(searchEdit->text());
++
++ TQListViewItem* item;
++ if (_groupType != TraceItem::Function) {
++ // if current group not matching, select first matching group
++ item = groupList->currentItem();
++ if (!item || !item->isVisible()) {
++ item = groupList->firstChild();
++ for (;item;item = item->nextSibling())
++ if (item->isVisible()) break;
++ if (!item) return;
++
++ setGroup(((CostListItem*)item)->costItem());
++ return;
++ }
++ }
++
++ functionActivated(functionList->firstChild());
++}
++
++// trigger the query after some delay, dependent on length
++void FunctionSelection::searchChanged(const TQString& q)
++{
++ _searchDelayed = q;
++ int ms = 100;
++ if (q.length()<5) ms = 200;
++ if (q.length()<2) ms = 300;
++ _searchTimer.start(ms,true);
++}
++
++void FunctionSelection::queryDelayed()
++{
++ query(_searchDelayed);
++}
++
++void FunctionSelection::functionContext(TQListViewItem* i,
++ const TQPoint & p, int c)
++{
++ TQPopupMenu popup;
++ TraceFunction* f = 0;
++
++ if (i) {
++ f = ((FunctionItem*) i)->function();
++ if (f) {
++ popup.insertItem(i18n("Go to %1").arg(f->prettyName()), 93);
++ popup.insertSeparator();
++ }
++ }
++
++ if ((c == 0) || (c == 1)) {
++ addCostMenu(&popup,false);
++ popup.insertSeparator();
++ }
++ addGroupMenu(&popup);
++ popup.insertSeparator();
++ addGoMenu(&popup);
++
++ int r = popup.exec(p);
++ if (r == 93) activated(f);
++}
++
++void FunctionSelection::groupContext(TQListViewItem* /*i*/,
++ const TQPoint & p, int c)
++{
++ TQPopupMenu popup;
++
++#if 0
++ TraceCostItem* g = 0;
++ if (i) {
++ g = ((CostListItem*) i)->costItem();
++ if (!g) {
++ popup.insertItem(i18n("Show All Items"), 93);
++ popup.insertSeparator();
++ }
++ }
++#endif
++ if (c == 0) {
++ addCostMenu(&popup,false);
++ popup.insertSeparator();
++ }
++ addGroupMenu(&popup);
++ popup.insertSeparator();
++ addGoMenu(&popup);
++
++ popup.exec(p);
++}
++
++
++void FunctionSelection::addGroupMenu(TQPopupMenu* popup)
++{
++ TQPopupMenu *popup1 = new TQPopupMenu(popup);
++ popup1->setCheckable(true);
++
++ if (_groupType != TraceItem::Function) {
++ popup1->insertItem(i18n("No Grouping"),0);
++ popup1->insertSeparator();
++ }
++ popup1->insertItem(TraceCost::i18nTypeName(TraceItem::Object),1);
++ popup1->insertItem(TraceCost::i18nTypeName(TraceItem::File),2);
++ popup1->insertItem(TraceCost::i18nTypeName(TraceItem::Class),3);
++ popup1->insertItem(TraceCost::i18nTypeName(TraceItem::FunctionCycle),4);
++ switch(_groupType) {
++ case TraceItem::Object: popup1->setItemChecked(1, true); break;
++ case TraceItem::File: popup1->setItemChecked(2, true); break;
++ case TraceItem::Class: popup1->setItemChecked(3, true); break;
++ case TraceItem::FunctionCycle: popup1->setItemChecked(4, true); break;
++ default: break;
++ }
++ connect(popup1,TQT_SIGNAL(activated(int)),
++ _topLevel,TQT_SLOT(groupTypeSelected(int)));
++
++ popup->insertItem(i18n("Grouping"), popup1);
++}
++
++
++TraceItem* FunctionSelection::canShow(TraceItem* i)
++{
++ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType;
++
++ switch(t) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ case TraceItem::Object:
++ case TraceItem::File:
++ case TraceItem::Class:
++ break;
++
++ case TraceItem::Instr:
++ i = ((TraceInstr*)i)->function();
++ break;
++
++ case TraceItem::Line:
++ i = ((TraceLine*)i)->functionSource()->function();
++ break;
++
++ default:
++ i = 0;
++ break;
++ }
++ return i;
++}
++
++
++void FunctionSelection::doUpdate(int changeType)
++{
++ // Special case ?
++ if (changeType == selectedItemChanged) return;
++
++ // we don't show cost 2 at all...
++ if (changeType == costType2Changed) return;
++
++ if (changeType == activeItemChanged) {
++ if (_activeItem ==0) {
++ functionList->clearSelection();
++ return;
++ }
++ switch(_activeItem->type()) {
++ case TraceItem::Object:
++ case TraceItem::File:
++ case TraceItem::Class:
++ setGroup((TraceCostItem*)_activeItem);
++ return;
++ default: break;
++ }
++
++ // active item is a function
++ TraceFunction* f = (TraceFunction*) _activeItem;
++
++ // if already current, nothing to do
++ TQListViewItem* i = functionList->currentItem();
++ if (i && (((FunctionItem*)i)->function() == f)) {
++ functionList->setSelected(i,true);
++ return;
++ }
++
++ // reset searchEdit (as not activated from this view)
++ _searchString = TQString();
++ query(TQString());
++
++ // select cost item group of function
++ switch(_groupType) {
++ case TraceItem::Object: setGroup(f->object()); break;
++ case TraceItem::Class: setGroup(f->cls()); break;
++ case TraceItem::File: setGroup(f->file()); break;
++ case TraceItem::FunctionCycle: setGroup(f->cycle()); break;
++ default:
++ break;
++ }
++
++ TQListViewItem* item = functionList->firstChild();
++ for (;item;item = item->nextSibling())
++ if (((FunctionItem*)item)->function() == f)
++ break;
++
++ if (!item)
++ item = new FunctionItem(functionList, f, _costType, _groupType);
++
++ functionList->ensureItemVisible(item);
++ // prohibit signalling of a function selection
++ _inSetFunction = true;
++ functionList->setSelected(item, true);
++ _inSetFunction = false;
++
++ return;
++ }
++
++ if (changeType & groupTypeChanged) {
++ if (_activeItem && (_activeItem->type() == TraceItem::Function)) {
++ TraceFunction* f = (TraceFunction*) _activeItem;
++
++ // select cost item group of function
++ switch(_groupType) {
++ case TraceItem::Object: _group = f->object(); break;
++ case TraceItem::Class: _group = f->cls(); break;
++ case TraceItem::File: _group = f->file(); break;
++ case TraceItem::FunctionCycle: _group = f->cycle(); break;
++ default:
++ _group = 0;
++ break;
++ }
++ }
++
++ int id;
++ switch(_groupType) {
++ case TraceItem::Object: id = 1; break;
++ case TraceItem::File: id = 2; break;
++ case TraceItem::Class: id = 3; break;
++ case TraceItem::FunctionCycle: id = 4; break;
++ default: id = 0; break;
++ }
++ groupBox->setCurrentItem(id);
++
++ if (_groupType == TraceItem::Function)
++ groupList->hide();
++ else
++ groupList->show();
++ }
++
++ // reset searchEdit
++ _searchString = TQString();
++ query(TQString());
++
++ refresh();
++}
++
++
++/*
++ * This set/selects a group of the set available within the
++ * current group type
++ */
++void FunctionSelection::setGroup(TraceCostItem* g)
++{
++ if (!g) return;
++ if (g->type() != _groupType) return;
++ if (g == _group) return;
++ _group = g;
++
++ TQListViewItem* item = groupList->firstChild();
++ for (;item;item = item->nextSibling())
++ if (((CostListItem*)item)->costItem() == g)
++ break;
++
++ if (item) {
++ groupList->ensureItemVisible(item);
++ // prohibit signalling of a group selection
++ _inSetGroup = true;
++ groupList->setSelected(item, true);
++ _inSetGroup = false;
++ }
++ else
++ groupList->clearSelection();
++}
++
++
++void FunctionSelection::refresh()
++{
++ groupList->setUpdatesEnabled(false);
++ groupList->clear();
++
++ // make cost columns as small as possible:
++ // the new functions make them as wide as needed
++ groupList->setColumnWidth(0, 50);
++
++ groupList->setColumnText(1, TraceItem::i18nTypeName(_groupType));
++
++ if (!_data || _data->parts().count()==0) {
++ functionList->clear();
++ groupList->setUpdatesEnabled(true);
++ groupList->repaint();
++
++ // this clears all other lists
++ functionList->setSelected(functionList->firstChild(), true);
++ return;
++ }
++
++ /*
++ qDebug("FunctionSelection::fillLists (%s)",
++ _data->command().ascii());
++ */
++
++ TraceObjectMap::Iterator oit;
++ TraceClassMap::Iterator cit;
++ TraceFileMap::Iterator fit;
++ TQListViewItem *i = 0, *item = 0, *fitem = 0;
++
++ // Fill up group list.
++ // Always show group of current function, even if cost below low limit.
++ //
++
++ _hc.clear(Configuration::maxListCount());
++
++ TraceCostItem *group;
++
++ // update group from _activeItem if possible
++ if (_activeItem && (_activeItem->type() == _groupType))
++ _group = (TraceCostItem*) _activeItem;
++
++ switch(_groupType) {
++ case TraceItem::Object:
++
++ for ( oit = _data->objectMap().begin();
++ oit != _data->objectMap().end(); ++oit )
++ _hc.addCost(&(*oit), (*oit).subCost(_costType));
++ break;
++
++ case TraceItem::Class:
++
++ for ( cit = _data->classMap().begin();
++ cit != _data->classMap().end(); ++cit )
++ _hc.addCost(&(*cit), (*cit).subCost(_costType));
++ break;
++
++ case TraceItem::File:
++
++ for ( fit = _data->fileMap().begin();
++ fit != _data->fileMap().end(); ++fit )
++ _hc.addCost(&(*fit), (*fit).subCost(_costType));
++ break;
++
++ case TraceItem::FunctionCycle:
++ {
++ // add all cycles
++ TraceFunctionCycleList l = _data->functionCycles();
++ for (group=l.first();group;group=l.next())
++ _hc.addCost(group, group->subCost(_costType));
++ }
++
++ break;
++
++ default:
++ {
++ TQListViewItem* oldItem = functionList->selectedItem();
++ TraceFunction* oldFunction = 0;
++ int oldPos = 0;
++ if (oldItem) {
++ oldFunction = ((FunctionItem*)oldItem)->function();
++ oldPos = oldItem->itemPos();
++ oldPos -= functionList->contentsY();
++ if (oldPos < 0 || oldPos > functionList->height())
++ oldFunction = 0;
++ }
++
++ // switching off TQListView updates is buggy with some QT versions...
++ //functionList->setUpdatesEnabled(false);
++ functionList->clear();
++ setCostColumnWidths();
++
++ if (0) qDebug("Function %s at %d, Item %p",
++ oldFunction ? oldFunction->name().ascii() : "-",
++ oldPos, (void*)oldItem);
++
++ TraceFunctionMap::Iterator it;
++ TraceFunction *f;
++ i = 0;
++ fitem = 0;
++ for ( it = _data->functionMap().begin();
++ it != _data->functionMap().end(); ++it )
++ _hc.addCost(&(*it), (*it).inclusive()->subCost(_costType));
++
++ TraceFunctionCycleList l = _data->functionCycles();
++ for (f=l.first();f;f=l.next())
++ _hc.addCost(f, f->inclusive()->subCost(_costType));
++
++ if (_activeItem &&
++ ((_activeItem->type() == TraceItem::Function) ||
++ (_activeItem->type() == TraceItem::FunctionCycle)))
++ fitem = new FunctionItem(functionList, (TraceFunction*)_activeItem,
++ _costType, _groupType);
++
++ for(int i=0;i<_hc.realCount();i++) {
++ f = (TraceFunction*)_hc[i];
++ if (f == _activeItem) continue;
++ new FunctionItem(functionList, f, _costType, _groupType);
++ }
++ if (_hc.hasMore()) {
++ // a placeholder for all the cost items skipped ...
++ new FunctionItem(functionList, _hc.count() - _hc.maxSize(),
++ (TraceFunction*)_hc[_hc.maxSize()-1], _costType);
++ }
++ functionList->sort();
++
++ if (fitem && oldFunction) {
++ _inSetFunction = true;
++ functionList->setSelected(fitem, true);
++ _inSetFunction = false;
++ int newPos = functionList->itemPos(fitem) - functionList->contentsY();
++ functionList->scrollBy(0, newPos-oldPos);
++ }
++ else if (fitem) {
++ functionList->ensureItemVisible(fitem);
++ _inSetFunction = true;
++ functionList->setSelected(fitem, true);
++ _inSetFunction = false;
++ }
++ else
++ functionList->clearSelection();
++
++ //functionList->setUpdatesEnabled(true);
++ //functionList->repaint();
++ groupList->setUpdatesEnabled(true);
++ groupList->repaint();
++ return;
++ }
++ }
++
++ // we always put group of active item in list, even if
++ // it would be skipped because of small costs
++ if (_group)
++ item = new CostListItem(groupList, _group, _costType);
++
++ for(int i=0;i<_hc.realCount();i++) {
++ group = (TraceCostItem*)_hc[i];
++ // don't put group of active item twice into list
++ if (group == _group) continue;
++ new CostListItem(groupList, group, _costType);
++ }
++ if (_hc.hasMore()) {
++ // a placeholder for all the cost items skipped ...
++ new CostListItem(groupList, _hc.count() - _hc.maxSize(),
++ (TraceCostItem*)_hc[_hc.maxSize()-1], _costType);
++ }
++ groupList->sort();
++ if (item) {
++ groupList->ensureItemVisible(item);
++ _inSetGroup = true;
++ groupList->setSelected(item, true);
++ _inSetGroup = false;
++ }
++ else
++ groupList->clearSelection();
++
++ groupList->setUpdatesEnabled(true);
++ groupList->repaint();
++}
++
++
++void FunctionSelection::groupSelected(TQListViewItem* i)
++{
++ if (!i) return;
++ if (!_data) return;
++
++ TraceCostItem* g = ((CostListItem*) i)->costItem();
++ if (!g) return;
++
++ _group = g;
++
++ TraceFunctionList list;
++
++ switch(g->type()) {
++ case TraceItem::Object:
++ list = ((TraceObject*)g)->functions();
++ break;
++ case TraceItem::Class:
++ list = ((TraceClass*)g)->functions();
++ break;
++ case TraceItem::File:
++ list = ((TraceFile*)g)->functions();
++ break;
++ case TraceItem::FunctionCycle:
++ list = ((TraceFunctionCycle*)g)->members();
++ break;
++ default:
++ return;
++ }
++
++ // switching off TQListView updates is buggy with some QT versions...
++ //functionList->setUpdatesEnabled(false);
++
++ functionList->clear();
++ setCostColumnWidths();
++
++ double total;
++ if (Configuration::showExpanded())
++ total = (double) g->subCost(_costType);
++ else
++ total = (double) _data->subCost(_costType);
++#if 0
++ if (total == 0.0) {
++ functionList->setUpdatesEnabled(true);
++ functionList->repaint();
++ return;
++ }
++#endif
++
++ TQRegExp re(_searchString, false, true);
++
++ FunctionItem* fitem = 0;
++ TraceFunction *f;
++ _hc.clear(Configuration::maxListCount());
++ for (f=list.first();f;f=list.next()) {
++ if (re.search(f->prettyName())<0) continue;
++
++ _hc.addCost(f, f->inclusive()->subCost(_costType));
++ if (_activeItem == f)
++ fitem = new FunctionItem(functionList, (TraceFunction*)_activeItem,
++ _costType, _groupType);
++ }
++
++ for(int i=0;i<_hc.realCount();i++) {
++ if (_activeItem == (TraceFunction*)_hc[i]) continue;
++ new FunctionItem(functionList, (TraceFunction*)_hc[i],
++ _costType, _groupType);
++ }
++
++ if (_hc.hasMore()) {
++ // a placeholder for all the functions skipped ...
++ new FunctionItem(functionList, _hc.count() - _hc.maxSize(),
++ (TraceFunction*)_hc[_hc.maxSize()-1], _costType);
++ }
++ functionList->sort();
++
++ if (fitem) {
++ functionList->ensureItemVisible(fitem);
++ _inSetFunction = true;
++ functionList->setSelected(fitem, true);
++ _inSetFunction = false;
++ }
++
++ //functionList->setUpdatesEnabled(true);
++ //functionList->repaint();
++
++ // Don't emit signal if cost item was changed programatically
++ if (!_inSetGroup) {
++ _selectedItem = g;
++ selected(g);
++ }
++}
++
++void FunctionSelection::groupDoubleClicked(TQListViewItem* i)
++{
++ if (!i) return;
++ if (!_data) return;
++ TraceCostItem* g = ((CostListItem*) i)->costItem();
++
++ if (!g) return;
++ // group must be selected first
++ if (g != _group) return;
++
++ activated(g);
++}
++
++
++TraceCostItem* FunctionSelection::group(TQString s)
++{
++ TQListViewItem *item;
++ item = groupList->firstChild();
++ for(;item;item = item->nextSibling())
++ if (((CostListItem*)item)->costItem()->name() == s)
++ return ((CostListItem*)item)->costItem();
++
++ return 0;
++}
++
++
++
++void FunctionSelection::functionSelected(TQListViewItem* i)
++{
++ if (!i) return;
++ if (!_data) return;
++
++ TraceFunction* f = ((FunctionItem*) i)->function();
++ if (!f) return;
++
++ //qDebug("FunctionSelection::functionSelected %s", f->name().ascii());
++
++ // Don't emit signal if function was changed programatically
++ if (!_inSetFunction) {
++ _selectedItem = f;
++ selected(f);
++ }
++}
++
++void FunctionSelection::functionActivated(TQListViewItem* i)
++{
++ if (!i) return;
++ if (!_data) return;
++ TraceFunction* f = ((FunctionItem*) i)->function();
++
++ if (!f) return;
++
++ if (!_inSetFunction)
++ activated(f);
++}
++
++void FunctionSelection::updateGroupSizes(bool hideEmpty)
++{
++ TQListViewItem* item = groupList->firstChild();
++ for (;item;item = item->nextSibling()) {
++ CostListItem* i = (CostListItem*)item;
++ int size = (_groupSize.contains(i->costItem())) ?
++ _groupSize[i->costItem()] : -1;
++ i->setSize(size);
++ i->setVisible(!hideEmpty || (size>0));
++ }
++}
++
++void FunctionSelection::query(TQString query)
++{
++ if (searchEdit->text() != query)
++ searchEdit->setText(query);
++ if (_searchString == query) {
++ // when resetting query, get rid of group sizes
++ if (query.isEmpty()) {
++ _groupSize.clear();
++ updateGroupSizes(false);
++ }
++ return;
++ }
++ _searchString = query;
++
++ TQRegExp re(query, false, true);
++ _groupSize.clear();
++
++ TraceFunction* f = 0;
++ TraceFunctionList list2;
++
++ _hc.clear(Configuration::maxListCount());
++
++ TraceFunctionMap::Iterator it;
++ for ( it = _data->functionMap().begin();
++ it != _data->functionMap().end(); ++it ) {
++ f = &(*it);
++ if (re.search(f->prettyName())>=0) {
++ if (_group) {
++ if (_groupType==TraceItem::Object) {
++ if (_groupSize.contains(f->object()))
++ _groupSize[f->object()]++;
++ else
++ _groupSize[f->object()] = 1;
++ if (f->object() != _group) continue;
++ }
++ else if (_groupType==TraceItem::Class) {
++ if (_groupSize.contains(f->cls()))
++ _groupSize[f->cls()]++;
++ else
++ _groupSize[f->cls()] = 1;
++ if (f->cls() != _group) continue;
++ }
++ else if (_groupType==TraceItem::File) {
++ if (_groupSize.contains(f->file()))
++ _groupSize[f->file()]++;
++ else
++ _groupSize[f->file()] = 1;
++ if (f->file() != _group) continue;
++ }
++ else if (_groupType==TraceItem::FunctionCycle) {
++ if (_groupSize.contains(f->cycle()))
++ _groupSize[f->cycle()]++;
++ else
++ _groupSize[f->cycle()] = 1;
++ if (f->cycle() != _group) continue;
++ }
++ }
++ _hc.addCost(f, f->inclusive()->subCost(_costType));
++ }
++ }
++
++ updateGroupSizes(true);
++
++ FunctionItem *fi, *item = 0;
++
++ functionList->clear();
++ setCostColumnWidths();
++
++ for(int i=0;i<_hc.realCount();i++) {
++ fi = new FunctionItem(functionList, (TraceFunction*)_hc[i],
++ _costType, _groupType);
++ if (_activeItem == f) item = fi;
++ }
++ if (_hc.hasMore()) {
++ // a placeholder for all the functions skipped ...
++ new FunctionItem(functionList, _hc.count() - _hc.maxSize(),
++ (TraceFunction*)_hc[_hc.maxSize()-1], _costType);
++ }
++
++ functionList->sort();
++
++
++ if (item) {
++ functionList->ensureItemVisible(item);
++ _inSetFunction = true;
++ functionList->setSelected(item, true);
++ _inSetFunction = false;
++ }
++ else {
++ // this emits a function selection
++ functionList->setSelected(functionList->firstChild(), true);
++ }
++}
++
++bool FunctionSelection::setTopFunction()
++{
++ TQListViewItem* i = functionList->firstChild();
++ // this emits a function selection
++ functionList->setSelected(i, true);
++ functionActivated(i);
++ return i!=0;
++}
++
++void FunctionSelection::setCostColumnWidths()
++{
++ if (_costType && (_costType->subCost(_data->callMax())>0) ) {
++ functionList->setColumnWidthMode(0, TQListView::Maximum);
++ functionList->setColumnWidth(0,50);
++ functionList->setColumnWidthMode(2, TQListView::Maximum);
++ functionList->setColumnWidth(2,50);
++ }
++ else {
++ functionList->setColumnWidthMode(0, TQListView::Manual);
++ functionList->setColumnWidth(0,0);
++ functionList->setColumnWidthMode(2, TQListView::Manual);
++ functionList->setColumnWidth(2,0);
++ }
++
++ functionList->setColumnWidth(1, 50);
++}
++
++
++
++#include "functionselection.moc"
+diff --git a/kdecachegrind/kdecachegrind/functionselection.h b/kdecachegrind/kdecachegrind/functionselection.h
+new file mode 100644
+index 0000000..c5f7810
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/functionselection.h
+@@ -0,0 +1,86 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * For function selection, to be put into a TQDockWindow
++ */
++
++#ifndef FUNCTIONSELECTION_H
++#define FUNCTIONSELECTION_H
++
++#include "functionselectionbase.h"
++#include "traceitemview.h"
++#include "tracedata.h"
++#include "listutils.h"
++
++class TQPopupMenu;
++
++class TraceFunction;
++class TraceData;
++class StackBrowser;
++class NestedAreaItem;
++
++class FunctionSelection : public FunctionSelectionBase, public TraceItemView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ FunctionSelection( TopLevel*, TQWidget* parent = 0, const char* name = 0);
++ ~FunctionSelection();
++
++ TraceCostItem* group(TQString);
++ void setGroup(TraceCostItem*);
++ void query(TQString);
++ bool setTopFunction();
++
++ TQWidget* widget() { return this; }
++
++ void addGroupMenu(TQPopupMenu*);
++
++public slots:
++ void searchReturnPressed();
++ void searchChanged(const TQString&);
++ void queryDelayed();
++ void groupDoubleClicked( TQListViewItem* );
++ void functionActivated( TQListViewItem* );
++ void groupSelected( TQListViewItem* );
++ void functionSelected( TQListViewItem* );
++ void functionContext(TQListViewItem*, const TQPoint &, int);
++ void groupContext(TQListViewItem*, const TQPoint &, int);
++
++private:
++ TraceItem* canShow(TraceItem* i);
++ void doUpdate(int);
++ void selectFunction();
++ void refresh();
++ void setCostColumnWidths();
++ void updateGroupSizes(bool hideEmpty);
++
++ TraceCostItem* _group;
++
++ TQString _searchString, _searchDelayed;
++ TQTimer _searchTimer;
++ TQMap<TraceCostItem*,int> _groupSize;
++
++ HighestCostList _hc;
++ // when setting a
++ bool _inSetGroup, _inSetFunction;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/functionselectionbase.ui b/kdecachegrind/kdecachegrind/functionselectionbase.ui
+new file mode 100644
+index 0000000..eec019d
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/functionselectionbase.ui
+@@ -0,0 +1,163 @@
++<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
++<class>FunctionSelectionBase</class>
++<widget class="TQWidget">
++ <property name="name">
++ <cstring>FunctionSelectionBase</cstring>
++ </property>
++ <property name="geometry">
++ <rect>
++ <x>0</x>
++ <y>0</y>
++ <width>223</width>
++ <height>485</height>
++ </rect>
++ </property>
++ <property name="caption">
++ <string>Function Profile</string>
++ </property>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <property name="margin">
++ <number>3</number>
++ </property>
++ <property name="spacing">
++ <number>6</number>
++ </property>
++ <widget class="TQLayoutWidget">
++ <property name="name">
++ <cstring>layout1</cstring>
++ </property>
++ <hbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>searchLabel</cstring>
++ </property>
++ <property name="text">
++ <string>&amp;Search:</string>
++ </property>
++ <property name="buddy" stdset="0">
++ <cstring>searchEdit</cstring>
++ </property>
++ </widget>
++ <widget class="TQLineEdit">
++ <property name="name">
++ <cstring>searchEdit</cstring>
++ </property>
++ </widget>
++ <widget class="TQComboBox">
++ <property name="name">
++ <cstring>groupBox</cstring>
++ </property>
++ </widget>
++ </hbox>
++ </widget>
++ <widget class="TQListView">
++ <column>
++ <property name="text">
++ <string>Self</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Group</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <property name="name">
++ <cstring>groupList</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>7</hsizetype>
++ <vsizetype>5</vsizetype>
++ <horstretch>0</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ <property name="maximumSize">
++ <size>
++ <width>32767</width>
++ <height>150</height>
++ </size>
++ </property>
++ </widget>
++ <widget class="TQListView">
++ <column>
++ <property name="text">
++ <string>Incl.</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Self</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Called</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Function</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Location</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <property name="name">
++ <cstring>functionList</cstring>
++ </property>
++ </widget>
++ </vbox>
++</widget>
++<layoutdefaults spacing="6" margin="11"/>
++</UI>
+diff --git a/kdecachegrind/kdecachegrind/hi32-app-kcachegrind.png b/kdecachegrind/kdecachegrind/hi32-app-kcachegrind.png
+new file mode 100644
+index 0000000..bd41dae
+Binary files /dev/null and b/kdecachegrind/kdecachegrind/hi32-app-kcachegrind.png differ
+diff --git a/kdecachegrind/kdecachegrind/hi48-app-kcachegrind.png b/kdecachegrind/kdecachegrind/hi48-app-kcachegrind.png
+new file mode 100644
+index 0000000..58c2efd
+Binary files /dev/null and b/kdecachegrind/kdecachegrind/hi48-app-kcachegrind.png differ
+diff --git a/kdecachegrind/kdecachegrind/instritem.cpp b/kdecachegrind/kdecachegrind/instritem.cpp
+new file mode 100644
+index 0000000..ce5e81b
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/instritem.cpp
+@@ -0,0 +1,469 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of instruction view.
++ */
++
++#include <tqpixmap.h>
++#include <tqpainter.h>
++
++#include <klocale.h>
++#include <kapplication.h>
++#include <kiconloader.h>
++#include <kdebug.h>
++
++#include "configuration.h"
++#include "listutils.h"
++#include "instritem.h"
++#include "instrview.h"
++
++
++// InstrItem
++
++// for messages
++InstrItem::InstrItem(InstrView* iv, TQListView* parent,
++ Addr addr, const TQString& msg)
++ : TQListViewItem(parent)
++{
++ _view = iv;
++ _addr = addr;
++ _instr = 0;
++ _instrCall = 0;
++ _instrJump = 0;
++ _inside = false;
++
++ setText(0, addr.pretty());
++ setText(6, msg);
++
++ updateGroup();
++ updateCost();
++}
++
++// for code lines
++InstrItem::InstrItem(InstrView* iv, TQListView* parent,
++ Addr addr, bool inside,
++ const TQString& code, const TQString& cmd,
++ const TQString& args, TraceInstr* instr)
++ : TQListViewItem(parent)
++{
++ _view = iv;
++ _addr = addr;
++ _instr = instr;
++ _instrCall = 0;
++ _instrJump = 0;
++ _inside = inside;
++
++ if (args == "...")
++ setText(0, args);
++ else
++ setText(0, addr.pretty());
++ setText(4, code);
++ setText(5, cmd);
++ setText(6, args);
++
++ TraceLine* l;
++ if (instr && (l = instr->line()))
++ setText(7, l->name());
++
++ updateGroup();
++ updateCost();
++}
++
++// for call lines
++InstrItem::InstrItem(InstrView* iv, TQListViewItem* parent, Addr addr,
++ TraceInstr* instr, TraceInstrCall* instrCall)
++ : TQListViewItem(parent)
++{
++ _view = iv;
++ _addr = addr;
++ _instr = instr;
++ _instrCall = instrCall;
++ _instrJump = 0;
++ _inside = true;
++
++ //qDebug("InstrItem: (file %d, line %d) Linecall to %s",
++ // fileno, lineno, _lineCall->call()->called()->prettyName().ascii());
++
++ SubCost cc = _instrCall->callCount();
++ TQString templ = " ";
++ if (cc==0)
++ templ += i18n("Active call to '%1'");
++ else
++ templ += i18n("%n call to '%1'", "%n calls to '%1'", cc);
++
++ TQString callStr = templ.arg(_instrCall->call()->calledName());
++ TraceFunction* calledF = _instrCall->call()->called();
++ calledF->addPrettyLocation(callStr);
++
++ setText(6, callStr);
++
++ updateGroup();
++ updateCost();
++}
++
++// for jump lines
++InstrItem::InstrItem(InstrView* iv, TQListViewItem* parent, Addr addr,
++ TraceInstr* instr, TraceInstrJump* instrJump)
++ : TQListViewItem(parent)
++{
++ _view = iv;
++ _addr = addr;
++ _inside = true;
++ _instr = instr;
++ _instrCall = 0;
++ _instrJump = instrJump;
++
++ //qDebug("SourceItem: (file %d, line %d) Linecall to %s",
++ // fileno, lineno, _lineCall->call()->called()->prettyName().ascii());
++
++ TQString jStr;
++ if (_instrJump->isCondJump())
++ jStr = i18n("Jump %1 of %2 times to 0x%3")
++ .arg(_instrJump->followedCount().pretty())
++ .arg(_instrJump->executedCount().pretty())
++ .arg(_instrJump->instrTo()->addr().toString());
++ else
++ jStr = i18n("Jump %1 times to 0x%2")
++ .arg(_instrJump->executedCount().pretty())
++ .arg(_instrJump->instrTo()->addr().toString());
++
++ setText(6, jStr);
++
++ updateGroup();
++ updateCost();
++}
++
++
++void InstrItem::updateGroup()
++{
++ if (!_instrCall) return;
++
++ TraceFunction* f = _instrCall->call()->called();
++ TQColor c = Configuration::functionColor(_view->groupType(), f);
++ setPixmap(6, colorPixmap(10, 10, c));
++}
++
++void InstrItem::updateCost()
++{
++ _pure = SubCost(0);
++ _pure2 = SubCost(0);
++
++ if (!_instr) return;
++ if (_instrJump) return;
++
++ TraceCost* instrCost = _instrCall ?
++ (TraceCost*)_instrCall : (TraceCost*)_instr;
++
++ // don't show any cost inside of cycles
++ if (_instrCall &&
++ ((_instrCall->call()->inCycle()>0) ||
++ (_instrCall->call()->isRecursion()>0))) {
++ TQString str;
++ TQPixmap p;
++
++ TQString icon = "undo";
++ KIconLoader* loader = KApplication::kApplication()->iconLoader();
++ p= loader->loadIcon(icon, KIcon::Small, 0,
++ KIcon::DefaultState, 0, true);
++ if (p.isNull())
++ str = i18n("(cycle)");
++
++ setText(1, str);
++ setPixmap(1, p);
++ setText(2, str);
++ setPixmap(2, p);
++ return;
++ }
++
++ TraceCost* totalCost;
++ if (Configuration::showExpanded())
++ totalCost = _instr->function()->inclusive();
++ else
++ totalCost = _instr->function()->data();
++
++ TraceCostType *ct = _view->costType();
++ _pure = ct ? instrCost->subCost(ct) : SubCost(0);
++ if (_pure == 0) {
++ setText(1, TQString());
++ setPixmap(1, TQPixmap());
++ }
++ else {
++ double total = totalCost->subCost(ct);
++ double pure = 100.0 * _pure / total;
++
++ if (Configuration::showPercentage())
++ setText(1, TQString("%1")
++ .arg(pure, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(1, _pure.pretty());
++
++ setPixmap(1, costPixmap(ct, instrCost, total, false));
++ }
++
++ TraceCostType *ct2 = _view->costType2();
++ _pure2 = ct2 ? instrCost->subCost(ct2) : SubCost(0);
++ if (_pure2 == 0) {
++ setText(2, TQString());
++ setPixmap(2, TQPixmap());
++ }
++ else {
++ double total = totalCost->subCost(ct2);
++ double pure = 100.0 * _pure2 / total;
++
++ if (Configuration::showPercentage())
++ setText(2, TQString("%1")
++ .arg(pure, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(2, _pure2.pretty());
++
++ setPixmap(2, costPixmap(ct2, instrCost, total, false));
++ }
++}
++
++
++int InstrItem::compare(TQListViewItem * i, int col, bool ascending ) const
++{
++ const InstrItem* ii1 = this;
++ const InstrItem* ii2 = (InstrItem*) i;
++
++ // we always want descending order
++ if (((col>0) && ascending) ||
++ ((col==0) && !ascending) ) {
++ ii1 = ii2;
++ ii2 = this;
++ }
++
++ if (col==1) {
++ if (ii1->_pure < ii2->_pure) return -1;
++ if (ii1->_pure > ii2->_pure) return 1;
++ return 0;
++ }
++ if (col==2) {
++ if (ii1->_pure2 < ii2->_pure2) return -1;
++ if (ii1->_pure2 > ii2->_pure2) return 1;
++ return 0;
++ }
++ if (col==0) {
++ if (ii1->_addr < ii2->_addr) return -1;
++ if (ii1->_addr > ii2->_addr) return 1;
++
++ // Same address: code gets above calls/jumps
++ if (!ii1->_instrCall && !ii1->_instrJump) return -1;
++ if (!ii2->_instrCall && !ii2->_instrJump) return 1;
++
++ // calls above jumps
++ if (ii1->_instrCall && !ii2->_instrCall) return -1;
++ if (ii2->_instrCall && !ii1->_instrCall) return 1;
++
++ if (ii1->_instrCall && ii2->_instrCall) {
++ // Two calls: desending sort according costs
++ if (ii1->_pure < ii2->_pure) return 1;
++ if (ii1->_pure > ii2->_pure) return -1;
++
++ // Two calls: sort according function names
++ TraceFunction* f1 = ii1->_instrCall->call()->called();
++ TraceFunction* f2 = ii2->_instrCall->call()->called();
++ if (f1->prettyName() > f2->prettyName()) return 1;
++ return -1;
++ }
++
++ // Two jumps: descending sort according target address
++ if (ii1->_instrJump->instrTo()->addr() <
++ ii2->_instrJump->instrTo()->addr())
++ return -1;
++ if (ii1->_instrJump->instrTo()->addr() >
++ ii2->_instrJump->instrTo()->addr())
++ return 1;
++ return 0;
++
++ }
++ return TQListViewItem::compare(i, col, ascending);
++}
++
++void InstrItem::paintCell( TQPainter *p, const TQColorGroup &cg,
++ int column, int width, int alignment )
++{
++ TQColorGroup _cg( cg );
++
++ if ( !_inside || ((column==1) || column==2))
++ _cg.setColor( TQColorGroup::Base, cg.button() );
++ else if ((_instrCall || _instrJump) && column>2)
++ _cg.setColor( TQColorGroup::Base, cg.midlight() );
++
++ if (column == 3)
++ paintArrows(p, _cg, width);
++ else
++ TQListViewItem::paintCell( p, _cg, column, width, alignment );
++}
++
++void InstrItem::setJumpArray(const TQMemArray<TraceInstrJump*>& a)
++{
++ _jump.duplicate(a);
++}
++
++void InstrItem::paintArrows(TQPainter *p, const TQColorGroup &cg, int width)
++{
++ TQListView *lv = listView();
++ if ( !lv ) return;
++ InstrView* iv = (InstrView*) lv;
++
++ const BackgroundMode bgmode = lv->viewport()->backgroundMode();
++ const TQColorGroup::ColorRole crole
++ = TQPalette::backgroundRoleFromMode( bgmode );
++ if ( cg.brush( crole ) != lv->colorGroup().brush( crole ) )
++ p->fillRect( 0, 0, width, height(), cg.brush( crole ) );
++ else
++ iv->paintEmptyArea( p, TQRect( 0, 0, width, height() ) );
++
++ if ( isSelected() && lv->allColumnsShowFocus() )
++ p->fillRect( 0, 0, width, height(), cg.brush( TQColorGroup::Highlight ) );
++
++ int marg = lv->itemMargin();
++ int yy = height()/2, y1, y2;
++ TQColor c;
++
++ int start = -1, end = -1;
++
++ // draw line borders, detect start/stop of a line
++ for(int i=0;i< (int)_jump.size();i++) {
++ if (_jump[i] == 0) continue;
++
++ y1 = 0;
++ y2 = height();
++ if ((_instrJump == _jump[i]) &&
++ (_jump[i]->instrFrom()->addr() == _addr)) {
++
++ //kdDebug() << "InstrItem " << _addr.toString() << ": start " << i << endl;
++ if (start<0) start = i;
++ if (_jump[i]->instrTo()->addr() <= _addr)
++ y2 = yy;
++ else
++ y1 = yy;
++ }
++ else if (!_instrJump && !_instrCall &&
++ (_jump[i]->instrTo()->addr() == _addr)) {
++
++ //kdDebug() << "InstrItem " << _addr.toString() << ": end " << i << endl;
++ if (end<0) end = i;
++ if (_jump[i]->instrFrom()->addr() < _addr)
++ y2 = yy;
++ else
++ y1 = yy;
++ }
++
++ c = _jump[i]->isCondJump() ? red : blue;
++#if 0
++ if (_jump[i] == ((TraceItemView*)_view)->selectedItem()) {
++ p->fillRect( marg + 6*i-2, (y1==0) ? y1: y1-2,
++ 8, (y2-y1==height())? y2:y2+2,
++ cg.brush( TQColorGroup::Highlight ) );
++ c = lv->colorGroup().highlightedText();
++ }
++#endif
++ p->fillRect( marg + 6*i, y1, 4, y2, c);
++ p->setPen(c.light());
++ p->drawLine( marg + 6*i, y1, marg + 6*i, y2);
++ p->setPen(c.dark());
++ p->drawLine( marg + 6*i +3, y1, marg + 6*i +3, y2);
++ }
++
++ // draw start/stop horizontal line
++ int x, y = yy-2, w, h = 4;
++ if (start >= 0) {
++#if 0
++ if (_jump[start] == ((TraceItemView*)_view)->selectedItem()) {
++ c = lv->colorGroup().highlightedText();
++ }
++#endif
++ c = _jump[start]->isCondJump() ? red : blue;
++ x = marg + 6*start;
++ w = 6*(iv->arrowLevels() - start) + 10;
++ p->fillRect( x, y, w, h, c);
++ p->setPen(c.light());
++ p->drawLine(x, y, x+w-1, y);
++ p->drawLine(x, y, x, y+h-1);
++ p->setPen(c.dark());
++ p->drawLine(x+w-1, y, x+w-1, y+h-1);
++ p->drawLine(x+1, y+h-1, x+w-1, y+h-1);
++ }
++ if (end >= 0) {
++ c = _jump[end]->isCondJump() ? red : blue;
++ x = marg + 6*end;
++ w = 6*(iv->arrowLevels() - end) + 10;
++
++ TQPointArray a;
++ a.putPoints(0, 7, x, y+h,
++ x,y, x+w-8, y, x+w-8, y-2,
++ x+w, yy,
++ x+w-8, y+h+2, x+w-8, y+h);
++ p->setBrush(c);
++ p->drawConvexPolygon(a);
++
++ p->setPen(c.light());
++ p->drawPolyline(a, 0, 5);
++ p->setPen(c.dark());
++ p->drawPolyline(a, 4, 2);
++ p->setPen(c.light());
++ p->drawPolyline(a, 5, 2);
++ p->setPen(c.dark());
++ p->drawPolyline(a, 6, 2);
++ }
++
++ // draw inner vertical line for start/stop
++ // this overwrites borders of horizontal line
++ for(int i=0;i< (int)_jump.size();i++) {
++ if (_jump[i] == 0) continue;
++
++ c = _jump[i]->isCondJump() ? red : blue;
++
++ if (_jump[i]->instrFrom()->addr() == _addr) {
++ bool drawUp = true;
++ if (_jump[i]->instrTo()->addr() == _addr)
++ if (start<0) drawUp=false;
++ if (_jump[i]->instrTo()->addr() > _addr) drawUp=false;
++ if (drawUp)
++ p->fillRect( marg + 6*i +1, 0, 2, yy, c);
++ else
++ p->fillRect( marg + 6*i +1, yy, 2, height()-yy, c);
++ }
++ else if (_jump[i]->instrTo()->addr() == _addr) {
++ if (end<0) end = i;
++ if (_jump[i]->instrFrom()->addr() < _addr)
++ p->fillRect( marg + 6*i +1, 0, 2, yy, c);
++ else
++ p->fillRect( marg + 6*i +1, yy, 2, height()-yy, c);
++ }
++ }
++
++}
++
++int InstrItem::width( const TQFontMetrics& fm,
++ const TQListView* lv, int c ) const
++{
++ if (c != 3) return TQListViewItem::width(fm, lv, c);
++
++ InstrView* iv = (InstrView*) lv;
++ int levels = iv->arrowLevels();
++
++ if (levels == 0) return 0;
++
++ // 10 pixels for the arrow
++ return 10 + 6*levels + lv->itemMargin() * 2;
++}
++
+diff --git a/kdecachegrind/kdecachegrind/instritem.h b/kdecachegrind/kdecachegrind/instritem.h
+new file mode 100644
+index 0000000..2bbce71
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/instritem.h
+@@ -0,0 +1,86 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of instruction view.
++ */
++
++#ifndef INSTRITEM_H
++#define INSTRITEM_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++
++class InstrView;
++
++class InstrItem: public TQListViewItem
++{
++
++public:
++ // for messages
++ InstrItem(InstrView* iv, TQListView* parent,
++ Addr addr, const TQString&);
++
++ // for instruction lines
++ InstrItem(InstrView* iv, TQListView* parent,
++ Addr addr, bool inside,
++ const TQString&, const TQString&, const TQString&,
++ TraceInstr* instr);
++
++ // for call instr
++ InstrItem(InstrView* iv, TQListViewItem* parent, Addr addr,
++ TraceInstr* instr, TraceInstrCall* instrCall);
++
++ // for jump lines
++ InstrItem(InstrView* iv, TQListViewItem* parent, Addr addr,
++ TraceInstr* instr, TraceInstrJump* instrJump);
++
++ Addr addr() const { return _addr; }
++ TraceInstr* instr() const { return _instr; }
++ TraceInstrCall* instrCall() const { return _instrCall; }
++ TraceInstrJump* instrJump() const { return _instrJump; }
++
++ int compare(TQListViewItem * i, int col, bool ascending ) const;
++
++ void paintCell(TQPainter *p, const TQColorGroup &cg,
++ int column, int width, int alignment );
++ int width( const TQFontMetrics& fm,
++ const TQListView* lv, int c ) const;
++
++ void updateGroup();
++ void updateCost();
++
++ // arrow lines
++ void setJumpArray(const TQMemArray<TraceInstrJump*>& a);
++
++protected:
++ void paintArrows(TQPainter *p, const TQColorGroup &cg, int width);
++ TQMemArray<TraceInstrJump*> _jump;
++
++private:
++ InstrView* _view;
++ SubCost _pure, _pure2;
++ Addr _addr;
++ TraceInstr* _instr;
++ TraceInstrJump* _instrJump;
++ TraceInstrCall* _instrCall;
++ bool _inside;
++};
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/instrview.cpp b/kdecachegrind/kdecachegrind/instrview.cpp
+new file mode 100644
+index 0000000..3df1679
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/instrview.cpp
+@@ -0,0 +1,949 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Instruction View
++ */
++
++#include <tqfile.h>
++#include <tqregexp.h>
++#include <tqwhatsthis.h>
++#include <tqpopupmenu.h>
++#include <klocale.h>
++#include <kconfig.h>
++#include <kdebug.h>
++
++#include "configuration.h"
++#include "instritem.h"
++#include "instrview.h"
++
++// InstrView defaults
++
++#define DEFAULT_SHOWHEXCODE true
++
++
++// Helpers for parsing output of 'objdump'
++
++static Addr parseAddr(char* buf)
++{
++ Addr addr;
++ uint pos = 0;
++
++ // check for instruction line: <space>* <hex address> ":" <space>*
++ while(buf[pos]==' ' || buf[pos]=='\t') pos++;
++
++ int digits = addr.set(buf + pos);
++ if ((digits==0) || (buf[pos+digits] != ':')) return Addr(0);
++
++ return addr;
++}
++
++
++static bool parseLine(char* buf, Addr& addr,
++ uint& pos1, uint& pos2, uint& pos3)
++{
++ // check for instruction line: <space>* <hex address> ":" <space>*
++
++ pos1 = 0;
++ while(buf[pos1]==' ' || buf[pos1]=='\t') pos1++;
++
++ int digits = addr.set(buf + pos1);
++ pos1 += digits;
++ if ((digits==0) || (buf[pos1] != ':')) return false;
++
++ // further parsing of objdump output...
++ pos1++;
++ while(buf[pos1]==' ' || buf[pos1]=='\t') pos1++;
++
++ // skip code, pattern "xx "*
++ pos2 = pos1;
++ while(1) {
++ if (! ((buf[pos2]>='0' && buf[pos2]<='9') ||
++ (buf[pos2]>='a' && buf[pos2]<='f')) ) break;
++ if (! ((buf[pos2+1]>='0' && buf[pos2+1]<='9') ||
++ (buf[pos2+1]>='a' && buf[pos2+1]<='f')) ) break;
++ if (buf[pos2+2] != ' ') break;
++ pos2 += 3;
++ }
++ buf[pos2-1]=0;
++ while(buf[pos2]==' '|| buf[pos2]=='\t') pos2++;
++
++ // skip mnemonic
++ pos3 = pos2;
++ while(buf[pos3] && buf[pos3]!=' ' && buf[pos3]!='\t') pos3++;
++ if (buf[pos3] != 0) {
++ buf[pos3] = 0;
++ pos3++;
++ while(buf[pos3]==' '|| buf[pos3]=='\t') pos3++;
++ }
++
++ // maximal 50 chars
++ if (strlen(buf+pos2) > 50)
++ strcpy(buf+pos2+47, "...");
++
++ if (0) qDebug("For 0x%s: Code '%s', Mnc '%s', Args '%s'",
++ addr.toString().ascii(), buf+pos1, buf+pos2, buf+pos3);
++
++ return true;
++}
++
++
++
++
++//
++// InstrView
++//
++
++
++InstrView::InstrView(TraceItemView* parentView,
++ TQWidget* parent, const char* name)
++ : TQListView(parent, name), TraceItemView(parentView)
++{
++ _showHexCode = DEFAULT_SHOWHEXCODE;
++ _lastHexCodeWidth = 50;
++
++ _inSelectionUpdate = false;
++ _arrowLevels = 0;
++ _lowList.setSortLow(true);
++ _highList.setSortLow(false);
++
++ addColumn( i18n( "#" ) );
++ addColumn( i18n( "Cost" ) );
++ addColumn( i18n( "Cost 2" ) );
++ addColumn( "" );
++ addColumn( i18n( "Hex" ) );
++ addColumn( "" ); // Instruction
++ addColumn( i18n( "Assembler" ) );
++ addColumn( i18n( "Source Position" ) );
++
++ setAllColumnsShowFocus(true);
++ setColumnAlignment(1, TQt::AlignRight);
++ setColumnAlignment(2, TQt::AlignRight);
++
++ connect(this,
++ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
++ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int)));
++
++ connect(this, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
++ TQT_SLOT(selectedSlot(TQListViewItem*)));
++
++ connect(this,
++ TQT_SIGNAL(doubleClicked(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ connect(this,
++ TQT_SIGNAL(returnPressed(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ TQWhatsThis::add( this, whatsThis());
++}
++
++void InstrView::paintEmptyArea( TQPainter * p, const TQRect & r)
++{
++ TQListView::paintEmptyArea(p, r);
++}
++
++TQString InstrView::whatsThis() const
++{
++ return i18n( "<b>Annotated Assembler</b>"
++ "<p>The annotated assembler list shows the "
++ "machine code instructions of the current selected "
++ "function together with (self) cost spent while "
++ "executing an instruction. If this is a call "
++ "instruction, lines with details on the "
++ "call happening are inserted into the source: "
++ "the cost spent inside of the call, the "
++ "number of calls happening, and the call destination.</p>"
++ "<p>The disassembler output shown is generated with "
++ "the 'objdump' utility from the 'binutils' package.</p>"
++ "<p>Select a line with call information to "
++ "make the destination function of this call current.</p>");
++}
++
++void InstrView::context(TQListViewItem* i, const TQPoint & p, int c)
++{
++ TQPopupMenu popup;
++
++ TraceInstrCall* ic = i ? ((InstrItem*) i)->instrCall() : 0;
++ TraceInstrJump* ij = i ? ((InstrItem*) i)->instrJump() : 0;
++ TraceFunction* f = ic ? ic->call()->called() : 0;
++ TraceInstr* instr = ij ? ij->instrTo() : 0;
++
++ if (f) {
++ TQString name = f->name();
++ if ((int)name.length()>Configuration::maxSymbolLength())
++ name = name.left(Configuration::maxSymbolLength()) + "...";
++ popup.insertItem(i18n("Go to '%1'").arg(name), 93);
++ popup.insertSeparator();
++ }
++ else if (instr) {
++ popup.insertItem(i18n("Go to Address %1").arg(instr->name()), 93);
++ popup.insertSeparator();
++ }
++
++ if ((c == 1) || (c == 2)) {
++ addCostMenu(&popup);
++ popup.insertSeparator();
++ }
++ addGoMenu(&popup);
++
++ popup.insertSeparator();
++ popup.setCheckable(true);
++ popup.insertItem(i18n("Hex Code"), 94);
++ if (_showHexCode) popup.setItemChecked(94,true);
++
++ int r = popup.exec(p);
++ if (r == 93) {
++ if (f) activated(f);
++ if (instr) activated(instr);
++ }
++ else if (r == 94) {
++ _showHexCode = !_showHexCode;
++ // remember width when hiding
++ if (!_showHexCode)
++ _lastHexCodeWidth = columnWidth(4);
++ setColumnWidths();
++ }
++}
++
++
++void InstrView::selectedSlot(TQListViewItem * i)
++{
++ if (!i) return;
++ // programatically selected items are not signalled
++ if (_inSelectionUpdate) return;
++
++ TraceInstrCall* ic = ((InstrItem*) i)->instrCall();
++ TraceInstrJump* ij = ((InstrItem*) i)->instrJump();
++
++ if (!ic && !ij) {
++ TraceInstr* instr = ((InstrItem*) i)->instr();
++ if (instr) {
++ _selectedItem = instr;
++ selected(instr);
++ }
++ return;
++ }
++
++ if (ic) {
++ _selectedItem = ic;
++ selected(ic);
++ }
++ else if (ij) {
++ _selectedItem = ij;
++ selected(ij);
++ }
++}
++
++void InstrView::activatedSlot(TQListViewItem * i)
++{
++ if (!i) return;
++ TraceInstrCall* ic = ((InstrItem*) i)->instrCall();
++ TraceInstrJump* ij = ((InstrItem*) i)->instrJump();
++
++ if (!ic && !ij) {
++ TraceInstr* instr = ((InstrItem*) i)->instr();
++ if (instr) activated(instr);
++ return;
++ }
++
++ if (ic) {
++ TraceFunction* f = ic->call()->called();
++ if (f) activated(f);
++ }
++ else if (ij) {
++ TraceInstr* instr = ij->instrTo();
++ if (instr) activated(instr);
++ }
++}
++
++
++TraceItem* InstrView::canShow(TraceItem* i)
++{
++ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType;
++ TraceFunction* f = 0;
++
++ switch(t) {
++ case TraceItem::Function:
++ f = (TraceFunction*) i;
++ break;
++
++ case TraceItem::Instr:
++ f = ((TraceInstr*)i)->function();
++ select(i);
++ break;
++
++ case TraceItem::Line:
++ f = ((TraceLine*)i)->functionSource()->function();
++ select(i);
++ break;
++
++ default:
++ break;
++ }
++
++ return f;
++}
++
++
++void InstrView::doUpdate(int changeType)
++{
++ // Special case ?
++ if (changeType == selectedItemChanged) {
++
++ if (!_selectedItem) {
++ clearSelection();
++ return;
++ }
++
++ InstrItem *ii = (InstrItem*)TQListView::selectedItem();
++ if (ii) {
++ if ((ii->instr() == _selectedItem) ||
++ (ii->instr() && (ii->instr()->line() == _selectedItem))) return;
++ }
++
++ TQListViewItem *item, *item2;
++ for (item = firstChild();item;item = item->nextSibling()) {
++ ii = (InstrItem*)item;
++ if ((ii->instr() == _selectedItem) ||
++ (ii->instr() && (ii->instr()->line() == _selectedItem))) {
++ ensureItemVisible(item);
++ _inSelectionUpdate = true;
++ setCurrentItem(item);
++ _inSelectionUpdate = false;
++ break;
++ }
++ item2 = item->firstChild();
++ for (;item2;item2 = item2->nextSibling()) {
++ ii = (InstrItem*)item2;
++ if (!ii->instrCall()) continue;
++ if (ii->instrCall()->call()->called() == _selectedItem) {
++ ensureItemVisible(item2);
++ _inSelectionUpdate = true;
++ setCurrentItem(item2);
++ _inSelectionUpdate = false;
++ break;
++ }
++ }
++ if (item2) break;
++ }
++ return;
++ }
++
++ if (changeType == groupTypeChanged) {
++ TQListViewItem *item, *item2;
++ for (item = firstChild();item;item = item->nextSibling())
++ for (item2 = item->firstChild();item2;item2 = item2->nextSibling())
++ ((InstrItem*)item2)->updateGroup();
++ return;
++ }
++
++ refresh();
++}
++
++void InstrView::setColumnWidths()
++{
++ if (_showHexCode) {
++ setColumnWidthMode(4, TQListView::Maximum);
++ setColumnWidth(4, _lastHexCodeWidth);
++ }
++ else {
++ setColumnWidthMode(4, TQListView::Manual);
++ setColumnWidth(4, 0);
++ }
++}
++
++void InstrView::refresh()
++{
++ _arrowLevels = 0;
++
++ // reset to automatic sizing to get column width
++ setColumnWidthMode(4, TQListView::Maximum);
++
++ clear();
++ setColumnWidth(0, 20);
++ setColumnWidth(1, 50);
++ setColumnWidth(2, _costType2 ? 50:0);
++ setColumnWidth(3, 0); // arrows, defaults to invisible
++ setColumnWidth(4, 0); // hex code column
++ setColumnWidth(5, 20); // command column
++ setColumnWidth(6, 200); // arg column
++ setSorting(0); // always reset to address number sort
++ if (_costType)
++ setColumnText(1, _costType->name());
++ if (_costType2)
++ setColumnText(2, _costType2->name());
++
++ if (!_data || !_activeItem) return;
++
++ TraceItem::CostType t = _activeItem->type();
++ TraceFunction* f = 0;
++ if (t == TraceItem::Function) f = (TraceFunction*) _activeItem;
++ if (t == TraceItem::Instr) {
++ f = ((TraceInstr*)_activeItem)->function();
++ if (!_selectedItem) _selectedItem = _activeItem;
++ }
++ if (t == TraceItem::Line) {
++ f = ((TraceLine*)_activeItem)->functionSource()->function();
++ if (!_selectedItem) _selectedItem = _activeItem;
++ }
++
++ if (!f) return;
++
++ // Allow resizing of column 2
++ setColumnWidthMode(2, TQListView::Maximum);
++
++ // check for instruction map
++ TraceInstrMap::Iterator itStart, it, tmpIt, itEnd;
++ TraceInstrMap* instrMap = f->instrMap();
++ if (instrMap) {
++ it = instrMap->begin();
++ itEnd = instrMap->end();
++ // get first instruction with cost of selected type
++ while(it != itEnd) {
++ if ((*it).hasCost(_costType)) break;
++ if (_costType2 && (*it).hasCost(_costType2)) break;
++ ++it;
++ }
++ }
++ if (!instrMap || (it == itEnd)) {
++ new InstrItem(this, this, 1,
++ i18n("There is no instruction info in the profile data file."));
++ new InstrItem(this, this, 2,
++ i18n("For the Valgrind Calltree Skin, rerun with option"));
++ new InstrItem(this, this, 3, i18n(" --dump-instr=yes"));
++ new InstrItem(this, this, 4, i18n("To see (conditional) jumps, additionally specify"));
++ new InstrItem(this, this, 5, i18n(" --trace-jump=yes"));
++ return;
++ }
++
++ // initialisation for arrow drawing
++ // create sorted list of jumps (for jump arrows)
++ _lowList.clear();
++ _highList.clear();
++ itStart = it;
++ while(1) {
++ TraceInstrJumpList jlist = (*it).instrJumps();
++ TraceInstrJump* ij;
++ for (ij=jlist.first();ij;ij=jlist.next()) {
++ if (ij->executedCount()==0) continue;
++ _lowList.append(ij);
++ _highList.append(ij);
++ }
++ ++it;
++ while(it != itEnd) {
++ if ((*it).hasCost(_costType)) break;
++ if (_costType2 && (*it).hasCost(_costType2)) break;
++ ++it;
++ }
++ if (it == itEnd) break;
++ }
++ _lowList.sort();
++ _highList.sort();
++ _lowList.first(); // iterators to list start
++ _highList.first();
++ _arrowLevels = 0;
++ _jump.resize(0);
++
++
++ // do multiple calls to 'objdump' if there are large gaps in addresses
++ it = itStart;
++ while(1) {
++ itStart = it;
++ while(1) {
++ tmpIt = it;
++ ++it;
++ while(it != itEnd) {
++ if ((*it).hasCost(_costType)) break;
++ if (_costType2 && (*it).hasCost(_costType2)) break;
++ ++it;
++ }
++ if (it == itEnd) break;
++ if (!(*it).addr().isInRange( (*tmpIt).addr(),10000) ) break;
++ }
++
++ // tmpIt is always last instruction with cost
++ if (!fillInstrRange(f, itStart, ++tmpIt)) break;
++ if (it == itEnd) break;
++ }
++
++ _lastHexCodeWidth = columnWidth(4);
++ setColumnWidths();
++
++ if (!_costType2) {
++ setColumnWidthMode(2, TQListView::Manual);
++ setColumnWidth(2, 0);
++ }
++}
++
++/* This is called after adding instrItems, for each of them in
++ * address order. _jump is the global array of valid jumps
++ * for a line while we iterate downwards.
++ * The existing jumps, sorted in lowList according lower address,
++ * is iterated in the same way.
++ */
++void InstrView::updateJumpArray(Addr addr, InstrItem* ii,
++ bool ignoreFrom, bool ignoreTo)
++{
++ TraceInstrJump* ij;
++ Addr lowAddr, highAddr;
++ int iEnd = -1, iStart = -1;
++
++ if (0) qDebug("updateJumpArray(addr 0x%s, jump to %s)",
++ addr.toString().ascii(),
++ ii->instrJump()
++ ? ii->instrJump()->instrTo()->name().ascii() : "?" );
++
++ // check for new arrows starting from here downwards
++ ij=_lowList.current();
++ while(ij) {
++ lowAddr = ij->instrFrom()->addr();
++ if (ij->instrTo()->addr() < lowAddr)
++ lowAddr = ij->instrTo()->addr();
++
++ if (lowAddr > addr) break;
++
++ // if target is downwards but we draw no source, break
++ if (ignoreFrom && (lowAddr < ij->instrTo()->addr())) break;
++ // if source is downward but we draw no target, break
++ if (ignoreTo && (lowAddr < ij->instrFrom()->addr())) break;
++ // if this is another jump start, break
++ if (ii->instrJump() && (ij != ii->instrJump())) break;
++
++#if 0
++ for(iStart=0;iStart<_arrowLevels;iStart++)
++ if (_jump[iStart] &&
++ (_jump[iStart]->instrTo() == ij->instrTo())) break;
++#else
++ iStart = _arrowLevels;
++#endif
++
++ if (iStart==_arrowLevels) {
++ for(iStart=0;iStart<_arrowLevels;iStart++)
++ if (_jump[iStart] == 0) break;
++ if (iStart==_arrowLevels) {
++ _arrowLevels++;
++ _jump.resize(_arrowLevels);
++ }
++ if (0) qDebug(" new start at %d for %s", iStart, ij->name().ascii());
++ _jump[iStart] = ij;
++ }
++ ij=_lowList.next();
++ }
++
++ ii->setJumpArray(_jump);
++
++ // check for active arrows ending here
++ ij=_highList.current();
++ while(ij) {
++ highAddr = ij->instrFrom()->addr();
++ if (ij->instrTo()->addr() > highAddr) {
++ highAddr = ij->instrTo()->addr();
++ if (ignoreTo) break;
++ }
++ else if (ignoreFrom) break;
++
++ if (highAddr > addr) break;
++
++ for(iEnd=0;iEnd<_arrowLevels;iEnd++)
++ if (_jump[iEnd] == ij) break;
++ if (iEnd==_arrowLevels) {
++ kdDebug() << "InstrView: no jump start for end at 0x"
++ << highAddr.toString() << " ?" << endl;
++ iEnd = -1;
++ }
++
++ if (0 && (iEnd>=0))
++ qDebug(" end %d (%s to %s)",
++ iEnd,
++ _jump[iEnd]->instrFrom()->name().ascii(),
++ _jump[iEnd]->instrTo()->name().ascii());
++
++ if (0 && ij) qDebug("next end: %s to %s",
++ ij->instrFrom()->name().ascii(),
++ ij->instrTo()->name().ascii());
++
++ ij=_highList.next();
++ if (highAddr > addr)
++ break;
++ else {
++ if (iEnd>=0) _jump[iEnd] = 0;
++ iEnd = -1;
++ }
++ }
++ if (iEnd>=0) _jump[iEnd] = 0;
++}
++
++
++
++/**
++ * Fill up with instructions from cost range [it;itEnd[
++ */
++bool InstrView::fillInstrRange(TraceFunction* function,
++ TraceInstrMap::Iterator it,
++ TraceInstrMap::Iterator itEnd)
++{
++ Addr costAddr, nextCostAddr, objAddr, addr;
++ Addr dumpStartAddr, dumpEndAddr;
++ TraceInstrMap::Iterator costIt;
++
++ // shouldn't happen
++ if (it == itEnd) return false;
++
++ // calculate address range for call to objdump
++ TraceInstrMap::Iterator tmpIt = itEnd;
++ --tmpIt;
++ nextCostAddr = (*it).addr();
++ dumpStartAddr = (nextCostAddr<20) ? Addr(0) : nextCostAddr -20;
++ dumpEndAddr = (*tmpIt).addr() +20;
++
++ // generate command
++ TQString popencmd, objfile;
++ objfile = function->object()->name();
++ objfile = objfile.replace(TQRegExp("[\"']"), ""); // security...
++ popencmd = TQString("objdump -C -d "
++ "--start-address=0x%1 --stop-address=0x%2 \"%3\"")
++ .arg(dumpStartAddr.toString()).arg(dumpEndAddr.toString())
++ .arg(objfile);
++ if (1) qDebug("Running '%s'...", popencmd.ascii());
++
++ // and run...
++ FILE* iFILE = popen(TQFile::encodeName( popencmd ), "r");
++ if (iFILE == 0) {
++ new InstrItem(this, this, 1,
++ i18n("There is an error trying to execute the command"));
++ new InstrItem(this, this, 2, "");
++ new InstrItem(this, this, 3, popencmd);
++ new InstrItem(this, this, 4, "");
++ new InstrItem(this, this, 5,
++ i18n("Check that you have installed 'objdump'."));
++ new InstrItem(this, this, 6,
++ i18n("This utility can be found in the 'binutils' package."));
++ return false;
++ }
++ TQFile file;
++ file.open(IO_ReadOnly, iFILE);
++
++#define BUF_SIZE 256
++
++ char buf[BUF_SIZE];
++ bool inside = false, skipLineWritten = true;
++ int readBytes = -1;
++ int objdumpLineno = 0, dumpedLines = 0, noAssLines = 0;
++ SubCost most = 0;
++ TraceInstr* currInstr;
++ InstrItem *ii, *ii2, *item = 0, *first = 0, *selected = 0;
++ TQString code, cmd, args;
++ bool needObjAddr = true, needCostAddr = true;
++
++ costAddr = 0;
++ objAddr = 0;
++
++ while (1) {
++
++ if (needObjAddr) {
++ needObjAddr = false;
++
++ // read next objdump line
++ while (1) {
++ readBytes=file.readLine(buf, BUF_SIZE);
++ if (readBytes<=0) {
++ objAddr = 0;
++ break;
++ }
++
++ objdumpLineno++;
++ if (readBytes == BUF_SIZE) {
++ qDebug("ERROR: Line %d of '%s' too long\n",
++ objdumpLineno, popencmd.ascii());
++ }
++ else if ((readBytes>0) && (buf[readBytes-1] == '\n'))
++ buf[readBytes-1] = 0;
++
++ objAddr = parseAddr(buf);
++ if ((objAddr<dumpStartAddr) || (objAddr>dumpEndAddr))
++ objAddr = 0;
++ if (objAddr != 0) break;
++ }
++
++ if (0) kdDebug() << "Got ObjAddr: 0x" << objAddr.toString() << endl;
++ }
++
++ // try to keep objAddr in [costAddr;nextCostAddr]
++ if (needCostAddr &&
++ (nextCostAddr > 0) &&
++ ((objAddr == Addr(0)) || (objAddr >= nextCostAddr)) ) {
++ needCostAddr = false;
++
++ costIt = it;
++ ++it;
++ while(it != itEnd) {
++ if ((*it).hasCost(_costType)) break;
++ if (_costType2 && (*it).hasCost(_costType2)) break;
++ ++it;
++ }
++ costAddr = nextCostAddr;
++ nextCostAddr = (it == itEnd) ? Addr(0) : (*it).addr();
++
++ if (0) kdDebug() << "Got nextCostAddr: 0x" << nextCostAddr.toString()
++ << ", costAddr 0x" << costAddr.toString() << endl;
++ }
++
++ // if we have no more address from objdump, stop
++ if (objAddr == 0) break;
++
++ if ((nextCostAddr==0) || (costAddr == 0) ||
++ (objAddr < nextCostAddr)) {
++ // next line is objAddr
++
++ uint pos1, pos2, pos3;
++
++ // this sets addr
++ parseLine(buf, addr, pos1, pos2, pos3);
++ code = TQString(buf + pos1);
++ cmd = TQString(buf + pos2);
++ args = TQString(buf + pos3);
++
++ if (costAddr == objAddr) {
++ currInstr = &(*costIt);
++ needCostAddr = true;
++ }
++ else
++ currInstr = 0;
++
++ needObjAddr = true;
++
++ if (0) kdDebug() << "Dump Obj Addr: 0x" << addr.toString()
++ << " [" << cmd << " " << args << "], cost (0x"
++ << costAddr.toString() << ", next 0x"
++ << nextCostAddr.toString() << ")" << endl;
++ }
++ else {
++ addr = costAddr;
++ code = cmd = TQString();
++ args = i18n("(No Assembler)");
++
++ currInstr = &(*costIt);
++ needCostAddr = true;
++
++ noAssLines++;
++ if (0) kdDebug() << "Dump Cost Addr: 0x" << addr.toString()
++ << " (no ass), objAddr 0x" << objAddr.toString() << endl;
++ }
++
++ // update inside
++ if (!inside) {
++ if (currInstr) inside = true;
++ }
++ else {
++ if (0) kdDebug() << "Check if 0x" << addr.toString() << " is in ]0x"
++ << costAddr.toString() << ",0x"
++ << (nextCostAddr - 3*Configuration::noCostInside()).toString()
++ << "[" << endl;
++
++ // Suppose a average instruction len of 3 bytes
++ if ( (addr > costAddr) &&
++ ((nextCostAddr==0) ||
++ (addr < nextCostAddr - 3*Configuration::noCostInside()) ))
++ inside = false;
++ }
++
++ int context = Configuration::context();
++
++ if ( ((costAddr==0) || (addr > costAddr + 3*context)) &&
++ ((nextCostAddr==0) || (addr < nextCostAddr - 3*context)) ) {
++
++ // the very last skipLine can be ommitted
++ if ((it == itEnd) &&
++ (itEnd == function->instrMap()->end())) skipLineWritten=true;
++
++ if (!skipLineWritten) {
++ skipLineWritten = true;
++ // a "skipping" line: print "..." instead of a line number
++ code = cmd = TQString();
++ args = TQString("...");
++ }
++ else
++ continue;
++ }
++ else
++ skipLineWritten = false;
++
++
++ ii = new InstrItem(this, this, addr, inside,
++ code, cmd, args, currInstr);
++ dumpedLines++;
++ if (0) kdDebug() << "Dumped 0x" << addr.toString() << " "
++ << (inside ? "Inside " : "Outside")
++ << (currInstr ? "Cost" : "") << endl;
++
++ // no calls/jumps if we have no cost for this line
++ if (!currInstr) continue;
++
++ if (!selected &&
++ (currInstr == _selectedItem) ||
++ (currInstr->line() == _selectedItem)) selected = ii;
++
++ if (!first) first = ii;
++
++ if (currInstr->subCost(_costType) > most) {
++ item = ii;
++ most = currInstr->subCost(_costType);
++ }
++
++ ii->setOpen(true);
++ TraceInstrCallList list = currInstr->instrCalls();
++ TraceInstrCall* ic;
++ for (ic=list.first();ic;ic=list.next()) {
++ if ((ic->subCost(_costType)==0) &&
++ (ic->subCost(_costType2)==0)) continue;
++
++ if (ic->subCost(_costType) > most) {
++ item = ii;
++ most = ic->subCost(_costType);
++ }
++
++ ii2 = new InstrItem(this, ii, addr, currInstr, ic);
++
++ if (!selected && (ic->call()->called() == _selectedItem))
++ selected = ii2;
++ }
++
++ TraceInstrJumpList jlist = currInstr->instrJumps();
++ TraceInstrJump* ij;
++ for (ij=jlist.first();ij;ij=jlist.next()) {
++ if (ij->executedCount()==0) continue;
++
++ new InstrItem(this, ii, addr, currInstr, ij);
++ }
++ }
++
++ if (selected) item = selected;
++ if (item) first = item;
++ if (first) {
++ ensureItemVisible(first);
++ _inSelectionUpdate = true;
++ setCurrentItem(first);
++ _inSelectionUpdate = false;
++ }
++
++ file.close();
++ pclose(iFILE);
++
++ // for arrows: go down the list according to list sorting
++ sort();
++ TQListViewItem *item1, *item2;
++ for (item1=firstChild();item1;item1 = item1->nextSibling()) {
++ ii = (InstrItem*)item1;
++ updateJumpArray(ii->addr(), ii, true, false);
++
++ for (item2=item1->firstChild();item2;item2 = item2->nextSibling()) {
++ ii2 = (InstrItem*)item2;
++ if (ii2->instrJump())
++ updateJumpArray(ii->addr(), ii2, false, true);
++ else
++ ii2->setJumpArray(_jump);
++ }
++ }
++
++ if (arrowLevels())
++ setColumnWidth(3, 10 + 6*arrowLevels() + itemMargin() * 2);
++ else
++ setColumnWidth(3, 0);
++
++
++ if (noAssLines > 1) {
++ // trace cost not machting code
++
++ new InstrItem(this, this, 1,
++ i18n("There is %n cost line without assembler code.",
++ "There are %n cost lines without assembler code.", noAssLines));
++ new InstrItem(this, this, 2,
++ i18n("This happens because the code of"));
++ new InstrItem(this, this, 3, TQString(" %1").arg(objfile));
++ new InstrItem(this, this, 4,
++ i18n("does not seem to match the profile data file."));
++ new InstrItem(this, this, 5, "");
++ new InstrItem(this, this, 6,
++ i18n("Are you using an old profile data file or is the above mentioned"));
++ new InstrItem(this, this, 7,
++ i18n("ELF object from an updated installation/another machine?"));
++ new InstrItem(this, this, 8, "");
++ return false;
++ }
++
++ if (dumpedLines == 0) {
++ // no matching line read from popen
++ new InstrItem(this, this, 1,
++ i18n("There seems to be an error trying to execute the command"));
++ new InstrItem(this, this, 2, "");
++ new InstrItem(this, this, 3, popencmd);
++ new InstrItem(this, this, 4, "");
++ new InstrItem(this, this, 5,
++ i18n("Check that the ELF object used in the command exists."));
++ new InstrItem(this, this, 6,
++ i18n("Check that you have installed 'objdump'."));
++ new InstrItem(this, this, 7,
++ i18n("This utility can be found in the 'binutils' package."));
++ return false;
++ }
++
++ return true;
++}
++
++
++void InstrView::updateInstrItems()
++{
++ InstrItem* ii;
++ TQListViewItem* item = firstChild();
++ for (;item;item = item->nextSibling()) {
++ ii = (InstrItem*)item;
++ TraceInstr* instr = ii->instr();
++ if (!instr) continue;
++
++ ii->updateCost();
++
++ TQListViewItem *next, *i = ii->firstChild();
++ for (;i;i = next) {
++ next = i->nextSibling();
++ ((InstrItem*)i)->updateCost();
++ }
++ }
++}
++
++void InstrView::readViewConfig(KConfig* c,
++ TQString prefix, TQString postfix, bool)
++{
++ KConfigGroup* g = configGroup(c, prefix, postfix);
++
++ if (0) qDebug("InstrView::readViewConfig");
++
++ _showHexCode = g->readBoolEntry("ShowHexCode", DEFAULT_SHOWHEXCODE);
++
++ delete g;
++}
++
++void InstrView::saveViewConfig(KConfig* c,
++ TQString prefix, TQString postfix, bool)
++{
++ KConfigGroup g(c, (prefix+postfix).ascii());
++
++ writeConfigEntry(&g, "ShowHexCode", _showHexCode, DEFAULT_SHOWHEXCODE);
++}
++
++#include "instrview.moc"
+diff --git a/kdecachegrind/kdecachegrind/instrview.h b/kdecachegrind/kdecachegrind/instrview.h
+new file mode 100644
+index 0000000..79d3d76
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/instrview.h
+@@ -0,0 +1,83 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Instruction View
++ */
++
++#ifndef INSTRVIEW_H
++#define INSTRVIEW_H
++
++#include <tqlistview.h>
++#include "traceitemview.h"
++
++class InstrItem;
++
++class InstrView : public TQListView, public TraceItemView
++{
++ friend class InstrItem;
++
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ InstrView(TraceItemView* parentView,
++ TQWidget* parent = 0, const char* name = 0);
++
++ virtual TQWidget* widget() { return this; }
++ TQString whatsThis() const;
++
++ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++
++protected:
++ int arrowLevels() { return _arrowLevels; }
++ void paintEmptyArea( TQPainter *, const TQRect & );
++
++private slots:
++ void context(TQListViewItem*, const TQPoint &, int);
++ void selectedSlot(TQListViewItem *);
++ void activatedSlot(TQListViewItem *);
++
++private:
++ TraceItem* canShow(TraceItem*);
++ void doUpdate(int);
++ void refresh();
++ void setColumnWidths();
++ void fillInstr();
++ void updateJumpArray(Addr,InstrItem*,bool,bool);
++ bool fillInstrRange(TraceFunction*,
++ TraceInstrMap::Iterator,TraceInstrMap::Iterator);
++ void updateInstrItems();
++
++ bool _inSelectionUpdate;
++
++ // arrows
++ int _arrowLevels;
++ // temporary needed on creation...
++ TQMemArray<TraceInstrJump*> _jump;
++ TraceInstrJumpList _lowList, _highList;
++
++ // remember width of hex code column if hidden
++ int _lastHexCodeWidth;
++
++ // widget options
++ bool _showHexCode;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/listutils.cpp b/kdecachegrind/kdecachegrind/listutils.cpp
+new file mode 100644
+index 0000000..0053646
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/listutils.cpp
+@@ -0,0 +1,266 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Some helper functions for TQListViewItem derivates
++ */
++
++#include <tqpainter.h>
++#include "listutils.h"
++
++#define COSTPIX_WIDTH 25
++
++TQPixmap colorPixmap(int w, int h, TQColor c)
++{
++ static TQPixmap* pixs[37];
++ static TQColor cols[37];
++ static bool inited = false;
++
++ if (!inited) {
++ for (int i=0;i<37;i++) pixs[i]=0;
++ inited = true;
++ }
++ int hash = (w+h+c.red()+c.green()+c.blue()) % 37;
++ if (pixs[hash]) {
++ if ((pixs[hash]->width() == w) &&
++ (pixs[hash]->height() == h) &&
++ (cols[hash] == c))
++ return *pixs[hash];
++
++ delete pixs[hash];
++ }
++
++
++ TQPixmap* pix = new TQPixmap(w, h);
++ pix->fill(c);
++ TQPainter p(pix);
++ p.setPen(c.light());
++ p.drawLine(0, 0, w-1, 0);
++ p.drawLine(0, 0, 0, h-1);
++ p.setPen(c.dark());
++ p.drawLine(w-1, 0, w-1, h-1);
++ p.drawLine(0, h-1, w-1, h-1);
++
++ pixs[hash] = pix;
++ cols[hash] = c;
++ return *pix;
++}
++
++/**
++ * Create a percentage pixmap with a filling rate of p percent (0-100).
++ * When withFrame==false, the pixmap is truncated to only the filled portion.
++ */
++TQPixmap percentagePixmap(int w, int h, int percent, TQColor c, bool framed)
++{
++ int iw, ix1, ix2, ih, iy1, iy2;
++
++ // inner rectangle to fill with bar
++ if (framed) {
++ iw = w-2, ix1 = 1, ix2 = w-2;
++ ih = h-2, iy1 = 1, iy2 = h-2;
++ }
++ else {
++ iw = w; ix1 = 0; ix2 = w-1;
++ ih = h; iy1 = 0; iy2 = h-1;
++ }
++
++ /* Limit bar to 100% */
++ int filled = (percent>100) ? iw+1 : iw*percent/100+1;
++ if (!framed) w=filled-1;
++ if (w<3) return TQPixmap();
++
++ TQPixmap pix(w, h);
++ pix.fill(TQt::white);
++ TQPainter p(&pix);
++ p.setPen(TQt::black);
++ if (framed)
++ p.drawRect(0, 0, w, h);
++
++ // inside
++ p.setPen(TQt::NoPen);
++ p.setBrush(c);
++ p.drawRect(ix1, iy1, filled-1,ih);
++
++ // frame
++ ix2 = ix1+filled-2;
++ p.setPen(c.light());
++ p.drawLine(ix1, iy1, ix2, iy1);
++ p.drawLine(ix1, iy1, ix1, iy2);
++ p.setPen(c.dark());
++ p.drawLine(ix1+1, iy2, ix2, iy2);
++ p.drawLine(ix2, iy1, ix2, iy2);
++
++ return pix;
++}
++
++inline TQColor partitionColor(int d, int max)
++{
++ return TQColor( (720*d/max) % 360,
++ 255-(128*d/max), 192, TQColor::Hsv);
++}
++
++
++TQPixmap partitionPixmap(int w, int h,
++ double* hist, TQColor* cArray, int maxIndex, bool framed)
++{
++ int lastPos = 0, nextPos;
++ double val=0.0, sum=0.0;
++ int d, dmin=maxIndex, dmax=0;
++ for (d = 0;d<maxIndex;d++)
++ if (hist[d]>0.0) {
++ sum += hist[d];
++ if (dmin>d) dmin = d;
++ if (dmax<d) dmax = d;
++ }
++
++ // inner rectangle to fill with bar
++ int iw, ix1, ix2, ih, iy1, iy2;
++ if (framed) {
++ iw = w-2, ix1 = 1, ix2 = w-2;
++ ih = h-2, iy1 = 1, iy2 = h-2;
++ }
++ else {
++ iw = w; ix1 = 0; ix2 = w-1;
++ ih = h; iy1 = 0; iy2 = h-1;
++ }
++
++ int filled = (int)(iw*sum+1);
++ if (!framed && (filled < w)) w=filled;
++ if (w<3) return TQPixmap();
++
++ TQPixmap pix(w, h);
++ pix.fill(TQt::white);
++ TQPainter p(&pix);
++ p.setPen(TQt::black);
++ if (framed)
++ p.drawRect(0, 0, w, h);
++
++ //qDebug("Sum %f, dw %d", sum,dw);
++
++ TQColor c, cLast;
++ bool leftDrawn = false;
++ int x1, x2=0;
++ int lastDiff=0, diff;
++ d=dmin;
++ while (d<dmax+1) {
++ val += hist[d];
++ nextPos = (int)(filled * val/sum);
++
++ //qDebug(" hist[%d] %f, val %f, nextPos %d", d, hist[d], val, nextPos);
++
++ diff = nextPos-lastPos;
++ if (diff==0) { d++; continue; }
++
++ c = cArray ? cArray[d] : partitionColor(d,maxIndex);
++
++ x1 = ix1+lastPos;
++ x2 = ix1+nextPos;
++ if (x2>=iw) x2=iw-1;
++
++ // inside
++ p.setPen(TQt::NoPen);
++ p.setBrush(c);
++ p.drawRect(x1, iy1, x2-x1+1, ih);
++
++ // lighter top border
++ p.setPen(c.light());
++ p.drawLine(x1, iy1, x2-1, iy1);
++
++ // when width for last and current distance >2, draw full 3D effect...
++ if (!leftDrawn) {
++ p.drawLine(x1, iy1+1, x1, iy2);
++ leftDrawn = true;
++ }
++
++ // darker bottom border
++ p.setPen(c.dark());
++ p.drawLine(x1, iy2, x2-1, iy2);
++
++ lastPos = nextPos;
++ lastDiff = diff;
++ cLast = c;
++ d++;
++ }
++
++ // right border (in last color)
++ if (x2>0)
++ p.drawLine(x2, iy1, x2, iy2);
++
++ return pix;
++}
++
++
++TQPixmap costPixmap(TraceCostType* ct, TraceCost* cost, double total, bool framed)
++{
++ if (ct->isReal()) {
++ TQColor color = ct->color();
++ double p = 100.0 * cost->subCost(ct) / total;
++ return percentagePixmap(COSTPIX_WIDTH, 10, (int)(p+.5), color, framed);
++ }
++
++ int maxIndex;
++ double h[MaxRealIndexValue];
++ TQColor* cs = ct->mapping()->realColors();
++ maxIndex = ct->histCost(cost, total, h);
++
++ if (maxIndex ==0) return TQPixmap();
++ return partitionPixmap(COSTPIX_WIDTH, 10, h, cs, maxIndex, framed);
++}
++
++
++
++// HighestCostList
++
++HighestCostList::HighestCostList()
++{
++ _maxSize = 0;
++ _count = 0;
++ _costType = 0;
++}
++
++void HighestCostList::clear(int maxSize)
++{
++ _maxSize = maxSize;
++ _count = 0;
++ _item.resize(maxSize);
++ _cost.resize(maxSize);
++}
++
++void HighestCostList::addCost(TraceCost* c, SubCost cost)
++{
++ int i;
++
++ _count++;
++ if (_count > _maxSize) {
++ if (_cost[_maxSize-1] >= cost) return;
++ i = _maxSize-1;
++ }
++ else i = _count-1;
++
++ for(; i>0; i--) {
++ if (_cost[i-1] >= cost) break;
++ else {
++ _cost[i] = _cost[i-1];
++ _item[i] = _item[i-1];
++ }
++ }
++ _cost[i] = cost;
++ _item[i] = c;
++}
++
++
+diff --git a/kdecachegrind/kdecachegrind/listutils.h b/kdecachegrind/kdecachegrind/listutils.h
+new file mode 100644
+index 0000000..e3e13fb
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/listutils.h
+@@ -0,0 +1,65 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Some helper functions for TQListViewItem derivates
++ */
++
++#ifndef LISTUTILS_H
++#define LISTUTILS_H
++
++#include <tqpixmap.h>
++#include <tqstring.h>
++#include <tqcolor.h>
++#include "tracedata.h"
++
++TQString bigNum(SubCost);
++TQPixmap colorPixmap(int w, int h, TQColor c);
++TQPixmap percentagePixmap(int w, int h, int percent, TQColor c, bool framed);
++TQPixmap partitionPixmap(int w, int h, double* hist, TQColor*,
++ int maxIndex, bool framed);
++TQPixmap costPixmap(TraceCostType* ct, TraceCost* cost, double total, bool framed);
++
++/**
++ * A class to calculate the <maxSize> TraceCost items
++ * with highest cost.
++ */
++
++class HighestCostList
++{
++ public:
++ HighestCostList();
++
++ void clear(int maxSize);
++ void addCost(TraceCost*, SubCost);
++ int count() { return _count; }
++ int realCount() { return (_count > _maxSize) ? _maxSize:_count; }
++ int maxSize() { return _maxSize; }
++ bool hasMore() { return _count > _maxSize; }
++ TraceCost* operator[] (int i)
++ { return (i>=0 && i<_count && i<_maxSize) ? _item[i] : 0; }
++
++ private:
++ TraceCostList _list;
++ int _maxSize, _count;
++ TraceCostType* _costType;
++ TQMemArray<TraceCost*> _item;
++ TQMemArray<SubCost> _cost;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/lo16-app-kcachegrind.png b/kdecachegrind/kdecachegrind/lo16-app-kcachegrind.png
+new file mode 100644
+index 0000000..0985586
+Binary files /dev/null and b/kdecachegrind/kdecachegrind/lo16-app-kcachegrind.png differ
+diff --git a/kdecachegrind/kdecachegrind/lo32-app-kcachegrind.png b/kdecachegrind/kdecachegrind/lo32-app-kcachegrind.png
+new file mode 100644
+index 0000000..12542c8
+Binary files /dev/null and b/kdecachegrind/kdecachegrind/lo32-app-kcachegrind.png differ
+diff --git a/kdecachegrind/kdecachegrind/loader.cpp b/kdecachegrind/kdecachegrind/loader.cpp
+new file mode 100644
+index 0000000..a4aecf5
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/loader.cpp
+@@ -0,0 +1,85 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Base class for loaders of profiling data.
++ */
++
++#include "loader.h"
++
++
++/// Loader
++
++LoaderList Loader::_loaderList;
++
++Loader::Loader(TQString name, TQString desc)
++{
++ _name = name;
++ _description = desc;
++}
++
++Loader::~Loader()
++{}
++
++bool Loader::canLoadTrace(TQFile*)
++{
++ return false;
++}
++
++bool Loader::loadTrace(TracePart*)
++{
++ return false;
++}
++
++Loader* Loader::matchingLoader(TQFile* file)
++{
++ Loader* l;
++ for (l=_loaderList.first(); l; l = _loaderList.next())
++ if (l->canLoadTrace(file))
++ return l;
++
++ return 0;
++}
++
++Loader* Loader::loader(TQString name)
++{
++ Loader* l;
++ for (l=_loaderList.first(); l; l = _loaderList.next())
++ if (l->name() == name)
++ return l;
++
++ return 0;
++}
++
++// factories of available loaders
++Loader* createCachegrindLoader();
++
++void Loader::initLoaders()
++{
++ _loaderList.append(createCachegrindLoader());
++ //_loaderList.append(GProfLoader::createLoader());
++}
++
++void Loader::deleteLoaders()
++{
++ _loaderList.setAutoDelete(true);
++ _loaderList.clear();
++}
++
++
++#include "loader.moc"
+diff --git a/kdecachegrind/kdecachegrind/loader.h b/kdecachegrind/kdecachegrind/loader.h
+new file mode 100644
+index 0000000..f79f13d
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/loader.h
+@@ -0,0 +1,80 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Base class for loaders of profiling data.
++ */
++
++#ifndef LOADER_H
++#define LOADER_H
++
++#include <tqobject.h>
++#include <tqptrlist.h>
++#include <tqstring.h>
++
++class TQFile;
++class TraceData;
++class TracePart;
++class Loader;
++
++
++typedef TQPtrList<Loader> LoaderList;
++
++/**
++ * To implement a new loader, inherit from the Loader class
++ * and implement canLoadTrace(), loadTrace() and if a trace in
++ * this format can consist out of multiple parts, implement
++ * isPartOfTrace(), too.
++ * For registration, put into the static initLoaders() function
++ * of this base class a _loaderList.append(new MyLoader()).
++ *
++ * KCachegrind will use the first matching loader.
++ */
++
++class Loader: public TQObject
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ Loader(TQString name, TQString desc);
++ virtual ~Loader();
++
++ virtual bool canLoadTrace(TQFile* file);
++ virtual bool loadTrace(TracePart*);
++
++ static Loader* matchingLoader(TQFile* file);
++ static Loader* loader(TQString name);
++ static void initLoaders();
++ static void deleteLoaders();
++
++ TQString name() const { return _name; }
++ TQString description() const { return _description; }
++
++signals:
++ void updateStatus(TQString, int);
++
++private:
++ TQString _name, _description;
++
++ static LoaderList _loaderList;
++};
++
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/main.cpp b/kdecachegrind/kdecachegrind/main.cpp
+new file mode 100644
+index 0000000..fd9df1b
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/main.cpp
+@@ -0,0 +1,95 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * KCachegrind startup
++ */
++
++// for KCACHEGRIND_VERSION
++#include "../version.h"
++
++#include <tqfile.h>
++#include <kapplication.h>
++#include <kcmdlineargs.h>
++#include <kaboutdata.h>
++#include <klocale.h>
++
++#include "toplevel.h"
++#include "tracedata.h"
++#include "loader.h"
++
++static KCmdLineOptions options[] =
++{
++ { "r <exec>", I18N_NOOP("Run <exec> under cachegrind"), 0 },
++ { "+[trace]", I18N_NOOP("Show information of this trace"), 0 },
++ KCmdLineLastOption // End of options.
++};
++
++int main( int argc, char ** argv )
++{
++ KAboutData aboutData("kdecachegrind",
++ I18N_NOOP("KCachegrind"),
++ KCACHEGRIND_VERSION,
++ I18N_NOOP("KDE Frontend for Cachegrind"),
++ KAboutData::License_GPL,
++ I18N_NOOP("(C) 2002, 2003, 2004"), 0,
++ "http://kdecachegrind.sf.net");
++ aboutData.addAuthor("Josef Weidendorfer",
++ I18N_NOOP("Author/Maintainer"),
++ "Josef.Weidendorfer@gmx.de");
++
++ KCmdLineArgs::init(argc, argv, &aboutData);
++ KCmdLineArgs::addCmdLineOptions( options );
++
++ KApplication a;
++ TopLevel* t;
++ Loader::initLoaders();
++
++ if (a.isRestored()){
++ int n = 1;
++ while (KMainWindow::canBeRestored(n)){
++ (new TopLevel())->restore(n);
++ n++;
++ }
++ }
++ else {
++ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
++ if (args->count()>0) {
++ for(int i = 0; i < args->count(); i++) {
++ t = new TopLevel();
++ t->show();
++ t->loadDelayed(TQFile::decodeName(args->arg(i)));
++ }
++ }
++ else {
++ // load trace in current dir
++ t = new TopLevel();
++ t->show();
++ t->loadDelayed(".");
++ }
++ }
++
++ a.connect( &a, TQT_SIGNAL( lastWindowClosed() ), &a, TQT_SLOT( quit() ) );
++ int res = a.exec();
++
++ // to make leak checking in valgrind happy...
++ Loader::deleteLoaders();
++ TraceItem::cleanup();
++
++ return res;
++}
+diff --git a/kdecachegrind/kdecachegrind/multiview.cpp b/kdecachegrind/kdecachegrind/multiview.cpp
+new file mode 100644
+index 0000000..4288e2d
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/multiview.cpp
+@@ -0,0 +1,224 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * MultiView, enclosing multiple TabView's with a user choosable
++ * active view (i.e. focus), separated by a splitter.
++ * Selection of the active view is shown in the next to the right view
++ * (with wrap around).
++ */
++
++#include <tqobjectlist.h>
++#include <kconfig.h>
++#include <kdebug.h>
++
++#include "multiview.h"
++#include "tabview.h"
++
++//
++// MultiView
++//
++
++MultiView::MultiView(TopLevel* top, TQWidget* parent, const char* name)
++ : TQSplitter(parent, name), TraceItemView(0, top)
++{
++ // default
++ setOrientation(Qt::Horizontal);
++
++ appendView();
++ _active = _views.first();
++ _active->setActive(true);
++}
++
++void MultiView::setData(TraceData* d)
++{
++ TraceItemView::setData(d);
++
++ TabView* tv;
++ for(tv=_views.first(); tv; tv=_views.next())
++ tv->setData(d);
++}
++
++void MultiView::setChildCount(int n)
++{
++ while(n< (int)_views.count()) removeView();
++ while(n> (int)_views.count()) appendView();
++}
++
++void MultiView::appendView()
++{
++ int n = _views.count()+1;
++
++ TabView* tv = new TabView(this, this,
++ TQString("TabView-%1").arg(n).ascii());
++ connect(tv, TQT_SIGNAL(activated(TabView*)),
++ this, TQT_SLOT(tabActivated(TabView*)) );
++ _views.append(tv);
++ tv->show();
++
++ // set same attributes as in active view
++ tv->set(0, _data, _costType, _costType2,
++ _groupType, _partList, _activeItem, 0);
++ tv->updateView();
++
++ if (0) kdDebug() << "MultiView::appendView, now "
++ << _views.count() << endl;
++}
++
++void MultiView::removeView()
++{
++ if (_views.count()<=1) return;
++
++ TabView* last = _views.last();
++
++ // if last tab is active, make first active
++ if (last == _active) {
++ TabView* newActive = _views.first();
++ newActive->setActive(true);
++ tabActivated(newActive);
++ }
++
++ _views.removeRef(last);
++ delete last;
++
++ if (0) kdDebug() << "MultiView::removeView, now "
++ << _views.count() << endl;
++}
++
++
++void MultiView::tabActivated(TabView* newActiveTab)
++{
++ if (_active == newActiveTab) return;
++
++ if (0) kdDebug() << "MultiView::tabActivated "
++ << newActiveTab->name() << endl;
++
++ TraceItem* oldActiveItem = 0;
++ if (_active) {
++ oldActiveItem = _active->activeItem();
++ _active->setActive(false);
++ }
++ _active = newActiveTab;
++
++ // make the active item of the new TabView active
++ if (_active && (oldActiveItem != _active->activeItem()))
++ TraceItemView::activated(_active->activeItem());
++}
++
++void MultiView::selected(TraceItemView* sender, TraceItem* i)
++{
++ if (0) kdDebug() << "MultiView::selected " << i->name()
++ << ", sender " << sender->widget()->name() << endl;
++
++ // we react only on selection changes of the active TabView
++ if (sender != (TraceItemView*)_active) return;
++
++ _views.findRef(_active);
++ TabView* next = _views.next();
++ if (!next) next = _views.first();
++
++ // don't change item of active tab
++ if (next == _active) return;
++
++ next->activate(i);
++ next->updateView();
++}
++
++void MultiView::activated(TraceItemView* sender, TraceItem* i)
++{
++ if (0) kdDebug() << "MultiView::activated " << i->name()
++ << ", sender " << sender->widget()->name() << endl;
++
++ // we react only on selection changes of the active TabView
++ if (sender != (TraceItemView*)_active) return;
++
++ TraceItemView::activated(sender,i);
++}
++
++void MultiView::doUpdate(int changeType)
++{
++ TabView* tv;
++ for(tv=_views.first(); tv; tv=_views.next()) {
++ tv->set(changeType, _data, _costType, _costType2,
++ _groupType, _partList,
++ (tv == _active) ? _activeItem : tv->activeItem(),
++ tv->selectedItem());
++ tv->notifyChange(changeType);
++ if (tv->isViewVisible())
++ tv->updateView();
++ }
++}
++
++
++void MultiView::readViewConfig(KConfig* c,
++ TQString prefix, TQString postfix,
++ bool withOptions)
++{
++ if (0) qDebug("%s::readConfig(%s%s)", name(),
++ prefix.ascii(), postfix.ascii());
++
++ TQString active;
++ KConfigGroup* g = configGroup(c, prefix, postfix);
++ int n = g->readNumEntry("Panels", 1);
++ setChildCount(n);
++ setOrientation( (g->readEntry("Orientation") == TQString("Horizontal")) ?
++ Qt::Horizontal : Qt::Vertical );
++
++ setSizes(g->readIntListEntry("PanelSizes"));
++
++ active = g->readEntry("ActivePanel", "");
++ delete g;
++
++ TabView* tv, *activeTV = 0;
++ for(tv=_views.first();tv;tv=_views.next()) {
++ if (tv->name() == active) activeTV=tv;
++ tv->readViewConfig(c, TQString("%1-%2").arg(prefix).arg(tv->name()),
++ postfix, withOptions);
++ }
++
++ // activate panel after restoring
++ if (!activeTV) activeTV = _views.first();
++
++ if (_active == activeTV)
++ TraceItemView::activated(_active->activeItem());
++ else
++ activeTV->setActive(true);
++}
++
++void MultiView::saveViewConfig(KConfig* c,
++ TQString prefix, TQString postfix,
++ bool withOptions)
++{
++ KConfigGroup g(c, (prefix+postfix).ascii());
++
++ g.writeEntry("Panels", childCount());
++ g.writeEntry("Orientation",
++ (orientation() == Qt::Horizontal) ?
++ "Horizontal" : "Vertical");
++
++ g.writeEntry("PanelSizes", sizes());
++ g.writeEntry("ActivePanel", _active ? _active->name() : "none");
++
++ TabView* tv;
++ for(tv=_views.first();tv;tv=_views.next())
++ tv->saveViewConfig(c, TQString("%1-%2").arg(prefix).arg(tv->name()),
++ postfix, withOptions);
++}
++
++
++#include "multiview.moc"
+diff --git a/kdecachegrind/kdecachegrind/multiview.h b/kdecachegrind/kdecachegrind/multiview.h
+new file mode 100644
+index 0000000..9d77101
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/multiview.h
+@@ -0,0 +1,67 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * MultiView, enclosing multiple (default: 2) TabView's with a user
++ * choosable active view (i.e. focus). This is a splitter itself.
++ * Selection of the active view is shown in the next to the right view
++ * (with wrap around).
++ */
++
++#ifndef MULTIVIEW_H
++#define MULTIVIEW_H
++
++#include <tqsplitter.h>
++#include <tqptrlist.h>
++#include "traceitemview.h"
++#include "tabview.h" // because of TQPtrList<TabView>
++
++class MultiView : public TQSplitter, public TraceItemView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ MultiView(TopLevel* top, TQWidget* parent = 0, const char* name = 0);
++
++ TQWidget* widget() { return this; }
++ TabView* activeTabView() const { return _active; }
++ void setData(TraceData*);
++
++ void appendView();
++ void removeView();
++ void setChildCount(int);
++ int childCount() { return _views.count(); }
++
++ void selected(TraceItemView*, TraceItem*);
++ void activated(TraceItemView*, TraceItem*);
++
++ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++
++public slots:
++ void tabActivated(TabView*);
++
++ private:
++ void doUpdate(int);
++
++ TabView* _active;
++ TQPtrList<TabView> _views;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/partgraph.cpp b/kdecachegrind/kdecachegrind/partgraph.cpp
+new file mode 100644
+index 0000000..a20f53d
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/partgraph.cpp
+@@ -0,0 +1,534 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * TracePart as Nested Area
++ */
++
++#include <klocale.h>
++
++#include "partgraph.h"
++#include "configuration.h"
++#include "listutils.h"
++
++
++// PartAreaWidget
++
++PartAreaWidget::PartAreaWidget(TQWidget* parent, const char* name)
++ : TreeMapWidget(new BasePartItem(), parent, name)
++{
++ _data = 0;
++ _function = 0;
++
++ _costType = 0;
++ _groupType = TraceCost::NoCostType;
++ _visualisation = NoVisualisation;
++ _zoomFunction = false;
++ _callLevels = 1;
++}
++
++void PartAreaWidget::setData(TraceData* data)
++{
++ if (data == _data) return;
++
++ _data = data;
++ _function = 0;
++ _hiddenParts.clear();
++
++ ((BasePartItem*)base())->setData(data);
++}
++
++void PartAreaWidget::changeHidden(const TracePartList& list)
++{
++ _hiddenParts = list;
++ base()->refresh();
++}
++
++
++void PartAreaWidget::setCostType(TraceCostType* ct)
++{
++ _costType = ct;
++
++ // this resizes items
++ base()->redraw();
++}
++
++void PartAreaWidget::setVisualisation(VisualisationMode m)
++{
++ _visualisation = m;
++ refreshParts();
++}
++
++void PartAreaWidget::setZoomFunction(bool zoomFunction)
++{
++ _zoomFunction = zoomFunction;
++ refreshParts();
++}
++
++void PartAreaWidget::setCallLevels(int callLevels)
++{
++ _callLevels = callLevels;
++ refreshParts();
++}
++
++void PartAreaWidget::refreshParts()
++{
++ // rebuild only subparts to keep part selection state
++ TreeMapItem* i;
++ TreeMapItemList* l = base()->children();
++ if (l)
++ for (i=l->first();i;i=l->next())
++ i->refresh();
++
++ // but resize part areas
++ base()->redraw();
++}
++
++
++void PartAreaWidget::setFunction(TraceFunction* f)
++{
++ _function = f;
++
++ if (_visualisation == PartAreaWidget::Inclusive)
++ refreshParts();
++}
++
++void PartAreaWidget::setGroupType(TraceCost::CostType gt)
++{
++ _groupType = gt;
++
++ // rebuild hierarchy below parts.
++ // thus, selected parts stay selected
++ TreeMapItem* i;
++ TreeMapItemList* l = base()->children();
++ if (l)
++ for (i=l->first();i;i=l->next())
++ i->refresh();
++
++ base()->redraw();
++}
++
++bool PartAreaWidget::isHidden(TracePart* part) const
++{
++ return (_hiddenParts.containsRef(part)>0);
++}
++
++TQColor PartAreaWidget::groupColor(TraceFunction* f) const
++{
++ if (!f)
++ return colorGroup().button();
++
++ return Configuration::functionColor(_groupType, f);
++}
++
++TQString PartAreaWidget::tipString(TreeMapItem* i) const
++{
++ TQString tip, itemTip;
++ int count = 0;
++
++ //qDebug("PartAreaWidget::tipString for '%s'", i->name().ascii());
++
++ // first, SubPartItem's
++ while (i && count<Configuration::maxSymbolCount() && i->rtti() == 3) {
++ itemTip = i->text(0);
++ if ((int)itemTip.length()>Configuration::maxSymbolLength())
++ itemTip = itemTip.left(Configuration::maxSymbolLength()) + "...";
++
++ if (!i->text(1).isEmpty())
++ itemTip += " (" + i->text(1) + ")";
++
++ if (!tip.isEmpty())
++ itemTip += "\n";
++
++ tip = itemTip + tip;
++ i = i->parent();
++ count++;
++ }
++
++ // skip to part
++ while (i && i->rtti()==3) i = i->parent();
++
++ if (i && i->rtti()==2) {
++ itemTip = i18n("Profile Part %1").arg(i->text(0));
++ if (!i->text(1).isEmpty())
++ itemTip += " (" + i->text(1) + ")";
++
++ if (!tip.isEmpty())
++ itemTip += "\n";
++
++ tip = itemTip + tip;
++ }
++
++// qDebug("PartAreaWidget:: tip %s, itemTip %s",
++// tip.ascii(), itemTip.ascii());
++
++ return tip;
++}
++
++
++
++
++
++// BasePartItem
++
++BasePartItem::BasePartItem()
++ : TreeMapItem()
++{
++ _data = 0;
++ setSorting(-1);
++}
++
++void BasePartItem::setData(TraceData* data)
++{
++ if (data == _data) return;
++
++ _data = data;
++ refresh();
++}
++
++TreeMapItemList* BasePartItem::children()
++{
++ if (!_data) return _children;
++
++ if (!initialized()) {
++// qDebug("Create Parts (%s)", name().ascii());
++
++ PartAreaWidget* w = (PartAreaWidget*) widget();
++ TracePart* part;
++ TracePartList l = _data->parts();
++ for (part=l.first();part;part=l.next())
++ if (!w->isHidden(part))
++ addItem(new PartItem(part));
++ }
++
++ return _children;
++}
++
++TQString BasePartItem::text(int textNo) const
++{
++ if (textNo == 0) {
++ if (!_data)
++ return i18n("(no trace)");
++
++ if (_data->parts().count() == 0)
++ return i18n("(no part)");
++ }
++ return TQString();
++}
++
++
++TQColor BasePartItem::backColor() const
++{
++ return widget()->colorGroup().base();
++}
++
++double BasePartItem::value() const
++{
++ if (!_data) return 0;
++
++ PartAreaWidget* w = (PartAreaWidget*) widget();
++ return (double)_data->subCost(w->costType());
++}
++
++
++
++
++
++// PartItem
++
++PartItem::PartItem(TracePart* p)
++{
++ _p = p;
++ _factor=1;
++}
++
++TQString PartItem::text(int textNo) const
++{
++ if (textNo == 0)
++ return _p->prettyName();
++
++ if (textNo != 1)
++ return TQString();
++
++ TraceCostType* ct;
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++ SubCost v;
++
++ ct = w->costType();
++ v = _p->subCost(ct);
++
++ if (Configuration::showPercentage()) {
++ TraceCost* t = _p->data()->totals();
++ double p = 100.0 * v / t->subCost(ct);
++ return TQString("%1 %")
++ .arg(p, 0, 'f', Configuration::percentPrecision());
++ }
++ return v.pretty();
++}
++
++
++TQPixmap PartItem::pixmap(int i) const
++{
++ if (i != 1) return TQPixmap();
++
++ // Cost pixmap
++
++ TraceCostType* ct = ((PartAreaWidget*)widget())->costType();
++ return costPixmap( ct, _p, (double) (_p->data()->totals()->subCost(ct)), false );
++}
++
++
++double PartItem::value() const
++{
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++ TraceCostType* ct = w->costType();
++ if ((w->visualisation() == PartAreaWidget::Inclusive) &&
++ w->zoomFunction()) {
++
++ // use value of zoomed function
++ TraceFunction* f = w->function();
++ if (f) {
++ TracePartFunction* pf = (TracePartFunction*) f->findDepFromPart(_p);
++ if (pf)
++ return (double) pf->inclusive()->subCost(ct);
++ // when function is not available in part, hide part
++ return 0.0;
++ }
++ }
++ return (double) _p->subCost(ct);
++}
++
++double PartItem::sum() const
++{
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++ if (w->visualisation() == PartAreaWidget::Inclusive) {
++ double s = value();
++ //qDebug("PartItem::sum [part %s]: %d", _p->name().ascii(), s);
++ return s;
++ }
++ return 0.0;
++}
++
++TreeMapItemList* PartItem::children()
++{
++ if (initialized()) return _children;
++
++ TraceCost* c;
++// qDebug("Create Part subitems (%s)", name().ascii());
++
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++ if (w->visualisation() == PartAreaWidget::Inclusive) {
++ TraceFunction* f = w->function();
++ if (f) {
++ c = f->findDepFromPart(_p);
++ if (c) addItem(new SubPartItem(c));
++ }
++
++ return _children;
++ }
++
++
++ switch( ((PartAreaWidget*)widget())->groupType() ) {
++
++ case TraceCost::Object:
++ {
++ TraceObjectMap::Iterator it;
++ for ( it = _p->data()->objectMap().begin();
++ it != _p->data()->objectMap().end(); ++it ) {
++ c = (*it).findDepFromPart(_p);
++ if (c)
++ addItem(new SubPartItem(c));
++ }
++ }
++ break;
++
++ case TraceCost::Class:
++ {
++ TraceClassMap::Iterator it;
++ for ( it = _p->data()->classMap().begin();
++ it != _p->data()->classMap().end(); ++it ) {
++ c = (*it).findDepFromPart(_p);
++ if (c)
++ addItem(new SubPartItem(c));
++ }
++ }
++ break;
++
++ case TraceCost::File:
++ {
++ TraceFileMap::Iterator it;
++ for ( it = _p->data()->fileMap().begin();
++ it != _p->data()->fileMap().end(); ++it ) {
++ c = (*it).findDepFromPart(_p);
++ if (c)
++ addItem(new SubPartItem(c));
++ }
++ }
++ break;
++
++ case TraceCost::Function:
++ {
++ TraceFunctionMap::Iterator it;
++ for ( it = _p->data()->functionMap().begin();
++ it != _p->data()->functionMap().end(); ++it ) {
++ c = (*it).findDepFromPart(_p);
++ if (c)
++ addItem(new SubPartItem(c));
++ }
++ }
++ break;
++
++ default:
++ break;
++ }
++
++ return _children;
++}
++
++
++TQColor PartItem::backColor() const
++{
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++ return w->groupColor(0);
++}
++
++
++// SubPartItem
++
++SubPartItem::SubPartItem(TraceCost* c)
++{
++ _partCostItem = c;
++ _factor=1;
++}
++
++TQString SubPartItem::text(int textNo) const
++{
++ if (textNo == 0) {
++ if (!_partCostItem)
++ return i18n("(unknown)");
++
++ return _partCostItem->dependant()->prettyName();
++ }
++
++ if (textNo != 1)
++ return TQString();
++
++ TraceCostType* ct;
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++ SubCost v;
++
++ ct = w->costType();
++ if (w->visualisation() == PartAreaWidget::Inclusive)
++ v = ((TracePartFunction*)_partCostItem)->inclusive()->subCost(ct);
++ else
++ v = _partCostItem->subCost(ct);
++
++ if (Configuration::showPercentage()) {
++ TraceCost* t = Configuration::showExpanded() ?
++ _partCostItem->part() : _partCostItem->part()->data()->totals();
++ double p = 100.0 * v / t->subCost(ct);
++ return TQString("%1 %")
++ .arg(p, 0, 'f', Configuration::percentPrecision());
++ }
++ return v.pretty();
++}
++
++TQPixmap SubPartItem::pixmap(int i) const
++{
++ if (i != 1) return TQPixmap();
++
++ // Cost pixmap
++
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++ TraceCostType* ct = w->costType();
++ TraceCost* t = Configuration::showExpanded() ?
++ _partCostItem->part() : _partCostItem->part()->data()->totals();
++ TraceCost* c;
++ if (w->visualisation() == PartAreaWidget::Inclusive)
++ c = ((TracePartFunction*)_partCostItem)->inclusive();
++ else
++ c = _partCostItem;
++
++ return costPixmap( ct, c, (double) (t->subCost(ct)), false );
++}
++
++double SubPartItem::value() const
++{
++ TraceCostType* ct;
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++
++ ct = w->costType();
++ if (w->visualisation() == PartAreaWidget::Inclusive)
++ return (double)
++ ((TracePartFunction*)_partCostItem)->inclusive()->subCost(ct);
++
++ return (double) _partCostItem->subCost(ct);
++}
++
++double SubPartItem::sum() const
++{
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++ if (w->visualisation() == PartAreaWidget::Inclusive) {
++ double s = value();
++ //qDebug("SubPartItem::sum [Cost %s]: %d", _cost->name().ascii(), s);
++ return s;
++ }
++ return 0.0;
++}
++
++TreeMapItemList* SubPartItem::children()
++{
++ if (!initialized()) {
++// qDebug("Create Part sub-subitems (%s)", name().ascii());
++
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++
++ if (depth()-2 > w->callLevels())
++ return _children;
++
++ if (w->visualisation() == PartAreaWidget::Inclusive) {
++ TracePartCall* call;
++ TracePartCallList l;
++
++ setSum(value());
++
++ l = ((TracePartFunction*)_partCostItem)->partCallings();
++ for (call=l.first();call;call=l.next()) {
++ TraceFunction* called = call->call()->called();
++ TraceCost* partCalled = called->findDepFromPart(call->part());
++ if (partCalled)
++ addItem(new SubPartItem(partCalled));
++ }
++ }
++ }
++
++ return _children;
++}
++
++
++TQColor SubPartItem::backColor() const
++{
++ PartAreaWidget* w = (PartAreaWidget*)widget();
++ if (w->visualisation() == PartAreaWidget::Inclusive)
++ return w->groupColor((TraceFunction*)(_partCostItem->dependant()));
++
++ return Configuration::groupColor(_partCostItem->dependant());
++}
++
++
++#include "partgraph.moc"
+diff --git a/kdecachegrind/kdecachegrind/partgraph.h b/kdecachegrind/kdecachegrind/partgraph.h
+new file mode 100644
+index 0000000..f28f12e
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/partgraph.h
+@@ -0,0 +1,132 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * TracePart Graph
++ */
++
++#ifndef PARTGRAPH_H
++#define PARTGRAPH_H
++
++#include "treemap.h"
++#include "tracedata.h"
++
++class PartAreaWidget: public TreeMapWidget
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ // Visualisation inside of trace parts
++ enum VisualisationMode { NoVisualisation, Partitioning, Inclusive };
++
++ PartAreaWidget(TQWidget* parent=0, const char* name=0);
++
++ void setData(TraceData* d);
++ void setCostType(TraceCostType* ct);
++ void setGroupType(TraceCost::CostType gt);
++ void setVisualisation(VisualisationMode);
++ void setZoomFunction(bool zoomFunction);
++ void setCallLevels(int callLevels);
++ void setFunction(TraceFunction* f);
++
++ TraceCostType* costType() const { return _costType; }
++ TraceCost::CostType groupType() const { return _groupType; }
++ TraceFunction* function() const { return _function; }
++ VisualisationMode visualisation() const { return _visualisation; }
++ bool zoomFunction() const { return _zoomFunction; }
++ int callLevels() const { return _callLevels; }
++
++ TQColor groupColor(TraceFunction*) const;
++ TQString tipString(TreeMapItem*) const;
++
++ void changeHidden(const TracePartList& list);
++ bool isHidden(TracePart*) const;
++
++private:
++ void refreshParts();
++
++ TraceData* _data;
++ TraceCostType* _costType;
++ TraceCost::CostType _groupType;
++ TraceFunction* _function;
++ VisualisationMode _visualisation;
++ bool _zoomFunction;
++ int _callLevels;
++
++ TracePartList _hiddenParts;
++};
++
++class BasePartItem: public TreeMapItem
++{
++public:
++ BasePartItem();
++
++ void setData(TraceData* d);
++
++ int rtti() const { return 1; }
++ double value() const;
++ TQString text(int) const;
++ int borderWidth() const { return 0; }
++ TreeMapItemList* children();
++ TQColor backColor() const;
++
++private:
++ TraceData* _data;
++};
++
++class PartItem: public TreeMapItem
++{
++public:
++ PartItem(TracePart* p);
++ int rtti() const { return 2; }
++ TracePart* part() { return _p; }
++ double value() const;
++ double sum() const;
++ int borderWidth() const { return 0; }
++ TQString text(int) const;
++ TQPixmap pixmap(int) const;
++ TreeMapItemList* children();
++ TQColor backColor() const;
++
++private:
++ TracePart* _p;
++ unsigned int _factor;
++};
++
++class SubPartItem: public TreeMapItem
++{
++public:
++ SubPartItem(TraceCost*);
++ int rtti() const { return 3; }
++ TraceCost* partCostItem() { return _partCostItem; }
++ double value() const;
++ double sum() const;
++ SplitMode splitMode() const { return Vertical; }
++ TQString text(int) const;
++ TQPixmap pixmap(int) const;
++ TreeMapItemList* children();
++ TQColor backColor() const;
++
++private:
++ TraceCost* _partCostItem;
++ unsigned int _factor;
++};
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/partlistitem.cpp b/kdecachegrind/kdecachegrind/partlistitem.cpp
+new file mode 100644
+index 0000000..40c2db3
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/partlistitem.cpp
+@@ -0,0 +1,189 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#include <math.h>
++
++#include <tqpainter.h>
++#include <tqregexp.h>
++
++#include <klocale.h>
++#include <kiconloader.h>
++#include <kapplication.h>
++
++#include "listutils.h"
++#include "partlistitem.h"
++#include "coverage.h"
++#include "configuration.h"
++
++
++// PartListItem
++
++PartListItem::PartListItem(TQListView* parent, TraceCostItem* costItem,
++ TraceCostType* ct, TraceCost::CostType gt,
++ TracePart* part)
++ :TQListViewItem(parent)
++{
++ _partCostItem = costItem->findDepFromPart(part);
++ _part = part;
++ _groupType = gt;
++ _costType = ct;
++
++#if 0
++ TQString partName = TQString::number(part->partNumber());
++ if (part->data()->maxThreadID() >1)
++ partName += i18n(" (Thread %1)").arg(part->threadID());
++ setText(0, partName);
++#else
++ setText(0, _part->prettyName());
++#endif
++
++ if (_part->trigger().isEmpty())
++ setText(4,i18n("(none)"));
++ else
++ setText(4, _part->trigger());
++
++ update();
++}
++
++void PartListItem::setCostType(TraceCostType* ct)
++{
++ if (_costType == ct) return;
++
++ _costType = ct;
++ update();
++}
++
++void PartListItem::setGroupType(TraceCost::CostType gt)
++{
++ if (_groupType == gt) return;
++
++ _groupType = gt;
++ update();
++}
++
++void PartListItem::update()
++{
++ TracePartFunction* pf;
++ pf = !_partCostItem ? 0 :
++ (_partCostItem->type()==TraceCost::PartFunction) ?
++ ((TracePartFunction*)_partCostItem) : 0;
++
++ double total = _part->subCost(_costType);
++
++ TraceCost* selfTotalCost = _part;
++ if (pf && Configuration::showExpanded()) {
++ switch(_groupType) {
++ case TraceCost::Object: selfTotalCost = pf->partObject(); break;
++ case TraceCost::Class: selfTotalCost = pf->partClass(); break;
++ case TraceCost::File: selfTotalCost = pf->partFile(); break;
++ default: break;
++ }
++ }
++ double selfTotal = selfTotalCost->subCost(_costType);
++
++ _pure = _partCostItem ? _partCostItem->subCost(_costType) : SubCost(0);
++ _sum = pf ? pf->inclusive()->subCost(_costType) : SubCost(0);
++
++ if (selfTotal == 0 || !_partCostItem) {
++ setText(2, TQString("-"));
++ setPixmap(2, TQPixmap());
++ }
++ else {
++ double pure = 100.0 * _pure / selfTotal;
++ if (Configuration::showPercentage()) {
++ setText(2, TQString("%1")
++ .arg(pure, 0, 'f', Configuration::percentPrecision()));
++ }
++ else
++ setText(2, _partCostItem->prettySubCost(_costType));
++
++ setPixmap(2, costPixmap(_costType, _partCostItem, selfTotal, false));
++ }
++
++ if (total == 0 || !pf) {
++ setText(1, TQString("-"));
++ setPixmap(1, TQPixmap());
++ }
++ else {
++ double sum = 100.0 * _sum / total;
++ if (Configuration::showPercentage()) {
++ setText(1, TQString("%1")
++ .arg(sum, 0, 'f', Configuration::percentPrecision()));
++ }
++ else
++ setText(1, _sum.pretty());
++
++ setPixmap(1, costPixmap(_costType, pf->inclusive(), total, false));
++ }
++
++ if (!pf) {
++ setText(3, TQString("-"));
++ _callers = 0;
++ return;
++ }
++
++ TracePartCall* pc;
++ TracePartCallList pl;
++ SubCost callers, callees;
++ TQString str;
++
++ callers = 0;
++ pl = pf->partCallers();
++ for (pc=pl.first();pc;pc=pl.next()) {
++ callers += pc->callCount();
++ }
++
++ if ((callers == 0) && (pf->calledContexts()>0))
++ str = i18n("(active)");
++ else
++ str = callers.pretty();
++
++ _callers = callers;
++ setText(3, str);
++}
++
++
++int PartListItem::compare(TQListViewItem * i, int col, bool ascending ) const
++{
++ PartListItem* fi = (PartListItem*) i;
++ if (col==0) {
++ int mTID = _part->data()->maxThreadID()+1;
++ int mNum = _part->data()->maxPartNumber()+1;
++
++ return
++ (_part->processID() - fi->_part->processID()) * mTID * mNum +
++ (_part->partNumber() - fi->_part->partNumber()) * mTID +
++ (_part->threadID() - fi->_part->threadID());
++ }
++ if (col==1) {
++ if (_sum < fi->_sum) return -1;
++ if (_sum > fi->_sum) return 1;
++ return 0;
++ }
++ if (col==2) {
++ if (_pure < fi->_pure) return -1;
++ if (_pure > fi->_pure) return 1;
++ return 0;
++ }
++ if (col==3) {
++ if (_callers < fi->_callers) return -1;
++ if (_callers > fi->_callers) return 1;
++ return 0;
++ }
++ return TQListViewItem::compare(i, col, ascending);
++}
+diff --git a/kdecachegrind/kdecachegrind/partlistitem.h b/kdecachegrind/kdecachegrind/partlistitem.h
+new file mode 100644
+index 0000000..0ab99a9
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/partlistitem.h
+@@ -0,0 +1,54 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#ifndef PARTLISTITEM_H
++#define PARTLISTITEM_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++
++/**
++ * For info tab, trace part list.
++ * Needs update on
++ * - cost type change
++ *
++ * Note: on a cost item / percentage change, the list is rebuild
++ */
++class PartListItem: public TQListViewItem
++{
++public:
++ PartListItem(TQListView* parent, TraceCostItem* costItem,
++ TraceCostType* ct, TraceCost::CostType gt, TracePart* part);
++
++ int compare(TQListViewItem * i, int col, bool ascending ) const;
++ TraceCost* partCostItem() { return _partCostItem; }
++ void setCostType(TraceCostType* ct);
++ void setGroupType(TraceCost::CostType);
++ TracePart* part() { return _part; }
++ void update();
++
++private:
++ SubCost _sum, _pure;
++ SubCost _callers;
++ TraceCostType* _costType;
++ TraceCost* _partCostItem;
++ TracePart* _part;
++ TraceCost::CostType _groupType;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/partselection.cpp b/kdecachegrind/kdecachegrind/partselection.cpp
+new file mode 100644
+index 0000000..703dd75
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/partselection.cpp
+@@ -0,0 +1,567 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * For part file selection, to be put into a TQDockWindow
++ */
++
++#include <tqtimer.h>
++#include <tqlistview.h>
++#include <tqlabel.h>
++#include <tqpushbutton.h>
++#include <tqcombobox.h>
++#include <tqlineedit.h>
++#include <tqpopupmenu.h>
++#include <tqlayout.h>
++
++#include <klocale.h>
++#include <kconfig.h>
++#include <kdebug.h>
++
++#include "partselection.h"
++#include "partgraph.h"
++
++PartSelection::PartSelection( TQWidget* parent, const char* name)
++ : PartSelectionBase(parent, name)
++{
++ _data = 0;
++ _costType = 0;
++ _costType2 = 0;
++ _groupType = TraceItem::NoCostType;
++ _group = 0;
++ _function = 0;
++ _inSelectionUpdate = false;
++
++ _diagramMode = false;
++ _drawFrames = true;
++
++ partAreaWidget->setAllowRotation(false);
++ partAreaWidget->setMaxSelectDepth(2);
++ partAreaWidget->setSelectionMode(TreeMapWidget::Extended);
++ partAreaWidget->setSplitMode(TreeMapItem::HAlternate);
++ partAreaWidget->setVisibleWidth(2, true);
++ partAreaWidget->setFieldType(0, i18n( "Name" ));
++ partAreaWidget->setFieldType(1, i18n( "Cost" ));
++
++ connect(partAreaWidget, TQT_SIGNAL(selectionChanged()),
++ this, TQT_SLOT(selectionChanged()));
++ connect(partAreaWidget, TQT_SIGNAL(currentChanged(TreeMapItem*, bool)),
++ this, TQT_SLOT(currentChangedSlot(TreeMapItem*, bool)));
++ connect(partAreaWidget, TQT_SIGNAL(doubleClicked(TreeMapItem*)),
++ this, TQT_SLOT(doubleClicked(TreeMapItem*)));
++ connect(partAreaWidget,
++ TQT_SIGNAL(contextMenuRequested(TreeMapItem*,const TQPoint &)),
++ this,
++ TQT_SLOT(contextMenuRequested(TreeMapItem*,const TQPoint &)));
++
++ _showInfo = true;
++ showInfo(false);
++}
++
++PartSelection::~PartSelection()
++{
++}
++
++void PartSelection::setData(TraceData* data)
++{
++ if (_data == data) return;
++
++ _data = data;
++ partAreaWidget->setData(data);
++ fillInfo();
++}
++
++
++void PartSelection::refresh()
++{
++ partAreaWidget->redraw();
++ fillInfo();
++}
++
++void PartSelection::setCostType(TraceCostType* ct)
++{
++ if (ct == _costType) return;
++ _costType = ct;
++
++ partAreaWidget->setCostType(ct);
++}
++
++void PartSelection::setCostType2(TraceCostType* ct)
++{
++ if (ct == _costType2) return;
++ _costType2 = ct;
++ if (!_diagramMode) return;
++
++ //TODO: get max cost(type1)/cost(type2) of shown parts
++ //partAreaWidget->setCostType(ct);
++}
++
++void PartSelection::setGroupType(TraceItem::CostType gt)
++{
++ if (gt == _groupType) return;
++ _groupType = gt;
++
++ partAreaWidget->setGroupType(gt);
++}
++
++void PartSelection::setGroup(TraceCostItem*)
++{
++}
++
++void PartSelection::setFunction(TraceFunction* f)
++{
++ if (_function == f) return;
++ _function = f;
++
++ //kdDebug() << "PartSelection::setFunction " << f->name() << endl;
++
++ // FIXME: The TreeMap shouldn't produce spurious selectionChanged events
++ _inSelectionUpdate = true;
++ partAreaWidget->setFunction(_function);
++ _inSelectionUpdate = false;
++}
++
++void PartSelection::setPart(TracePart*)
++{}
++
++void PartSelection::currentChangedSlot(TreeMapItem* i, bool kbd)
++{
++ if (!i) return;
++ if (!kbd) return;
++ if (i->text(0).isEmpty()) return;
++
++ TQString str = i->text(0);
++ if (!i->text(1).isEmpty())
++ str += " (" + i->text(1) + ")";
++ TQString msg = i18n("Profile Part Overview: Current is '%1'").arg(str);
++ emit showMessage(msg, 5000);
++
++ if (_showInfo) fillInfo();
++}
++
++
++void PartSelection::doubleClicked(TreeMapItem* i)
++{
++ if (!i || i->rtti() != 3) return;
++
++ TraceCost* c = ((SubPartItem*) i)->partCostItem();
++ TraceCostItem* ci = 0;
++
++ switch(c->type()) {
++ case TraceItem::PartFunction:
++ {
++ TraceFunction* f = ((TracePartFunction*)c)->function();
++ if (f)
++ emit functionChanged(f);
++ }
++ return;
++
++ case TraceItem::PartObject:
++ ci = ((TracePartObject*)c)->object();
++ break;
++ case TraceItem::PartClass:
++ ci = ((TracePartClass*)c)->cls();
++ break;
++ case TraceItem::PartFile:
++ ci = ((TracePartFile*)c)->file();
++ break;
++ default:
++ break;
++ }
++
++ if (ci)
++ emit groupChanged(ci);
++}
++
++
++void PartSelection::selectionChanged()
++{
++ if (_inSelectionUpdate) return;
++
++ kdDebug() << "PartSelection::selectionChanged" << endl;
++
++ bool something_changed = false;
++ bool nothingSelected = true;
++
++ TracePartList pList;
++ TreeMapItem* i;
++ TracePart* part;
++
++ // if nothing is selected, activate all parts
++ TreeMapItemList* list = partAreaWidget->base()->children();
++ if (!list) return;
++
++ for (i=list->first();i;i=list->next())
++ if (partAreaWidget->isSelected(i)) {
++ nothingSelected = false;
++ break;
++ }
++
++ for (i=list->first();i;i=list->next()) {
++ part = ((PartItem*)i)->part();
++ bool active = nothingSelected || partAreaWidget->isSelected(i);
++ if (active) {
++ pList.append(part);
++ something_changed = true;
++ }
++ }
++
++ if (something_changed) {
++ //qDebug("PartSelection: Something changed.");
++ emit activePartsChanged(pList);
++ }
++}
++
++/* this makes the graph selection the same to the parts in the list */
++void PartSelection::activePartsChangedSlot(const TracePartList& list)
++{
++ _inSelectionUpdate = true;
++
++ kdDebug() << "Entering PartSelection::activePartsChangedSlot" << endl;
++
++ TreeMapItem* i;
++ TreeMapItemList l = *partAreaWidget->base()->children();
++ // first deselect inactive, then select active (makes current active)
++ for (i=l.first();i;i=l.next()) {
++ TracePart* part = ((PartItem*)i)->part();
++ bool active = (list.containsRef(part)>0);
++ if (!active && partAreaWidget->isSelected(i)) {
++#if 0
++ qDebug("PartSelection::partsChangedSlot: Part %s changed to unselected.",
++ ((PartItem*)i)->part()->shortName().ascii());
++#endif
++
++ partAreaWidget->setSelected(i, false);
++ }
++ }
++ for (i=l.first();i;i=l.next()) {
++ TracePart* part = ((PartItem*)i)->part();
++ bool active = (list.containsRef(part)>0);
++ if (active && !partAreaWidget->isSelected(i)) {
++#if 0
++ qDebug("PartSelection::partsChangedSlot: Part %s changed to selected.",
++ ((PartItem*)i)->part()->shortName().ascii());
++#endif
++ partAreaWidget->setSelected(i, true);
++ }
++ }
++
++ _inSelectionUpdate = false;
++
++ kdDebug() << "Leaving PartSelection::activePartsChangedSlot" << endl;
++
++ fillInfo();
++}
++
++void PartSelection::contextMenuRequested(TreeMapItem* i,
++ const TQPoint & p)
++{
++ if (!i) return;
++
++ TQPopupMenu popup;
++ TQPopupMenu ppopup;
++ TQPopupMenu vpopup;
++
++ TQString str;
++ TreeMapItem* s = 0;
++
++ if (_data && (_data->parts().count()>1)) {
++ s = partAreaWidget->possibleSelection(i);
++ if (!s->text(0).isEmpty()) {
++ str = (partAreaWidget->isSelected(s)) ?
++ i18n("Deselect") : i18n("Select");
++ str += " '" + s->text(0) + "'";
++ popup.insertItem(str, 1);
++ }
++
++ popup.insertItem(i18n("Select All Parts"), 2);
++
++ popup.insertItem(i18n("Visible Parts"), &ppopup, 10);
++
++ ppopup.insertItem(i18n("Hide Selected Parts"), 3);
++ ppopup.insertItem(i18n("Unhide Hidden Parts"), 4);
++
++ popup.insertSeparator();
++ }
++
++ popup.insertItem(i18n("Go Back"), 99);
++ if (i->rtti() == 3) {
++ TreeMapItem* ni = i;
++ int id = 100;
++ while (ni && ni->rtti() == 3) {
++ TraceCost* c = ((SubPartItem*)ni)->partCostItem();
++ if (c->type() == TraceItem::PartFunction)
++ if ( ((TracePartFunction*)c)->function() == _function) break;
++
++ str = i18n("Select") + " '" + ni->text(0) + "'";
++ popup.insertItem(str, id);
++ ni = ni->parent();
++ id++;
++ }
++ }
++ popup.insertSeparator();
++
++ vpopup.setCheckable(true);
++ popup.insertItem(i18n("Visualization"), &vpopup, 10);
++
++ vpopup.insertItem(i18n("Partitioning Mode"), 30);
++ vpopup.insertItem(i18n("Diagram Mode"), 34);
++ vpopup.insertItem(i18n("Zoom Function"), 31);
++ vpopup.insertItem(i18n("Show Direct Calls"), 32);
++ vpopup.insertItem(i18n("Increment Shown Call Levels"), 33);
++ if (partAreaWidget->visualisation() == PartAreaWidget::Partitioning) {
++ vpopup.setItemChecked(30, true);
++ vpopup.setItemEnabled(31, false);
++ vpopup.setItemEnabled(32, false);
++ vpopup.setItemEnabled(33, false);
++ }
++ else {
++ vpopup.setItemChecked(31, partAreaWidget->zoomFunction());
++ }
++ vpopup.setItemChecked(34, _diagramMode);
++
++ vpopup.insertSeparator();
++
++ vpopup.insertItem(i18n("Draw Names"), 20);
++ vpopup.insertItem(i18n("Draw Costs"), 21);
++ vpopup.insertItem(i18n("Ignore Proportions"), 22);
++ vpopup.insertItem(i18n("Draw Frames"), 24);
++ vpopup.insertItem(i18n("Allow Rotation"), 23);
++ if (!partAreaWidget->fieldVisible(0) &&
++ !partAreaWidget->fieldVisible(1)) {
++ vpopup.setItemEnabled(22, false);
++ vpopup.setItemEnabled(23, false);
++ }
++ else {
++ vpopup.setItemChecked(20,partAreaWidget->fieldVisible(0));
++ vpopup.setItemChecked(21,partAreaWidget->fieldVisible(1));
++ vpopup.setItemChecked(22,partAreaWidget->fieldForced(0));
++ vpopup.setItemChecked(23,partAreaWidget->allowRotation());
++ vpopup.setItemChecked(24,_drawFrames);
++ }
++
++ if (_showInfo)
++ popup.insertItem(i18n("Hide Info"), 40);
++ else
++ popup.insertItem(i18n("Show Info"), 41);
++
++ int r = popup.exec(partAreaWidget->mapToGlobal(p));
++
++ if (r>=100) {
++ TreeMapItem* ci = i;
++ while (ci && r>100) {
++ ci = ci->parent();
++ r--;
++ }
++ doubleClicked(ci);
++ return;
++ }
++
++ switch(r) {
++ case 1:
++ // select/deselect part under mouse
++ partAreaWidget->setSelected(s, !partAreaWidget->isSelected(s));
++ break;
++
++ case 2:
++ // select all parts
++ {
++ TreeMapItemList list = *partAreaWidget->base()->children();
++ partAreaWidget->setRangeSelection(list.first(), list.last(), true);
++ }
++ break;
++
++ case 3:
++ emit partsHideSelected();
++ break;
++
++ case 4:
++ emit partsUnhideAll();
++ break;
++
++ case 99:
++ // last selected function
++ emit goBack();
++ break;
++
++ case 20:
++ partAreaWidget->setFieldVisible(0, !vpopup.isItemChecked(20));
++ break;
++
++ case 21:
++ partAreaWidget->setFieldVisible(1, !vpopup.isItemChecked(21));
++ break;
++
++ case 22:
++ partAreaWidget->setFieldForced(0, !vpopup.isItemChecked(22));
++ partAreaWidget->setFieldForced(1, !vpopup.isItemChecked(22));
++ break;
++
++ case 23: partAreaWidget->setAllowRotation(!vpopup.isItemChecked(23)); break;
++
++ case 24:
++ _drawFrames = !_drawFrames;
++ partAreaWidget->drawFrame(2,_drawFrames);
++ partAreaWidget->drawFrame(3,_drawFrames);
++ break;
++
++ case 30:
++ partAreaWidget->setVisualisation(!vpopup.isItemChecked(30) ?
++ PartAreaWidget::Partitioning :
++ PartAreaWidget::Inclusive);
++ break;
++
++ case 31:
++ // zoom/unzoom function
++ partAreaWidget->setZoomFunction(!vpopup.isItemChecked(31));
++ break;
++
++ case 32:
++ case 33:
++ // change call Levels
++ {
++ int l = (r==32) ? 1 : partAreaWidget->callLevels()+1;
++ partAreaWidget->setCallLevels(l);
++ }
++ break;
++
++ case 34:
++ _diagramMode = !_diagramMode;
++ partAreaWidget->setTransparent(2,_diagramMode);
++ break;
++
++
++ case 40:
++ case 41:
++ showInfo(r==41);
++ break;
++
++ default:
++ break;
++ }
++}
++
++void PartSelection::hiddenPartsChangedSlot(const TracePartList& list)
++{
++ partAreaWidget->changeHidden(list);
++}
++
++void PartSelection::readVisualisationConfig(KConfigGroup* config)
++{
++ bool enable;
++
++ TQString mode = config->readEntry("PartitionMode", "Inclusive");
++ if (mode == "Inclusive")
++ partAreaWidget->setVisualisation(PartAreaWidget::Inclusive);
++ else
++ partAreaWidget->setVisualisation(PartAreaWidget::Partitioning);
++
++ _diagramMode = config->readBoolEntry("DiagramMode", false);
++ partAreaWidget->setTransparent(2,_diagramMode);
++
++ _drawFrames = config->readBoolEntry("DrawFrames", true);
++ partAreaWidget->drawFrame(2,_drawFrames);
++ partAreaWidget->drawFrame(3,_drawFrames);
++
++ enable = config->readBoolEntry("GraphZoom", false);
++ partAreaWidget->setZoomFunction(enable);
++
++ int levels = config->readNumEntry("GraphLevels", 1);
++ partAreaWidget->setCallLevels(levels);
++
++ enable = config->readBoolEntry("GraphDrawName", true);
++ partAreaWidget->setFieldVisible(0, enable);
++
++ enable = config->readBoolEntry("GraphDrawCost", true);
++ partAreaWidget->setFieldVisible(1, enable);
++
++ enable = config->readBoolEntry("GraphForceStrings", false);
++ partAreaWidget->setFieldForced(0, enable);
++ partAreaWidget->setFieldForced(1, enable);
++
++ enable = config->readBoolEntry("GraphAllowRotation", true);
++ partAreaWidget->setAllowRotation(enable);
++
++ showInfo(config->readBoolEntry("ShowInfo", false));
++}
++
++void PartSelection::saveVisualisationConfig(KConfigGroup* config)
++{
++ TQString mode;
++ if (partAreaWidget->visualisation() == PartAreaWidget::Inclusive)
++ mode = "Inclusive";
++ else
++ mode = "Partitioning";
++ config->writeEntry("PartitionMode", mode);
++
++ config->writeEntry("DiagramMode", _diagramMode);
++ config->writeEntry("DrawFrames", _drawFrames);
++
++ config->writeEntry("GraphZoom", partAreaWidget->zoomFunction());
++ config->writeEntry("GraphLevels", partAreaWidget->callLevels());
++ config->writeEntry("GraphDrawName", partAreaWidget->fieldVisible(0));
++ config->writeEntry("GraphDrawCosts", partAreaWidget->fieldVisible(1));
++ config->writeEntry("GraphForceStrings", partAreaWidget->fieldForced(0));
++ config->writeEntry("GraphAllowRotation", partAreaWidget->allowRotation());
++
++ config->writeEntry("ShowInfo", _showInfo);
++}
++
++void PartSelection::showInfo(bool enable)
++{
++ if (_showInfo == enable) return;
++
++ _showInfo = enable;
++ if (enable) {
++ rangeLabel->show();
++ fillInfo();
++ }
++ else
++ rangeLabel->hide();
++}
++
++void PartSelection::fillInfo()
++{
++ if (!_data) {
++ rangeLabel->setText(i18n("(no trace loaded)"));
++ return;
++ }
++
++ TQString info = _data->activePartRange();
++
++ TreeMapItem* i = partAreaWidget->current();
++ while (i && i->rtti()!=2) i = i->parent();
++ if (i) {
++ TracePart* part = ((PartItem*)i)->part();
++
++ //if (!part->trigger().isEmpty()) info += ", " + part->trigger();
++ if (!part->timeframe().isEmpty())
++ info += ", Time " + part->timeframe() + " BBs";
++ }
++ else {
++ TracePart* part = _data->parts().first();
++
++ if (part && !part->version().isEmpty())
++ info += ", Cachegrind " + part->version();
++ }
++
++
++ rangeLabel->setText(info);
++}
++
++#include "partselection.moc"
+diff --git a/kdecachegrind/kdecachegrind/partselection.h b/kdecachegrind/kdecachegrind/partselection.h
+new file mode 100644
+index 0000000..b8a195f
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/partselection.h
+@@ -0,0 +1,96 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * PartSelection for KCachegrind
++ * For part file selection, to be put into a TQDockWindow
++ */
++
++#ifndef PARTSELECTION_H
++#define PARTSELECTION_H
++
++#include <tqobject.h>
++
++#include "partselectionbase.h"
++#include "partgraph.h"
++#include "tracedata.h"
++
++class KConfigGroup;
++class TraceFunction;
++class TraceData;
++class TreeMapItem;
++
++class PartSelection: public PartSelectionBase
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ PartSelection( TQWidget* parent = 0, const char* name = 0);
++ ~PartSelection();
++
++ TraceData* data() { return _data; }
++ void setData(TraceData*);
++
++ PartAreaWidget* graph() { return partAreaWidget; }
++
++ void readVisualisationConfig(KConfigGroup*);
++ void saveVisualisationConfig(KConfigGroup*);
++
++signals:
++ void activePartsChanged(const TracePartList& list);
++ void partsHideSelected();
++ void partsUnhideAll();
++ void groupChanged(TraceCostItem*);
++ void functionChanged(TraceItem*);
++ void showMessage(const TQString&, int);
++ void goBack();
++
++public slots:
++ void selectionChanged();
++ void doubleClicked(TreeMapItem*);
++ void contextMenuRequested(TreeMapItem*, const TQPoint &);
++ void currentChangedSlot(TreeMapItem*, bool);
++
++ void setPart(TracePart*);
++ void setCostType(TraceCostType*);
++ void setCostType2(TraceCostType*);
++ void setGroupType(TraceItem::CostType);
++ void setGroup(TraceCostItem*);
++ void setFunction(TraceFunction*);
++ void activePartsChangedSlot(const TracePartList& list);
++ void hiddenPartsChangedSlot(const TracePartList& list);
++ void refresh();
++ void showInfo(bool);
++
++private:
++ void fillInfo();
++
++ TraceData* _data;
++ TraceCostType *_costType, *_costType2;
++ TraceItem::CostType _groupType;
++ TraceCostItem* _group;
++ TraceFunction* _function;
++ bool _showInfo;
++ bool _diagramMode;
++ bool _drawFrames;
++
++ bool _inSelectionUpdate;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/partselectionbase.ui b/kdecachegrind/kdecachegrind/partselectionbase.ui
+new file mode 100644
+index 0000000..53320d5
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/partselectionbase.ui
+@@ -0,0 +1,89 @@
++<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
++<class>PartSelectionBase</class>
++<widget class="TQWidget">
++ <property name="name">
++ <cstring>PartSelectionBase</cstring>
++ </property>
++ <property name="geometry">
++ <rect>
++ <x>0</x>
++ <y>0</y>
++ <width>460</width>
++ <height>402</height>
++ </rect>
++ </property>
++ <property name="caption">
++ <string>Parts Overview</string>
++ </property>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <property name="margin">
++ <number>6</number>
++ </property>
++ <property name="spacing">
++ <number>6</number>
++ </property>
++ <widget class="PartAreaWidget">
++ <property name="name">
++ <cstring>partAreaWidget</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>5</hsizetype>
++ <vsizetype>7</vsizetype>
++ <horstretch>0</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ <property name="minimumSize">
++ <size>
++ <width>0</width>
++ <height>50</height>
++ </size>
++ </property>
++ </widget>
++ <widget class="TQLabel">
++ <property name="name">
++ <cstring>rangeLabel</cstring>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy>
++ <hsizetype>7</hsizetype>
++ <vsizetype>5</vsizetype>
++ <horstretch>0</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ <property name="text">
++ <string>(no trace parts)</string>
++ </property>
++ </widget>
++ </vbox>
++</widget>
++<customwidgets>
++ <customwidget>
++ <class>PartAreaWidget</class>
++ <header location="local">partgraph.h</header>
++ <sizehint>
++ <width>-1</width>
++ <height>-1</height>
++ </sizehint>
++ <container>0</container>
++ <sizepolicy>
++ <hordata>5</hordata>
++ <verdata>7</verdata>
++ <horstretch>0</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ <pixmap>image0</pixmap>
++ </customwidget>
++</customwidgets>
++<images>
++ <image name="image0">
++ <data format="XPM.GZ" length="5230">789c9597db4e1d4b0e86eff31428be8b46b5fb54dd551acd051020211c4320c0682eecaa5e9ccf90005bf3ee53cbbfe9d9c9c548a38ea27c2977b5cbfe6dd7fae3c3c2e1cee6c2873fde3d3cf2e3595a48a77cbff0213f5d5dbdfcf35ffff8f3ddfba65998fff161a179ffb777ef771f17d2c2d6cdf53807c705a889cdac6ee72c47736eebd637b5f2b672d70ecd30e744ca7d9b9a4ad7579587363433e527e5d072abefbb03636978ceb4a31c5bc13a91716ad41f89e0aec2fe74abcc6d6ad5f9e4945357375ef75f997357751dd61d19c71afb61bdef421b951f274ebaffb6716cb3f2b2f230f18d3183dd95b1b441d7d59f2e94757ccf1b27eceff69563618d0f5dcfd9d7beeb7a5dd7f3fac6fb4ee32b87c619f1168d976f7d6ff6df26d6ef4b301e1bac7f54f63e747a5e87f5c173276aff605c22a8fefc540e5e3af5972f956359577bf2c6d978cb78d6697edc9eb2f8b143fed7945359d778b0e6c3e7be81bf7465dce23cf4ac3c16567f19fecefaae53bd081b7baccbb131b7d05f679ca03f27c6b9d1f388c6bbaffab7f80dca4d1fed7bfafdbeedb9533d490f1e2ae8d5693ccacb83d77cd027e3d4416faa97beefa3d7f8f086f168f9d9020f43a3f5c5aa877e28eb88f74fe319becfaa873e0c15de775f95639f3dec37c143d361bf2be3cef4b76bdcb7d84ff5d2cbd0227facf1ecd360fa67d54b9f078ffcd10f636e11ff53e3847853ad3c1b668837e9fe43358c2df45a81430b3db2e6676842d368fd48abdc068b87e0fd2e788bf792b21f861e7afd0e0e5ce37dcdd7d0872218e5d789f57b3218a71ae7bb501eca3af67b510e21c05fd27a1b6218ac3ef17d0ed68fe8cb1be3fc6e5159863ca0bfed824340fe687d62c4838c23f677f0370de380fcdd2be7e03dfab1d6cf300bcd80fa80bfb358dbf9547fa18abe413d68fe421d63ade7737aded094cf63fdcc38f4d0bfee17dac2d08380a3a0dff24cb90bdc23ffaa87e0636c912fed87612e38d4df1e982bc4dbdd29872001f14aca319413eb793e83cbfbe8af27606e4c0f5f8d3bcb7763ec6b8da73b57e69083d61f9d82b9b5fada31f635fcaf8d7b7b5ffb41f16e34ff34fe214dfc0c8e1ef1a22330bfcdc345e31e4c33e3c1e6e181b1609e3ac43f8759803e8cd9f2e7e0ff18ab80ef5d8239e2fc0ef129f90ff0bf0773347fee8d13ce279bc6b34af5c61abf58157bf4b765b05435f4abfec726968c2b67e536fa80fe388279067f680d2c750dff75fe9766da07e44bc02521ba4e1d584c1fb261dcc23fd97f63f8c3af136bfc687362c4e76962ed8fac7a2ecdb7853f7c63ec6bf467bd3fc421c680780c60b6f9275fc045aea84fadaf18a2e0fc04ff0237bd9e8fefc0d236e8ef3f8d83c57fdd38daf94edeb886be74fec618b3ed7f3731e66b0fe67a403e76c0454ef8de9231dbfe9f8dc5fc47be38a6887ad2f950964d2fdc1a27d3c7b6710693f6ef9864b4fdb4ffc6cc5540fea0972c339c87afc1c9f4443a5fe2c84d40bd2f82cb3ae6c7b1716dbc37b1e68bf5be118b7e3dead78125d87d0bfa99bd7d8fb78c1bdb4fcfcfd51bcb9d716bebda3fb8966cf7cf57709103f2e327c6fe5a2fdc4ab4fb01deef5283fa65d50ffb54c13fd67ec37d61e845fb070f8571df7c341eec7e7a691c6ae453fb771937d1fa999ebfa43358bf573d3327c6fdd0a9de59b87414e59f60911ef3ff07380d16bf0b63b6fbb8ce0f4e523a80ee8ff8a5f21fe83f384f2e8cf9d419db7d4bb4bff32cb1dd871ae38c79417962dd9f8f2786bfaa3fa992ddbf68d5d8d6797d62dc27b4bf4a9bdeee5be7c619efbb169c2b9bb7aa67e972857a67d59bf8943cf4a6f5237dae3b9c3f4f8cef5713637e6a3c6548e546a7eb87e0b28e7cf7c68ddd2fb15f28acf166bd2f484c19f921f8cbc57de84ff52c397b8f7e178d7bbb7f7e9f18f743d593ccd210d12f9e8c05fd8417c1e5e704e2afefa7aa5cf850ff4fc6a1473debfc4d7561c4ebd3c48897f69fd4e4d8eb7e4efb736a0b23fe9adfd465bb3f388d6ff22933fa1df6f7597ad483c62371f6e6ff8671b6f89e198fb8cfb0ea3f49619c6f6562cc27d5474a7906e6b589d1df549f29e78479450fe0b1c2fc67d5731a0ba33ffc97a167fd7d92ebb1b1f9a87acdcdd8a23ff2e3c4a81fed0fb91bbb88f8e9f772f9b9c6b8bfac187bd41febbcc8c35831f4bb6edc227eeec8b847bc58ef0f398d91a1179d6f391746bdebfd60ac4716b0180bd8a97e473f8ea2dfdb7d9c3f8e1cff8f8760057b27e57f92cb6e743377e24efff29cb97377e12edd55b190c99eddb5bb71b7eeceddbb07f7e89edc0ff7d33dbb17f7ea16dd925b761fdd8a63d8174f52b15e756bee93fbecd6dd17b7e136dd96db763b6ed77d2dd67bee9bdb77078ed49e8b27b7c5fabb3b7447eed855ae768d6bcbd339ef7a37b8e022392a2734fbd1dd119350a24c23cde8844ee98ccee9c2f9c2977445d77443b793fd8ceee89e1ee8919ee807fdb4e7995ee8b5d82fd252b15ffe8bfd097da4155aa535fa34597fa6f5f2f717da28f69bb445dbb433d99fd22e7da53dfa3659efd3017da7c3f2af233aa68aeadfec1b6aa9236fd63d0d14ca15c0719913737b965fedcbf0c83cc29a677cc2a77cc6e77cc1977cc5d7c5fee637fbdbb2db9d5adff343b17ee427fec1737ee69762fffa9bfd222ff17259fdc82bbcca6bfc893ff33a7fe10ddee42ddee69ddfec77f92beff137dee703fece877cc4c7aee58a6b6ee8b8fc10ed7eb13f635f9a4bc5e54719477152ba671977a505c84845c57222a7bfd89fcb999ccb855cca955cbfc5546ee456ee68b14cf67b799047799aec2fdc92fc28999cef567224cff222afb2c85b32e36d599265f9282bb23ad95fba6559934f2593f3e798b74acc8fd5f6b3accb17d9904dd9926db3a7520d1fdd37d9915df95a72599e1291566df7e49beccb817c974339829eb55e56dc7e51ec0d2dcbb1545297a791563af1c5eff2d3beb4faf8562f568f0744745b9e9d5f1f7992d5e412a186ffef7afff7dfdffd077c99ae99</data>
++ </image>
++</images>
++<layoutdefaults spacing="6" margin="11"/>
++</UI>
+diff --git a/kdecachegrind/kdecachegrind/partview.cpp b/kdecachegrind/kdecachegrind/partview.cpp
+new file mode 100644
+index 0000000..3f344bb
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/partview.cpp
+@@ -0,0 +1,235 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Part View
++ */
++
++#include <tqwhatsthis.h>
++#include <tqpopupmenu.h>
++#include <tqheader.h>
++#include <klocale.h>
++
++#include "configuration.h"
++#include "partlistitem.h"
++#include "toplevel.h"
++#include "partview.h"
++
++
++
++//
++// PartView
++//
++
++
++PartView::PartView(TraceItemView* parentView,
++ TQWidget* parent, const char* name)
++ : TQListView(parent, name), TraceItemView(parentView)
++{
++ _inSelectionUpdate = false;
++
++ addColumn( i18n( "Profile Part" ) );
++ addColumn( i18n( "Incl." ) );
++ addColumn( i18n( "Self" ) );
++ addColumn( i18n( "Called" ) );
++ //addColumn( i18n( "Fixed" ) );
++ addColumn( i18n( "Comment" ) );
++
++ setAllColumnsShowFocus(true);
++ setColumnAlignment(1, TQt::AlignRight);
++ setColumnAlignment(2, TQt::AlignRight);
++ setColumnAlignment(3, TQt::AlignRight);
++ setMinimumHeight(50);
++ setSelectionMode(Extended);
++
++ connect( this,
++ TQT_SIGNAL( selectionChanged() ),
++ TQT_SLOT( selectionChangedSlot() ) );
++
++ connect( this,
++ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
++ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int)));
++
++ TQWhatsThis::add( this, whatsThis() );
++}
++
++TQString PartView::whatsThis() const
++{
++ return i18n( "<b>Trace Part List</b>"
++ "<p>This list shows all trace parts of the loaded "
++ "trace. For each part, the "
++ "self/inclusive cost of the current selected "
++ "function, spent in the part, is shown; "
++ "percentage costs are always relative to the "
++ "total cost <em>of the part</em> (not to the whole "
++ "trace as in the Trace Part Overview). "
++ "Also shown are the calls happening to/from the "
++ "current function inside of the trace part.</p>"
++ "<p>By choosing one or more trace parts from the "
++ "list, the costs shown all over KCachegrind will "
++ "only be the ones spent in the selected part(s). "
++ "If no list selection is shown, in fact all trace "
++ "parts are selected implicitly.</p>"
++ "<p>This is a multi-selection list. You can select "
++ "ranges by dragging the mouse or use SHIFT/CTRL "
++ "modifiers. "
++ "Selection/Deselection of trace parts can also be "
++ "done by using the Trace Part Overview Dockable. "
++ "This one also supports multiple selection.</p>"
++ "<p>Note that the list is hidden if only one trace "
++ "part is loaded.</p>");
++}
++
++
++void PartView::context(TQListViewItem* i, const TQPoint & pos, int)
++{
++ TQPopupMenu popup;
++
++ TracePart* p = i ? ((PartListItem*) i)->part() : 0;
++
++ if (p) {
++ popup.insertItem(i18n("Select '%1'").arg(p->name()), 93);
++ popup.insertItem(i18n("Hide '%1'").arg(p->name()), 94);
++ popup.insertSeparator();
++ }
++
++ popup.insertItem(i18n("Hide Selected"), 95);
++ popup.insertItem(i18n("Show All"), 96);
++ popup.insertSeparator();
++
++ addGoMenu(&popup);
++
++ int r = popup.exec(pos);
++ if (r == 95) {
++ ;
++ }
++
++ // TODO: ...
++}
++
++void PartView::selectionChangedSlot()
++{
++ if (_inSelectionUpdate) return;
++
++ TracePartList l;
++ TQListViewItem* item = firstChild();
++ for(;item;item = item->nextSibling())
++ if (item->isSelected())
++ l.append( ((PartListItem*)item)->part() );
++
++ selected(l);
++}
++
++
++TraceItem* PartView::canShow(TraceItem* i)
++{
++ if (!TraceItemView::data()) return 0;
++ if (TraceItemView::data()->parts().count()>1) return i;
++ return 0;
++}
++
++void PartView::doUpdate(int changeType)
++{
++ // Special case ?
++ if (changeType == costType2Changed) return;
++ if (changeType == selectedItemChanged) return;
++
++ if (changeType == groupTypeChanged) {
++ TQListViewItem *item;
++ for (item = firstChild();item;item = item->nextSibling())
++ ((PartListItem*)item)->setGroupType(_groupType);
++
++ return;
++ }
++
++ if (changeType == costTypeChanged) {
++ TQListViewItem *item;
++ for (item = firstChild();item;item = item->nextSibling())
++ ((PartListItem*)item)->setCostType(_costType);
++
++ return;
++ }
++
++ if (changeType == partsChanged) {
++
++ TracePart* part;
++
++ TQListViewItem* item;
++ _inSelectionUpdate = true;
++ item = firstChild();
++ for(;item;item = item->nextSibling()) {
++ part = ((PartListItem*)item)->part();
++
++ if (_partList.containsRef(part)>0) {
++ setSelected(item, true);
++ ensureItemVisible(item);
++ }
++ else
++ setSelected(item, false);
++ }
++ _inSelectionUpdate = false;
++
++ return;
++ }
++
++ refresh();
++}
++
++void PartView::refresh()
++{
++ clear();
++ setColumnWidth(1, 50);
++ setColumnWidth(2, 50);
++
++ if (!_data || !_activeItem) return;
++
++ TraceItem::CostType t = _activeItem->type();
++ TraceFunction* f = 0;
++ if (t == TraceItem::Function) f = (TraceFunction*) _activeItem;
++ if (!f) return;
++
++ TracePart* part;
++ TracePartList hidden;
++ if (_topLevel)
++ hidden = _topLevel->hiddenParts();
++
++ TracePartList allParts = _data->parts();
++
++ _inSelectionUpdate = true;
++
++ TQListViewItem* item = 0;
++ for (part = allParts.first(); part; part = allParts.next()) {
++ if (hidden.findRef(part)>=0) continue;
++ item = new PartListItem(this, f, _costType, _groupType, part);
++
++ if (part->isActive()) {
++ setSelected(item, true);
++ ensureItemVisible(item);
++ }
++ }
++
++ _inSelectionUpdate = false;
++
++ if (item) {
++ int headerHeight = header()->height();
++ int itemHeight = item->height();
++ setMinimumHeight(headerHeight + 2*itemHeight + 2);
++ }
++}
++
++#include "partview.moc"
+diff --git a/kdecachegrind/kdecachegrind/partview.h b/kdecachegrind/kdecachegrind/partview.h
+new file mode 100644
+index 0000000..92761cc
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/partview.h
+@@ -0,0 +1,55 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Part View
++ */
++
++#ifndef PARTVIEW_H
++#define PARTVIEW_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++#include "traceitemview.h"
++
++class PartView: public TQListView, public TraceItemView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ PartView(TraceItemView* parentView,
++ TQWidget* parent=0, const char* name=0);
++
++ virtual TQWidget* widget() { return this; }
++ TQString whatsThis() const;
++
++ void refresh();
++
++private slots:
++ void context(TQListViewItem*,const TQPoint &, int);
++ void selectionChangedSlot();
++
++private:
++ TraceItem* canShow(TraceItem*);
++ void doUpdate(int);
++
++ bool _inSelectionUpdate;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/pool.cpp b/kdecachegrind/kdecachegrind/pool.cpp
+new file mode 100644
+index 0000000..d4a89a7
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/pool.cpp
+@@ -0,0 +1,258 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002-2004 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#include <string.h>
++#include <stdlib.h>
++#include <tqglobal.h>
++#include "pool.h"
++
++// FixPool
++
++#define CHUNK_SIZE 100000
++
++struct SpaceChunk
++{
++ struct SpaceChunk* next;
++ unsigned int used;
++ char space[1];
++};
++
++FixPool::FixPool()
++{
++ _first = _last = 0;
++ _reservation = 0;
++ _count = 0;
++ _size = 0;
++}
++
++FixPool::~FixPool()
++{
++ struct SpaceChunk* chunk = _first, *next;
++
++ while(chunk) {
++ next = chunk->next;
++ free(chunk);
++ chunk = next;
++ }
++
++ if (0) qDebug("~FixPool: Had %d objects with total size %d\n",
++ _count, _size);
++}
++
++void* FixPool::allocate(unsigned int size)
++{
++ if (!ensureSpace(size)) return 0;
++
++ _reservation = 0;
++ void* result = _last->space + _last->used;
++ _last->used += size;
++
++ _count++;
++ _size += size;
++
++ return result;
++}
++
++void* FixPool::reserve(unsigned int size)
++{
++ if (!ensureSpace(size)) return 0;
++ _reservation = size;
++
++ return _last->space + _last->used;
++}
++
++
++bool FixPool::allocateReserved(unsigned int size)
++{
++ if (_reservation < size) return false;
++
++ _reservation = 0;
++ _last->used += size;
++
++ _count++;
++ _size += size;
++
++ return true;
++}
++
++bool FixPool::ensureSpace(unsigned int size)
++{
++ if (_last && _last->used + size <= CHUNK_SIZE) return true;
++
++ struct SpaceChunk* newChunk;
++
++ // we don't allow allocation sizes > CHUNK_SIZE
++ if (size > CHUNK_SIZE) return false;
++
++ newChunk = (struct SpaceChunk*) malloc(sizeof(struct SpaceChunk) +
++ CHUNK_SIZE);
++ newChunk->next = 0;
++ newChunk->used = 0;
++
++ if (!_last) {
++ _last = _first = newChunk;
++ }
++ else {
++ _last->next = newChunk;
++ _last = newChunk;
++ }
++ return true;
++}
++
++
++// DynPool
++
++DynPool::DynPool()
++{
++ _data = (char*) malloc(CHUNK_SIZE);
++ _used = 0;
++ _size = CHUNK_SIZE;
++
++ // end marker
++ *(int*)_data = 0;
++}
++
++DynPool::~DynPool()
++{
++ // we could check for correctness by iteration over all objects
++
++ ::free(_data);
++}
++
++bool DynPool::allocate(char** ptr, unsigned int size)
++{
++ // round up to multiple of 4
++ size = (size+3) & ~3;
++
++ /* need 12 bytes more:
++ * - 4 bytes for forward chain
++ * - 4 bytes for pointer to ptr
++ * - 4 bytes as end marker (not used for new object)
++ */
++ if (!ensureSpace(size + 12)) return false;
++
++ char** obj = (char**) (_data+_used);
++ obj[0] = (char*)(_data + _used + size + 8);
++ obj[1] = (char*)ptr;
++ *(int*)(_data+_used+size+8) = 0;
++ *ptr = _data+_used+8;
++
++ _used += size + 8;
++
++ return true;
++}
++
++void DynPool::free(char** ptr)
++{
++ if (!ptr ||
++ !*ptr ||
++ (*(char**)(*ptr - 4)) != (char*)ptr )
++ qFatal("Chaining error in DynPool::free");
++
++ (*(char**)(*ptr - 4)) = 0;
++ *ptr = 0;
++}
++
++bool DynPool::ensureSpace(unsigned int size)
++{
++ if (_used + size <= _size) return true;
++
++ unsigned int newsize = _size *3/2 + CHUNK_SIZE;
++ char* newdata = (char*) malloc(newsize);
++
++ unsigned int freed = 0, len;
++ char **p, **pnext, **pnew;
++
++ qDebug("DynPool::ensureSpace size: %d => %d, used %d. %p => %p",
++ _size, newsize, _used, _data, newdata);
++
++ pnew = (char**) newdata;
++ p = (char**) _data;
++ while(*p) {
++ pnext = (char**) *p;
++ len = (char*)pnext - (char*)p;
++
++ if (0) qDebug(" [%8p] Len %d (ptr %p), freed %d (=> %p)",
++ p, len, p[1], freed, pnew);
++
++ /* skip freed space ? */
++ if (p[1] == 0) {
++ freed += len;
++ p = pnext;
++ continue;
++ }
++
++ // new and old still at same address ?
++ if (pnew == p) {
++ pnew = p = pnext;
++ continue;
++ }
++
++ // copy object
++ pnew[0] = (char*)pnew + len;
++ pnew[1] = p[1];
++ memcpy((char*)pnew + 8, (char*)p + 8, len-8);
++
++ // update pointer to object
++ char** ptr = (char**) p[1];
++ if (*ptr != ((char*)p)+8)
++ qFatal("Chaining error in DynPool::ensureSpace");
++ *ptr = ((char*)pnew)+8;
++
++ pnew = (char**) pnew[0];
++ p = pnext;
++ }
++ pnew[0] = 0;
++
++ unsigned int newused = (char*)pnew - (char*)newdata;
++ qDebug("DynPool::ensureSpace size: %d => %d, used %d => %d (%d freed)",
++ _size, newsize, _used, newused, freed);
++
++ ::free(_data);
++ _data = newdata;
++ _size = newsize;
++ _used = newused;
++
++ return true;
++}
++
++/* Testing the DynPool
++int main()
++{
++ char* bufs[CHUNK_SIZE];
++ int i;
++
++ DynPool p;
++
++ for(i=0;i<CHUNK_SIZE;i++) {
++ p.allocate(bufs+i, 10+i%10);
++ if (((i%3)==0) && (i>20))
++ p.free(bufs+i-20);
++ }
++
++ for(i=0;i<CHUNK_SIZE;i++) {
++ if ((bufs[i]==0) || ((i%7)==0)) continue;
++ p.free(bufs+i);
++ }
++
++ for(i=0;i<CHUNK_SIZE;i++) {
++ if (bufs[i]) continue;
++ p.allocate(bufs+i, 10+i%10);
++ }
++}
++*/
+diff --git a/kdecachegrind/kdecachegrind/pool.h b/kdecachegrind/kdecachegrind/pool.h
+new file mode 100644
+index 0000000..c9d70c1
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/pool.h
+@@ -0,0 +1,107 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002-2004 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#ifndef POOL_H
++#define POOL_H
++
++/**
++ * Pool objects: containers for many small objects.
++ */
++
++struct SpaceChunk;
++
++/**
++ * FixPool
++ *
++ * For objects with fixed size and life time
++ * ending with that of the pool.
++ */
++class FixPool
++{
++ public:
++ FixPool();
++ ~FixPool();
++
++ /**
++ * Take <size> bytes from the pool
++ */
++ void* allocate(unsigned int size);
++
++ /**
++ * Reserve space. If you call allocateReservedSpace(realsize)
++ * with realSize < reserved size directly after, you
++ * will get the same memory area.
++ */
++ void* reserve(unsigned int size);
++
++ /**
++ * Before calling this, you have to reserve at least <size> bytes
++ * with reserveSpace().
++ */
++ bool allocateReserved(unsigned int size);
++
++ private:
++ /* Checks that there is enough space in the last chunk.
++ * Returns false if this is not possible.
++ */
++ bool ensureSpace(unsigned int);
++
++ struct SpaceChunk *_first, *_last;
++ unsigned int _reservation;
++ int _count, _size;
++};
++
++/**
++ * DynPool
++ *
++ * For objects which probably need to be resized
++ * in the future. Objects also can be deleted to free up space.
++ * As objects can also be moved in a defragmentation step,
++ * access has to be done via the given pointer object.
++ */
++class DynPool
++{
++ public:
++ DynPool();
++ ~DynPool();
++
++ /**
++ * Take <size> bytes from the pool, changing <*ptr>
++ * to point to this allocated space.
++ * <*ptr> will be changed if the object is moved.
++ * Returns false if no space available.
++ */
++ bool allocate(char** ptr, unsigned int size);
++
++ /**
++ * To resize, first allocate new space, and free old
++ * afterwards.
++ */
++ void free(char** ptr);
++
++ private:
++ /* Checks that there is enough space. If not,
++ * it compactifies, possibly moving objects.
++ */
++ bool ensureSpace(unsigned int);
++
++ char* _data;
++ unsigned int _used, _size;
++};
++
++#endif // POOL_H
+diff --git a/kdecachegrind/kdecachegrind/sourceitem.cpp b/kdecachegrind/kdecachegrind/sourceitem.cpp
+new file mode 100644
+index 0000000..305b824
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/sourceitem.cpp
+@@ -0,0 +1,444 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of source view.
++ */
++
++#include <tqpixmap.h>
++#include <tqregexp.h>
++#include <tqpainter.h>
++
++#include <klocale.h>
++#include <kiconloader.h>
++#include <kapplication.h>
++
++#include "configuration.h"
++#include "listutils.h"
++#include "sourceview.h"
++#include "sourceitem.h"
++
++
++// SourceItem
++
++// for source lines
++SourceItem::SourceItem(SourceView* sv, TQListView* parent,
++ int fileno, unsigned int lineno,
++ bool inside, const TQString& src,
++ TraceLine* line)
++ : TQListViewItem(parent)
++{
++ _view = sv;
++ _lineno = lineno;
++ _fileno = fileno;
++ _inside = inside;
++ _line = line;
++ _lineCall = 0;
++ _lineJump = 0;
++
++ if (src == "...")
++ setText(0, src);
++ else
++ setText(0, TQString::number(lineno));
++
++ TQString s = src;
++ setText(4, s.replace( TQRegExp("\t"), " " ));
++
++ updateGroup();
++ updateCost();
++}
++
++// for call lines
++SourceItem::SourceItem(SourceView* sv, TQListViewItem* parent,
++ int fileno, unsigned int lineno,
++ TraceLine* line, TraceLineCall* lineCall)
++ : TQListViewItem(parent)
++{
++ _view = sv;
++ _lineno = lineno;
++ _fileno = fileno;
++ _inside = true;
++ _line = line;
++ _lineCall = lineCall;
++ _lineJump = 0;
++
++ //qDebug("SourceItem: (file %d, line %d) Linecall to %s",
++ // fileno, lineno, _lineCall->call()->called()->prettyName().ascii());
++
++ SubCost cc = _lineCall->callCount();
++ TQString templ = " ";
++ if (cc==0)
++ templ += i18n("Active call to '%1'");
++ else
++ templ += i18n("%n call to '%1'", "%n calls to '%1'", cc);
++
++ TQString callStr = templ.arg(_lineCall->call()->calledName());
++ TraceFunction* calledF = _lineCall->call()->called();
++ calledF->addPrettyLocation(callStr);
++
++ setText(4, callStr);
++
++ updateGroup();
++ updateCost();
++}
++
++// for jump lines
++SourceItem::SourceItem(SourceView* sv, TQListViewItem* parent,
++ int fileno, unsigned int lineno,
++ TraceLine* line, TraceLineJump* lineJump)
++ : TQListViewItem(parent)
++{
++ _view = sv;
++ _lineno = lineno;
++ _fileno = fileno;
++ _inside = true;
++ _line = line;
++ _lineCall = 0;
++ _lineJump = lineJump;
++
++ //qDebug("SourceItem: (file %d, line %d) Linecall to %s",
++ // fileno, lineno, _lineCall->call()->called()->prettyName().ascii());
++
++ TQString to;
++ if (_lineJump->lineTo()->functionSource() == _line->functionSource())
++ to = _lineJump->lineTo()->name();
++ else
++ to = _lineJump->lineTo()->prettyName();
++
++ TQString jStr;
++ if (_lineJump->isCondJump())
++ jStr = i18n("Jump %1 of %2 times to %3")
++ .arg(_lineJump->followedCount().pretty())
++ .arg(_lineJump->executedCount().pretty())
++ .arg(to);
++ else
++ jStr = i18n("Jump %1 times to %2")
++ .arg(_lineJump->executedCount().pretty())
++ .arg(to);
++
++ setText(4, jStr);
++}
++
++
++void SourceItem::updateGroup()
++{
++ if (!_lineCall) return;
++
++ TraceFunction* f = _lineCall->call()->called();
++ TQColor c = Configuration::functionColor(_view->groupType(), f);
++ setPixmap(4, colorPixmap(10, 10, c));
++}
++
++void SourceItem::updateCost()
++{
++ _pure = SubCost(0);
++ _pure2 = SubCost(0);
++
++ if (!_line) return;
++ if (_lineJump) return;
++
++ TraceCost* lineCost = _lineCall ? (TraceCost*)_lineCall : (TraceCost*)_line;
++
++ // don't show any cost inside of cycles
++ if (_lineCall &&
++ ((_lineCall->call()->inCycle()>0) ||
++ (_lineCall->call()->isRecursion()>0))) {
++ TQString str;
++ TQPixmap p;
++
++ TQString icon = "undo";
++ KIconLoader* loader = KApplication::kApplication()->iconLoader();
++ p= loader->loadIcon(icon, KIcon::Small, 0,
++ KIcon::DefaultState, 0, true);
++ if (p.isNull())
++ str = i18n("(cycle)");
++
++ setText(1, str);
++ setPixmap(1, p);
++ setText(2, str);
++ setPixmap(2, p);
++ return;
++ }
++
++ TraceCost* totalCost;
++ if (Configuration::showExpanded())
++ totalCost = _line->functionSource()->function()->inclusive();
++ else
++ totalCost = _line->functionSource()->function()->data();
++
++ TraceCostType* ct = _view->costType();
++ _pure = ct ? lineCost->subCost(ct) : SubCost(0);
++ if (_pure == 0) {
++ setText(1, TQString());
++ setPixmap(1, TQPixmap());
++ }
++ else {
++ double total = totalCost->subCost(ct);
++ double pure = 100.0 * _pure / total;
++
++ if (Configuration::showPercentage())
++ setText(1, TQString("%1")
++ .arg(pure, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(1, _pure.pretty());
++
++ setPixmap(1, costPixmap(ct, lineCost, total, false));
++ }
++
++ TraceCostType* ct2 = _view->costType2();
++ _pure2 = ct2 ? lineCost->subCost(ct2) : SubCost(0);
++ if (_pure2 == 0) {
++ setText(2, TQString());
++ setPixmap(2, TQPixmap());
++ }
++ else {
++ double total = totalCost->subCost(ct2);
++ double pure2 = 100.0 * _pure2 / total;
++
++ if (Configuration::showPercentage())
++ setText(2, TQString("%1")
++ .arg(pure2, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(2, _pure2.pretty());
++
++ setPixmap(2, costPixmap(ct2, lineCost, total, false));
++ }
++}
++
++
++int SourceItem::compare(TQListViewItem * i, int col, bool ascending ) const
++{
++ const SourceItem* si1 = this;
++ const SourceItem* si2 = (SourceItem*) i;
++
++ // we always want descending order
++ if (((col>0) && ascending) ||
++ ((col==0) && !ascending) ) {
++ si1 = si2;
++ si2 = this;
++ }
++
++ if (col==1) {
++ if (si1->_pure < si2->_pure) return -1;
++ if (si1->_pure > si2->_pure) return 1;
++ return 0;
++ }
++ if (col==2) {
++ if (si1->_pure2 < si2->_pure2) return -1;
++ if (si1->_pure2 > si2->_pure2) return 1;
++ return 0;
++ }
++ if (col==0) {
++ // Sort file numbers
++ if (si1->_fileno < si2->_fileno) return -1;
++ if (si1->_fileno > si2->_fileno) return 1;
++
++ // Sort line numbers
++ if (si1->_lineno < si2->_lineno) return -1;
++ if (si1->_lineno > si2->_lineno) return 1;
++
++ // Same line: code gets above calls/jumps
++ if (!si1->_lineCall && !si1->_lineJump) return -1;
++ if (!si2->_lineCall && !si2->_lineJump) return 1;
++
++ // calls above jumps
++ if (si1->_lineCall && !si2->_lineCall) return -1;
++ if (si2->_lineCall && !si1->_lineCall) return 1;
++
++ if (si1->_lineCall && si2->_lineCall) {
++ // Two calls: desending sort according costs
++ if (si1->_pure < si2->_pure) return 1;
++ if (si1->_pure > si2->_pure) return -1;
++
++ // Two calls: sort according function names
++ TraceFunction* f1 = si1->_lineCall->call()->called();
++ TraceFunction* f2 = si2->_lineCall->call()->called();
++ if (f1->prettyName() > f2->prettyName()) return 1;
++ return -1;
++ }
++
++ // Two jumps: descending sort according target line
++ if (si1->_lineJump->lineTo()->lineno() <
++ si2->_lineJump->lineTo()->lineno())
++ return -1;
++ if (si1->_lineJump->lineTo()->lineno() >
++ si2->_lineJump->lineTo()->lineno())
++ return 1;
++ return 0;
++ }
++ return TQListViewItem::compare(i, col, ascending);
++}
++
++void SourceItem::paintCell( TQPainter *p, const TQColorGroup &cg,
++ int column, int width, int alignment )
++{
++ TQColorGroup _cg( cg );
++
++ if ( !_inside || ((column==1) || (column==2)))
++ _cg.setColor( TQColorGroup::Base, cg.button() );
++ else if ((_lineCall || _lineJump) && column>2)
++ _cg.setColor( TQColorGroup::Base, cg.midlight() );
++
++ if (column == 3)
++ paintArrows(p, _cg, width);
++ else
++ TQListViewItem::paintCell( p, _cg, column, width, alignment );
++}
++
++void SourceItem::setJumpArray(const TQMemArray<TraceLineJump*>& a)
++{
++ _jump.duplicate(a);
++}
++
++void SourceItem::paintArrows(TQPainter *p, const TQColorGroup &cg, int width)
++{
++ TQListView *lv = listView();
++ if ( !lv ) return;
++ SourceView* sv = (SourceView*) lv;
++
++ const BackgroundMode bgmode = lv->viewport()->backgroundMode();
++ const TQColorGroup::ColorRole crole
++ = TQPalette::backgroundRoleFromMode( bgmode );
++ if ( cg.brush( crole ) != lv->colorGroup().brush( crole ) )
++ p->fillRect( 0, 0, width, height(), cg.brush( crole ) );
++ else
++ sv->paintEmptyArea( p, TQRect( 0, 0, width, height() ) );
++
++ if ( isSelected() && lv->allColumnsShowFocus() )
++ p->fillRect( 0, 0, width, height(), cg.brush( TQColorGroup::Highlight ) );
++
++ int marg = lv->itemMargin();
++ int yy = height()/2, y1, y2;
++ TQColor c;
++
++ int start = -1, end = -1;
++
++ // draw line borders, detect start/stop of a line
++ for(int i=0;i< (int)_jump.size();i++) {
++ if (_jump[i] == 0) continue;
++
++ y1 = 0;
++ y2 = height();
++ if (_lineJump &&
++ (_lineJump->lineTo() == _jump[i]->lineTo()) &&
++ (_jump[i]->lineFrom()->lineno() == _lineno)) {
++
++ if (start<0) start = i;
++ if (_lineJump == _jump[i]) {
++ if (_jump[i]->lineTo()->lineno() <= _lineno)
++ y2 = yy;
++ else
++ y1 = yy;
++ }
++ }
++ else if (!_lineJump && !_lineCall &&
++ (_jump[i]->lineTo()->lineno() == _lineno)) {
++ if (end<0) end = i;
++ if (_jump[i]->lineFrom()->lineno() < _lineno)
++ y2 = yy;
++ else
++ y1 = yy;
++ }
++
++ c = _jump[i]->isCondJump() ? red : blue;
++ p->fillRect( marg + 6*i, y1, 4, y2, c);
++ p->setPen(c.light());
++ p->drawLine( marg + 6*i, y1, marg + 6*i, y2);
++ p->setPen(c.dark());
++ p->drawLine( marg + 6*i +3, y1, marg + 6*i +3, y2);
++ }
++
++ // draw start/stop horizontal line
++ int x, y = yy-2, w, h = 4;
++ if (start >= 0) {
++ c = _jump[start]->isCondJump() ? red : blue;
++ x = marg + 6*start;
++ w = 6*(sv->arrowLevels() - start) + 10;
++ p->fillRect( x, y, w, h, c);
++ p->setPen(c.light());
++ p->drawLine(x, y, x+w-1, y);
++ p->drawLine(x, y, x, y+h-1);
++ p->setPen(c.dark());
++ p->drawLine(x+w-1, y, x+w-1, y+h-1);
++ p->drawLine(x+1, y+h-1, x+w-1, y+h-1);
++ }
++ if (end >= 0) {
++ c = _jump[end]->isCondJump() ? red : blue;
++ x = marg + 6*end;
++ w = 6*(sv->arrowLevels() - end) + 10;
++
++ TQPointArray a;
++ a.putPoints(0, 7, x, y+h,
++ x,y, x+w-8, y, x+w-8, y-2,
++ x+w, yy,
++ x+w-8, y+h+2, x+w-8, y+h);
++ p->setBrush(c);
++ p->drawConvexPolygon(a);
++
++ p->setPen(c.light());
++ p->drawPolyline(a, 0, 5);
++ p->setPen(c.dark());
++ p->drawPolyline(a, 4, 2);
++ p->setPen(c.light());
++ p->drawPolyline(a, 5, 2);
++ p->setPen(c.dark());
++ p->drawPolyline(a, 6, 2);
++ }
++
++ // draw inner vertical line for start/stop
++ // this overwrites borders of horizontal line
++ for(int i=0;i< (int)_jump.size();i++) {
++ if (_jump[i] == 0) continue;
++
++ c = _jump[i]->isCondJump() ? red : blue;
++
++ if (_jump[i]->lineFrom()->lineno() == _lineno) {
++ bool drawUp = true;
++ if (_jump[i]->lineTo()->lineno() == _lineno)
++ if (start<0) drawUp = false;
++ if (_jump[i]->lineTo()->lineno() > _lineno) drawUp = false;
++ if (drawUp)
++ p->fillRect( marg + 6*i +1, 0, 2, yy, c);
++ else
++ p->fillRect( marg + 6*i +1, yy, 2, height()-yy, c);
++ }
++ else if (_jump[i]->lineTo()->lineno() == _lineno) {
++ if (end<0) end = i;
++ if (_jump[i]->lineFrom()->lineno() < _lineno)
++ p->fillRect( marg + 6*i +1, 0, 2, yy, c);
++ else
++ p->fillRect( marg + 6*i +1, yy, 2, height()-yy, c);
++ }
++ }
++
++}
++
++int SourceItem::width( const TQFontMetrics& fm,
++ const TQListView* lv, int c ) const
++{
++ if (c != 3) return TQListViewItem::width(fm, lv, c);
++
++ SourceView* sv = (SourceView*) lv;
++ int levels = sv->arrowLevels();
++
++ if (levels == 0) return 0;
++
++ // 10 pixels for the arrow
++ return 10 + 6*levels + lv->itemMargin() * 2;
++}
++
+diff --git a/kdecachegrind/kdecachegrind/sourceitem.h b/kdecachegrind/kdecachegrind/sourceitem.h
+new file mode 100644
+index 0000000..925e575
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/sourceitem.h
+@@ -0,0 +1,84 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of source view.
++ */
++
++#ifndef SOURCEITEM_H
++#define SOURCEITEM_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++
++class SourceView;
++
++class SourceItem: public TQListViewItem
++{
++public:
++ // for source lines
++ SourceItem(SourceView* sv, TQListView* parent,
++ int fileno, unsigned int lineno,
++ bool inside, const TQString& src,
++ TraceLine* line = 0);
++
++ // for call lines
++ SourceItem(SourceView* sv, TQListViewItem* parent,
++ int fileno, unsigned int lineno,
++ TraceLine* line, TraceLineCall* lineCall);
++
++ // for jump lines
++ SourceItem(SourceView* sv, TQListViewItem* parent,
++ int fileno, unsigned int lineno,
++ TraceLine* line, TraceLineJump* lineJump);
++
++ uint lineno() const { return _lineno; }
++ int fileNumber() const { return _fileno; }
++ bool inside() const { return _inside; }
++ TraceLine* line() const { return _line; }
++ TraceLineCall* lineCall() const { return _lineCall; }
++ TraceLineJump* lineJump() const { return _lineJump; }
++
++ int compare(TQListViewItem * i, int col, bool ascending ) const;
++
++ void paintCell( TQPainter *p, const TQColorGroup &cg,
++ int column, int width, int alignment );
++ int width( const TQFontMetrics& fm,
++ const TQListView* lv, int c ) const;
++ void updateGroup();
++ void updateCost();
++
++ // arrow lines
++ void setJumpArray(const TQMemArray<TraceLineJump*>& a);
++
++protected:
++ void paintArrows(TQPainter *p, const TQColorGroup &cg, int width);
++ TQMemArray<TraceLineJump*> _jump;
++
++private:
++ SourceView* _view;
++ SubCost _pure, _pure2;
++ uint _lineno;
++ int _fileno; // for line sorting (even with multiple files)
++ bool _inside;
++ TraceLine* _line;
++ TraceLineJump* _lineJump;
++ TraceLineCall* _lineCall;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/sourceview.cpp b/kdecachegrind/kdecachegrind/sourceview.cpp
+new file mode 100644
+index 0000000..dde291e
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/sourceview.cpp
+@@ -0,0 +1,813 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Source View
++ */
++
++#include <tqdir.h>
++#include <tqfile.h>
++#include <tqwhatsthis.h>
++#include <tqpopupmenu.h>
++#include <klocale.h>
++#include <kdebug.h>
++
++#include "configuration.h"
++#include "sourceitem.h"
++#include "sourceview.h"
++
++
++//
++// SourceView
++//
++
++
++SourceView::SourceView(TraceItemView* parentView,
++ TQWidget* parent, const char* name)
++ : TQListView(parent, name), TraceItemView(parentView)
++{
++ _inSelectionUpdate = false;
++
++ _arrowLevels = 0;
++ _lowList.setSortLow(true);
++ _highList.setSortLow(false);
++
++ addColumn( i18n( "#" ) );
++ addColumn( i18n( "Cost" ) );
++ addColumn( i18n( "Cost 2" ) );
++ addColumn( "" );
++ addColumn( i18n( "Source (unknown)" ) );
++
++ setAllColumnsShowFocus(true);
++ setColumnAlignment(0, TQt::AlignRight);
++ setColumnAlignment(1, TQt::AlignRight);
++ setColumnAlignment(2, TQt::AlignRight);
++ setResizeMode(TQListView::LastColumn);
++
++ connect(this,
++ TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint &, int)),
++ TQT_SLOT(context(TQListViewItem*, const TQPoint &, int)));
++
++ connect(this,
++ TQT_SIGNAL(selectionChanged(TQListViewItem*)),
++ TQT_SLOT(selectedSlot(TQListViewItem*)));
++
++ connect(this,
++ TQT_SIGNAL(doubleClicked(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ connect(this,
++ TQT_SIGNAL(returnPressed(TQListViewItem*)),
++ TQT_SLOT(activatedSlot(TQListViewItem*)));
++
++ TQWhatsThis::add( this, whatsThis());
++}
++
++void SourceView::paintEmptyArea( TQPainter * p, const TQRect & r)
++{
++ TQListView::paintEmptyArea(p, r);
++}
++
++
++TQString SourceView::whatsThis() const
++{
++ return i18n( "<b>Annotated Source</b>"
++ "<p>The annotated source list shows the "
++ "source lines of the current selected function "
++ "together with (self) cost spent while executing the "
++ "code of this source line. If there was a call "
++ "in a source line, lines with details on the "
++ "call happening are inserted into the source: "
++ "the cost spent inside of the call, the "
++ "number of calls happening, and the call destination.</p>"
++ "<p>Select a inserted call information line to "
++ "make the destination function current.</p>");
++}
++
++void SourceView::context(TQListViewItem* i, const TQPoint & p, int c)
++{
++ TQPopupMenu popup;
++
++ // Menu entry:
++ TraceLineCall* lc = i ? ((SourceItem*) i)->lineCall() : 0;
++ TraceLineJump* lj = i ? ((SourceItem*) i)->lineJump() : 0;
++ TraceFunction* f = lc ? lc->call()->called() : 0;
++ TraceLine* line = lj ? lj->lineTo() : 0;
++
++ if (f) {
++ TQString name = f->name();
++ if ((int)name.length()>Configuration::maxSymbolLength())
++ name = name.left(Configuration::maxSymbolLength()) + "...";
++ popup.insertItem(i18n("Go to '%1'").arg(name), 93);
++ popup.insertSeparator();
++ }
++ else if (line) {
++ popup.insertItem(i18n("Go to Line %1").arg(line->name()), 93);
++ popup.insertSeparator();
++ }
++
++ if ((c == 1) || (c == 2)) {
++ addCostMenu(&popup);
++ popup.insertSeparator();
++ }
++ addGoMenu(&popup);
++
++ int r = popup.exec(p);
++ if (r == 93) {
++ if (f) activated(f);
++ if (line) activated(line);
++ }
++}
++
++
++void SourceView::selectedSlot(TQListViewItem * i)
++{
++ if (!i) return;
++ // programatically selected items are not signalled
++ if (_inSelectionUpdate) return;
++
++ TraceLineCall* lc = ((SourceItem*) i)->lineCall();
++ TraceLineJump* lj = ((SourceItem*) i)->lineJump();
++
++ if (!lc && !lj) {
++ TraceLine* l = ((SourceItem*) i)->line();
++ if (l) {
++ _selectedItem = l;
++ selected(l);
++ }
++ return;
++ }
++
++ TraceFunction* f = lc ? lc->call()->called() : 0;
++ if (f) {
++ _selectedItem = f;
++ selected(f);
++ }
++ else {
++ TraceLine* line = lj ? lj->lineTo() : 0;
++ if (line) {
++ _selectedItem = line;
++ selected(line);
++ }
++ }
++}
++
++void SourceView::activatedSlot(TQListViewItem * i)
++{
++ if (!i) return;
++ TraceLineCall* lc = ((SourceItem*) i)->lineCall();
++ TraceLineJump* lj = ((SourceItem*) i)->lineJump();
++
++ if (!lc && !lj) {
++ TraceLine* l = ((SourceItem*) i)->line();
++ if (l) activated(l);
++ return;
++ }
++
++ TraceFunction* f = lc ? lc->call()->called() : 0;
++ if (f) activated(f);
++ else {
++ TraceLine* line = lj ? lj->lineTo() : 0;
++ if (line) activated(line);
++ }
++}
++
++TraceItem* SourceView::canShow(TraceItem* i)
++{
++ TraceItem::CostType t = i ? i->type() : TraceItem::NoCostType;
++ TraceFunction* f = 0;
++
++ switch(t) {
++ case TraceItem::Function:
++ f = (TraceFunction*) i;
++ break;
++
++ case TraceItem::Instr:
++ f = ((TraceInstr*)i)->function();
++ select(i);
++ break;
++
++ case TraceItem::Line:
++ f = ((TraceLine*)i)->functionSource()->function();
++ select(i);
++ break;
++
++ default:
++ break;
++ }
++
++ return f;
++}
++
++void SourceView::doUpdate(int changeType)
++{
++ // Special case ?
++ if (changeType == selectedItemChanged) {
++
++ if (!_selectedItem) {
++ clearSelection();
++ return;
++ }
++
++ TraceLine* sLine = 0;
++ if (_selectedItem->type() == TraceItem::Line)
++ sLine = (TraceLine*) _selectedItem;
++ if (_selectedItem->type() == TraceItem::Instr)
++ sLine = ((TraceInstr*)_selectedItem)->line();
++
++ SourceItem* si = (SourceItem*)TQListView::selectedItem();
++ if (si) {
++ if (si->line() == sLine) return;
++ if (si->lineCall() &&
++ (si->lineCall()->call()->called() == _selectedItem)) return;
++ }
++
++ TQListViewItem *item, *item2;
++ for (item = firstChild();item;item = item->nextSibling()) {
++ si = (SourceItem*)item;
++ if (si->line() == sLine) {
++ ensureItemVisible(item);
++ _inSelectionUpdate = true;
++ setCurrentItem(item);
++ _inSelectionUpdate = false;
++ break;
++ }
++ item2 = item->firstChild();
++ for (;item2;item2 = item2->nextSibling()) {
++ si = (SourceItem*)item2;
++ if (!si->lineCall()) continue;
++ if (si->lineCall()->call()->called() == _selectedItem) {
++ ensureItemVisible(item2);
++ _inSelectionUpdate = true;
++ setCurrentItem(item2);
++ _inSelectionUpdate = false;
++ break;
++ }
++ }
++ if (item2) break;
++ }
++ return;
++ }
++
++ if (changeType == groupTypeChanged) {
++ TQListViewItem *item, *item2;
++ for (item = firstChild();item;item = item->nextSibling())
++ for (item2 = item->firstChild();item2;item2 = item2->nextSibling())
++ ((SourceItem*)item2)->updateGroup();
++ }
++
++ refresh();
++}
++
++void SourceView::refresh()
++{
++ clear();
++ setColumnWidth(0, 20);
++ setColumnWidth(1, 50);
++ setColumnWidth(2, _costType2 ? 50:0);
++ setColumnWidth(3, 0); // arrows, defaults to invisible
++ setSorting(0); // always reset to line number sort
++ if (_costType)
++ setColumnText(1, _costType->name());
++ if (_costType2)
++ setColumnText(2, _costType2->name());
++
++ _arrowLevels = 0;
++
++ if (!_data || !_activeItem) {
++ setColumnText(4, i18n("(No Source)"));
++ return;
++ }
++
++ TraceItem::CostType t = _activeItem->type();
++ TraceFunction* f = 0;
++ if (t == TraceItem::Function) f = (TraceFunction*) _activeItem;
++ if (t == TraceItem::Instr) {
++ f = ((TraceInstr*)_activeItem)->function();
++ if (!_selectedItem) _selectedItem = _activeItem;
++ }
++ if (t == TraceItem::Line) {
++ f = ((TraceLine*)_activeItem)->functionSource()->function();
++ if (!_selectedItem) _selectedItem = _activeItem;
++ }
++
++ if (!f) return;
++
++ // Allow resizing of column 2
++ setColumnWidthMode(2, TQListView::Maximum);
++
++ TraceFunctionSource* mainSF = f->sourceFile();
++
++ // skip first source if there's no debug info and there are more sources
++ // (this is for a bug in GCC 2.95.x giving unknown source for prologs)
++ if (mainSF &&
++ (mainSF->firstLineno() == 0) &&
++ (mainSF->lastLineno() == 0) &&
++ (f->sourceFiles().count()>1) ) {
++ // skip
++ }
++ else
++ fillSourceFile(mainSF, 0);
++
++ TraceFunctionSource* sf;
++ int fileno = 1;
++ TraceFunctionSourceList l = f->sourceFiles();
++ for (sf=l.first();sf;sf=l.next(), fileno++)
++ if (sf != mainSF)
++ fillSourceFile(sf, fileno);
++
++ if (!_costType2) {
++ setColumnWidthMode(2, TQListView::Manual);
++ setColumnWidth(2, 0);
++ }
++}
++
++
++// helper for fillSourceList:
++// search recursive for a file, starting from a base dir
++static bool checkFileExistance(TQString& dir, const TQString& name)
++{
++ // we leave this in...
++ qDebug("Checking %s/%s", dir.ascii(), name.ascii());
++
++ if (TQFile::exists(dir + "/" + name)) return true;
++
++ // check in subdirectories
++ TQDir d(dir);
++ d.setFilter( TQDir::Dirs | TQDir::NoSymLinks );
++ d.setSorting( TQDir::Unsorted );
++ TQStringList subdirs = d.entryList();
++ TQStringList::Iterator it =subdirs.begin();
++ for(; it != subdirs.end(); ++it ) {
++ if (*it == "." || *it == ".." || *it == "CVS") continue;
++
++ dir = d.filePath(*it);
++ if (checkFileExistance(dir, name)) return true;
++ }
++ return false;
++}
++
++
++void SourceView::updateJumpArray(uint lineno, SourceItem* si,
++ bool ignoreFrom, bool ignoreTo)
++{
++ TraceLineJump* lj;
++ uint lowLineno, highLineno;
++ int iEnd = -1, iStart = -1;
++
++ if (0) qDebug("updateJumpArray(line %d, jump to %s)",
++ lineno,
++ si->lineJump()
++ ? si->lineJump()->lineTo()->name().ascii() : "?" );
++
++
++ lj=_lowList.current();
++ while(lj) {
++ lowLineno = lj->lineFrom()->lineno();
++ if (lj->lineTo()->lineno() < lowLineno)
++ lowLineno = lj->lineTo()->lineno();
++
++ if (lowLineno > lineno) break;
++
++ if (ignoreFrom && (lowLineno < lj->lineTo()->lineno())) break;
++ if (ignoreTo && (lowLineno < lj->lineFrom()->lineno())) break;
++
++ if (si->lineJump() && (lj != si->lineJump())) break;
++
++ int asize = (int)_jump.size();
++#if 0
++ for(iStart=0;iStart<asize;iStart++)
++ if (_jump[iStart] &&
++ (_jump[iStart]->lineTo() == lj->lineTo())) break;
++#else
++ iStart = asize;
++#endif
++
++ if (iStart == asize) {
++ for(iStart=0;iStart<asize;iStart++)
++ if (_jump[iStart] == 0) break;
++
++ if (iStart== asize) {
++ asize++;
++ _jump.resize(asize);
++ if (asize > _arrowLevels) _arrowLevels = asize;
++ }
++
++ if (0) qDebug(" start %d (%s to %s)",
++ iStart,
++ lj->lineFrom()->name().ascii(),
++ lj->lineTo()->name().ascii());
++
++ _jump[iStart] = lj;
++ }
++ lj=_lowList.next();
++ }
++
++ si->setJumpArray(_jump);
++
++ lj=_highList.current();
++ while(lj) {
++ highLineno = lj->lineFrom()->lineno();
++ if (lj->lineTo()->lineno() > highLineno) {
++ highLineno = lj->lineTo()->lineno();
++ if (ignoreTo) break;
++ }
++ else if (ignoreFrom) break;
++
++ if (highLineno > lineno) break;
++
++ for(iEnd=0;iEnd< (int)_jump.size();iEnd++)
++ if (_jump[iEnd] == lj) break;
++ if (iEnd == (int)_jump.size()) {
++ qDebug("LineView: no jump start for end at %x ?", highLineno);
++ iEnd = -1;
++ }
++ lj=_highList.next();
++
++ if (0 && (iEnd>=0))
++ qDebug(" end %d (%s to %s)",
++ iEnd,
++ _jump[iEnd]->lineFrom()->name().ascii(),
++ _jump[iEnd]->lineTo()->name().ascii());
++
++ if (0 && lj) qDebug("next end: %s to %s",
++ lj->lineFrom()->name().ascii(),
++ lj->lineTo()->name().ascii());
++
++ if (highLineno > lineno)
++ break;
++ else {
++ if (iEnd>=0) _jump[iEnd] = 0;
++ iEnd = -1;
++ }
++ }
++ if (iEnd>=0) _jump[iEnd] = 0;
++}
++
++
++/* If sourceList is empty we set the source file name into the header,
++ * else this code is of a inlined function, and we add "inlined from..."
++ */
++void SourceView::fillSourceFile(TraceFunctionSource* sf, int fileno)
++{
++ if (!sf) return;
++
++ if (0) qDebug("Selected Item %s",
++ _selectedItem ? _selectedItem->name().ascii() : "(none)");
++
++ TraceLineMap::Iterator lineIt, lineItEnd;
++ int nextCostLineno = 0, lastCostLineno = 0;
++
++ bool validSourceFile = (!sf->file()->name().isEmpty());
++
++ TraceLine* sLine = 0;
++ if (_selectedItem) {
++ if (_selectedItem->type() == TraceItem::Line)
++ sLine = (TraceLine*) _selectedItem;
++ if (_selectedItem->type() == TraceItem::Instr)
++ sLine = ((TraceInstr*)_selectedItem)->line();
++ }
++
++ if (validSourceFile) {
++ TraceLineMap* lineMap = sf->lineMap();
++ if (lineMap) {
++ lineIt = lineMap->begin();
++ lineItEnd = lineMap->end();
++ // get first line with cost of selected type
++ while(lineIt != lineItEnd) {
++ if (&(*lineIt) == sLine) break;
++ if ((*lineIt).hasCost(_costType)) break;
++ if (_costType2 && (*lineIt).hasCost(_costType2)) break;
++ ++lineIt;
++ }
++
++ nextCostLineno = (lineIt == lineItEnd) ? 0 : (*lineIt).lineno();
++ if (nextCostLineno<0) {
++ kdError() << "SourceView::fillSourceFile: Negative line number "
++ << nextCostLineno << endl
++ << " Function '" << sf->function()->name() << "'" << endl
++ << " File '" << sf->file()->name() << "'" << endl;
++ nextCostLineno = 0;
++ }
++
++ }
++
++ if (nextCostLineno == 0) {
++ new SourceItem(this, this, fileno, 0, false,
++ i18n("There is no cost of current selected type associated"));
++ new SourceItem(this, this, fileno, 1, false,
++ i18n("with any source line of this function in file"));
++ new SourceItem(this, this, fileno, 2, false,
++ TQString(" '%1'").arg(sf->function()->prettyName()));
++ new SourceItem(this, this, fileno, 3, false,
++ i18n("Thus, no annotated source can be shown."));
++ return;
++ }
++ }
++
++ TQString filename = sf->file()->shortName();
++ TQString dir = sf->file()->directory();
++ if (!dir.isEmpty())
++ filename = dir + "/" + filename;
++
++ if (nextCostLineno>0) {
++ // we have debug info... search for source file
++ if (!TQFile::exists(filename)) {
++ TQStringList list = Configuration::sourceDirs(_data,
++ sf->function()->object());
++ TQStringList::Iterator it;
++
++ for ( it = list.begin(); it != list.end(); ++it ) {
++ dir = *it;
++ if (checkFileExistance(dir, sf->file()->shortName())) break;
++ }
++
++ if (it == list.end())
++ nextCostLineno = 0;
++ else {
++ filename = dir + "/" + sf->file()->shortName();
++ // no need to search again
++ sf->file()->setDirectory(dir);
++ }
++ }
++ }
++
++ // do it here, because the source directory could have been set before
++ if (childCount()==0) {
++ setColumnText(4, validSourceFile ?
++ i18n("Source ('%1')").arg(filename) :
++ i18n("Source (unknown)"));
++ }
++ else {
++ new SourceItem(this, this, fileno, 0, true,
++ validSourceFile ?
++ i18n("--- Inlined from '%1' ---").arg(filename) :
++ i18n("--- Inlined from unknown source ---"));
++ }
++
++ if (nextCostLineno == 0) {
++ new SourceItem(this, this, fileno, 0, false,
++ i18n("There is no source available for the following function:"));
++ new SourceItem(this, this, fileno, 1, false,
++ TQString(" '%1'").arg(sf->function()->prettyName()));
++ if (sf->file()->name().isEmpty()) {
++ new SourceItem(this, this, fileno, 2, false,
++ i18n("This is because no debug information is present."));
++ new SourceItem(this, this, fileno, 3, false,
++ i18n("Recompile source and redo the profile run."));
++ if (sf->function()->object()) {
++ new SourceItem(this, this, fileno, 4, false,
++ i18n("The function is located in this ELF object:"));
++ new SourceItem(this, this, fileno, 5, false,
++ TQString(" '%1'")
++ .arg(sf->function()->object()->prettyName()));
++ }
++ }
++ else {
++ new SourceItem(this, this, fileno, 2, false,
++ i18n("This is because its source file cannot be found:"));
++ new SourceItem(this, this, fileno, 3, false,
++ TQString(" '%1'").arg(sf->file()->name()));
++ new SourceItem(this, this, fileno, 4, false,
++ i18n("Add the folder of this file to the source folder list."));
++ new SourceItem(this, this, fileno, 5, false,
++ i18n("The list can be found in the configuration dialog."));
++ }
++ return;
++ }
++
++
++ // initialisation for arrow drawing
++ // create sorted list of jumps (for jump arrows)
++ TraceLineMap::Iterator it = lineIt, nextIt;
++ _lowList.clear();
++ _highList.clear();
++ while(1) {
++
++ nextIt = it;
++ ++nextIt;
++ while(nextIt != lineItEnd) {
++ if (&(*nextIt) == sLine) break;
++ if ((*nextIt).hasCost(_costType)) break;
++ if (_costType2 && (*nextIt).hasCost(_costType2)) break;
++ ++nextIt;
++ }
++
++ TraceLineJumpList jlist = (*it).lineJumps();
++ TraceLineJump* lj;
++ for (lj=jlist.first();lj;lj=jlist.next()) {
++ if (lj->executedCount()==0) continue;
++ // skip jumps to next source line with cost
++ //if (lj->lineTo() == &(*nextIt)) continue;
++
++ _lowList.append(lj);
++ _highList.append(lj);
++ }
++ it = nextIt;
++ if (it == lineItEnd) break;
++ }
++ _lowList.sort();
++ _highList.sort();
++ _lowList.first(); // iterators to list start
++ _highList.first();
++ _jump.resize(0);
++
++
++ char buf[256];
++ bool inside = false, skipLineWritten = true;
++ int readBytes;
++ int fileLineno = 0;
++ SubCost most = 0;
++
++ TraceLine* currLine;
++ SourceItem *si, *si2, *item = 0, *first = 0, *selected = 0;
++ TQFile file(filename);
++ if (!file.open(IO_ReadOnly)) return;
++ while (1) {
++ readBytes=file.readLine(buf, sizeof( buf ));
++ if (readBytes<=0) {
++ // for nice empty 4 lines after function with EOF
++ buf[0] = 0;
++ }
++
++ if (readBytes >= (int) sizeof( buf )) {
++ qDebug("%s:%d Line too long\n",
++ sf->file()->name().ascii(), fileLineno);
++ }
++ else if ((readBytes>0) && (buf[readBytes-1] == '\n'))
++ buf[readBytes-1] = 0;
++
++
++ // keep fileLineno inside [lastCostLineno;nextCostLineno]
++ fileLineno++;
++ if (fileLineno == nextCostLineno) {
++ currLine = &(*lineIt);
++
++ // get next line with cost of selected type
++ ++lineIt;
++ while(lineIt != lineItEnd) {
++ if (&(*lineIt) == sLine) break;
++ if ((*lineIt).hasCost(_costType)) break;
++ if (_costType2 && (*lineIt).hasCost(_costType2)) break;
++ ++lineIt;
++ }
++
++ lastCostLineno = nextCostLineno;
++ nextCostLineno = (lineIt == lineItEnd) ? 0 : (*lineIt).lineno();
++ }
++ else
++ currLine = 0;
++
++ // update inside
++ if (!inside) {
++ if (currLine) inside = true;
++ }
++ else {
++ if ( (fileLineno > lastCostLineno) &&
++ ((nextCostLineno == 0) ||
++ (fileLineno < nextCostLineno - Configuration::noCostInside()) ))
++ inside = false;
++ }
++
++ int context = Configuration::context();
++
++ if ( ((lastCostLineno==0) || (fileLineno > lastCostLineno + context)) &&
++ ((nextCostLineno==0) || (fileLineno < nextCostLineno - context))) {
++ if (lineIt == lineItEnd) break;
++
++ if (!skipLineWritten) {
++ skipLineWritten = true;
++ // a "skipping" line: print "..." instead of a line number
++ strcpy(buf,"...");
++ }
++ else
++ continue;
++ }
++ else
++ skipLineWritten = false;
++
++ si = new SourceItem(this, this,
++ fileno, fileLineno, inside, TQString(buf),
++ currLine);
++
++ if (!currLine) continue;
++
++ if (!selected && (currLine == sLine)) selected = si;
++ if (!first) first = si;
++
++ if (currLine->subCost(_costType) > most) {
++ item = si;
++ most = currLine->subCost(_costType);
++ }
++
++ si->setOpen(true);
++ TraceLineCallList list = currLine->lineCalls();
++ TraceLineCall* lc;
++ for (lc=list.first();lc;lc=list.next()) {
++ if ((lc->subCost(_costType)==0) &&
++ (lc->subCost(_costType2)==0)) continue;
++
++ if (lc->subCost(_costType) > most) {
++ item = si;
++ most = lc->subCost(_costType);
++ }
++
++ si2 = new SourceItem(this, si, fileno, fileLineno, currLine, lc);
++
++ if (!selected && (lc->call()->called() == _selectedItem))
++ selected = si2;
++ }
++
++ TraceLineJumpList jlist = currLine->lineJumps();
++ TraceLineJump* lj;
++ for (lj=jlist.first();lj;lj=jlist.next()) {
++ if (lj->executedCount()==0) continue;
++
++ new SourceItem(this, si, fileno, fileLineno, currLine, lj);
++ }
++ }
++
++ if (selected) item = selected;
++ if (item) first = item;
++ if (first) {
++ ensureItemVisible(first);
++ _inSelectionUpdate = true;
++ setCurrentItem(first);
++ _inSelectionUpdate = false;
++ }
++
++ file.close();
++
++ // for arrows: go down the list according to list sorting
++ sort();
++ TQListViewItem *item1, *item2;
++ for (item1=firstChild();item1;item1 = item1->nextSibling()) {
++ si = (SourceItem*)item1;
++ updateJumpArray(si->lineno(), si, true, false);
++
++ for (item2=item1->firstChild();item2;item2 = item2->nextSibling()) {
++ si2 = (SourceItem*)item2;
++ if (si2->lineJump())
++ updateJumpArray(si->lineno(), si2, false, true);
++ else
++ si2->setJumpArray(_jump);
++ }
++ }
++
++ if (arrowLevels())
++ setColumnWidth(3, 10 + 6*arrowLevels() + itemMargin() * 2);
++ else
++ setColumnWidth(3, 0);
++}
++
++
++void SourceView::updateSourceItems()
++{
++ setColumnWidth(1, 50);
++ setColumnWidth(2, _costType2 ? 50:0);
++ // Allow resizing of column 2
++ setColumnWidthMode(2, TQListView::Maximum);
++
++ if (_costType)
++ setColumnText(1, _costType->name());
++ if (_costType2)
++ setColumnText(2, _costType2->name());
++
++ SourceItem* si;
++ TQListViewItem* item = firstChild();
++ for (;item;item = item->nextSibling()) {
++ si = (SourceItem*)item;
++ TraceLine* l = si->line();
++ if (!l) continue;
++
++ si->updateCost();
++
++ TQListViewItem *next, *i = si->firstChild();
++ for (;i;i = next) {
++ next = i->nextSibling();
++ ((SourceItem*)i)->updateCost();
++ }
++ }
++
++ if (!_costType2) {
++ setColumnWidthMode(2, TQListView::Manual);
++ setColumnWidth(2, 0);
++ }
++}
++
++#include "sourceview.moc"
+diff --git a/kdecachegrind/kdecachegrind/sourceview.h b/kdecachegrind/kdecachegrind/sourceview.h
+new file mode 100644
+index 0000000..b72fc7a
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/sourceview.h
+@@ -0,0 +1,71 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Source View
++ */
++
++#ifndef SOURCEVIEW_H
++#define SOURCEVIEW_H
++
++#include <tqlistview.h>
++#include "traceitemview.h"
++
++class SourceItem;
++
++class SourceView : public TQListView, public TraceItemView
++{
++ friend class SourceItem;
++
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ SourceView(TraceItemView* parentView,
++ TQWidget* parent = 0, const char* name = 0);
++
++ TQWidget* widget() { return this; }
++ TQString whatsThis() const;
++
++protected:
++ int arrowLevels() { return _arrowLevels; }
++ void paintEmptyArea( TQPainter *, const TQRect & );
++
++private slots:
++ void context(TQListViewItem*, const TQPoint &, int);
++ void selectedSlot(TQListViewItem *);
++ void activatedSlot(TQListViewItem *);
++
++private:
++ TraceItem* canShow(TraceItem*);
++ void doUpdate(int);
++ void refresh();
++ void updateJumpArray(uint,SourceItem*,bool,bool);
++ void fillSourceFile(TraceFunctionSource*, int);
++ void updateSourceItems();
++
++ bool _inSelectionUpdate;
++
++ // arrows
++ int _arrowLevels;
++ // temporary needed on creation...
++ TQMemArray<TraceLineJump*> _jump;
++ TraceLineJumpList _lowList, _highList;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/stackbrowser.cpp b/kdecachegrind/kdecachegrind/stackbrowser.cpp
+new file mode 100644
+index 0000000..78095eb
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/stackbrowser.cpp
+@@ -0,0 +1,417 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#include <tqlistview.h>
++
++#include "stackbrowser.h"
++
++// Stack
++
++Stack::Stack(TraceFunction* top, TraceCallList calls)
++{
++ _refCount = 0;
++ _top = top;
++ _calls = calls;
++
++ extendBottom();
++}
++
++Stack::Stack(TraceFunction* f)
++{
++ _refCount = 0;
++ _top = f;
++
++ extendBottom();
++ extendTop();
++}
++
++void Stack::extendBottom()
++{
++ TraceCallList l;
++ TraceCall *c, *call;
++ SubCost most;
++ TraceFunction* f;
++
++ if (_calls.last())
++ f = _calls.last()->called();
++ else
++ f = _top;
++
++ if (!f) return;
++ // don't follow calls from cycles
++ if (f->cycle() == f) return;
++
++
++ int max = 30;
++
++ // try to extend to lower stack frames
++ while (f && (max-- >0)) {
++ l = f->callings();
++ call = 0;
++ most = 0;
++ for (c=l.first();c;c=l.next()) {
++ // no cycle calls in stack: could be deleted without notice
++ if (c->called()->cycle() == c->called()) continue;
++ // no simple recursions
++ if (c->called() == _top) continue;
++
++ if (c->called()->name().isEmpty()) continue;
++ SubCost sc = c->subCost(0); // FIXME
++ if (sc == 0) continue;
++
++ if (sc > most) {
++ most = sc;
++ call = c;
++ }
++ }
++ if (!call)
++ break;
++
++ _calls.append(call);
++ f = call->called();
++ }
++}
++
++
++void Stack::extendTop()
++{
++ TraceCallList l;
++ TraceCall *c, *call;
++ SubCost most;
++
++ int max = 10;
++
++ // don't follow calls from cycles
++ if (_top->cycle() == _top) return;
++
++ // try to extend to upper stack frames
++ while (_top && (max-- >0)) {
++ l = _top->callers();
++ call = 0;
++ most = 0;
++ for (c=l.first();c;c=l.next()) {
++ // no cycle calls in stack: could be deleted without notice
++ if (c->caller()->cycle() == c->caller()) continue;
++ // no simple recursions
++ if (c->caller() == _top) continue;
++
++ if (c->caller()->name().isEmpty()) continue;
++ SubCost sc = c->subCost(0); // FIXME
++ if (sc == 0) continue;
++
++ if (sc > most) {
++ most = sc;
++ call = c;
++ }
++ }
++ if (!call)
++ break;
++
++ _calls.prepend(call);
++ _top = call->caller();
++ }
++}
++
++TraceFunction* Stack::caller(TraceFunction* fn, bool extend)
++{
++ TraceFunction* f;
++ TraceCall* c;
++
++ if (extend && (_top == fn)) {
++ // extend at top
++ extendTop();
++ f = _top;
++ }
++
++ for (c=_calls.first();c;c=_calls.next()) {
++ f = c->called();
++ if (f == fn)
++ return c->caller();
++ }
++ return 0;
++}
++
++TraceFunction* Stack::called(TraceFunction* fn, bool extend)
++{
++ TraceFunction* f;
++ TraceCall* c;
++
++ for (c=_calls.first();c;c=_calls.next()) {
++ f = c->caller();
++ if (f == fn)
++ return c->called();
++ }
++
++ if (extend && (c->called() == fn)) {
++ // extend at bottom
++ extendBottom();
++
++ // and search again
++ for (c=_calls.first();c;c=_calls.next()) {
++ f = c->caller();
++ if (f == fn)
++ return c->called();
++ }
++ }
++
++ return 0;
++}
++
++bool Stack::contains(TraceFunction* fn)
++{
++ // cycles are listed on there own
++ if (fn->cycle() == fn) return false;
++ if (_top->cycle() == _top) return false;
++
++ if (fn == _top)
++ return true;
++
++ TraceFunction* f = _top;
++ TraceCall* c;
++
++ for (c=_calls.first();c;c=_calls.next()) {
++ f = c->called();
++ if (f == fn)
++ return true;
++ }
++
++ TraceCallList l;
++
++ // try to extend at bottom (even if callCount 0)
++ l = f->callings();
++ for (c=l.first();c;c=l.next()) {
++ f = c->called();
++ if (f == fn)
++ break;
++ }
++
++ if (c) {
++ _calls.append(c);
++
++ // extend at bottom after found one
++ extendBottom();
++ return true;
++ }
++
++ // try to extend at top (even if callCount 0)
++ l = _top->callers();
++ for (c=l.first();c;c=l.next()) {
++ f = c->caller();
++ if (f == fn)
++ break;
++ }
++
++ if (c) {
++ _calls.prepend(c);
++
++ // extend at top after found one
++ extendTop();
++ return true;
++ }
++
++ return false;
++}
++
++Stack* Stack::split(TraceFunction* f)
++{
++ TraceCallList calls = _calls;
++ TraceCall *c, *c2;
++
++ // cycles are listed on there own
++ if (f->cycle() == f) return 0;
++ if (_top->cycle() == _top) return false;
++
++ for (c=calls.first();c;c=calls.next()) {
++ TraceCallList l = c->called()->callings();
++ for (c2=l.first();c2;c2=l.next()) {
++ if (c2 == c) continue;
++ if (c2->called() == f)
++ break;
++ }
++ if (c2)
++ break;
++ }
++
++ if (!c)
++ return 0;
++
++ // remove bottom part
++ calls.last();
++ while (calls.current() && calls.current()!=c)
++ calls.removeLast();
++
++ calls.append(c2);
++ return new Stack(_top, calls );
++}
++
++TQString Stack::toString()
++{
++ TQString res = _top->name();
++ TraceCall *c;
++ for (c=_calls.first();c;c=_calls.next())
++ res += "\n > " + c->called()->name();
++
++ return res;
++}
++
++
++// HistoryItem
++
++HistoryItem::HistoryItem(Stack* stack, TraceFunction* function)
++{
++ _stack = stack;
++ _function = function;
++ if (_stack)
++ _stack->ref();
++
++ _last = 0;
++ _next = 0;
++
++/*
++ qDebug("New Stack History Item (sRef %d): %s\n %s",
++ _stack->refCount(), _function->name().ascii(),
++ _stack->toString().ascii());
++*/
++}
++
++HistoryItem::~HistoryItem()
++{
++ if (0) qDebug("Deleting Stack History Item (sRef %d): %s",
++ _stack->refCount(),
++ _function->name().ascii());
++
++ if (_last)
++ _last->_next = _next;
++ if (_stack) {
++ if (_stack->deref() == 0)
++ delete _stack;
++ }
++}
++
++
++// StackBrowser
++
++StackBrowser::StackBrowser()
++{
++ _current = 0;
++}
++
++StackBrowser::~StackBrowser()
++{
++ delete _current;
++}
++
++HistoryItem* StackBrowser::select(TraceFunction* f)
++{
++ if (!_current) {
++ Stack* s = new Stack(f);
++ _current = new HistoryItem(s, f);
++ }
++ else if (_current->function() != f) {
++ // make current item the last one
++ HistoryItem* item = _current;
++ if (item->next()) {
++ item = item->next();
++ item->last()->setNext(0);
++
++ while (item->next()) {
++ item = item->next();
++ delete item->last();
++ }
++ delete item;
++ }
++
++ Stack* s = _current->stack();
++ if (!s->contains(f)) {
++ s = s->split(f);
++ if (!s)
++ s = new Stack(f);
++ }
++
++ item = _current;
++ _current = new HistoryItem(s, f);
++ item->setNext(_current);
++ _current->setLast(item);
++ }
++
++ // qDebug("Selected %s in StackBrowser", f->name().ascii());
++
++ return _current;
++}
++
++HistoryItem* StackBrowser::goBack()
++{
++ if (_current && _current->last())
++ _current = _current->last();
++
++ return _current;
++}
++
++HistoryItem* StackBrowser::goForward()
++{
++ if (_current && _current->next())
++ _current = _current->next();
++
++ return _current;
++}
++
++HistoryItem* StackBrowser::goUp()
++{
++ if (_current) {
++ TraceFunction* f = _current->stack()->caller(_current->function(), true);
++ if (f)
++ _current = select(f);
++ }
++
++ return _current;
++}
++
++HistoryItem* StackBrowser::goDown()
++{
++ if (_current) {
++ TraceFunction* f = _current->stack()->called(_current->function(), true);
++ if (f)
++ _current = select(f);
++ }
++
++ return _current;
++}
++
++bool StackBrowser::canGoBack()
++{
++ return _current && _current->last();
++}
++
++bool StackBrowser::canGoForward()
++{
++ return _current && _current->next();
++}
++
++bool StackBrowser::canGoUp()
++{
++ if (!_current) return false;
++
++ return _current->stack()->caller(_current->function(), false);
++}
++
++bool StackBrowser::canGoDown()
++ {
++ if (!_current) return false;
++
++ return _current->stack()->called(_current->function(), false);
++}
+diff --git a/kdecachegrind/kdecachegrind/stackbrowser.h b/kdecachegrind/kdecachegrind/stackbrowser.h
+new file mode 100644
+index 0000000..e7d6b80
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/stackbrowser.h
+@@ -0,0 +1,109 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#ifndef STACKBROWSER_H
++#define STACKBROWSER_H
++
++#include "tracedata.h"
++
++// A history of selected functions within stacks
++
++class Stack
++{
++public:
++ Stack(TraceFunction*);
++
++ // extend the stack at top/bottom if possible
++ bool contains(TraceFunction*);
++
++ void extendBottom();
++ void extendTop();
++
++ // search for a function on stack calling specified function.
++ // if found, return upper part with new function call
++ Stack* split(TraceFunction*);
++
++ // increment reference count
++ void ref() { _refCount++; }
++ // decrement reference count
++ bool deref() { return --_refCount; }
++ int refCount() { return _refCount; }
++
++ TraceFunction* top() { return _top; }
++ TraceCallList calls() { return _calls; }
++ TraceFunction* caller(TraceFunction*, bool extend);
++ TraceFunction* called(TraceFunction*, bool extend);
++
++ TQString toString();
++
++private:
++ Stack(TraceFunction* top, TraceCallList list);
++
++ // at the top of the stack we have a function...
++ TraceFunction* _top;
++ // list ordered from top to bottom
++ TraceCallList _calls;
++ int _refCount;
++};
++
++class HistoryItem
++{
++public:
++ HistoryItem(Stack*, TraceFunction*);
++ ~HistoryItem();
++
++ Stack* stack() { return _stack; }
++ TraceFunction* function() { return _function; }
++ HistoryItem* last() { return _last; }
++ HistoryItem* next() { return _next; }
++ void setLast(HistoryItem* h) { _last = h; }
++ void setNext(HistoryItem* h) { _next = h; }
++
++private:
++
++ HistoryItem *_last, *_next;
++ Stack* _stack;
++ TraceFunction* _function;
++};
++
++
++class StackBrowser
++{
++public:
++ StackBrowser();
++ ~StackBrowser();
++
++ // A function was selected. This creates a new history entry
++ HistoryItem* select(TraceFunction*);
++
++ HistoryItem* current() { return _current; }
++ bool canGoBack();
++ bool canGoForward();
++ bool canGoUp();
++ bool canGoDown();
++ HistoryItem* goBack();
++ HistoryItem* goForward();
++ HistoryItem* goUp();
++ HistoryItem* goDown();
++
++private:
++ HistoryItem* _current;
++};
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/stackitem.cpp b/kdecachegrind/kdecachegrind/stackitem.cpp
+new file mode 100644
+index 0000000..e3763ab
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/stackitem.cpp
+@@ -0,0 +1,116 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of stack dockable.
++ */
++
++#include <tqpixmap.h>
++#include <klocale.h>
++
++#include "configuration.h"
++#include "listutils.h"
++#include "stackitem.h"
++#include "stackselection.h"
++
++// StackItem
++
++StackItem::StackItem(StackSelection* ss,
++ TQListView* parent, TraceFunction* f)
++ :TQListViewItem(parent)
++{
++ _view = ss;
++ _function = f;
++ _call = 0;
++
++ updateGroup();
++ updateCost();
++
++ setText(2, TQString("-- "));
++ setText(3, f->prettyName());
++}
++
++StackItem::StackItem(StackSelection* ss,
++ TQListView* parent, TraceCall* call)
++ :TQListViewItem(parent)
++{
++ _view = ss;
++ _call = call;
++ _function = call->called();
++
++ updateGroup();
++ updateCost();
++
++ setText(3, _function->prettyName());
++}
++
++
++void StackItem::updateGroup()
++{
++ TQColor c = Configuration::functionColor(_view->groupType(),
++ _function);
++ setPixmap(3, colorPixmap(10, 10, c));
++}
++
++void StackItem::updateCost()
++{
++ if (!_call) return;
++
++ setText(2, _call->prettyCallCount());
++
++ TraceCostType* ct = _view->costType();
++ _sum = _call->subCost(ct);
++ double total = _call->called()->data()->subCost(ct);
++ if (total == 0.0) {
++ setText(0, "-");
++ setPixmap(0, TQPixmap());
++ }
++ else {
++ double sum = 100.0 * _sum / total;
++
++ if (Configuration::showPercentage())
++ setText(0, TQString("%1")
++ .arg(sum, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(0, _call->prettySubCost(ct));
++
++ setPixmap(0, costPixmap(ct, _call, total, false));
++ }
++
++ // if _costType2 is 0, column1 is hidden, no change needed
++ TraceCostType* ct2 = _view->costType2();
++ if (!ct2) return;
++
++ _sum = _call->subCost(ct2);
++ total = _call->called()->data()->subCost(ct2);
++ if (total == 0.0) {
++ setText(1, "-");
++ setPixmap(1, TQPixmap());
++ }
++ else {
++ double sum = 100.0 * _sum / total;
++
++ if (Configuration::showPercentage())
++ setText(1, TQString("%1")
++ .arg(sum, 0, 'f', Configuration::percentPrecision()));
++ else
++ setText(1, _call->prettySubCost(ct2));
++
++ setPixmap(1, costPixmap(ct2, _call, total, false));
++ }
++}
+diff --git a/kdecachegrind/kdecachegrind/stackitem.h b/kdecachegrind/kdecachegrind/stackitem.h
+new file mode 100644
+index 0000000..250e9f6
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/stackitem.h
+@@ -0,0 +1,56 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003, 2004
++ Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Items of stack dockable.
++ */
++
++#ifndef STACKITEM_H
++#define STACKITEM_H
++
++#include <tqlistview.h>
++#include "tracedata.h"
++
++class StackSelection;
++
++
++// for the stack browser
++
++class StackItem: public TQListViewItem
++{
++public:
++ // for top
++ StackItem(StackSelection* ss, TQListView* parent, TraceFunction* f);
++ StackItem(StackSelection* ss, TQListView* parent, TraceCall* c);
++
++ TraceFunction* function() { return _function; }
++ TraceCall* call() { return _call; }
++ void updateGroup();
++ void updateCost();
++
++private:
++ StackSelection* _view;
++ SubCost _sum;
++ TraceFunction* _function;
++ TraceCall* _call;
++};
++
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/stackselection.cpp b/kdecachegrind/kdecachegrind/stackselection.cpp
+new file mode 100644
+index 0000000..5909475
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/stackselection.cpp
+@@ -0,0 +1,230 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * StackSelection for KCachegrind
++ * For function selection of a most expected stack,
++ * to be put into a TQDockWindow
++ */
++
++#include <tqtimer.h>
++#include <tqlistview.h>
++#include <tqlabel.h>
++#include <tqpushbutton.h>
++#include <tqcombobox.h>
++#include <tqlineedit.h>
++
++#include <kdebug.h>
++
++#include "stackbrowser.h"
++#include "stackselection.h"
++#include "stackitem.h"
++
++StackSelection::StackSelection( TQWidget* parent, const char* name)
++ : StackSelectionBase(parent, name)
++{
++ _data = 0;
++ _browser = new StackBrowser();
++ _item = 0;
++ _function = 0;
++ _costType = 0;
++ _costType2 = 0;
++ _groupType = TraceItem::Function;
++
++ stackList->setSorting(-1);
++ stackList->setAllColumnsShowFocus(true);
++ stackList->setResizeMode(TQListView::LastColumn);
++ stackList->setColumnAlignment(0, TQt::AlignRight);
++ stackList->setColumnAlignment(1, TQt::AlignRight);
++ stackList->setColumnAlignment(2, TQt::AlignRight);
++ stackList->setColumnWidth(0, 50);
++ // 2nd cost column hidden at first (_costType2 == 0)
++ stackList->setColumnWidth(1, 0);
++ stackList->setColumnWidth(2, 50);
++
++ connect(stackList, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
++ this, TQT_SLOT(stackSelected(TQListViewItem*)));
++}
++
++StackSelection::~StackSelection()
++{
++ delete _browser;
++}
++
++void StackSelection::setData(TraceData* data)
++{
++ if (_data == data) return;
++
++ _data = data;
++
++ stackList->clear();
++ delete _browser;
++ _browser = new StackBrowser();
++ _function = 0;
++}
++
++
++void StackSelection::setFunction(TraceFunction* f)
++{
++ if (_function == f) return;
++ _function = f;
++
++ if (!_data || !_function) return;
++
++ //kdDebug() << "StackSelection::setFunction " << f->name() << endl;
++
++ HistoryItem* item = _browser->current();
++ if (!item || item->function() != f) {
++ _browser->select(f);
++ rebuildStackList();
++ }
++}
++
++
++void StackSelection::rebuildStackList()
++{
++ HistoryItem* item = _browser->current();
++ stackList->clear();
++ stackList->setColumnWidth(0, 50);
++ stackList->setColumnWidth(1, _costType2 ? 50:0);
++ stackList->setColumnWidth(2, 50);
++ if (!item || !item->stack()) return;
++
++ TraceFunction* top = item->stack()->top();
++ if (!top) return;
++
++ stackList->setColumnWidthMode(1, TQListView::Maximum);
++
++ TraceCallList l = item->stack()->calls();
++ TraceCall* call;
++ for (call=l.last();call;call=l.prev())
++ new StackItem(this, stackList, call);
++
++ new StackItem(this, stackList, top);
++
++ // select current function
++ TQListViewItem* i = stackList->firstChild();
++ for (;i;i=i->nextSibling())
++ if (((StackItem*)i)->function() == item->function())
++ break;
++
++ if (i) {
++ // this calls stackFunctionSelected()
++ stackList->setCurrentItem(i);
++ stackList->ensureItemVisible(i);
++ }
++
++ if (!_costType2) {
++ stackList->setColumnWidthMode(1, TQListView::Manual);
++ stackList->setColumnWidth(1, 0);
++ }
++}
++
++void StackSelection::stackSelected(TQListViewItem* i)
++{
++ if (!i) return;
++
++ TraceFunction* f = ((StackItem*)i)->function();
++ emit functionSelected(f);
++}
++
++
++void StackSelection::browserBack()
++{
++ if (_browser && _browser->canGoBack()) {
++ _browser->goBack();
++ rebuildStackList();
++ }
++}
++
++void StackSelection::browserForward()
++{
++ if (_browser && _browser->canGoForward()) {
++ _browser->goForward();
++ rebuildStackList();
++ }
++}
++
++void StackSelection::browserUp()
++{
++ if (_browser) {
++ _browser->goUp();
++ rebuildStackList();
++ }
++}
++
++void StackSelection::browserDown()
++{
++ if (_browser) {
++ _browser->goDown();
++ rebuildStackList();
++ }
++}
++
++void StackSelection::refresh()
++{
++ TQListViewItem* item = stackList->firstChild();
++ for(;item;item = item->nextSibling())
++ ((StackItem*)item)->updateCost();
++}
++
++void StackSelection::setCostType(TraceCostType* ct)
++{
++ if (ct == _costType) return;
++ _costType = ct;
++
++ stackList->setColumnWidth(0, 50);
++ if (_costType)
++ stackList->setColumnText(0, _costType->name());
++
++ TQListViewItem* item = stackList->firstChild();
++ for(;item;item = item->nextSibling())
++ ((StackItem*)item)->updateCost();
++}
++
++void StackSelection::setCostType2(TraceCostType* ct)
++{
++ if (ct == _costType2) return;
++ _costType2 = ct;
++
++ stackList->setColumnWidth(1, 50);
++ stackList->setColumnWidthMode(1, TQListView::Maximum);
++ if (_costType2)
++ stackList->setColumnText(1, _costType2->name());
++
++ TQListViewItem* item = stackList->firstChild();
++ for(;item;item = item->nextSibling())
++ ((StackItem*)item)->updateCost();
++
++ if (!_costType2) {
++ stackList->setColumnWidthMode(1, TQListView::Manual);
++ stackList->setColumnWidth(1, 0);
++ }
++}
++
++void StackSelection::setGroupType(TraceItem::CostType gt)
++{
++ if (_groupType == gt) return;
++ _groupType = gt;
++
++ TQListViewItem* item = stackList->firstChild();
++ for(;item;item = item->nextSibling())
++ ((StackItem*)item)->updateGroup();
++}
++
++#include "stackselection.moc"
+diff --git a/kdecachegrind/kdecachegrind/stackselection.h b/kdecachegrind/kdecachegrind/stackselection.h
+new file mode 100644
+index 0000000..2bb3a75
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/stackselection.h
+@@ -0,0 +1,81 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * StackSelection for KCachegrind
++ * For function selection of a most expected stack,
++ * to be put into a TQDockWindow
++ */
++
++#ifndef STACKSELECTION_H
++#define STACKSELECTION_H
++
++#include "stackselectionbase.h"
++#include "tracedata.h"
++
++class TraceFunction;
++class TraceData;
++class StackBrowser;
++class NestedAreaItem;
++
++class StackSelection : public StackSelectionBase
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ StackSelection( TQWidget* parent = 0, const char* name = 0);
++ ~StackSelection();
++
++ TraceData* data() const { return _data; }
++ void setData(TraceData*);
++ StackBrowser* browser() const { return _browser; }
++ TraceCostType* costType() { return _costType; }
++ TraceCostType* costType2() { return _costType2; }
++ TraceItem::CostType groupType() { return _groupType; }
++
++signals:
++ void functionSelected(TraceItem*);
++
++public slots:
++ void setFunction(TraceFunction*);
++ void setCostType(TraceCostType*);
++ void setCostType2(TraceCostType*);
++ void setGroupType(TraceItem::CostType);
++
++ void stackSelected( TQListViewItem* );
++ void browserBack();
++ void browserForward();
++ void browserUp();
++ void browserDown();
++ void refresh();
++ void rebuildStackList();
++
++private:
++ void selectFunction();
++
++ TraceData* _data;
++ StackBrowser* _browser;
++ TQListViewItem* _item;
++ TraceFunction* _function;
++ TraceCostType* _costType;
++ TraceCostType* _costType2;
++ TraceItem::CostType _groupType;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/stackselectionbase.ui b/kdecachegrind/kdecachegrind/stackselectionbase.ui
+new file mode 100644
+index 0000000..c61010f
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/stackselectionbase.ui
+@@ -0,0 +1,80 @@
++<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
++<class>StackSelectionBase</class>
++<widget class="TQWidget">
++ <property name="name">
++ <cstring>StackSelectionBase</cstring>
++ </property>
++ <property name="geometry">
++ <rect>
++ <x>0</x>
++ <y>0</y>
++ <width>168</width>
++ <height>108</height>
++ </rect>
++ </property>
++ <property name="caption">
++ <string>Stack Selection</string>
++ </property>
++ <vbox>
++ <property name="name">
++ <cstring>unnamed</cstring>
++ </property>
++ <property name="margin">
++ <number>3</number>
++ </property>
++ <property name="spacing">
++ <number>6</number>
++ </property>
++ <widget class="TQListView">
++ <column>
++ <property name="text">
++ <string>Cost</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizeable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Cost2</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizeable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Calls</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizeable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <column>
++ <property name="text">
++ <string>Function</string>
++ </property>
++ <property name="clickable">
++ <bool>true</bool>
++ </property>
++ <property name="resizeable">
++ <bool>true</bool>
++ </property>
++ </column>
++ <property name="name">
++ <cstring>stackList</cstring>
++ </property>
++ </widget>
++ </vbox>
++</widget>
++<layoutdefaults spacing="6" margin="11"/>
++</UI>
+diff --git a/kdecachegrind/kdecachegrind/subcost.cpp b/kdecachegrind/kdecachegrind/subcost.cpp
+new file mode 100644
+index 0000000..7b5034e
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/subcost.cpp
+@@ -0,0 +1,62 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2004 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#include <tqstring.h>
++
++#include "subcost.h"
++
++//---------------------------------------------------
++// SubCost
++
++bool SubCost::set(const char** ps)
++{
++ const char* s = *ps;
++ if (!s || (*s < '0') || (*s > '9')) return false;
++
++ v = *s - '0';
++ s++;
++ while(*s >= '0' && *s <= '9') {
++ v = 10* v + (*s-'0');
++ s++;
++ }
++ while(*s == ' ') s++;
++ *ps = s;
++
++ return true;
++}
++
++TQString SubCost::pretty()
++{
++ unsigned long long n = v;
++
++ if (n==0) return TQString(" 0");
++
++ int i = 0;
++ TQString res = "";
++
++ while (n) {
++ if ((i>0) && !(i%3)) res = " " + res;
++ i++;
++ res = TQChar('0'+int(n%10)) + res;
++ n /= 10;
++ }
++ res = " " + res;
++ return res;
++}
++
++
+diff --git a/kdecachegrind/kdecachegrind/subcost.h b/kdecachegrind/kdecachegrind/subcost.h
+new file mode 100644
+index 0000000..8169280
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/subcost.h
+@@ -0,0 +1,66 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002-2004 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#ifndef SUBCOST_H
++#define SUBCOST_H
++
++#include "utils.h"
++
++typedef unsigned long long uint64;
++
++/**
++ * Cost event counter, simple wrapper around a 64bit entity
++ */
++class SubCost
++{
++ public:
++ SubCost() {}
++ SubCost(uint64 i) { v=i; }
++ SubCost(unsigned i) { v=i; }
++ SubCost(int i) { v=(unsigned)i; }
++ SubCost(double d) { v= (uint64)(d + .5); }
++
++ SubCost& operator=(uint64 i) { v = i; return *this; }
++ SubCost& operator=(unsigned i) { v = i; return *this; }
++ SubCost& operator=(int i) { v = i; return *this; }
++ SubCost& operator=(double d) { v = (uint64)(d + .5); return *this; }
++
++ bool set(const char** s);
++ bool set(FixString& s) { return s.stripUInt64(v); }
++
++ operator uint64&() { return v; }
++
++ bool operator==(unsigned i) const { return v == i; }
++ bool operator==(int i) const { return v == (unsigned)i; }
++ bool operator<(unsigned i) const { return v < i; }
++ bool operator<(int i) const { return v < (unsigned)i; }
++ bool operator<(const SubCost& s) const { return v < s.v; }
++ bool operator>(unsigned i) const { return v > i; }
++ bool operator>(int i) const { return v > (unsigned)i; }
++ bool operator>(const SubCost& s) const { return v > s.v; }
++
++ /**
++ * Convert SubCost value into a TQString,
++ * spaced every 3 digits.
++ */
++ TQString pretty();
++
++ uint64 v;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/tabview.cpp b/kdecachegrind/kdecachegrind/tabview.cpp
+new file mode 100644
+index 0000000..0049d1e
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/tabview.cpp
+@@ -0,0 +1,890 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Tab View, enclosing detailed views for one trace item in
++ * two tab widgets, separated by a splitter
++ */
++
++#include <tqobjectlist.h>
++#include <tqsplitter.h>
++#include <tqtabwidget.h>
++#include <tqlayout.h>
++#include <tqwhatsthis.h>
++#include <tqpopupmenu.h>
++
++#include <klocale.h>
++#include <kconfig.h>
++
++#include "tabview.h"
++#include "costtypeview.h"
++#include "partview.h"
++#include "callview.h"
++#include "coverageview.h"
++#include "callmapview.h"
++#include "instrview.h"
++#include "sourceview.h"
++#include "callgraphview.h"
++
++// TabBar
++
++TabBar::TabBar(TabView* v, TQTabWidget* parent, const char *name)
++ : TQTabBar(parent, name)
++{
++ _tabWidget = parent;
++ _tabView = v;
++}
++
++void TabBar::mousePressEvent(TQMouseEvent *e)
++{
++ if (e->button() == Qt::RightButton) {
++ TQTab *tab = selectTab( e->pos() );
++ TQWidget* page;
++ page = tab ? _tabWidget->page( indexOf( tab->identifier() ) ) :0;
++
++ TQPopupMenu popup, popup1, popup2, popup3;
++ if (page) {
++ TraceItemView::Position p = _tabView->tabPosition(page);
++ if (p != TraceItemView::Top) {
++ popup.insertItem(i18n("Move to Top"), 81);
++ popup2.insertItem(i18n("Top"), 91);
++ }
++ if (p != TraceItemView::Right) {
++ popup.insertItem(i18n("Move to Right"), 82);
++ popup2.insertItem(i18n("Right"), 92);
++ }
++ if (p != TraceItemView::Bottom) {
++ popup.insertItem(i18n("Move to Bottom"), 83);
++ popup2.insertItem(i18n("Bottom"), 93);
++ }
++ if (p != TraceItemView::Left) {
++ popup.insertItem(i18n("Move to Bottom Left"), 84);
++ popup2.insertItem(i18n("Bottom Left"), 94);
++ }
++ popup.insertItem(i18n("Move Area To"), &popup2, 2);
++ popup.insertSeparator();
++ popup.insertItem(i18n("Hide This Tab"), 80);
++ popup.insertItem(i18n("Hide Area"), 90);
++
++ if (_tabView->visibleTabs() <2) {
++ popup.setItemEnabled(80, false);
++ popup.setItemEnabled(90, false);
++ }
++ else if (_tabView->visibleAreas() <2)
++ popup.setItemEnabled(90, false);
++ }
++ popup3.insertItem(i18n("Top"), 101);
++ popup3.insertItem(i18n("Right"), 102);
++ popup3.insertItem(i18n("Bottom"), 103);
++ popup3.insertItem(i18n("Bottom Left"), 104);
++ popup.insertItem(i18n("Show Hidden On"), &popup3, 3);
++
++ int r = popup.exec( mapToGlobal( e->pos() ) );
++
++ TraceItemView::Position p = TraceItemView::Hidden;
++ if ((r % 10) == 1) p = TraceItemView::Top;
++ if ((r % 10) == 2) p = TraceItemView::Right;
++ if ((r % 10) == 3) p = TraceItemView::Bottom;
++ if ((r % 10) == 4) p = TraceItemView::Left;
++
++ if (r>=80 && r<100) _tabView->moveTab(page, p, r>=90);
++ if (r>=100 && r<110) _tabView->moveTab(0, p, true);
++ }
++
++ TQTabBar::mousePressEvent( e );
++}
++
++
++//
++// Splitter
++//
++
++Splitter::Splitter(Qt::Orientation o, TQWidget* parent, const char* name)
++ : TQSplitter(o, parent, name)
++{}
++
++void Splitter::moveEvent(TQMoveEvent* e)
++{
++ TQSplitter::moveEvent(e);
++
++ if (0) qDebug("Splitter %s: Move", name());
++ checkVisiblity();
++}
++
++void Splitter::checkVisiblity()
++{
++ const TQObjectList l = childrenListObject();
++ TQObjectListIt it( l );
++ TQObject *obj;
++ while ( (obj = it.current()) != 0 ) {
++ ++it;
++ if (obj->isA("Splitter")) ((Splitter*)obj)->checkVisiblity();
++ else if (obj->isA("TabWidget")) ((TabWidget*)obj)->checkVisibility();
++ }
++}
++
++
++
++
++//
++// TabWidget
++//
++
++TabWidget::TabWidget(TabView* v, TQWidget* parent,
++ const char* name, WFlags f)
++ : TQTabWidget(parent, name, f)
++{
++ _hasVisibleRect = false;
++ setTabBar(new TabBar(v, this));
++}
++
++void TabWidget::checkVisibility()
++{
++ bool hasVisibleRect = (visibleRect().width()>1) &&
++ (visibleRect().height()>1);
++
++ if (0) qDebug("TabWidget %s: VR (%dx%d) HasVisibleRect: %s => %s",
++ name(),
++ visibleRect().width(), visibleRect().height(),
++ _hasVisibleRect ? "Yes":"No",
++ hasVisibleRect ? "Yes":"No");
++
++ if (hasVisibleRect != _hasVisibleRect) {
++ _hasVisibleRect = hasVisibleRect;
++ emit visibleRectChanged(this);
++ }
++}
++
++void TabWidget::resizeEvent(TQResizeEvent *e)
++{
++ TQTabWidget::resizeEvent(e);
++ if (0) qDebug("TabWidget %s:\n Resize from (%d/%d) to (%d/%d)",
++ name(),
++ e->oldSize().width(), e->oldSize().height(),
++ e->size().width(), e->size().height());
++ checkVisibility();
++}
++
++void TabWidget::showEvent(TQShowEvent* e)
++{
++ TQTabWidget::showEvent(e);
++
++ if (0) qDebug("TabWidget %s: Show", name());
++ checkVisibility();
++}
++
++void TabWidget::hideEvent(TQHideEvent* e)
++{
++ TQTabWidget::hideEvent(e);
++
++ if (0) qDebug("TabWidget %s: Hide", name());
++ checkVisibility();
++}
++
++void TabWidget::moveEvent(TQMoveEvent* e)
++{
++ TQTabWidget::moveEvent(e);
++
++ if (0) qDebug("TabWidget %s: Move", name());
++ checkVisibility();
++}
++
++
++
++//
++// TabView
++//
++
++/*
++ * Areas for child views
++ *
++ * leftSplitter
++ * |
++ * | ----- -----
++ * | _/ \_______________/ \____
++ * | | Top | TopRight |
++ * | | | |
++ * -> |---------------------| |
++ * | BottomLeft | Bottom | |
++ * | | | |
++ * -\_____/------\____/--------------
++ *
++ * ^ ^
++ * bottomSplitter mainSplitter
++ */
++
++TabView::TabView(TraceItemView* parentView,
++ TQWidget* parent, const char* name)
++ : TQWidget(parent, name), TraceItemView(parentView)
++{
++ setFocusPolicy(TQ_StrongFocus);
++
++ _isCollapsed = true;
++
++ TQVBoxLayout* vbox = new TQVBoxLayout( this, 6, 6);
++
++ _nameLabel = new KSqueezedTextLabel( this, "nameLabel" );
++ _nameLabel->setText(i18n("(No profile data file loaded)"));
++ vbox->addWidget( _nameLabel );
++
++ _mainSplitter = new TQSplitter(Qt::Horizontal, this);
++ _leftSplitter = new Splitter(Qt::Vertical, _mainSplitter, "Left");
++ vbox->addWidget( _mainSplitter );
++
++ _rightTW = new TabWidget(this, _mainSplitter, "Right");
++ connect(_rightTW, TQT_SIGNAL(currentChanged(TQWidget*)),
++ this, TQT_SLOT(tabChanged(TQWidget*)));
++ connect(_rightTW, TQT_SIGNAL(visibleRectChanged(TabWidget*)),
++ this, TQT_SLOT(visibleRectChangedSlot(TabWidget*)));
++
++ _topTW = new TabWidget(this, _leftSplitter, "Top");
++ connect(_topTW, TQT_SIGNAL(currentChanged(TQWidget*)),
++ this, TQT_SLOT(tabChanged(TQWidget*)));
++ connect(_topTW, TQT_SIGNAL(visibleRectChanged(TabWidget*)),
++ this, TQT_SLOT(visibleRectChangedSlot(TabWidget*)));
++
++ _bottomSplitter = new Splitter(Qt::Horizontal,
++ _leftSplitter, "Bottom");
++
++ _leftTW = new TabWidget(this, _bottomSplitter, "Left");
++ _leftTW->setTabPosition(TQTabWidget::Bottom);
++ connect(_leftTW, TQT_SIGNAL(currentChanged(TQWidget*)),
++ this, TQT_SLOT(tabChanged(TQWidget*)));
++ connect(_leftTW, TQT_SIGNAL(visibleRectChanged(TabWidget*)),
++ this, TQT_SLOT(visibleRectChangedSlot(TabWidget*)));
++
++ _bottomTW = new TabWidget(this, _bottomSplitter, "Bottom");
++ _bottomTW->setTabPosition(TQTabWidget::Bottom);
++ connect(_bottomTW, TQT_SIGNAL(currentChanged(TQWidget*)),
++ this, TQT_SLOT(tabChanged(TQWidget*)));
++ connect(_bottomTW, TQT_SIGNAL(visibleRectChanged(TabWidget*)),
++ this, TQT_SLOT(visibleRectChangedSlot(TabWidget*)));
++
++
++ // default positions...
++
++ addTop( addTab( i18n("Types"),
++ new CostTypeView(this, _topTW,
++ "CostTypeView")));
++ addTop( addTab( i18n("Callers"),
++ new CallView(true, this, _topTW,
++ "CallerView")));
++ addTop( addTab( i18n("All Callers"),
++ new CoverageView(true, this, _topTW,
++ "AllCallerView")));
++ addTop( addTab( i18n("Caller Map"),
++ new CallMapView(true, this, _bottomTW,
++ "CallerMapView")));
++ addTop( addTab( i18n("Source"),
++ new SourceView(this, _topTW,
++ "SourceView")));
++
++ addBottom( addTab( i18n("Parts"),
++ new PartView(this, _bottomTW,
++ "PartView")));
++ addBottom( addTab( i18n("Call Graph"),
++ new CallGraphView(this, _bottomTW,
++ "CallGraphView")));
++ addBottom( addTab( i18n("Callees"),
++ new CallView(false, this, _bottomTW,
++ "CalleeView")));
++ addBottom( addTab( i18n("All Callees"),
++ new CoverageView(false, this, _bottomTW,
++ "AllCalleeView")));
++
++ addBottom( addTab( i18n("Callee Map"),
++ new CallMapView(false, this, _topTW,
++ "CalleeMapView")));
++ addBottom( addTab( i18n("Assembler"),
++ new InstrView(this, _bottomTW,
++ "InstrView")));
++
++ // after all child widgets are created...
++ _lastFocus = 0;
++ _active = false;
++ installFocusFilters();
++
++ updateVisibility();
++
++ TQWhatsThis::add( this, whatsThis() );
++}
++
++void TabView::setData(TraceData* d)
++{
++ TraceItemView::setData(d);
++
++ TraceItemView* v;
++ for (v=_tabs.first();v;v=_tabs.next())
++ v->setData(d);
++}
++
++TraceItemView* TabView::addTab(TQString label, TraceItemView* view)
++{
++ view->setTitle(label);
++ _tabs.append(view);
++ return view;
++}
++
++void TabView::addTop(TraceItemView* view)
++{
++ view->setPosition(TraceItemView::Top);
++ _topTW->insertTab(view->widget(), view->title());
++}
++
++void TabView::addBottom(TraceItemView* view)
++{
++ view->setPosition(TraceItemView::Bottom);
++ _bottomTW->insertTab(view->widget(), view->title());
++}
++
++TraceItemView::Position TabView::tabPosition(TQWidget* w)
++{
++ TraceItemView* v;
++ for (v=_tabs.first();v;v=_tabs.next())
++ if (v->widget() == w) return v->position();
++
++ return Hidden;
++}
++
++int TabView::visibleTabs()
++{
++ int c = 0;
++ TraceItemView* v;
++ for (v=_tabs.first();v;v=_tabs.next()) {
++ if (v->position() == Hidden) continue;
++ c++;
++ }
++ return c;
++}
++
++
++int TabView::visibleAreas()
++{
++ int c = 0, t = 0, b = 0, r = 0, l = 0;
++ TraceItemView* v;
++ for (v=_tabs.first();v;v=_tabs.next()) {
++ switch(v->position()) {
++ case TraceItemView::Top: t++; break;
++ case TraceItemView::Bottom: b++; break;
++ case TraceItemView::Left: l++; break;
++ case TraceItemView::Right: r++; break;
++ default: break;
++ }
++ }
++ if (t>0) c++;
++ if (b>0) c++;
++ if (l>0) c++;
++ if (r>0) c++;
++
++ return c;
++}
++
++
++
++// This hides/shows splitters and tabwidgets according to tab childs
++void TabView::updateVisibility()
++{
++ // calculate count of tabs in areas
++ int t = 0, b = 0, r = 0, l = 0;
++ TraceItemView* v;
++ for (v=_tabs.first();v;v=_tabs.next()) {
++ switch(v->position()) {
++ case TraceItemView::Top: t++; break;
++ case TraceItemView::Bottom: b++; break;
++ case TraceItemView::Left: l++; break;
++ case TraceItemView::Right: r++; break;
++ default: break;
++ }
++ }
++
++ if (0) qDebug("TabView::updateVisiblity t %d, b %d, l %d, r %d",
++ t, b, l, r);
++
++ TQValueList<int> s;
++ s.append(100);
++
++
++ // children of mainSplitter
++ if (_rightTW->isHidden() != (r == 0)) {
++ if (r == 0) {
++ _rightTW->hide();
++
++ if (!_topTW->hasVisibleRect() &&
++ !_bottomTW->hasVisibleRect() &&
++ !_leftTW->hasVisibleRect()) _mainSplitter->setSizes(s);
++ }
++ else
++ _rightTW->show();
++ }
++ if (_leftSplitter->isHidden() != (t+b+l == 0)) {
++ if (t+b+l == 0) {
++ _leftSplitter->hide();
++
++ if (!_rightTW->hasVisibleRect()) _mainSplitter->setSizes(s);
++ }
++ else
++ _leftSplitter->show();
++ }
++
++ // children of leftSplitter
++ if (_topTW->isHidden() != (t == 0)) {
++ if (t == 0) {
++ _topTW->hide();
++
++ if (!_bottomTW->hasVisibleRect() &&
++ !_leftTW->hasVisibleRect()) _leftSplitter->setSizes(s);
++ }
++ else
++ _topTW->show();
++ }
++
++ if (_bottomSplitter->isHidden() != (b+l == 0)) {
++ if (b+l == 0) {
++ _bottomSplitter->hide();
++
++ if (!_topTW->hasVisibleRect()) _leftSplitter->setSizes(s);
++ }
++ else
++ _bottomSplitter->show();
++ }
++
++ // children of bottomSplitter
++ if (_bottomTW->isHidden() != (b == 0)) {
++ if (b == 0) {
++ _bottomTW->hide();
++
++ if (!_leftTW->hasVisibleRect()) _bottomSplitter->setSizes(s);
++ }
++ else
++ _bottomTW->show();
++ }
++ if (_leftTW->isHidden() != (l == 0)) {
++ if (l == 0) {
++ _leftTW->hide();
++
++ if (!_bottomTW->hasVisibleRect()) _bottomSplitter->setSizes(s);
++ }
++ else
++ _leftTW->show();
++ }
++}
++
++TabWidget* TabView::tabWidget(Position p)
++{
++ switch(p) {
++ case TraceItemView::Top: return _topTW;
++ case TraceItemView::Bottom: return _bottomTW;
++ case TraceItemView::Left: return _leftTW;
++ case TraceItemView::Right: return _rightTW;
++ default: break;
++ }
++ return 0;
++}
++
++void TabView::moveTab(TQWidget* w, Position p, bool wholeArea)
++{
++ TraceItemView *v;
++ Position origPos = Hidden;
++ if (w) {
++ for (v=_tabs.first();v;v=_tabs.next())
++ if (v->widget() == w) break;
++
++ if (!v) return;
++ origPos = v->position();
++ }
++ if (origPos == p) return;
++
++ TabWidget *from, *to;
++ from = tabWidget(origPos);
++ to = tabWidget(p);
++
++ TQPtrList<TraceItemView> tabs;
++ for (v=_tabs.first();v;v=_tabs.next())
++ if ((v->position() == origPos) &&
++ (wholeArea || (v->widget() == w))) tabs.append(v);
++
++ bool isEnabled;
++ for (v=tabs.first();v;v=tabs.next()) {
++ v->setPosition(p);
++ w = v->widget();
++
++ if (from) {
++ isEnabled = from->isTabEnabled(w);
++ from->removePage(w);
++ }
++ else isEnabled = (v->canShow(_activeItem)!=0);
++
++ if (to) {
++ TraceItemView *vv;
++ int idx = -1, i;
++ for(vv = _tabs.first(); vv && (vv!=v); vv = _tabs.next()) {
++ i = to->indexOf(vv->widget());
++ if (i>=0) idx = i;
++ }
++ to->insertTab(w, v->title(), idx+1);
++ to->setTabEnabled(w, isEnabled);
++ if (isEnabled) {
++ to->showPage(w);
++ v->updateView();
++ }
++ }
++ }
++ updateVisibility();
++}
++
++
++TQString TabView::whatsThis() const
++{
++ return i18n( "<b>Information Tabs</b>"
++ "<p>This widget shows information for the "
++ "current selected function in different tabs: "
++ "<ul>"
++ "<li>The Costs tab shows a list of available event types "
++ "and the inclusive and self costs regarding to these types.</li>"
++ "<li>The Parts tab shows a list of trace parts "
++ "if the trace consists of more than one part (otherwise, "
++ "this tab is hided). "
++ "The cost of the selected function spent in the different "
++ "parts together with the calls happening is shown.</li>"
++ "<li>The Call Lists tab shows direct callers and "
++ "callees of the function in more detail.</li>"
++ "<li>The Coverage tab shows the same is the Call "
++ "Lists tab, but not only direct callers and callees "
++ "but also indirect ones.</li>"
++ "<li>The Call Graph tab shows a graphical "
++ "visualization of the calls done by this function.</li>"
++ "<li>The Source tab presents annotated source code "
++ "if debugging information and the source file "
++ "is available.</li>"
++ "<li>The Assembler tab presents annotated assembler code "
++ "if trace information on instruction level "
++ "is available.</li></ul>"
++ "For more information, see the <em>What's This?</em> "
++ "help of the corresponding tab widget</p>");
++}
++
++void TabView::installFocusFilters()
++{
++ TQObjectList *l = queryList(TQWIDGET_OBJECT_NAME_STRING);
++ TQObjectListIt it( *l );
++ TQObject *obj;
++
++ while ( (obj = it.current()) != 0 ) {
++ ++it;
++ if ( ((TQWidget*)obj)->isFocusEnabled() )
++ obj->installEventFilter(this);
++ }
++ delete l;
++}
++
++
++bool TabView::eventFilter(TQObject* o, TQEvent* e)
++{
++ if (e->type() == TQEvent::FocusIn) {
++ _lastFocus = o->isWidgetType() ? (TQWidget*) o : 0;
++ setActive(_lastFocus != 0);
++ }
++ return TQWidget::eventFilter(o,e);
++}
++
++void TabView::mousePressEvent(TQMouseEvent*)
++{
++ if (_lastFocus)
++ _lastFocus->setFocus();
++ setActive(true);
++}
++
++void TabView::setActive(bool a)
++{
++ if (a == _active) return;
++ _active = a;
++
++ TQFont nameLabel_font( _nameLabel->font() );
++ nameLabel_font.setBold(a);
++ _nameLabel->setFont( nameLabel_font );
++
++ if (0) qDebug("%s::setActive(%s)", name(), a ? "true":"false");
++
++ if (a) emit activated(this);
++}
++
++void TabView::doUpdate(int changeType)
++{
++ if (changeType & (activeItemChanged | configChanged | dataChanged))
++
++ _nameLabel->setText( !_data ? i18n("(No Data loaded)") :
++ !_activeItem ? i18n("(No function selected)") :
++ _activeItem->prettyName());
++
++
++ // we use our own list iterators because setTabEnabled can
++ // invoke tabChanged, which mangles with the lists, too
++ bool canShow;
++ TraceItemView *v;
++ TQPtrListIterator<TraceItemView> it( _tabs );
++ while ( (v=it.current()) != 0) {
++ ++it;
++
++ TabWidget *tw = 0;
++ switch(v->position()) {
++ case TraceItemView::Top: tw = _topTW; break;
++ case TraceItemView::Bottom: tw = _bottomTW; break;
++ case TraceItemView::Left: tw = _leftTW; break;
++ case TraceItemView::Right: tw = _rightTW; break;
++ default: break;
++ }
++
++ // update even if hidden
++ if (tw) {
++ if (!tw->hasVisibleRect()) continue;
++ }
++ canShow = v->set(changeType, _data, _costType, _costType2,
++ _groupType, _partList,
++ _activeItem, _selectedItem);
++ v->notifyChange(changeType);
++
++ if (!tw) continue;
++ if (tw->isTabEnabled(v->widget()) != canShow)
++ tw->setTabEnabled(v->widget(), canShow);
++
++ if (v->widget() == tw->currentPage())
++ v->updateView();
++ }
++}
++
++
++void TabView::tabChanged(TQWidget* w)
++{
++ TraceItemView *v;
++ for (v=_tabs.first();v;v=_tabs.next())
++ if (v->widget() == w) v->updateView();
++}
++
++void TabView::visibleRectChangedSlot(TabWidget* tw)
++{
++ if (0) qDebug("%s: %svisible !",
++ tw->name(), tw->hasVisibleRect() ? "":"un");
++
++ if (tw->hasVisibleRect()) doUpdate(0);
++}
++
++void TabView::resizeEvent(TQResizeEvent* e)
++{
++ TQWidget::resizeEvent(e);
++
++ bool collapsed = (e->size().width()<=1) || (e->size().height()<=1);
++ if (_isCollapsed != collapsed) {
++ _isCollapsed = collapsed;
++ updateView();
++ }
++
++ if (0) qDebug("TabView::Resize from (%d/%d) to (%d/%d)",
++ e->oldSize().width(), e->oldSize().height(),
++ e->size().width(), e->size().height());
++}
++
++void TabView::selected(TraceItemView*, TraceItem* s)
++{
++ // we set selected item for our own children
++ select(s);
++ updateView();
++
++ // still forward to parent
++ if (_parentView) _parentView->selected(this, s);
++}
++
++
++void TabView::readViewConfig(KConfig* c,
++ TQString prefix, TQString postfix,
++ bool withOptions)
++{
++ if (0) qDebug("%s::readConfig(%s%s)", name(),
++ prefix.ascii(), postfix.ascii());
++
++ KConfigGroup* g = configGroup(c, prefix, postfix);
++
++ _mainSplitter->setSizes(g->readIntListEntry("MainSizes"));
++ _leftSplitter->setSizes(g->readIntListEntry("LeftSizes"));
++ _bottomSplitter->setSizes(g->readIntListEntry("BottomSizes"));
++
++ TQString activeT = g->readEntry("ActiveTop", "CallerView");
++ TQString activeB = g->readEntry("ActiveBottom", "CalleeView");
++ TQString activeL = g->readEntry("ActiveLeft", "");
++ TQString activeR = g->readEntry("ActiveRight", "");
++
++ TQStringList topTabs = g->readListEntry("TopTabs");
++ TQStringList bottomTabs = g->readListEntry("BottomTabs");
++ TQStringList leftTabs = g->readListEntry("LeftTabs");
++ TQStringList rightTabs = g->readListEntry("RightTabs");
++
++ if (topTabs.isEmpty() && bottomTabs.isEmpty() &&
++ rightTabs.isEmpty() && leftTabs.isEmpty()) {
++ // no tabs visible ?! Reset to default
++ topTabs << "CostTypeView" << "CallerView" << "AllCallerView"
++ << "CalleeMapView" << "SourceView";
++ bottomTabs << "PartView" << "CalleeView" << "CallGraphView"
++ << "AllCalleeView" << "CallerMapView" << "InstrView";
++ }
++
++ TraceItemView *activeTop = 0, *activeBottom = 0;
++ TraceItemView *activeLeft = 0, *activeRight = 0;
++
++ moveTab(0, TraceItemView::Top, true);
++ TraceItemView *v;
++ TQPtrListIterator<TraceItemView> it( _tabs );
++ while ( (v=it.current()) != 0) {
++ ++it;
++
++ TQString n = TQString(v->widget()->name());
++ if (topTabs.contains(n)) {
++ moveTab(v->widget(), TraceItemView::Top);
++ if (n == activeT) activeTop = v;
++ }
++ else if (bottomTabs.contains(n)) {
++ moveTab(v->widget(), TraceItemView::Bottom);
++ if (n == activeB) activeBottom = v;
++ }
++ else if (leftTabs.contains(n)) {
++ moveTab(v->widget(), TraceItemView::Left);
++ if (n == activeL) activeLeft = v;
++ }
++ else if (rightTabs.contains(n)) {
++ moveTab(v->widget(), TraceItemView::Right);
++ if (n == activeR) activeRight = v;
++ }
++ else moveTab(v->widget(), Hidden);
++
++ if (withOptions)
++ v->readViewConfig(c, TQString("%1-%2")
++ .arg(prefix).arg(v->widget()->name()),
++ postfix, true);
++ }
++ if (activeTop) _topTW->showPage(activeTop->widget());
++ if (activeBottom)_bottomTW->showPage(activeBottom->widget());
++ if (activeLeft) _leftTW->showPage(activeLeft->widget());
++ if (activeRight) _rightTW->showPage(activeRight->widget());
++
++ TQString activeType = g->readEntry("ActiveItemType", "");
++ TQString activeName = g->readEntry("ActiveItemName", "");
++ TQString selectedType = g->readEntry("SelectedItemType", "");
++ TQString selectedName = g->readEntry("SelectedItemName", "");
++ delete g;
++
++ if (!_data) return;
++
++ if (withOptions) {
++ // restore active item
++ TraceItem::CostType t = TraceItem::costType(activeType);
++ if (t==TraceItem::NoCostType) t = TraceItem::Function;
++ TraceCost* activeItem = _data->search(t, activeName, _costType);
++ if (!activeItem) return;
++ activate(activeItem);
++
++ // restore selected item
++ t = TraceItem::costType(selectedType);
++ if (t==TraceItem::NoCostType) t = TraceItem::Function;
++ TraceCost* selectedItem = _data->search(t, selectedName,
++ _costType, activeItem);
++ if (selectedItem) select(selectedItem);
++ }
++
++ updateView();
++}
++
++void TabView::saveViewConfig(KConfig* c,
++ TQString prefix, TQString postfix,
++ bool withOptions)
++{
++ KConfigGroup g(c, (prefix+postfix).ascii());
++
++ g.writeEntry("MainSizes", _mainSplitter->sizes());
++ g.writeEntry("LeftSizes", _leftSplitter->sizes());
++ g.writeEntry("BottomSizes", _bottomSplitter->sizes());
++
++ TQString a;
++ if ((_topTW->count()>0) &&
++ (_topTW->isTabEnabled(_topTW->currentPage())))
++ a = TQString(_topTW->currentPage()->name());
++ g.writeEntry("ActiveTop", a);
++
++ a.setLength(0);
++ if ((_bottomTW->count()>0) &&
++ (_bottomTW->isTabEnabled(_bottomTW->currentPage())))
++ a = TQString(_bottomTW->currentPage()->name());
++ g.writeEntry("ActiveBottom", a);
++
++ a.setLength(0);
++ if ((_leftTW->count()>0) &&
++ (_leftTW->isTabEnabled(_leftTW->currentPage())))
++ a = TQString(_leftTW->currentPage()->name());
++ g.writeEntry("ActiveLeft", a);
++
++ a.setLength(0);
++ if ((_rightTW->count()>0) &&
++ (_rightTW->isTabEnabled(_rightTW->currentPage())))
++ a = TQString(_rightTW->currentPage()->name());
++ g.writeEntry("ActiveRight", a);
++
++ if (withOptions)
++ if (_activeItem) {
++ g.writeEntry("ActiveItemType",
++ TraceItem::typeName(_activeItem->type()));
++ g.writeEntry("ActiveItemName", _activeItem->name());
++ if (_selectedItem) {
++ g.writeEntry("SelectedItemType",
++ TraceItem::typeName(_selectedItem->type()));
++ g.writeEntry("SelectedItemName", _selectedItem->name());
++ }
++ }
++
++ TQStringList topList, bottomList, leftList, rightList;
++ TraceItemView *v;
++ for (v=_tabs.first();v;v=_tabs.next()) {
++ switch(v->position()) {
++ case TraceItemView::Top:
++ topList << TQString(v->widget()->name());
++ break;
++
++ case TraceItemView::Bottom:
++ bottomList << TQString(v->widget()->name());
++ break;
++
++ case TraceItemView::Left:
++ leftList << TQString(v->widget()->name());
++ break;
++
++ case TraceItemView::Right:
++ rightList << TQString(v->widget()->name());
++ break;
++
++ default: break;
++ }
++ }
++
++ g.writeEntry("TopTabs", topList);
++ g.writeEntry("BottomTabs", bottomList);
++ g.writeEntry("LeftTabs", leftList);
++ g.writeEntry("RightTabs", rightList);
++
++ if (withOptions)
++ for (v=_tabs.first();v;v=_tabs.next())
++ v->saveViewConfig(c, TQString("%1-%2").arg(prefix)
++ .arg(v->widget()->name()), postfix, true);
++}
++
++#include "tabview.moc"
+diff --git a/kdecachegrind/kdecachegrind/tabview.h b/kdecachegrind/kdecachegrind/tabview.h
+new file mode 100644
+index 0000000..b9b4026
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/tabview.h
+@@ -0,0 +1,174 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Tab View, enclosing detailed views for one trace item in
++ * two tab widgets, separated by a splitter
++ */
++
++#ifndef TABVIEW_H
++#define TABVIEW_H
++
++#include <tqptrlist.h>
++#include <tqwidget.h>
++#include <tqtabwidget.h>
++#include <tqtabbar.h>
++#include <ksqueezedtextlabel.h>
++#include "traceitemview.h"
++
++class TQSplitter;
++class TabView;
++
++/**
++ * Subclass of TQTabBar to enable context menu on tabs
++ */
++class TabBar : public TQTabBar
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++ public:
++ TabBar(TabView*, TQTabWidget* parent, const char *name = 0);
++ protected:
++ void mousePressEvent(TQMouseEvent *e);
++
++ private:
++ TQTabWidget* _tabWidget;
++ TabView* _tabView;
++};
++
++
++/**
++ * Own Splitter:
++ * Call checkVisiblity for all TabWidget children of the splitter
++ * on a MoveEvent. This typically is produced when collapsing the widget
++ * inside of another splitter.
++ */
++class Splitter: public TQSplitter
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ Splitter(Qt::Orientation o, TQWidget* parent = 0, const char* name = 0);
++ void checkVisiblity();
++
++protected:
++ void moveEvent(TQMoveEvent *);
++};
++
++
++/**
++ * Own TabView:
++ * - A TQTabWidget able to track its visible rect via resizeEvents.
++ * This is needed to track if this widget is collapsed in a TQSplitter.
++ * - Use own TabBar for context menu
++ */
++class TabWidget: public TQTabWidget
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++
++ TabWidget(TabView*, TQWidget* parent = 0,
++ const char* name = 0, WFlags f = 0);
++
++ bool hasVisibleRect() { return _hasVisibleRect; }
++ void checkVisibility();
++
++signals:
++ void visibleRectChanged(TabWidget*);
++
++protected:
++ void resizeEvent(TQResizeEvent *);
++ void showEvent(TQShowEvent *);
++ void hideEvent(TQHideEvent *);
++ void moveEvent(TQMoveEvent *);
++
++private:
++ bool _hasVisibleRect;
++};
++
++
++
++class TabView : public TQWidget, public TraceItemView
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++
++ TabView(TraceItemView* parentView,
++ TQWidget* parent = 0, const char* name = 0);
++
++ virtual TQWidget* widget() { return this; }
++ TQString whatsThis() const ;
++ void setData(TraceData*);
++ bool isViewVisible() const { return !_isCollapsed; }
++ void selected(TraceItemView*, TraceItem*);
++ bool active() const { return _active; }
++ void setActive(bool);
++
++ /**
++ * Rearrange tabs
++ * if <w> == 0, move hidden tabs
++ */
++ void moveTab(TQWidget* w, Position, bool wholeArea = false);
++
++ Position tabPosition(TQWidget*);
++ int visibleTabs();
++ int visibleAreas();
++
++ void readViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++ void saveViewConfig(KConfig*, TQString prefix, TQString postfix, bool);
++
++public slots:
++ void tabChanged(TQWidget*);
++ void visibleRectChangedSlot(TabWidget*);
++
++signals:
++ void activated(TabView*);
++
++protected:
++ void resizeEvent(TQResizeEvent *);
++ bool eventFilter(TQObject*, TQEvent*);
++ void mousePressEvent(TQMouseEvent*);
++
++private:
++ TraceItemView* addTab(TQString, TraceItemView*);
++ void addTop(TraceItemView*);
++ void addBottom(TraceItemView*);
++ TabWidget* tabWidget(Position);
++ void updateVisibility();
++ void doUpdate(int);
++ void installFocusFilters();
++
++ // this is true if width or height <= 1, and no child updates are done
++ bool _isCollapsed;
++
++ KSqueezedTextLabel* _nameLabel;
++ TQSplitter *_mainSplitter, *_leftSplitter, *_bottomSplitter;
++ TabWidget *_topTW, *_leftTW, *_bottomTW, *_rightTW;
++ TQPtrList<TraceItemView> _tabs;
++
++ TQWidget* _lastFocus;
++ bool _active;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/kdecachegrind.desktop b/kdecachegrind/kdecachegrind/kdecachegrind.desktop
+new file mode 100644
+index 0000000..7089370
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/kdecachegrind.desktop
+@@ -0,0 +1,103 @@
++# KDE Config File
++[Desktop Entry]
++Type=Application
++Exec=kdecachegrind -caption "%c" %i %m %u
++MimeType=application/x-kcachegrind;
++Icon=kdecachegrind
++DocPath=kdecachegrind/index.html
++Terminal=false
++Name=KCachegrind
++Name[hi]=के-केश-ग्रिंड
++Name[sv]=Kcachegrind
++Name[ta]= இடைமாற்றகட்டம்
++GenericName=Profiler Frontend
++GenericName[bs]=Profiler frontend
++GenericName[ca]=Interfície de Profiler
++GenericName[cs]=Rozhraní pro profilaci
++GenericName[cy]=Blaen-wyneb Proffilydd
++GenericName[da]=Grænseflade til profilering
++GenericName[de]=Profiler Oberfläche
++GenericName[el]=Πρόγραμμα προφίλ
++GenericName[eo]=Fasado de Profililo
++GenericName[es]=Interfaz para Profiler
++GenericName[et]=Profileerimisrakendus
++GenericName[eu]=Profilatzailearen interfazea
++GenericName[fa]=پایانۀ گزارش‌گیر
++GenericName[fi]=Profiloijan käyttöliittymä
++GenericName[fr]=Interface de profilage
++GenericName[ga]=Comhéadan ar Phróifíleoir
++GenericName[gl]=Interface para o profiler
++GenericName[hi]=प्रोफ़ाइलर फ्रन्टएण्ड
++GenericName[hu]=Profilozó
++GenericName[is]=Myndrænt viðmót á afkastakönnuð
++GenericName[it]=Interfaccia a profiler
++GenericName[ja]=プロファイラフロントエンド
++GenericName[ka]=პროფილერის Frontend
++GenericName[kk]=Профильдеткіштің интерфейсі
++GenericName[lt]=Profiliuoklio naudotojo sąsaja
++GenericName[nb]=Grensesnitt for profilvisning
++GenericName[nds]=Profiler-Böversiet
++GenericName[ne]=प्रोफाइलर फ्रन्टइन्ड
++GenericName[nl]=Profiler-hulpprogramma
++GenericName[nn]=Grensesnitt for profilvising
++GenericName[pa]=ਪਰੋਫਾਇਲਰ ਮੁੱਖ ਭੂਮੀ
++GenericName[pl]=Interfejs do profilera
++GenericName[pt]=Interface de Profiler
++GenericName[pt_BR]=Interface para o Profiler
++GenericName[ru]=Профилировщик
++GenericName[sk]=Rozhranie pre profiler
++GenericName[sl]=Vmesnik profilnika
++GenericName[sr]=Графички интерфејс за профајлер
++GenericName[sr@Latn]=Grafički interfejs za profajler
++GenericName[sv]=Profileringsgränssnitt
++GenericName[ta]= விவரக்குறிப்பு முன்பகுதி
++GenericName[tg]=Интерфейс ба профилкунанда
++GenericName[tr]=Profil Önyüzü
++GenericName[uk]=Інтерфейс до Profiler
++GenericName[zh_CN]=个性数据前端
++GenericName[zh_TW]=分析器前端
++Comment=Visualization of Performance Profiling Data
++Comment[bg]=Визуализация на данните за производителност
++Comment[bs]=Vizualizacija podataka za profiliranje performansi
++Comment[ca]=Visualizació de dades de perfilat de rendiment
++Comment[cs]=Vizualizace profilovacích dat výkonu
++Comment[da]=Visualisering af profileringsdata
++Comment[de]=Visualisierung von Daten des Laufzeitverhaltens eines Programmes
++Comment[el]=Αναπαράσταση δεδομένων ταχύτητας προφίλ
++Comment[en_GB]=Visualisation of Performance Profiling Data
++Comment[es]=Visualización de datos de análisis de rendimiento
++Comment[et]=Jõudluse profileerimise andmete visualiseerimise vahend
++Comment[eu]=Errendimendu profil datuen bistaratzea
++Comment[fa]=تجسم کارایی گزارش داده‌ها
++Comment[fi]=Visualisointi tehokkuusprofiloinnin tiedoista
++Comment[fr]=Visualisation des données de performance de profilage
++Comment[gl]=Visualización dos datos da análise de rendimento
++Comment[hi]=परफार्मेस प्रोफाइलिंग डाटा का विजुअलाइज़ेशन
++Comment[hu]=Teljesítményprofil-adatok megjelenítése
++Comment[is]=Sjónræn framsetning gagna úr afkastakönnun
++Comment[it]=Visualizzazione dei dati di profiling delle prestazioni
++Comment[ja]=パフォーマンスプロファイルデータを視覚化
++Comment[ka]=წარმადობის მაპროფფილებელი მონაცემების ვიზუალიზაცია
++Comment[kk]=Деректерді профильдеудің визуализациясы
++Comment[lt]=Veikimo profiliavimo duomenų vizualizacija
++Comment[nb]=Vis informasjon om ytelse.
++Comment[nds]=Visualiseren vun Programmleisten-Looptietdaten
++Comment[ne]=सम्पादन प्रोफाइलिङ डाटाको दृष्टिकरण
++Comment[nl]=Visualisatie van Performance Profiling Data
++Comment[nn]=Vis informasjon om yting
++Comment[pl]=Wizualizacja danych profilowania wydajności
++Comment[pt]=Visualização dos Dados de Análise de Performance
++Comment[pt_BR]=Visualização de Dados de Perfil de Desempenho
++Comment[ru]=Утилита для визуального профилирования приложений
++Comment[sk]=Vizualizácia dát o výkone
++Comment[sl]=Vizualizacija podatkov profilnih zmogljivosti
++Comment[sr]=Визуелизација података о профилисању перформанси
++Comment[sr@Latn]=Vizuelizacija podataka o profilisanju performansi
++Comment[sv]=Åskådliggörande av profileringsdata för prestanda
++Comment[ta]= விவர தகவலை செயல்பாட்டு காட்சியாளிப்பு
++Comment[tg]=Утилита барои гузориши профили визуалӣ
++Comment[uk]=Візуалізація даних профілювання швидкодії
++Comment[zh_CN]=性能个性数据的可视化表现
++Comment[zh_TW]=效能分析資料視覺化
++X-DCOP-ServiceType=Multi
++Categories=Qt;KDE;Development;
+diff --git a/kdecachegrind/kdecachegrind/kdecachegrindui.rc b/kdecachegrind/kdecachegrind/kdecachegrindui.rc
+new file mode 100644
+index 0000000..9531829
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/kdecachegrindui.rc
+@@ -0,0 +1,57 @@
++<!DOCTYPE kpartgui>
++<kpartgui name="kdecachegrind" version="4">
++ <MenuBar>
++ <Menu name="file"><text>&amp;File</text>
++ <Action name="file_add" append="open_merge"/>
++ <Action name="reload" append="revert_merge"/>
++ <Action name="dump" append="revert_merge"/>
++ <Action name="export"/>
++ </Menu>
++ <Menu name="view"><text>&amp;View</text>
++ <Action name="view_cost_type"/>
++ <Action name="view_cost_type2"/>
++ <Action name="view_group_type"/>
++ <Separator/>
++ <Menu name="layouts"><text>&amp;Layout</text>
++ <Action name="layout_next"/>
++ <Action name="layout_previous"/>
++ <Action name="layout_duplicate"/>
++ <Action name="layout_remove"/>
++ <Separator/>
++ <Action name="layout_restore"/>
++ <Action name="layout_save"/>
++ </Menu>
++ <Action name="view_split"/>
++ <Action name="view_split_dir"/>
++ <Separator/>
++ <Action name="view_percentage"/>
++ <Action name="view_expanded"/>
++ <Action name="view_cycles"/>
++ </Menu>
++ <Menu name="settings">
++ <Menu append="show_toolbar_merge"><text>Sidebars</text>
++ <Action name="settings_show_dumpdock"/>
++ <Action name="settings_show_partdock"/>
++ <Action name="settings_show_stackdock"/>
++ <Action name="settings_show_profiledock"/>
++ </Menu>
++ </Menu>
++ </MenuBar>
++
++ <ToolBar name="mainToolBar" noMerge="1"><text>Main Toolbar</text>
++ <Action name="file_open"/>
++ <Action name="reload"/>
++ <Action name="dump"/>
++ <Separator/>
++ <Action name="go_up"/>
++ <Action name="go_back"/>
++ <Action name="go_forward"/>
++ <Separator/>
++ <Action name="view_percentage"/>
++ <Action name="view_expanded"/>
++ <Action name="view_cycles"/>
++ </ToolBar>
++ <ToolBar name="stateToolBar" noMerge="1"><text>State Toolbar</text>
++ <Action name="view_cost_type"/>
++ </ToolBar>
++</kpartgui>
+diff --git a/kdecachegrind/kdecachegrind/tips b/kdecachegrind/kdecachegrind/tips
+new file mode 100644
+index 0000000..1f555c0
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/tips
+@@ -0,0 +1,141 @@
++<tip category="KCachegrind|Help">
++<html>
++<p>...that the <em>What's This?</em> help for every GUI widget
++in KCachegrind contains detailed usage information for this widget?
++It is highly recommended to read at least these help texts on first
++use. Request <em>What's This?</em> help by pressing
++Shift+F1 and clicking on the widget.</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Explanation">
++<html>
++<p>...that you can get profile information at instruction level
++with Calltree when you provide the option <em>--dump-instr=yes</em>?
++Use the Assembler View for the instruction annotations.
++</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Keyboard">
++<html>
++<p>...that you can use Alt-Left/Right keys of your keyboard to go
++back/forward in the active object history ?</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Keyboard">
++<html>
++<p>...that you can navigate in the Callee/Caller Map View using
++arrow keys? Use Left/Right to change to siblings of the current
++item; use Up/Down to go one nesting level up/down. To select
++the current item, press Space, and to activate it, press Return.
++</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Keyboard">
++<html>
++<p>...that you can navigate in the Call Graph View using
++arrow keys? Use Up/Down to go one calling level up/down, alternating
++between calls and functions. Use Left/Right to change to siblings of a current
++selected call. To activate the current item, press Return.
++</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Filters">
++<html>
++<p>...that you can rapidly locate a function by entering part of its
++name (case-insensitive) into the edit line of the toolbar
++and hit return?</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Appearance">
++<html>
++<p>...that you can assign custom colors to
++ELF objects/C++ Classes/Source Files for graph coloring
++in <em>Settings->Configure KCachegrind...</em>?</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Configuration">
++<html>
++<p>...that you can see if debug info is available for a selected
++function by looking at the location label in the Info tab or
++the source listing header in the source tab?</p>
++<p>There must be the name of the source file (with extension).
++If KCachegrind still doesn't show the source, make sure that you
++have added the directory of the source file to the
++<em>Source Directories</em> list in the configuration.
++</html>
++</tip>
++
++<tip category="KCachegrind|Appearance">
++<html>
++<p>...that you can configure whether KCachgrind should
++show absolute event counts or relative ones (percentage display)?</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Appearance">
++<html>
++<p>...that you can configure the maximum number of items
++for all function lists in KCachegrind? Limiting the number
++of items is done to get a fast reacting GUI. The last item in
++the list will show you the number of skipped functions, together
++with a cost condition for these skipped functions.</p>
++<p>To activate a function with small costs, search for it and select
++it in the flat profile. Selecting functions with small cost will
++temporarily add them to the flat profile list.</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Explanation">
++<html>
++<p>...that the Coverage tab - in contrast to the Call Lists tab -
++shows <em>all</em> functions that are calling the selected function
++(upper part) / are called by the selected function (bottom part),
++no matter how many function are between them on the stack?</p>
++<p>Examples:</p>
++<p>An entry in the upper list for function foo1() with a value of 50%
++with function bar() selected means that 50% of all the cost of function
++bar() happened while called from function foo1().</p>
++<p>An entry in the bottom list for function foo2() with a value of 50%
++with function bar() selected means that 50% of all the cost of function
++bar() happened while calling foo2() from bar().</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Explanation">
++<html>
++<p>...that waiting for the tool tip inside of a tree map
++shows the list of names of the nested rectangles the mouse
++pointer is over?</p>
++<p>Items from this list can be selected by pressing the right
++mouse button.</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Explanation">
++<html>
++<p>...that you can constrain the cost counts shown to only a
++few parts of the whole trace by selecting these parts in the
++"Trace Selection" Dockable?</p>
++<p>To generate multiple parts in a profiling run with
++cachegrind, use e.g. option --cachedumps=xxx for parts
++of a length of xxx basic blocks (A basic block is a run
++of not-branching assembler statements inside of your program
++code).</p>
++</html>
++</tip>
++
++<tip category="KCachegrind|Explanation">
++<p>...that by splitting the view to show information of
++two functions simultaniously, selecting a function in
++one panel shows the information for that function
++in the other panel?</p>
++</html>
++</tip>
++
+diff --git a/kdecachegrind/kdecachegrind/toplevel.cpp b/kdecachegrind/kdecachegrind/toplevel.cpp
+new file mode 100644
+index 0000000..5a2e1de
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/toplevel.cpp
+@@ -0,0 +1,2389 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * KCachegrind top level window
++ */
++
++#define TRACE_UPDATES 0
++#define ENABLE_DUMPDOCK 0
++
++#include <stdlib.h> // for system()
++
++#include <tqvbox.h>
++#include <tqtimer.h>
++#include <tqwhatsthis.h>
++#include <tqlineedit.h>
++#include <tqtextstream.h>
++#include <tqsizepolicy.h>
++#include <tqprogressbar.h>
++#include <tqfile.h>
++#include <tqeventloop.h>
++
++#include <kapplication.h>
++#include <klocale.h>
++#include <kstatusbar.h>
++#include <kstdaccel.h>
++#include <kstdaction.h>
++#include <kaction.h>
++#include <kurl.h>
++#include <kfiledialog.h>
++#include <kio/netaccess.h>
++#include <kedittoolbar.h>
++#include <kkeydialog.h>
++#include <ktip.h>
++#include <kpopupmenu.h>
++#include <kdebug.h>
++
++#if ENABLE_DUMPDOCK
++#include "dumpselection.h"
++#endif
++
++#include "toplevel.h"
++#include "partselection.h"
++#include "functionselection.h"
++#include "stackselection.h"
++#include "stackbrowser.h"
++#include "tracedata.h"
++#include "configuration.h"
++#include "configdlg.h"
++#include "multiview.h"
++#include "callgraphview.h"
++
++
++TopLevel::TopLevel(const char *name)
++ : KMainWindow(0, name), DCOPObject("KCachegrindIface")
++{
++ init();
++
++ createDocks();
++
++ _multiView = new MultiView(this, this, "MultiView");
++ setCentralWidget(_multiView);
++
++ createActions();
++
++ _partDockShown->setChecked(!_partDock->isHidden());
++ _stackDockShown->setChecked(!_stackDock->isHidden());
++ _functionDockShown->setChecked(!_functionDock->isHidden());
++
++ connect(_partDock, TQT_SIGNAL(visibilityChanged(bool)),
++ TQT_TQOBJECT(this), TQT_SLOT(partVisibilityChanged(bool)));
++ connect(_stackDock, TQT_SIGNAL(visibilityChanged(bool)),
++ TQT_TQOBJECT(this), TQT_SLOT(stackVisibilityChanged(bool)));
++ connect(_functionDock, TQT_SIGNAL(visibilityChanged(bool)),
++ TQT_TQOBJECT(this), TQT_SLOT(functionVisibilityChanged(bool)));
++
++#if ENABLE_DUMPDOCK
++ _dumpDockShown->setChecked(!_dumpDock->isHidden());
++ connect(_dumpDock, TQT_SIGNAL(visibilityChanged(bool)),
++ TQT_TQOBJECT(this), TQT_SLOT(dumpVisibilityChanged(bool)));
++#endif
++
++ _statusbar = statusBar();
++ _statusLabel = new TQLabel(_statusbar);
++#if 0
++ // how to do avoid main window resizing on large statusbar label?
++ TQSizePolicy p(TQSizePolicy::Fixed, TQSizePolicy::Expanding);
++ _statusLabel->setSizePolicy(p);
++ _statusbar->setSizePolicy(p);
++#endif
++ _statusbar->addWidget(_statusLabel, 1);
++
++ KConfig* kconfig = KGlobal::config();
++ Configuration::readOptions( kconfig );
++ _openRecent->loadEntries( kconfig );
++
++ // set toggle after reading configuration
++ _showPercentage = Configuration::showPercentage();
++ _showExpanded = Configuration::showExpanded();
++ _showCycles = Configuration::showCycles();
++ _taPercentage->setChecked(_showPercentage);
++ _taExpanded->setChecked(_showExpanded);
++ _taCycles->setChecked(_showCycles);
++
++ setupPartSelection(_partSelection);
++
++ // KCachegrind for KDE 3.0.x does not allow to hide toolbars...
++#if KDE_VERSION >= 308 // KDE 3.1
++ setStandardToolBarMenuEnabled(true);
++#endif
++
++ // QT dock windows are created before (using QT position restoring)
++ createGUI();
++
++ setAutoSaveSettings();
++
++ // restore current state settings (not configuration options)
++ restoreCurrentState(TQString());
++
++ // if this is the first toplevel, show tip of day
++ if (memberList->count() == 1)
++ TQTimer::singleShot( 200, TQT_TQOBJECT(this), TQT_SLOT(slotShowTipOnStart()) );
++}
++
++void TopLevel::init()
++{
++ _activeParts.clear();
++ _hiddenParts.clear();
++
++ _progressBar = 0;
++
++ _data = 0;
++ _function = 0;
++ _costType = 0;
++ _costType2 = 0;
++ _groupType = TraceCost::NoCostType;
++ _group = 0;
++
++ _layoutCurrent = 0;
++ _layoutCount = 1;
++
++ // for delayed slots
++ _traceItemDelayed = 0;
++ _costTypeDelayed = 0;
++ _costType2Delayed = 0;
++ _groupTypeDelayed = TraceCost::NoCostType;
++ _groupDelayed = 0;
++ _directionDelayed = TraceItemView::None;
++ _lastSender = 0;
++}
++
++
++/**
++ * Setup the part selection widget.
++ * Statusbar has to be created before.
++ */
++void TopLevel::setupPartSelection(PartSelection* ps)
++{
++ // setup connections from the part selection widget
++
++ connect(ps, TQT_SIGNAL(activePartsChanged(const TracePartList&)),
++ TQT_TQOBJECT(this), TQT_SLOT(activePartsChangedSlot(const TracePartList&)));
++ connect(ps, TQT_SIGNAL(groupChanged(TraceCostItem*)),
++ TQT_TQOBJECT(this), TQT_SLOT(setGroupDelayed(TraceCostItem*)));
++ connect(ps, TQT_SIGNAL(functionChanged(TraceItem*)),
++ TQT_TQOBJECT(this), TQT_SLOT(setTraceItemDelayed(TraceItem*)));
++
++ connect(ps, TQT_SIGNAL(goBack()),
++ _stackSelection, TQT_SLOT(browserBack()));
++
++ connect(ps, TQT_SIGNAL(partsHideSelected()),
++ TQT_TQOBJECT(this), TQT_SLOT(partsHideSelectedSlotDelayed()));
++ connect(ps, TQT_SIGNAL(partsUnhideAll()),
++ TQT_TQOBJECT(this), TQT_SLOT(partsUnhideAllSlotDelayed()));
++
++ connect(ps, TQT_SIGNAL(showMessage(const TQString&, int)),
++ _statusbar, TQT_SLOT(message(const TQString&, int)));
++}
++
++/**
++ * This saves the current state of the main window and
++ * sub widgets.
++ *
++ * No positions are saved. These is done automatically for
++ * KToolbar, and manually in queryExit() for QT docks.
++ */
++void TopLevel::saveCurrentState(TQString postfix)
++{
++ KConfig* kconfig = KGlobal::config();
++ TQCString pf = postfix.ascii();
++
++ KConfigGroup psConfig(kconfig, TQCString("PartOverview")+pf);
++ _partSelection->saveVisualisationConfig(&psConfig);
++
++ KConfigGroup stateConfig(kconfig, TQCString("CurrentState")+pf);
++ stateConfig.writeEntry("CostType",
++ _costType ? _costType->name() : TQString("?"));
++ stateConfig.writeEntry("CostType2",
++ _costType2 ? _costType2->name() : TQString("?"));
++ stateConfig.writeEntry("GroupType", TraceItem::typeName(_groupType));
++
++ _multiView->saveViewConfig(kconfig, TQString("MainView"), postfix, true);
++}
++
++/**
++ * This function is called when a trace is closed.
++ * Save browsing position for later restoring
++ */
++void TopLevel::saveTraceSettings()
++{
++ TQString key = traceKey();
++
++ KConfigGroup pConfig(KGlobal::config(), TQCString("TracePositions"));
++ pConfig.writeEntry(TQString("CostType%1").arg(key),
++ _costType ? _costType->name() : TQString("?"));
++ pConfig.writeEntry(TQString("CostType2%1").arg(key),
++ _costType2 ? _costType2->name() : TQString("?"));
++ pConfig.writeEntry(TQString("GroupType%1").arg(key),
++ TraceItem::typeName(_groupType));
++
++ if (!_data) return;
++
++ KConfigGroup aConfig(KGlobal::config(), TQCString("Layouts"));
++ aConfig.writeEntry(TQString("Count%1").arg(key), _layoutCount);
++ aConfig.writeEntry(TQString("Current%1").arg(key), _layoutCurrent);
++
++ saveCurrentState(key);
++ pConfig.writeEntry(TQString("Group%1").arg(key),
++ _group ? _group->name() : TQString());
++}
++
++/**
++ * This restores the current state of the main window and
++ * sub widgets.
++ *
++ * This does NOT restore any positions. This is done automatically for
++ * KToolbar, and manually in the createDocks() for QT docks..
++ */
++void TopLevel::restoreCurrentState(TQString postfix)
++{
++ KConfig* kconfig = KGlobal::config();
++ TQStringList gList = kconfig->groupList();
++ TQCString pf = postfix.ascii();
++
++ // dock properties (not position, this should be have done before)
++ TQCString group = TQCString("PartOverview");
++ if (gList.contains(group+pf)) group += pf;
++ KConfigGroup psConfig(kconfig, group);
++ _partSelection->readVisualisationConfig(&psConfig);
++
++ _multiView->readViewConfig(kconfig, TQString("MainView"), postfix, true);
++ _taSplit->setChecked(_multiView->childCount()>1);
++ _taSplitDir->setEnabled(_multiView->childCount()>1);
++ _taSplitDir->setChecked(_multiView->orientation() == Qt::Horizontal);
++}
++
++
++void TopLevel::createDocks()
++{
++ _partDock = new TQDockWindow(TQDockWindow::InDock, this);
++ _partDock->setCaption(i18n("Parts Overview"));
++ _partDock->setCloseMode( TQDockWindow::Always );
++ _partSelection = new PartSelection(_partDock, "partSelection");
++ _partDock->setWidget(_partSelection);
++ _partDock->setResizeEnabled(true);
++ _partDock->setFixedExtentWidth(200);
++ TQWhatsThis::add( _partSelection, i18n(
++ "<b>The Parts Overview</b>"
++ "<p>A trace consists of multiple trace parts when "
++ "there are several profile data files from one profile run. "
++ "The Trace Part Overview dockable shows these, "
++ "horizontally ordered in execution time; "
++ "the rectangle sizes are proportional to the total "
++ "cost spent in the parts. You can select one or several "
++ "parts to constrain all costs shown to these parts only."
++ "</p>"
++ "<p>The parts are further subdivided: there is a "
++ "partitioning and an callee split mode: "
++ "<ul><li>Partitioning: You see the "
++ "partitioning into groups for a trace part, according to "
++ "the group type selected. E.g. if ELF object groups are "
++ "selected, you see colored rectangles for each "
++ "used ELF object (shared library or executable), sized "
++ "according to the cost spent therein.</li>"
++ "<li>Callee: A rectangle showing the inclusive "
++ "cost of the current selected function in the trace part "
++ "is shown. "
++ "This is split up into smaller rectangles to show the costs of its "
++ "callees.</li></ul></p>"));
++
++ _stackDock = new TQDockWindow(TQDockWindow::InDock, this);
++ _stackDock->setResizeEnabled(true);
++ // Why is the caption only correct with a close button?
++ _stackDock->setCloseMode( TQDockWindow::Always );
++ _stackSelection = new StackSelection(_stackDock, "stackSelection");
++ _stackDock->setWidget(_stackSelection);
++ _stackDock->setFixedExtentWidth(200);
++ _stackDock->setCaption(i18n("Top Cost Call Stack"));
++ TQWhatsThis::add( _stackSelection, i18n(
++ "<b>The Top Cost Call Stack</b>"
++ "<p>This is a purely fictional 'most probable' call stack. "
++ "It is built up by starting with the current selected "
++ "function and adds the callers/callees with highest cost "
++ "at the top and to bottom.</p>"
++ "<p>The <b>Cost</b> and <b>Calls</b> columns show the "
++ "cost used for all calls from the function in the line "
++ "above.</p>"));
++
++ connect(_stackSelection, TQT_SIGNAL(functionSelected(TraceItem*)),
++ TQT_TQOBJECT(this), TQT_SLOT(setTraceItemDelayed(TraceItem*)));
++
++ _functionDock = new TQDockWindow(TQDockWindow::InDock, this);
++ _functionDock->setCaption(i18n("Flat Profile"));
++ _functionDock->setCloseMode( TQDockWindow::Always );
++ _functionSelection = new FunctionSelection(this, _functionDock,
++ "functionSelection");
++ _functionSelection->setTopLevel(this);
++
++ _functionDock->setWidget(_functionSelection);
++ _functionDock->setResizeEnabled(true);
++ _functionDock->setFixedExtentWidth(200);
++ TQWhatsThis::add( _functionSelection, i18n(
++ "<b>The Flat Profile</b>"
++ "<p>The flat profile contains a group and a function "
++ "selection list. The group list contains all groups "
++ "where costs "
++ "are spent in, depending on the chosen group type. "
++ "The group list is hidden when group type 'Function' "
++ "is selected.<p>"
++ "<p>The function list contains the functions of the "
++ "selected group (or all for 'Function' group type), "
++ "ordered by the costs spent therein. Functions with "
++ "costs less than 1% are hidden on default.</p>"));
++
++#if ENABLE_DUMPDOCK
++ _dumpDock = new TQDockWindow(TQDockWindow::InDock, this);
++ _dumpDock->setCaption(i18n("Profile Dumps"));
++ _dumpDock->setCloseMode( TQDockWindow::Always );
++ _dumpSelection = new DumpSelection(this, _dumpDock,
++ "dumpSelection");
++ _dumpSelection->setTopLevel(this);
++
++ _dumpDock->setWidget(_dumpSelection);
++ _dumpDock->setResizeEnabled(true);
++ _dumpDock->setFixedExtentWidth(200);
++ TQWhatsThis::add( _dumpSelection, i18n(
++ "<b>Profile Dumps</b>"
++ "<p>This dockable shows in the top part the list of "
++ "loadable profile dumps in all subdirectories of: "
++ "<ul><li>current working directory of KCachegrind, "
++ "i.e. where it was started from, and "
++ "<li>the default profile dump directory given in the "
++ "configuration.</ul> "
++ "The list is sorted according the the target command "
++ "profiled in the corresponding dump.</p>"
++ "<p>On selecting a profile dump, information for it "
++ "is shown in the bottom area of the dockable: "
++ "<ul><li><b>Options</b> allows you to view the profiled "
++ "command and profile options of this dump. By changing "
++ "any item, a new (yet unexisting) profile template "
++ "is created. Press <b>Run Profile</b> to start a"
++ "profile run with these options in the background. "
++ "<li><b>Info</b> gives detailed info on the selected "
++ "dump like event cost summary and properties of the "
++ "simulated cache. "
++ "<li><b>State</b> is only available for current happening "
++ "profiles runs. Press <b>Update</b> to see different "
++ "counters of the run, and a stack trace of the current "
++ "position in the program profiled. Check the <b>Every</b> "
++ "option to let KCachegrind regularly poll these data. "
++ "Check the <b>Sync</b> option to let the dockable activate "
++ "the top function in the current loaded dump.</ul></p>"));
++#endif
++
++ // Restore QT Dock positions...
++ KConfigGroup dockConfig(KGlobal::config(), TQCString("Docks"));
++ TQString str = dockConfig.readEntry("Position", TQString());
++ if (0) qDebug("Docks/Position: '%s'", str.ascii());
++ if (str.isEmpty()) {
++ // default positions
++ addDockWindow(_partDock, DockLeft);
++ addDockWindow(_stackDock, DockLeft);
++ addDockWindow(_functionDock, DockLeft);
++ _stackDock->hide();
++#if ENABLE_DUMPDOCK
++ addDockWindow(_dumpDock, DockLeft);
++ _dumpDock->hide();
++#endif
++ }
++ else {
++ TQTextStream ts( &str, IO_ReadOnly );
++ ts >> *this;
++ }
++ _forcePartDock = dockConfig.readBoolEntry("ForcePartDockVisible", false);
++
++#if 0
++ // dock context menu
++ setAppropriate(_partDock, true);
++ setAppropriate(_stackDock, true);
++ setAppropriate(_dumpDock, true);
++ setAppropriate(_functionDock, true);
++
++ connect( _partDock, TQT_SIGNAL(contextMenuRequested(const TQPoint &)),
++ TQT_TQOBJECT(this), TQT_SLOT(showDockMenu(const TQPoint &)));
++#endif
++}
++
++
++TopLevel::~TopLevel()
++{
++ delete _data;
++}
++
++
++void TopLevel::saveProperties(KConfig* c)
++{
++ c->writeEntry("TraceName", _data->traceName());
++}
++
++void TopLevel::readProperties(KConfig* c)
++{
++ TQString traceName = c->readEntry("TraceName");
++ if (!traceName.isEmpty()) {
++ TraceData* d = new TraceData(this);
++ d->load(traceName);
++ setData(d);
++ }
++}
++
++void TopLevel::createLayoutActions()
++{
++ TQString hint;
++ KAction* action;
++
++ action = new KAction( i18n( "&Duplicate" ),
++ KShortcut(KKey("Ctrl+Plus")),
++ TQT_TQOBJECT(this), TQT_SLOT(layoutDuplicate()),
++ actionCollection(), "layout_duplicate" );
++ hint = i18n("<b>Duplicate Current Layout</b>"
++ "<p>Make a copy of the current layout.</p>");
++ action->setWhatsThis( hint );
++
++ action = new KAction( i18n( "&Remove" ), KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(layoutRemove()),
++ actionCollection(), "layout_remove" );
++ hint = i18n("<b>Remove Current Layout</b>"
++ "<p>Delete current layout and make the previous active.</p>");
++ action->setWhatsThis( hint );
++
++ action = new KAction( i18n( "&Go to Next" ),
++ KShortcut(KKey("Ctrl+Right")),
++ TQT_TQOBJECT(this), TQT_SLOT(layoutNext()),
++ actionCollection(), "layout_next" );
++ hint = i18n("Go to Next Layout");
++ action->setWhatsThis( hint );
++
++ action = new KAction( i18n( "&Go to Previous" ),
++ KShortcut(KKey("Ctrl+Left")),
++ TQT_TQOBJECT(this), TQT_SLOT(layoutPrevious()),
++ actionCollection(), "layout_previous" );
++ hint = i18n("Go to Previous Layout");
++ action->setWhatsThis( hint );
++
++ action = new KAction( i18n( "&Restore to Default" ), KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(layoutRestore()),
++ actionCollection(), "layout_restore" );
++ hint = i18n("Restore Layouts to Default");
++ action->setWhatsThis( hint );
++
++ action = new KAction( i18n( "&Save as Default" ), KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(layoutSave()),
++ actionCollection(), "layout_save" );
++ hint = i18n("Save Layouts as Default");
++ action->setWhatsThis( hint );
++}
++
++// TODO: split this up...
++void TopLevel::createMiscActions()
++{
++ TQString hint;
++ KAction* action;
++
++ action = KStdAction::openNew(TQT_TQOBJECT(this), TQT_SLOT(newWindow()), actionCollection());
++ hint = i18n("<b>New</b><p>Open new empty KCachegrind window.</p>");
++ action->setWhatsThis( hint );
++
++ action = new KAction( i18n( "&Add..." ), KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(addTrace()),
++ actionCollection(), "file_add" );
++ hint = i18n("<b>Add Profile Data</b>"
++ "<p>This opens an additional profile data file in the current window.</p>");
++ action->setWhatsThis( hint );
++
++ action = new KAction( i18n( "&Reload" ), "reload",
++#if KDE_VERSION > 0x030190
++ // for KDE 3.2: KStdAccel::key is deprecated
++ KStdAccel::shortcut(KStdAccel::Reload),
++#else
++ KStdAccel::key(KStdAccel::Reload),
++#endif
++ TQT_TQOBJECT(this), TQT_SLOT( reload() ), actionCollection(), "reload" );
++ hint = i18n("<b>Reload Profile Data</b>"
++ "<p>This loads any new created parts, too.</p>");
++ action->setWhatsThis( hint );
++
++ action = new KAction( i18n( "&Export Graph" ), KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(exportGraph()),
++ actionCollection(), "export" );
++
++ hint = i18n("<b>Export Call Graph</b>"
++ "<p>Generates a file with extension .dot for the tools "
++ "of the GraphViz package.</p>");
++ action->setWhatsThis( hint );
++
++
++ _taDump = new KToggleAction( i18n( "&Force Dump" ), "redo",
++#if KDE_VERSION > 0x030190
++ // for KDE 3.2: KStdAccel::key is deprecated
++ KStdAccel::shortcut(KStdAccel::Redo),
++#else
++ KStdAccel::key(KStdAccel::Redo),
++#endif
++ TQT_TQOBJECT(this), TQT_SLOT( forceTrace() ),
++ actionCollection(), "dump" );
++ hint = i18n("<b>Force Dump</b>"
++ "<p>This forces a dump for a Callgrind profile run "
++ "in the current directory. This action is checked while "
++ "KCachegrind looks for the dump. If the dump is "
++ "finished, it automatically reloads the current trace. "
++ "If this is the one from the running Callgrind, the new "
++ "created trace part will be loaded, too.</p>"
++ "<p>Force dump creates a file 'callgrind.cmd', and "
++ "checks every second for its existence. A running "
++ "Callgrind will detect this file, dump a trace part, "
++ "and delete 'callgrind.cmd'. "
++ "The deletion is detected by KCachegrind, "
++ "and it does a Reload. If there's <em>no</em> Callgrind "
++ "running, press 'Force Dump' again to cancel the dump "
++ "request. This deletes 'callgrind.cmd' itself and "
++ "stops polling for a new dump.</p>"
++ "<p>Note: A Callgrind run <em>only</em> detects "
++ "existence of 'callgrind.cmd' when actively running "
++ "a few milliseconds, i.e. "
++ "<em>not</em> sleeping. Tip: For a profiled GUI program, "
++ "you can awake Callgrind e.g. by resizing a window "
++ "of the program.</p>");
++ _taDump->setWhatsThis( hint );
++
++ action = KStdAction::open(TQT_TQOBJECT(this), TQT_SLOT(loadTrace()), actionCollection());
++ hint = i18n("<b>Open Profile Data</b>"
++ "<p>This opens a profile data file, with possible multiple parts</p>");
++ action->setToolTip( hint );
++ action->setWhatsThis( hint );
++
++ _openRecent = KStdAction::openRecent(TQT_TQOBJECT(this), TQT_SLOT(loadTrace(const KURL&)),
++ actionCollection());
++
++ KStdAction::showStatusbar(TQT_TQOBJECT(this),
++ TQT_SLOT(toggleStatusBar()), actionCollection());
++
++ _partDockShown = new KToggleAction(i18n("Parts Overview"), KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(togglePartDock()),
++ actionCollection(),
++ "settings_show_partdock");
++
++ hint = i18n("Show/Hide the Parts Overview Dockable");
++ _partDockShown->setToolTip( hint );
++ _partDockShown->setWhatsThis( hint );
++
++ _stackDockShown = new KToggleAction(i18n("Call Stack"), KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(toggleStackDock()),
++ actionCollection(),
++ "settings_show_stackdock");
++
++ hint = i18n("Show/Hide the Call Stack Dockable");
++ _stackDockShown->setToolTip( hint );
++ _stackDockShown->setWhatsThis( hint );
++
++ _functionDockShown = new KToggleAction(i18n("Function Profile"), KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(toggleFunctionDock()),
++ actionCollection(),
++ "settings_show_profiledock");
++
++ hint = i18n("Show/Hide the Function Profile Dockable");
++ _functionDockShown->setToolTip( hint );
++ _functionDockShown->setWhatsThis( hint );
++
++#if ENABLE_DUMPDOCK
++ _dumpDockShown = new KToggleAction(i18n("Profile Dumps"), KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(toggleDumpDock()),
++ actionCollection(),
++ "settings_show_dumpdock");
++
++ hint = i18n("Show/Hide the Profile Dumps Dockable");
++ _dumpDockShown->setToolTip( hint );
++ _dumpDockShown->setWhatsThis( hint );
++#endif
++
++ _taPercentage = new KToggleAction(i18n("Show Relative Costs"), "percent",
++ KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(togglePercentage()),
++ actionCollection(),
++ "view_percentage");
++#if KDE_VERSION >= 0x030290
++ // for KDE 3.3: show another text instead of a checkmark
++ _taPercentage->setCheckedState(i18n("Show Absolute Costs"));
++#endif
++
++ hint = i18n("Show relative instead of absolute costs");
++ _taPercentage->setToolTip( hint );
++ _taPercentage->setWhatsThis( hint );
++
++ _taExpanded = new KToggleAction(i18n("Percentage Relative to Parent"), "move",
++ KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(toggleExpanded()),
++ actionCollection(),
++ "view_expanded");
++
++ hint = i18n("Show percentage costs relative to parent");
++ _taExpanded->setToolTip( hint );
++ _taExpanded->setWhatsThis( hint );
++
++ hint = i18n("<b>Show percentage costs relative to parent</b>"
++ "<p>If this is switched off, percentage costs are always shown "
++ "relative to the total cost of the profile part(s) that are "
++ "currently browsed. By turning on this option, percentage cost "
++ "of shown cost items will be relative to the parent cost item."
++ "<ul><table>"
++ "<tr><td><b>Cost Type</td><td><b>Parent Cost</td></tr>"
++ "<tr><td>Function Cumulative</td><td>Total</td></tr>"
++ "<tr><td>Function Self</td><td>Function Group (*) / Total</td></tr>"
++ "<tr><td>Call</td><td>Function Cumulative</td></tr>"
++ "<tr><td>Source Line</td><td>Function Cumulative</td></tr>"
++ "</table>"
++ "<p>(*) Only if function grouping is switched on (e.g. ELF object grouping).");
++ _taExpanded->setWhatsThis( hint );
++
++ _taCycles = new KToggleAction( i18n( "Do Cycle Detection" ), "undo",
++ KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT( toggleCycles() ), actionCollection(),
++ "view_cycles" );
++#if KDE_VERSION >= 0x030290
++ // for KDE 3.3: show another text instead of a checkmark
++ _taCycles->setCheckedState(i18n("Skip Cycle Detection"));
++#endif
++
++ hint = i18n("<b>Detect recursive cycles</b>"
++ "<p>If this is switched off, the treemap drawing will show "
++ "black areas when a recursive call is made instead of drawing the "
++ "recursion ad infinitum. Note that "
++ "the size of black areas often will be wrong, as inside recursive "
++ "cycles the cost of calls cannot be determined; the error is small, "
++ "however, for false cycles (see documentation)."
++ "<p>The correct handling for cycles is to detect them and collapse all "
++ "functions of a cycle into a virtual function, which is done when this "
++ "option is selected. Unfortunately, with GUI applications, this often will "
++ "lead to huge false cycles, making the analysis impossible; therefore, there "
++ "is the option to switch this off.");
++ _taCycles->setWhatsThis( hint );
++
++ KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), actionCollection());
++ KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(configure()), actionCollection());
++ KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT(configureKeys()), actionCollection());
++ KStdAction::configureToolbars(TQT_TQOBJECT(this),TQT_SLOT(configureToolbars()),
++ actionCollection());
++#if 0
++ action = KStdAction::back(_stackSelection, TQT_SLOT(browserBack()),
++ actionCollection());
++ hint = i18n("Go back in function selection history");
++ action->setToolTip( hint );
++ action->setWhatsThis( hint );
++
++ action = KStdAction::forward(_stackSelection, TQT_SLOT(browserForward()),
++ actionCollection());
++ hint = i18n("Go forward in function selection history");
++ action->setToolTip( hint );
++ action->setWhatsThis( hint );
++
++ action = KStdAction::up(_stackSelection, TQT_SLOT(browserUp()),
++ actionCollection());
++ hint = i18n("<b>Go Up</b>"
++ "<p>Go to last selected caller of current function. "
++ "If no caller was visited, use that with highest cost.</p>");
++ action->setToolTip( hint );
++ action->setWhatsThis( hint );
++#else
++ _paUp = new KToolBarPopupAction( i18n( "&Up" ), "up",
++ ALT+Key_Up,
++ TQT_TQOBJECT(_stackSelection), TQT_SLOT( browserUp() ),
++ actionCollection(), "go_up" );
++ connect( _paUp->popupMenu(), TQT_SIGNAL( aboutToShow() ),
++ TQT_TQOBJECT(this), TQT_SLOT( upAboutToShow() ) );
++ connect( _paUp->popupMenu(), TQT_SIGNAL( activated( int ) ),
++ TQT_TQOBJECT(this), TQT_SLOT( upActivated( int ) ) );
++ hint = i18n("<b>Go Up</b>"
++ "<p>Go to last selected caller of current function. "
++ "If no caller was visited, use that with highest cost.</p>");
++ _paUp->setToolTip( hint );
++ _paUp->setWhatsThis( hint );
++
++ TQPair< KGuiItem, KGuiItem > backForward = KStdGuiItem::backAndForward();
++ _paBack = new KToolBarPopupAction( backForward.first, ALT+Key_Left,
++ TQT_TQOBJECT(_stackSelection), TQT_SLOT(browserBack()),
++ actionCollection(), "go_back" );
++ connect( _paBack->popupMenu(), TQT_SIGNAL( aboutToShow() ),
++ TQT_TQOBJECT(this), TQT_SLOT( backAboutToShow() ) );
++ connect( _paBack->popupMenu(), TQT_SIGNAL( activated( int ) ),
++ TQT_TQOBJECT(this), TQT_SLOT( backActivated( int ) ) );
++ hint = i18n("Go back in function selection history");
++ _paBack->setToolTip( hint );
++ _paBack->setWhatsThis( hint );
++
++ _paForward = new KToolBarPopupAction( backForward.second, ALT+Key_Right,
++ TQT_TQOBJECT(_stackSelection),
++ TQT_SLOT(browserForward()),
++ actionCollection(), "go_forward" );
++ connect( _paForward->popupMenu(), TQT_SIGNAL( aboutToShow() ),
++ this, TQT_SLOT( forwardAboutToShow() ) );
++ connect( _paForward->popupMenu(), TQT_SIGNAL( activated( int ) ),
++ this, TQT_SLOT( forwardActivated( int ) ) );
++ hint = i18n("Go forward in function selection history");
++ _paForward->setToolTip( hint );
++ _paForward->setWhatsThis( hint );
++#endif
++
++ _saCost = new KSelectAction( i18n("Primary Event Type"), KShortcut(),
++ actionCollection(), "view_cost_type");
++ hint = i18n("Select primary event type of costs");
++ _saCost->setComboWidth(300);
++ _saCost->setToolTip( hint );
++ _saCost->setWhatsThis( hint );
++
++ // cost types are dependent on loaded data, thus KSelectAction
++ // is filled in setData()
++ connect( _saCost, TQT_SIGNAL(activated(const TQString&)),
++ TQT_TQOBJECT(this), TQT_SLOT(costTypeSelected(const TQString&)));
++
++ _saCost2 = new KSelectAction( i18n("Secondary Event Type"), KShortcut(),
++ actionCollection(), "view_cost_type2");
++ hint = i18n("Select secondary event type for cost e.g. shown in annotations");
++ _saCost2->setComboWidth(300);
++ _saCost2->setToolTip( hint );
++ _saCost2->setWhatsThis( hint );
++
++ connect( _saCost2, TQT_SIGNAL(activated(const TQString&)),
++ TQT_TQOBJECT(this), TQT_SLOT(costType2Selected(const TQString&)));
++
++ saGroup = new KSelectAction( i18n("Grouping"), KShortcut(),
++ actionCollection(), "view_group_type");
++
++ hint = i18n("Select how functions are grouped into higher level cost items");
++ saGroup->setToolTip( hint );
++ saGroup->setWhatsThis( hint );
++
++ TQStringList args;
++
++ args << i18n("(No Grouping)")
++ << TraceCost::i18nTypeName(TraceItem::Object)
++ << TraceCost::i18nTypeName(TraceItem::File)
++ << TraceCost::i18nTypeName(TraceItem::Class)
++ << TraceCost::i18nTypeName(TraceItem::FunctionCycle);
++
++ saGroup->setItems(args);
++ connect( saGroup, TQT_SIGNAL(activated(int)),
++ TQT_TQOBJECT(this), TQT_SLOT(groupTypeSelected(int)));
++
++ _taSplit = new KToggleAction(i18n("Split"), "view_left_right", KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(splitSlot()),
++ actionCollection(), "view_split");
++
++ hint = i18n("Show two information panels");
++ _taSplit->setToolTip( hint );
++ _taSplit->setWhatsThis( hint );
++
++ _taSplitDir = new KToggleAction(i18n("SplitQt::Horizontal"),
++ "view_left_right", KShortcut(),
++ TQT_TQOBJECT(this), TQT_SLOT(splitDirSlot()),
++ actionCollection(), "view_split_dir");
++
++ hint = i18n("Change Split Qt::Orientation when main window is split.");
++ _taSplitDir->setToolTip( hint );
++ _taSplitDir->setWhatsThis( hint );
++
++ // copied from KMail...
++#if KDE_VERSION >= 308 // KDE 3.1
++ KStdAction::tipOfDay( TQT_TQOBJECT(this), TQT_SLOT( slotShowTip() ), actionCollection() );
++#else
++ (void) new KAction( KGuiItem( i18n("Tip of the &Day..."), "idea",
++ i18n("Show \"Tip of the Day\"") ),
++ 0, TQT_TQOBJECT(this), TQT_SLOT(slotShowTip()),
++ actionCollection(), "help_show_tip" );
++#endif
++}
++
++void TopLevel::createActions()
++{
++ createMiscActions();
++ createLayoutActions();
++}
++
++void TopLevel::toggleStatusBar()
++{
++ if (statusBar()->isVisible())
++ statusBar()->hide();
++ else
++ statusBar()->show();
++}
++
++void TopLevel::togglePartDock()
++{
++ if (!_partDock->isVisible())
++ _partDock->show();
++ else
++ _partDock->hide();
++}
++
++void TopLevel::toggleStackDock()
++{
++ if (!_stackDock->isVisible())
++ _stackDock->show();
++ else
++ _stackDock->hide();
++}
++
++void TopLevel::toggleDumpDock()
++{
++#if ENABLE_DUMPDOCK
++ if (!_dumpDock->isVisible())
++ _dumpDock->show();
++ else
++ _dumpDock->hide();
++#endif
++}
++
++void TopLevel::toggleFunctionDock()
++{
++ if (!_functionDock->isVisible())
++ _functionDock->show();
++ else
++ _functionDock->hide();
++}
++
++void TopLevel::togglePercentage()
++{
++ setPercentage(_taPercentage->isChecked());
++}
++
++void TopLevel::setAbsoluteCost()
++{
++ setPercentage(false);
++}
++
++void TopLevel::setRelativeCost()
++{
++ setPercentage(true);
++}
++
++void TopLevel::setPercentage(bool show)
++{
++ if (_showPercentage == show) return;
++ _showPercentage = show;
++ if (_taPercentage->isChecked() != show)
++ _taPercentage->setChecked(show);
++
++ // FIXME: Delete when no view gets this config from Configuration
++ Configuration::setShowPercentage(_showPercentage);
++
++ _partSelection->refresh();
++ _stackSelection->refresh();
++
++ _functionSelection->notifyChange(TraceItemView::configChanged);
++ _functionSelection->updateView();
++
++ _multiView->notifyChange(TraceItemView::configChanged);
++ _multiView->updateView();
++}
++
++void TopLevel::toggleExpanded()
++{
++ bool show = _taExpanded->isChecked();
++ if (_showExpanded == show) return;
++ _showExpanded = show;
++
++ // FIXME: Delete when no view gets this config from Configuration
++ Configuration::setShowExpanded(_showExpanded);
++
++ _partSelection->refresh();
++ _stackSelection->refresh();
++
++ _functionSelection->notifyChange(TraceItemView::configChanged);
++ _functionSelection->updateView();
++
++ _multiView->notifyChange(TraceItemView::configChanged);
++ _multiView->updateView();
++}
++
++void TopLevel::toggleCycles()
++{
++ bool show = _taCycles->isChecked();
++ if (_showCycles == show) return;
++ _showCycles = show;
++
++ // FIXME: Delete when no view gets this config from Configuration
++ Configuration::setShowCycles(_showCycles);
++
++ if (!_data) return;
++
++ _data->invalidateDynamicCost();
++ _data->updateFunctionCycles();
++
++ _partSelection->refresh();
++ _stackSelection->rebuildStackList();
++
++ _functionSelection->notifyChange(TraceItemView::configChanged);
++ _functionSelection->updateView();
++
++ _multiView->notifyChange(TraceItemView::configChanged);
++ _multiView->updateView();
++}
++
++void TopLevel::partVisibilityChanged(bool v)
++{
++ _partDockShown->setChecked(v);
++}
++
++void TopLevel::stackVisibilityChanged(bool v)
++{
++ _stackDockShown->setChecked(v);
++}
++
++#if ENABLE_DUMPDOCK
++void TopLevel::dumpVisibilityChanged(bool v)
++#else
++void TopLevel::dumpVisibilityChanged(bool)
++#endif
++{
++#if ENABLE_DUMPDOCK
++ _dumpDockShown->setChecked(v);
++#endif
++}
++
++void TopLevel::functionVisibilityChanged(bool v)
++{
++ _functionDockShown->setChecked(v);
++ if (v)
++ _functionSelection->updateView();
++}
++
++
++void TopLevel::querySlot()
++{
++ _functionSelection->query(queryLineEdit->text());
++}
++
++void TopLevel::configureKeys()
++{
++#if KDE_VERSION > 0x030190
++ // for KDE 3.2: KKeyDialog::configureKeys is deprecated
++ KKeyDialog::configure(actionCollection(), this, true);
++#else
++ KKeyDialog::configureKeys(actionCollection(), xmlFile(), true, this);
++#endif
++}
++
++
++void TopLevel::configureToolbars()
++{
++ KEditToolbar *dlg = new KEditToolbar(guiFactory(),this);
++
++ if (dlg->exec())
++ createGUI();
++
++ delete dlg;
++}
++
++
++void TopLevel::newTrace()
++{
++ // start cachegrind on command...
++}
++
++void TopLevel::newWindow()
++{
++ TopLevel* t = new TopLevel(0);
++ t->show();
++}
++
++
++void TopLevel::loadTrace()
++{
++ KURL url = KFileDialog::getOpenURL(":",
++ i18n("cachegrind.out* callgrind.out*|Callgrind Profile Data\n*|All Files"),
++ this,
++ i18n("Select Callgrind Profile Data"));
++ loadTrace(url);
++}
++
++void TopLevel::loadTrace(const KURL& url)
++{
++ if (url.isEmpty()) return;
++
++ // network transparancy
++ TQString tmpFile;
++#if KDE_VERSION > 0x030190
++ // for KDE 3.2: KIO::NetAccess::download with 2 args is deprecated
++ if(KIO::NetAccess::download( url, tmpFile, this )) {
++#else
++ if(KIO::NetAccess::download( url, tmpFile )) {
++#endif
++ _openRecent->addURL(url);
++ _openRecent->saveEntries( KGlobal::config() );
++
++ loadTrace(tmpFile);
++ KIO::NetAccess::removeTempFile( tmpFile );
++ }
++}
++
++void TopLevel::loadTrace(TQString file)
++{
++ if (file.isEmpty()) return;
++
++ if (_data && _data->parts().count()>0) {
++
++ // In new window
++ TopLevel* t = new TopLevel();
++ t->show();
++ t->loadDelayed(file);
++ return;
++ }
++
++ // this constructor enables progress bar callbacks
++ TraceData* d = new TraceData(this);
++ d->load(file);
++ setData(d);
++}
++
++
++void TopLevel::addTrace()
++{
++ KURL url = KFileDialog::getOpenURL(TQString(),
++ i18n("cachegrind.out* callgrind.out*|Callgrind Profile Data\n*|All Files"),
++ this,
++ i18n("Add Callgrind Profile Data"));
++ addTrace(url);
++}
++
++void TopLevel::addTrace(const KURL& url)
++{
++ if (url.isEmpty()) return;
++
++ // network transparancy
++ TQString tmpFile;
++#if KDE_VERSION > 0x030190
++ // for KDE 3.2: KIO::NetAccess::download with 2 args is deprecated
++ if(KIO::NetAccess::download( url, tmpFile, this )) {
++#else
++ if(KIO::NetAccess::download( url, tmpFile )) {
++#endif
++ _openRecent->addURL(url);
++ _openRecent->saveEntries( KGlobal::config() );
++
++ addTrace(tmpFile);
++ KIO::NetAccess::removeTempFile( tmpFile );
++ }
++}
++
++void TopLevel::addTrace(TQString file)
++{
++ if (file.isEmpty()) return;
++
++ if (_data) {
++ _data->load(file);
++
++ // GUI update for added data
++ configChanged();
++ return;
++ }
++
++ // this constructor enables progress bar callbacks
++ TraceData* d = new TraceData(this);
++ d->load(file);
++ setData(d);
++}
++
++
++
++void TopLevel::loadDelayed(TQString file)
++{
++ _loadTraceDelayed = file;
++ TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(loadTraceDelayed()));
++}
++
++void TopLevel::loadTraceDelayed()
++{
++ if (_loadTraceDelayed.isEmpty()) return;
++
++ loadTrace(_loadTraceDelayed);
++ _loadTraceDelayed = TQString();
++}
++
++
++void TopLevel::reload()
++{
++ TQString trace;
++ if (!_data || _data->parts().count()==0)
++ trace = "."; // open first trace found in dir
++ else
++ trace = _data->traceName();
++
++ // this also keeps sure we have the same browsing position...
++ TraceData* d = new TraceData(this);
++ d->load(trace);
++ setData(d);
++}
++
++void TopLevel::exportGraph()
++{
++ if (!_data || !_function) return;
++
++ TQString n = TQString("callgraph.dot");
++ GraphExporter ge(_data, _function, _costType, _groupType, n);
++ ge.writeDot();
++
++ TQString cmd = TQString("(dot %1 -Tps > %2.ps; kghostview %3.ps)&")
++ .arg(n).arg(n).arg(n);
++ system(TQFile::encodeName( cmd ));
++}
++
++
++bool TopLevel::setCostType(TQString s)
++{
++ TraceCostType* ct;
++
++ ct = (_data) ? _data->mapping()->type(s) : 0;
++
++ // if costtype with given name not found, use first available
++ if (!ct && _data) ct = _data->mapping()->type(0);
++
++ return setCostType(ct);
++}
++
++bool TopLevel::setCostType2(TQString s)
++{
++ TraceCostType* ct;
++
++ // Special type i18n("(Hidden)") gives 0
++ ct = (_data) ? _data->mapping()->type(s) : 0;
++
++ return setCostType2(ct);
++}
++
++void TopLevel::costTypeSelected(const TQString& s)
++{
++ TraceCostType* ct;
++
++ ct = (_data) ? _data->mapping()->typeForLong(s) : 0;
++ setCostType(ct);
++}
++
++void TopLevel::costType2Selected(const TQString& s)
++{
++ TraceCostType* ct;
++
++ ct = (_data) ? _data->mapping()->typeForLong(s) : 0;
++ setCostType2(ct);
++}
++
++bool TopLevel::setCostType(TraceCostType* ct)
++{
++ if (_costType == ct) return false;
++ _costType = ct;
++
++ if (ct) {
++ int idx=0;
++ TQStringList l = _saCost->items();
++ for (TQStringList::Iterator it = l.begin(); it != l.end(); ++it, ++idx ) {
++ if (*it == ct->longName())
++ _saCost->setCurrentItem(idx);
++ }
++ }
++
++ _partSelection->setCostType(_costType);
++ _stackSelection->setCostType(_costType);
++
++ _functionSelection->setCostType(_costType);
++ _functionSelection->updateView();
++
++ _multiView->setCostType(_costType);
++ _multiView->updateView();
++
++ updateStatusBar();
++
++ return true;
++}
++
++bool TopLevel::setCostType2(TraceCostType* ct)
++{
++ if (_costType2 == ct) return false;
++ _costType2 = ct;
++
++ TQString longName = ct ? ct->longName() : i18n("(Hidden)");
++
++ int idx=0;
++ TQStringList l = _saCost2->items();
++ for (TQStringList::Iterator it = l.begin(); it != l.end(); ++it, ++idx ) {
++ if (*it == longName)
++ _saCost2->setCurrentItem(idx);
++ }
++
++ _partSelection->setCostType2(_costType2);
++ _stackSelection->setCostType2(_costType2);
++
++ _functionSelection->setCostType2(_costType2);
++ _functionSelection->updateView();
++
++ _multiView->setCostType2(_costType2);
++ _multiView->updateView();
++
++ updateStatusBar();
++
++ return true;
++}
++
++
++void TopLevel::groupTypeSelected(int cg)
++{
++ switch(cg) {
++ case 0: setGroupType( TraceItem::Function ); break;
++ case 1: setGroupType( TraceItem::Object ); break;
++ case 2: setGroupType( TraceItem::File ); break;
++ case 3: setGroupType( TraceItem::Class ); break;
++ case 4: setGroupType( TraceItem::FunctionCycle ); break;
++ default: break;
++ }
++}
++
++bool TopLevel::setGroupType(TQString s)
++{
++ TraceItem::CostType gt;
++
++ gt = (_data) ? _data->costType(s) : TraceData::costType(s);
++ // only allow Function/Object/File/Class as grouptype
++ switch(gt) {
++ case TraceItem::Object:
++ case TraceItem::File:
++ case TraceItem::Class:
++ case TraceItem::FunctionCycle:
++ break;
++ default:
++ gt = TraceItem::Function;
++ }
++
++ return setGroupType(gt);
++}
++
++bool TopLevel::setGroupType(TraceItem::CostType gt)
++{
++ if (_groupType == gt) return false;
++ _groupType = gt;
++
++ int idx = -1;
++ switch(gt) {
++ case TraceItem::Function: idx = 0; break;
++ case TraceItem::Object: idx = 1; break;
++ case TraceItem::File: idx = 2; break;
++ case TraceItem::Class: idx = 3; break;
++ case TraceItem::FunctionCycle: idx = 4; break;
++ default:
++ break;
++ }
++
++ if (idx==-1) return false;
++
++ if (saGroup->currentItem() != idx)
++ saGroup->setCurrentItem(idx);
++
++ _stackSelection->setGroupType(_groupType);
++ _partSelection->setGroupType(_groupType);
++
++ _functionSelection->set(_groupType);
++ _functionSelection->updateView();
++
++ _multiView->set(_groupType);
++ _multiView->updateView();
++
++ updateStatusBar();
++
++ return true;
++}
++
++bool TopLevel::setGroup(TQString s)
++{
++ return true;
++ TraceCostItem* ci = _functionSelection->group(s);
++ if (!ci)
++ return false;
++
++ return setGroup(ci);
++}
++
++
++bool TopLevel::setGroup(TraceCostItem* g)
++{
++ _multiView->activate(g);
++ _multiView->updateView();
++ _functionSelection->activate(g);
++ _functionSelection->updateView();
++
++ if (_group == g) return false;
++ _group = g;
++
++
++ updateStatusBar();
++
++ return true;
++}
++
++bool TopLevel::setFunction(TQString s)
++{
++ if (!_data) return false;
++
++ TraceCost* f = _data->search(TraceItem::Function, s, _costType);
++ if (!f) return false;
++
++ return setFunction((TraceFunction*)f);
++}
++
++bool TopLevel::setFunction(TraceFunction* f)
++{
++ _multiView->activate(f);
++ _multiView->updateView();
++
++ _functionSelection->activate(f);
++ _functionSelection->updateView();
++
++ if (_function == f) return false;
++ _function = f;
++
++ _partSelection->setFunction(_function);
++ _stackSelection->setFunction(_function);
++
++ StackBrowser* b = _stackSelection->browser();
++ if (b) {
++ // don't disable up: a press forces stack-up extending...
++ _paForward->setEnabled(b->canGoForward());
++ _paBack->setEnabled(b->canGoBack());
++ }
++
++#if TRACE_UPDATES
++ qDebug("TopLevel::setFunction(%s), lastSender %s",
++ f ? f->prettyName().ascii() : "0",
++ _lastSender ? _lastSender->name() :"0" );
++#endif
++
++ return true;
++}
++
++
++/**
++ * Delayed versions.
++ * We always have a pair of slots: One receiver to start the
++ * delay with a singleShot Timer. It stores the parameter into a
++ * temporary variable. And one parameterless slot for
++ * forwarding, using this temporary.
++ */
++void TopLevel::setCostTypeDelayed(TraceCostType* ct)
++{
++ _costTypeDelayed = ct;
++ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setCostTypeDelayed()));
++}
++
++void TopLevel::setCostType2Delayed(TraceCostType* ct)
++{
++ _costType2Delayed = ct;
++ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setCostType2Delayed()));
++}
++
++void TopLevel::setCostTypeDelayed()
++{
++ setCostType(_costTypeDelayed);
++}
++
++void TopLevel::setCostType2Delayed()
++{
++ setCostType2(_costType2Delayed);
++}
++
++void TopLevel::setGroupTypeDelayed(TraceItem::CostType gt)
++{
++ _groupTypeDelayed = gt;
++ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setGroupTypeDelayed()));
++}
++
++void TopLevel::setGroupTypeDelayed()
++{
++ setGroupType(_groupTypeDelayed);
++}
++
++void TopLevel::setGroupDelayed(TraceCostItem* g)
++{
++#if TRACE_UPDATES
++ qDebug("TopLevel::setGroupDelayed(%s), sender %s",
++ g ? g->prettyName().ascii() : "0",
++ _lastSender ? _lastSender->name() :"0" );
++#endif
++
++ _groupDelayed = g;
++ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setGroupDelayed()));
++}
++
++void TopLevel::setGroupDelayed()
++{
++ setGroup(_groupDelayed);
++}
++
++void TopLevel::setDirectionDelayed(TraceItemView::Direction d)
++{
++ _directionDelayed = d;
++ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setDirectionDelayed()));
++}
++
++void TopLevel::setDirectionDelayed()
++{
++ switch(_directionDelayed) {
++ case TraceItemView::Back:
++ _stackSelection->browserBack();
++ break;
++
++ case TraceItemView::Forward:
++ _stackSelection->browserForward();
++ break;
++
++ case TraceItemView::Up:
++ {
++ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0;
++ HistoryItem* hi = b ? b->current() : 0;
++ TraceFunction* f = hi ? hi->function() : 0;
++
++ if (!f) break;
++ f = hi->stack()->caller(f, false);
++ if (f) setFunction(f);
++ }
++ break;
++
++ default: break;
++ }
++
++ _directionDelayed = TraceItemView::None;
++}
++
++
++void TopLevel::setTraceItemDelayed(TraceItem* i)
++{
++ // no need to select same item a 2nd time...
++ if (_traceItemDelayed == i) return;
++ _traceItemDelayed = i;
++ _lastSender = TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()));
++
++ kdDebug() << "Selected " << (i ? i->prettyName() : "(none)") << endl;
++
++#if TRACE_UPDATES
++ qDebug("TopLevel::setTraceItemDelayed(%s), sender %s",
++ i ? i->prettyName().ascii() : "0",
++ _lastSender ? _lastSender->name() :"0" );
++#endif
++
++ TQTimer::singleShot (0, TQT_TQOBJECT(this), TQT_SLOT(setTraceItemDelayed()));
++}
++
++void TopLevel::setTraceItemDelayed()
++{
++ if (!_traceItemDelayed) return;
++
++ switch(_traceItemDelayed->type()) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ setFunction((TraceFunction*)_traceItemDelayed);
++ break;
++
++ case TraceItem::Object:
++ case TraceItem::File:
++ case TraceItem::Class:
++ setGroup((TraceCostItem*)_traceItemDelayed);
++ break;
++
++#if 0
++ // this conflicts with the selection policy of InstrView ?!?
++ case TraceItem::Instr:
++ case TraceItem::Line:
++ // only for multiview
++ _multiView->activate(_traceItemDelayed);
++ _multiView->updateView();
++ break;
++#endif
++
++ default: break;
++ }
++
++ _traceItemDelayed = 0;
++ _lastSender = 0;
++}
++
++/**
++ * A TraceData object cannot be viewed many times in different
++ * toplevel windows. Thus, this toplevel window takes ownership
++ * of the TraceData object: on closing the window or opening
++ * another trace, the object is destroyed.
++ */
++void TopLevel::setData(TraceData* data)
++{
++ if (data == _data) return;
++
++ _lastSender = 0;
++
++ saveTraceSettings();
++
++ if (_data) {
++ _partSelection->setData(0);
++ _stackSelection->setData(0);
++
++ _functionSelection->setData(0);
++ _functionSelection->updateView();
++ _multiView->setData(0);
++ _multiView->updateView();
++
++ // we are the owner...
++ delete _data;
++ }
++
++ // reset members
++ init();
++
++ _data = data;
++
++ // fill cost type list
++ TQStringList types;
++
++ if (_data) {
++ /* add all supported virtual types */
++ TraceCostMapping* m = _data->mapping();
++ m->addKnownVirtualTypes();
++
++ /* first, fill selection list with available cost types */
++ for (int i=0;i<m->realCount();i++)
++ types << m->realType(i)->longName();
++ for (int i=0;i<m->virtualCount();i++)
++ types << m->virtualType(i)->longName();
++ }
++ _saCost->setItems(types);
++ _saCost->setComboWidth(300);
++
++ if (types.count()>0) {
++ // second type list gets an additional "(Hidden)"
++ types.prepend(i18n("(Hidden)"));
++ }
++ _saCost2->setItems(types);
++ _saCost2->setComboWidth(300);
++ // default is hidden
++ if (types.count()>0)
++ _saCost2->setCurrentItem(0);
++
++ _partSelection->setData(_data);
++ _stackSelection->setData(_data);
++ _functionSelection->setData(_data);
++ _functionSelection->updateView();
++ _multiView->setData(_data);
++ _multiView->updateView();
++
++ /* this is needed to let the other widgets know the types */
++ restoreTraceTypes();
++
++ restoreTraceSettings();
++
++ TQString caption;
++ if (_data) {
++ caption = _data->traceName();
++ if (!_data->command().isEmpty())
++ caption += " [" + _data->command() + "]";
++ }
++ setCaption(caption);
++
++ if (!_data || (!_forcePartDock && _data->parts().count()<2)) {
++ _partDock->hide();
++ _partDockShown->setChecked(false);
++ }
++ else {
++ _partDock->show();
++ _partDockShown->setChecked(true);
++ }
++
++ updateStatusBar();
++}
++
++void TopLevel::addCostMenu(TQPopupMenu* popup, bool withCost2)
++{
++ if (_data) {
++ TQPopupMenu *popup1 = new TQPopupMenu(popup);
++ TQPopupMenu *popup2 = 0;
++ popup1->setCheckable(true);
++
++ if (withCost2) {
++ popup2 = new TQPopupMenu(popup);
++ popup2->setCheckable(true);
++
++ if (_costType2) {
++ popup2->insertItem(i18n("Hide"),199);
++ popup2->insertSeparator();
++ }
++ }
++
++ TraceCostMapping* m = _data->mapping();
++ TraceCostType* ct;
++ for (int i=0;i<m->realCount();i++) {
++ ct = m->realType(i);
++ popup1->insertItem(ct->longName(), 100+i);
++ if (_costType == ct) popup1->setItemChecked(100+i,true);
++ if (popup2) {
++ popup2->insertItem(ct->longName(), 100+i);
++ if (_costType2 == ct) popup2->setItemChecked(100+i,true);
++ }
++ }
++ for (int i=0;i<m->virtualCount();i++) {
++ ct = m->virtualType(i);
++ popup1->insertItem(ct->longName(), 200+i);
++ if (_costType == ct) popup1->setItemChecked(200+i,true);
++ if (popup2) {
++ popup2->insertItem(ct->longName(), 200+i);
++ if (_costType2 == ct) popup2->setItemChecked(200+i,true);
++ }
++ }
++ popup->insertItem(i18n("Primary Event Type"), popup1);
++ connect(popup1,TQT_SIGNAL(activated(int)),this,TQT_SLOT(setCostType(int)));
++ if (popup2) {
++ popup->insertItem(i18n("Secondary Event Type"), popup2);
++ connect(popup2,TQT_SIGNAL(activated(int)),this,TQT_SLOT(setCostType2(int)));
++ }
++ }
++ if (_showPercentage)
++ popup->insertItem(i18n("Show Absolute Cost"),
++ TQT_TQOBJECT(this), TQT_SLOT(setAbsoluteCost()));
++ else
++ popup->insertItem(i18n("Show Relative Cost"),
++ TQT_TQOBJECT(this), TQT_SLOT(setRelativeCost()));
++}
++
++bool TopLevel::setCostType(int id)
++{
++ if (!_data) return false;
++
++ TraceCostMapping* m = _data->mapping();
++ TraceCostType* ct=0;
++ if (id >=100 && id<199) ct = m->realType(id-100);
++ if (id >=200 && id<299) ct = m->virtualType(id-200);
++
++ return ct ? setCostType(ct) : false;
++}
++
++bool TopLevel::setCostType2(int id)
++{
++ if (!_data) return false;
++
++ TraceCostMapping* m = _data->mapping();
++ TraceCostType* ct=0;
++ if (id >=100 && id<199) ct = m->realType(id-100);
++ if (id >=200 && id<299) ct = m->virtualType(id-200);
++
++ return setCostType2(ct);
++}
++
++void TopLevel::addGoMenu(TQPopupMenu* popup)
++{
++ popup->insertItem(i18n("Go Back"), TQT_TQOBJECT(this), TQT_SLOT(goBack()));
++ popup->insertItem(i18n("Go Forward"), TQT_TQOBJECT(this), TQT_SLOT(goForward()));
++ popup->insertItem(i18n("Go Up"), TQT_TQOBJECT(this), TQT_SLOT(goUp()));
++}
++
++void TopLevel::goBack()
++{
++ setDirectionDelayed(TraceItemView::Back);
++}
++
++void TopLevel::goForward()
++{
++ setDirectionDelayed(TraceItemView::Forward);
++}
++
++void TopLevel::goUp()
++{
++ setDirectionDelayed(TraceItemView::Up);
++}
++
++TQString TopLevel::traceKey()
++{
++ if (!_data || _data->command().isEmpty()) return TQString();
++
++ TQString name = _data->command();
++ TQString key;
++ for (unsigned int l=0;l<name.length();l++)
++ if (name[l].isLetterOrNumber()) key += name[l];
++
++ return TQString("-") + key;
++}
++
++
++void TopLevel::restoreTraceTypes()
++{
++ TQString key = traceKey();
++
++ KConfigGroup cConfig(KGlobal::config(), TQCString("CurrentState"));
++ KConfigGroup pConfig(KGlobal::config(), TQCString("TracePositions"));
++
++ TQString groupType, costType, costType2;
++ groupType = pConfig.readEntry(TQString("GroupType%1").arg(key));
++ costType = pConfig.readEntry(TQString("CostType%1").arg(key));
++ costType2 = pConfig.readEntry(TQString("CostType2%1").arg(key));
++
++ if (groupType.isEmpty()) groupType = cConfig.readEntry("GroupType");
++ if (costType.isEmpty()) costType = cConfig.readEntry("CostType");
++ if (costType2.isEmpty()) costType2 = cConfig.readEntry("CostType2");
++
++ setGroupType(groupType);
++ setCostType(costType);
++ setCostType2(costType2);
++
++ // if still no cost type set, use first available
++ if (!_costType && !_saCost->items().isEmpty())
++ costTypeSelected(_saCost->items().first());
++
++ KConfigGroup aConfig(KGlobal::config(), TQCString("Layouts"));
++ _layoutCount = aConfig.readNumEntry(TQString("Count%1").arg(key), 0);
++ _layoutCurrent = aConfig.readNumEntry(TQString("Current%1").arg(key), 0);
++ if (_layoutCount == 0) layoutRestore();
++ updateLayoutActions();
++}
++
++
++/**
++ * This must be called after setting group/cost types in the function
++ * selection widget, because the group/function choosing depends on
++ * filled lists in the function selection widget
++ */
++void TopLevel::restoreTraceSettings()
++{
++ if (!_data) return;
++
++ TQString key = traceKey();
++
++ KConfigGroup pConfig(KGlobal::config(), TQCString("TracePositions"));
++ TQString group = pConfig.readEntry(TQString("Group%1").arg(key));
++ if (!group.isEmpty()) setGroup(group);
++
++ restoreCurrentState(key);
++
++ // restoreCurrentState() usually leads to a call to setTraceItemDelayed()
++ // to restore last active item...
++ if (!_traceItemDelayed) {
++ // function not available any more.. try with "main"
++ if (!setFunction("main"))
++ _functionSelection->setTopFunction();
++ }
++}
++
++
++/* Layout */
++
++void TopLevel::layoutDuplicate()
++{
++ // save current and allocate a new slot
++ _multiView->saveViewConfig(KGlobal::config(),
++ TQString("Layout%1-MainView").arg(_layoutCurrent),
++ traceKey(), false);
++ _layoutCurrent = _layoutCount;
++ _layoutCount++;
++
++ updateLayoutActions();
++
++ kdDebug() << "TopLevel::layoutDuplicate: count " << _layoutCount << endl;
++}
++
++void TopLevel::layoutRemove()
++{
++ if (_layoutCount <2) return;
++
++ int from = _layoutCount-1;
++ if (_layoutCurrent == from) { _layoutCurrent--; from--; }
++ // restore from last and decrement count
++ _multiView->readViewConfig(KGlobal::config(),
++ TQString("Layout%1-MainView").arg(from),
++ traceKey(), false);
++ _layoutCount--;
++
++ updateLayoutActions();
++}
++
++void TopLevel::layoutNext()
++{
++ if (_layoutCount <2) return;
++
++ KConfig* config = KGlobal::config();
++ TQString key = traceKey();
++
++ _multiView->saveViewConfig(config,
++ TQString("Layout%1-MainView").arg(_layoutCurrent),
++ key, false);
++ _layoutCurrent++;
++ if (_layoutCurrent == _layoutCount) _layoutCurrent = 0;
++
++ _multiView->readViewConfig(config,
++ TQString("Layout%1-MainView").arg(_layoutCurrent),
++ key, false);
++
++ if (0) kdDebug() << "TopLevel::layoutNext: current "
++ << _layoutCurrent << endl;
++}
++
++void TopLevel::layoutPrevious()
++{
++ if (_layoutCount <2) return;
++
++ KConfig* config = KGlobal::config();
++ TQString key = traceKey();
++
++ _multiView->saveViewConfig(config,
++ TQString("Layout%1-MainView").arg(_layoutCurrent),
++ key, false);
++ _layoutCurrent--;
++ if (_layoutCurrent <0) _layoutCurrent = _layoutCount-1;
++
++ _multiView->readViewConfig(config,
++ TQString("Layout%1-MainView").arg(_layoutCurrent),
++ key, false);
++
++ if (0) kdDebug() << "TopLevel::layoutPrevious: current "
++ << _layoutCurrent << endl;
++}
++
++void TopLevel::layoutSave()
++{
++ KConfig* config = KGlobal::config();
++ TQString key = traceKey();
++
++ _multiView->saveViewConfig(config,
++ TQString("Layout%1-MainView").arg(_layoutCurrent),
++ key, false);
++
++ for(int i=0;i<_layoutCount;i++) {
++ _multiView->readViewConfig(config,
++ TQString("Layout%1-MainView").arg(i),
++ key, false);
++ _multiView->saveViewConfig(config,
++ TQString("Layout%1-MainView").arg(i),
++ TQString(), false);
++ }
++
++ _multiView->readViewConfig(config,
++ TQString("Layout%1-MainView").arg(_layoutCurrent),
++ key, false);
++
++ KConfigGroup aConfig(config, TQCString("Layouts"));
++ aConfig.writeEntry("DefaultCount", _layoutCount);
++ aConfig.writeEntry("DefaultCurrent", _layoutCurrent);
++}
++
++void TopLevel::layoutRestore()
++{
++ KConfig* config = KGlobal::config();
++ KConfigGroup aConfig(config, TQCString("Layouts"));
++ _layoutCount = aConfig.readNumEntry("DefaultCount", 0);
++ _layoutCurrent = aConfig.readNumEntry("DefaultCurrent", 0);
++ if (_layoutCount == 0) {
++ _layoutCount++;
++ return;
++ }
++
++ TQString key = traceKey();
++ for(int i=0;i<_layoutCount;i++) {
++ _multiView->readViewConfig(config,
++ TQString("Layout%1-MainView").arg(i),
++ TQString(), false);
++ _multiView->saveViewConfig(config,
++ TQString("Layout%1-MainView").arg(i),
++ key, false);
++ }
++
++ _multiView->readViewConfig(config,
++ TQString("Layout%1-MainView").arg(_layoutCurrent),
++ key, false);
++
++ updateLayoutActions();
++}
++
++
++void TopLevel::updateLayoutActions()
++{
++ KAction* ka;
++
++ ka = actionCollection()->action("layout_next");
++ if (ka) ka->setEnabled(_layoutCount>1);
++
++ ka = actionCollection()->action("layout_previous");
++ if (ka) ka->setEnabled(_layoutCount>1);
++
++ ka = actionCollection()->action("layout_remove");
++ if (ka) ka->setEnabled(_layoutCount>1);
++
++ _statusbar->message(i18n("Layout Count: %1").arg(_layoutCount), 1000);
++}
++
++
++void TopLevel::updateStatusBar()
++{
++ if (!_data || _data->parts().count()==0) {
++ _statusLabel->setText(i18n("No profile data file loaded."));
++ return;
++ }
++
++ TQString status = TQString("%1 [%2] - ")
++ .arg(_data->shortTraceName())
++ .arg(_data->activePartRange());
++
++ if (_costType) {
++ status += i18n("Total %1 Cost: %2")
++ .arg(_costType->longName())
++ .arg(_data->prettySubCost(_costType));
++
++ /* this gets too long...
++ if (_costType2 && (_costType2 != _costType))
++ status += i18n(", %1 Cost: %2")
++ .arg(_costType2->longName())
++ .arg(_data->prettySubCost(_costType2));
++ */
++ }
++ else
++ status += i18n("No event type selected");
++
++ /* Not working... should give group of selected function
++
++ if (_groupType != TraceItem::Function) {
++ status += TQString(" - %1 '%2'")
++ .arg(TraceItem::i18nTypeName(_groupType))
++ .arg(_group ? _group->prettyName() : i18n("(None)"));
++ }
++ */
++
++ _statusLabel->setText(status);
++}
++
++void TopLevel::configure()
++{
++ if (ConfigDlg::configure(Configuration::config(), _data, this)) {
++ Configuration::saveOptions(KGlobal::config());
++
++ configChanged();
++ }
++ else
++ Configuration::readOptions(KGlobal::config());
++}
++
++bool TopLevel::queryClose()
++{
++ saveTraceSettings();
++
++ return true;
++}
++
++bool TopLevel::queryExit()
++{
++ // save current toplevel options as defaults...
++ Configuration::setShowPercentage(_showPercentage);
++ Configuration::setShowExpanded(_showExpanded);
++ Configuration::setShowCycles(_showCycles);
++ Configuration::saveOptions(KGlobal::config());
++
++ saveCurrentState(TQString());
++
++ // save QT dock positions...
++
++ // We don't want to save the KToolbar position here.
++ // Its already stored.
++ delete toolBar();
++
++ KConfigGroup dockConfig(KGlobal::config(), TQCString("Docks"));
++ TQString str;
++ TQTextStream ts( &str, IO_WriteOnly );
++ ts << *this;
++#if 1
++ dockConfig.writeEntry("Position", str);
++#else
++ /* We store this with a localized key because for dock positions,
++ * QT uses the localized captions of docks.
++ * This way, when changing languages, you don't loose dock position
++ * settings.
++ * For the retrieval to work, we need to store a non-localized.
++ */
++ dockConfig.writeEntry("Position", str, true, false, true);
++#endif
++
++ // if part dock was chosen visible even for only 1 part loaded,
++ // keep this choice...
++ _forcePartDock = false;
++ if (_data && (_data->parts().count()<2) && _partDock->isVisible())
++ _forcePartDock=true;
++ dockConfig.writeEntry("ForcePartDockVisible", _forcePartDock);
++
++ return true;
++}
++
++
++void TopLevel::splitSlot()
++{
++ int count = _multiView->childCount();
++ if (count<1) count = 1;
++ if (count>2) count = 2;
++ count = 3-count;
++ _multiView->setChildCount(count);
++
++ _taSplit->setChecked(count>1);
++ _taSplitDir->setEnabled(count>1);
++ _taSplitDir->setChecked(_multiView->orientation() == Qt::Horizontal);
++}
++
++void TopLevel::splitDirSlot()
++{
++ _multiView->setOrientation( _taSplitDir->isChecked() ?
++ Qt::Horizontal : Qt::Vertical );
++}
++
++
++
++// this is called after a config change in the dialog
++void TopLevel::configChanged()
++{
++ //qDebug("TopLevel::configChanged");
++ //_showPercentage->setChecked(Configuration::showPercentage());
++
++ // invalidate found/cached dirs of source files
++ _data->resetSourceDirs();
++
++ _partSelection->refresh();
++ _stackSelection->refresh();
++
++ _functionSelection->notifyChange(TraceItemView::configChanged);
++ _functionSelection->updateView();
++
++ _multiView->notifyChange(TraceItemView::configChanged);
++ _multiView->updateView();
++}
++
++void TopLevel::slotShowTipOnStart() {
++ KTipDialog::showTip(this);
++}
++
++void TopLevel::slotShowTip() {
++ KTipDialog::showTip( this, TQString(), true );
++}
++
++void TopLevel::dummySlot()
++{
++}
++
++void TopLevel::activePartsChangedSlot(const TracePartList& list)
++{
++ if (!_data) return;
++
++ if (!_data->activateParts(list)) {
++// qDebug("TopLevel::activePartsChangedSlot: No Change!");
++ return;
++ }
++ _activeParts = list;
++
++ _partSelection->activePartsChangedSlot(list);
++
++ _multiView->set(list);
++ _multiView->updateView();
++
++ _functionSelection->set(list);
++ _functionSelection->updateView();
++
++ _stackSelection->refresh();
++
++ updateStatusBar();
++}
++
++void TopLevel::partsHideSelectedSlotDelayed()
++{
++ TQTimer::singleShot( 0, TQT_TQOBJECT(this), TQT_SLOT(partsHideSelectedSlot()) );
++}
++
++// this puts selected parts into hidden list,
++// deselects them and makes the remaining parts selected
++void TopLevel::partsHideSelectedSlot()
++{
++ if (!_data) return;
++
++ TracePart* part;
++ TracePartList newHidden, newActive;
++ TracePartList l = _data->parts();
++ for (part=l.first();part;part=l.next()) {
++ if ((_activeParts.findRef(part)>=0) ||
++ (_hiddenParts.findRef(part)>=0))
++ newHidden.append(part);
++ else
++ newActive.append(part);
++ }
++
++ _hiddenParts = newHidden;
++ _partSelection->hiddenPartsChangedSlot(_hiddenParts);
++
++#if 0
++ _mainWidget1->hiddenPartsChangedSlot(_hiddenParts);
++ _mainWidget2->hiddenPartsChangedSlot(_hiddenParts);
++#endif
++
++ activePartsChangedSlot(newActive);
++}
++
++void TopLevel::partsUnhideAllSlotDelayed()
++{
++ TQTimer::singleShot( 0, TQT_TQOBJECT(this), TQT_SLOT(partsUnhideAllSlot()) );
++}
++
++// this unhides all hidden parts. Does NOT change selection
++void TopLevel::partsUnhideAllSlot()
++{
++ if (!_data) return;
++
++ _hiddenParts.clear();
++ _partSelection->hiddenPartsChangedSlot(_hiddenParts);
++#if 0
++ _mainWidget1->hiddenPartsChangedSlot(_hiddenParts);
++ _mainWidget2->hiddenPartsChangedSlot(_hiddenParts);
++#endif
++}
++
++void TopLevel::forceTrace()
++{
++// qDebug("forceTrace");
++
++ // Needs Callgrind now...
++ TQFile cmd("callgrind.cmd");
++ if (!cmd.exists()) {
++ cmd.open(IO_WriteOnly);
++ cmd.writeBlock("DUMP\n", 5);
++ cmd.close();
++ }
++ if (_taDump->isChecked())
++ TQTimer::singleShot( 1000, TQT_TQOBJECT(this), TQT_SLOT(forceTraceReload()) );
++ else {
++ // cancel request
++ cmd.remove();
++ }
++
++}
++
++void TopLevel::forceTraceReload()
++{
++// qDebug("forceTraceReload");
++
++ TQFile cmd("callgrind.cmd");
++ if (cmd.exists()) {
++ if (_taDump->isChecked())
++ TQTimer::singleShot( 1000, TQT_TQOBJECT(this), TQT_SLOT(forceTraceReload()) );
++ return;
++ }
++ _taDump->setChecked(false);
++ reload();
++}
++
++void TopLevel::forwardAboutToShow()
++{
++ TQPopupMenu *popup = _paForward->popupMenu();
++
++ popup->clear();
++ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0;
++ HistoryItem* hi = b ? b->current() : 0;
++ TraceFunction* f;
++
++ if (!hi) {
++ popup->insertItem(i18n("(No Stack)"));
++ return;
++ }
++
++ hi = hi->next();
++ if (!hi) {
++ popup->insertItem(i18n("(No next function)"));
++ return;
++ }
++
++ int count = 1;
++ while (count<Configuration::maxSymbolCount() && hi) {
++ f = hi->function();
++ if (!f) break;
++
++ TQString name = f->prettyName();
++ if ((int)name.length()>Configuration::maxSymbolLength())
++ name = name.left(Configuration::maxSymbolLength()) + "...";
++
++ //qDebug("forward: Adding %s", name.ascii());
++ popup->insertItem(name, count);
++ hi = hi->next();
++ count++;
++ }
++}
++
++void TopLevel::backAboutToShow()
++{
++ TQPopupMenu *popup = _paBack->popupMenu();
++
++ popup->clear();
++ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0;
++ HistoryItem* hi = b ? b->current() : 0;
++ TraceFunction* f;
++
++ if (!hi) {
++ popup->insertItem(i18n("(No Stack)"));
++ return;
++ }
++
++ hi = hi->last();
++ if (!hi) {
++ popup->insertItem(i18n("(No previous function)"));
++ return;
++ }
++
++ int count = 1;
++ while (count<Configuration::maxSymbolCount() && hi) {
++ f = hi->function();
++ if (!f) break;
++
++ TQString name = f->prettyName();
++ if ((int)name.length()>Configuration::maxSymbolLength())
++ name = name.left(Configuration::maxSymbolLength()) + "...";
++
++ //qDebug("back: Adding %s", name.ascii());
++ popup->insertItem(name, count);
++ hi = hi->last();
++ count++;
++ }
++}
++
++void TopLevel::upAboutToShow()
++{
++ TQPopupMenu *popup = _paUp->popupMenu();
++
++ popup->clear();
++ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0;
++ HistoryItem* hi = b ? b->current() : 0;
++ TraceFunction* f = hi ? hi->function() : 0;
++
++ if (!f) {
++ popup->insertItem(i18n("(No Stack)"));
++ return;
++ }
++ f = hi->stack()->caller(f, false);
++ if (!f) {
++ popup->insertItem(i18n("(No Function Up)"));
++ return;
++ }
++
++ int count = 1;
++ while (count<Configuration::maxSymbolCount() && f) {
++ TQString name = f->prettyName();
++ if ((int)name.length()>Configuration::maxSymbolLength())
++ name = name.left(Configuration::maxSymbolLength()) + "...";
++
++ popup->insertItem(name, count);
++ f = hi->stack()->caller(f, false);
++ count++;
++ }
++
++}
++
++void TopLevel::forwardActivated(int id)
++{
++ //qDebug("forwardActivated: %d", id);
++
++ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0;
++ if (!b) return;
++
++ while (id>1) {
++ b->goForward();
++ id--;
++ }
++ _stackSelection->browserForward();
++}
++
++void TopLevel::backActivated(int id)
++{
++ //qDebug("backActivated: %d", id);
++
++ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0;
++ if (!b) return;
++
++ while (id>1) {
++ b->goBack();
++ id--;
++ }
++ _stackSelection->browserBack();
++}
++
++void TopLevel::upActivated(int id)
++{
++ //qDebug("upActivated: %d", id);
++
++ StackBrowser* b = _stackSelection ? _stackSelection->browser() : 0;
++ HistoryItem* hi = b ? b->current() : 0;
++ if (!hi) return;
++
++ TraceFunction* f = hi->function();
++
++ while (id>0 && f) {
++ f = hi->stack()->caller(f, false);
++ id--;
++ }
++
++ //qDebug("upActivated: %s", f ? f->prettyName().ascii() : "??" );
++ if (f)
++ setFunction(f);
++
++}
++
++void TopLevel::showMessage(const TQString& msg, int ms)
++{
++ if (_statusbar)
++ _statusbar->message(msg, ms);
++}
++
++void TopLevel::showStatus(TQString msg, int progress)
++{
++ static bool msgUpdateNeeded = true;
++
++ if (msg.isEmpty()) {
++ if (_progressBar) {
++ _statusbar->removeWidget(_progressBar);
++ delete _progressBar;
++ _progressBar = 0;
++ }
++ _statusbar->clear();
++ _progressMsg = msg;
++ return;
++ }
++
++ if (_progressMsg.isEmpty()) _progressStart.start();
++
++ if (msg != _progressMsg) {
++ _progressMsg = msg;
++ msgUpdateNeeded = true;
++ }
++
++ // do nothing if last change was less than 0.5 seconds ago
++ if (_progressStart.elapsed() < 500) return;
++
++ if (!_progressBar) {
++ _progressBar = new TQProgressBar(_statusbar);
++ _progressBar->setMaximumSize(200, _statusbar->height()-4);
++ _statusbar->addWidget(_progressBar, 1, true);
++ _progressBar->show();
++ msgUpdateNeeded = true;
++ }
++
++ _progressStart.restart();
++
++ if (msgUpdateNeeded) {
++ _statusbar->message(msg);
++ msgUpdateNeeded = false;
++ }
++ _progressBar->setProgress(progress);
++
++ // let the progress bar update itself
++ TQEventLoop* l = tqApp->eventLoop();
++ if (l) l->processEvents(TQEventLoop::ExcludeUserInput);
++}
++
++#include "toplevel.moc"
+diff --git a/kdecachegrind/kdecachegrind/toplevel.h b/kdecachegrind/kdecachegrind/toplevel.h
+new file mode 100644
+index 0000000..10e7cde
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/toplevel.h
+@@ -0,0 +1,275 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * KCachegrind top level window
++ */
++
++#ifndef TOPLEVEL_H
++#define TOPLEVEL_H
++
++#include <tqdatetime.h>
++
++#include <dcopobject.h>
++#include <kmainwindow.h>
++
++#include "traceitemview.h"
++#include "tracedata.h"
++
++class MultiView;
++class TQLineEdit;
++class TQDockWidget;
++class TQLabel;
++class TQProgressBar;
++class TQPopupMenu;
++
++class KURL;
++class KSelectAction;
++class KToggleAction;
++class KToolBarPopupAction;
++
++class TraceData;
++class KRecentFilesAction;
++class MainWidget;
++class PartSelection;
++class FunctionSelection;
++class DumpSelection;
++class StackSelection;
++class TraceFunction;
++
++class TopLevel : public KMainWindow, public DCOPObject
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++ TopLevel(const char *name = 0);
++ ~TopLevel();
++
++ TraceData* data() { return _data; }
++ void setData(TraceData*);
++
++ virtual void saveProperties(KConfig*);
++ virtual void readProperties(KConfig*);
++
++ void createActions();
++ void createDocks();
++
++ TraceItem::CostType groupType() { return _groupType; }
++ TraceCostType* costType() { return _costType; }
++ TraceCostType* costType2() { return _costType2; }
++ TracePartList activeParts() { return _activeParts; }
++ TracePartList hiddenParts() { return _hiddenParts; }
++
++ // current config
++ bool showPercentage() const { return _showPercentage; }
++ bool showExpanded() const { return _showExpanded; }
++ bool showCycles() const { return _showCycles; }
++
++ /* convenience functions for often used context menu items */
++ void addCostMenu(TQPopupMenu*,bool);
++ void addGoMenu(TQPopupMenu*);
++
++public slots:
++ void newTrace();
++ void loadTrace();
++ void loadTrace(const KURL&);
++ void loadTrace(TQString);
++ void addTrace();
++ void addTrace(const KURL&);
++ void addTrace(TQString);
++
++ // for quick showing the main window...
++ void loadDelayed(TQString);
++
++ void reload();
++ void exportGraph();
++ void newWindow();
++ void configure();
++ void querySlot();
++ void dummySlot();
++
++ // layouts
++ void layoutDuplicate();
++ void layoutRemove();
++ void layoutNext();
++ void layoutPrevious();
++ void layoutSave();
++ void layoutRestore();
++ void updateLayoutActions();
++
++ void updateStatusBar();
++ void costTypeSelected(const TQString&);
++ void costType2Selected(const TQString&);
++ void groupTypeSelected(int);
++ void splitSlot();
++ void splitDirSlot();
++ void configureToolbars();
++ void configureKeys();
++ bool queryExit();
++ bool queryClose();
++ void togglePartDock();
++ void toggleStackDock();
++ void toggleFunctionDock();
++ void toggleDumpDock();
++ void toggleStatusBar();
++ void partVisibilityChanged(bool);
++ void dumpVisibilityChanged(bool);
++ void stackVisibilityChanged(bool);
++ void functionVisibilityChanged(bool);
++ void togglePercentage();
++ void setPercentage(bool);
++ void setAbsoluteCost();
++ void setRelativeCost();
++ void toggleExpanded();
++ void toggleCycles();
++ void forceTrace();
++ void forceTraceReload();
++ void forwardAboutToShow();
++ void backAboutToShow();
++ void upAboutToShow();
++ void forwardActivated(int);
++ void backActivated(int);
++ void upActivated(int);
++
++ bool setCostType(TraceCostType*);
++ bool setCostType2(TraceCostType*);
++ bool setCostType(TQString);
++ bool setCostType2(TQString);
++ bool setCostType(int);
++ bool setCostType2(int);
++ bool setGroupType(TraceItem::CostType);
++ bool setGroupType(TQString);
++ bool setGroup(TraceCostItem*);
++ bool setGroup(TQString);
++ bool setFunction(TraceFunction*);
++ bool setFunction(TQString);
++ void activePartsChangedSlot(const TracePartList& list);
++ void partsHideSelectedSlot();
++ void partsUnhideAllSlot();
++
++ /* These go back to mainloop first by using a timer.
++ * So they can be called from event handlers that
++ * aren't allowed to delete list entries.
++ */
++ void setCostTypeDelayed(TraceCostType*);
++ void setCostType2Delayed(TraceCostType*);
++ void setGroupTypeDelayed(TraceItem::CostType);
++ void setGroupDelayed(TraceCostItem*);
++ void setTraceItemDelayed(TraceItem*);
++ void partsHideSelectedSlotDelayed();
++ void partsUnhideAllSlotDelayed();
++ void goBack();
++ void goForward();
++ void goUp();
++ void setDirectionDelayed(TraceItemView::Direction);
++
++ /* SingleShot Slots (without parameters) for the delayed versions */
++ void setCostTypeDelayed();
++ void setCostType2Delayed();
++ void setGroupTypeDelayed();
++ void setGroupDelayed();
++ void setTraceItemDelayed();
++ void loadTraceDelayed();
++ void setDirectionDelayed();
++
++ // configuration has changed
++ void configChanged();
++
++ //void refresh();
++ void slotShowTipOnStart();
++ void slotShowTip();
++
++ // progress in status bar, empty message disables progress display
++ void showStatus(TQString msg, int progress);
++ void showMessage(const TQString&, int msec);
++
++private:
++ void init();
++ void createLayoutActions();
++ void createMiscActions();
++ void setupMainWidget(MainWidget*);
++ void setupPartSelection(PartSelection*);
++ void restoreCurrentState(TQString postfix);
++ void saveCurrentState(TQString postfix);
++ void saveTraceSettings();
++ TQString traceKey();
++ void restoreTraceTypes();
++ void restoreTraceSettings();
++
++ KStatusBar* _statusbar;
++ TQLabel* _statusLabel;
++ KRecentFilesAction* _openRecent;
++ bool _twoMainWidgets;
++ Qt::Orientation _spOrientation;
++
++ MultiView* _multiView;
++ FunctionSelection* _functionSelection;
++ DumpSelection* _dumpSelection;
++ PartSelection* _partSelection;
++ StackSelection* _stackSelection;
++ TQLineEdit* queryLineEdit;
++
++ TQDockWindow *_partDock, *_stackDock, *_functionDock, *_dumpDock;
++ bool _forcePartDock;
++
++ KSelectAction *_saCost, *_saCost2, *saGroup;
++ KToggleAction *_partDockShown, *_stackDockShown;
++ KToggleAction *_functionDockShown, *_dumpDockShown;
++ KToggleAction *_taPercentage, *_taExpanded, *_taCycles;
++ KToggleAction *_taDump, *_taSplit, *_taSplitDir;
++ KToolBarPopupAction *_paForward, *_paBack, *_paUp;
++
++ TraceFunction* _function;
++ const TQObject* _lastSender;
++
++ // trace data shown in this window
++ TraceData* _data;
++ // subcost types used for visualisation
++ TraceCostType* _costType;
++ TraceCostType* _costType2;
++ // grouping of function list
++ TraceItem::CostType _groupType;
++ // selected group
++ TraceCostItem* _group;
++ // selected parts
++ TracePartList _activeParts;
++ // hidden parts
++ TracePartList _hiddenParts;
++ // layouts
++ int _layoutCurrent, _layoutCount;
++
++ // for delayed slots
++ TraceCostType* _costTypeDelayed;
++ TraceCostType* _costType2Delayed;
++ TraceItem::CostType _groupTypeDelayed;
++ TraceCostItem* _groupDelayed;
++ TraceItem* _traceItemDelayed;
++ TQString _loadTraceDelayed;
++ TraceItemView::Direction _directionDelayed;
++
++ // for status progress display
++ TQString _progressMsg;
++ TQTime _progressStart;
++ TQProgressBar* _progressBar;
++
++ // toplevel configuration options
++ bool _showPercentage, _showExpanded, _showCycles;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/tracedata.cpp b/kdecachegrind/kdecachegrind/tracedata.cpp
+new file mode 100644
+index 0000000..f129c2e
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/tracedata.cpp
+@@ -0,0 +1,5068 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++
++#include <stdlib.h>
++
++#include <tqfile.h>
++#include <tqdir.h>
++#include <tqfileinfo.h>
++#include <tqregexp.h>
++
++#include <klocale.h>
++#include <kdebug.h>
++
++#include "tracedata.h"
++#include "toplevel.h"
++#include "loader.h"
++#include "configuration.h"
++#include "utils.h"
++#include "fixcost.h"
++
++
++#define TRACE_DEBUG 0
++#define TRACE_ASSERTIONS 0
++
++const int TraceCost::MaxRealIndex = MaxRealIndexValue;
++const int TraceCost::InvalidIndex = -1;
++
++//---------------------------------------------------
++// Addr
++
++bool Addr::set(FixString& s)
++{
++ return s.stripUInt64(_v);
++}
++
++int Addr::set(const char *s)
++{
++ int n = 0;
++ _v = 0;
++
++ while((n<16) && *s) {
++ if ((*s>='0') && (*s<='9'))
++ _v = 16*_v + (*s-'0');
++ else if ((*s>='a') && (*s<='f'))
++ _v = 16*_v + 10 + (*s-'a');
++ else if ((*s>='A') && (*s<='F'))
++ _v = 16*_v + 10 + (*s-'A');
++ else break;
++ s++;
++ n++;
++ }
++
++ return n;
++}
++
++
++TQString Addr::toString() const
++{
++ if (_v == 0) return TQString("0");
++
++ uint64 n = _v;
++ TQString hex;
++ hex.reserve(16);
++
++ while(n>0) {
++ int d = (n & 15);
++ hex = TQChar((d<10) ? ('0'+d) : ('A'-10+d)) + hex;
++ n /= 16;
++ }
++
++ return hex;
++}
++
++TQString Addr::pretty() const
++{
++ if (_v == 0) return TQString("0");
++
++ uint64 n = _v;
++ int p = 0;
++ TQString hex;
++ hex.reserve(20);
++
++ while(n>0) {
++ int d = (n & 15);
++ if ((p>0) && ((p%4)==0)) hex = " " + hex;
++ hex = TQChar((d<10) ? ('0'+d) : ('A'-10+d)) + hex;
++ n /= 16;
++ p++;
++ }
++
++ return hex;
++}
++
++bool Addr::isInRange(Addr a, int distance)
++{
++ uint64 diff = (a._v > _v) ? (a._v - _v) : (_v - a._v);
++ uint64 dist = (distance<0) ? distance : -distance;
++ return (diff < dist);
++}
++
++//---------------------------------------------------
++// TraceItem
++
++TQString* TraceItem::_typeName = 0;
++TQString* TraceItem::_i18nTypeName = 0;
++
++TraceItem::TraceItem()
++{
++ _position = 0;
++ _dep = 0;
++ _dirty = true;
++}
++
++TraceItem::~TraceItem()
++{}
++
++void TraceItem::cleanup()
++{
++ if (_typeName) {
++ delete [] _typeName;
++ _typeName = 0;
++ }
++ if (_i18nTypeName) {
++ delete [] _i18nTypeName;
++ _i18nTypeName = 0;
++ }
++}
++
++TQString TraceItem::typeName(CostType t)
++{
++ if (!_typeName) {
++ _typeName = new TQString [MaxCostType+1];
++ TQString* strs = _typeName;
++ for(int i=0;i<=MaxCostType;i++)
++ strs[i] = TQString("?");
++
++ strs[Item] = I18N_NOOP("Abstract Item");
++ strs[Cost] = I18N_NOOP("Cost Item");
++ strs[PartLine] = I18N_NOOP("Part Source Line");
++ strs[Line] = I18N_NOOP("Source Line");
++ strs[PartLineCall] = I18N_NOOP("Part Line Call");
++ strs[LineCall] = I18N_NOOP("Line Call");
++ strs[PartLineJump] = I18N_NOOP("Part Jump");
++ strs[LineJump] = I18N_NOOP("Jump");
++ strs[PartInstr] = I18N_NOOP("Part Instruction");
++ strs[Instr] = I18N_NOOP("Instruction");
++ strs[PartInstrJump] = I18N_NOOP("Part Instruction Jump");
++ strs[InstrJump] = I18N_NOOP("Instruction Jump");
++ strs[PartInstrCall] = I18N_NOOP("Part Instruction Call");
++ strs[InstrCall] = I18N_NOOP("Instruction Call");
++ strs[PartCall] = I18N_NOOP("Part Call");
++ strs[Call] = I18N_NOOP("Call");
++ strs[PartFunction] = I18N_NOOP("Part Function");
++ strs[FunctionSource] = I18N_NOOP("Function Source File");
++ strs[Function] = I18N_NOOP("Function");
++ strs[FunctionCycle] = I18N_NOOP("Function Cycle");
++ strs[PartClass] = I18N_NOOP("Part Class");
++ strs[Class] = I18N_NOOP("Class");
++ strs[PartFile] = I18N_NOOP("Part Source File");
++ strs[File] = I18N_NOOP("Source File");
++ strs[PartObject] = I18N_NOOP("Part ELF Object");
++ strs[Object] = I18N_NOOP("ELF Object");
++ strs[Part] = I18N_NOOP("Profile Part");
++ strs[Data] = I18N_NOOP("Program Trace");
++ }
++ if (t<0 || t> MaxCostType) t = MaxCostType;
++ return _typeName[t];
++}
++
++TraceItem::CostType TraceItem::costType(TQString s)
++{
++ // This is the default cost Type
++ if (s.isEmpty()) return Function;
++
++ CostType type;
++ for (int i=0; i<MaxCostType;i++) {
++ type = (CostType) i;
++ if (typeName(type) == s)
++ return type;
++ }
++ return NoCostType;
++}
++
++// all strings of typeName() are translatable because of I18N_NOOP there
++TQString TraceItem::i18nTypeName(CostType t)
++{
++ if (!_i18nTypeName) {
++ _i18nTypeName = new TQString [MaxCostType+1];
++ for(int i=0;i<=MaxCostType;i++)
++ _i18nTypeName[i] = i18n(typeName((CostType)i).utf8().data());
++ }
++ if (t<0 || t> MaxCostType) t = MaxCostType;
++ return _i18nTypeName[t];
++}
++
++TraceItem::CostType TraceItem::i18nCostType(TQString s)
++{
++ // This is the default cost Type
++ if (s.isEmpty()) return Function;
++
++ CostType type;
++ for (int i=0; i<MaxCostType;i++) {
++ type = (CostType) i;
++ if (i18nTypeName(type) == s)
++ return type;
++ }
++ return NoCostType;
++}
++
++
++void TraceItem::clear()
++{
++ invalidate();
++}
++
++
++TQString TraceItem::costString(TraceCostMapping*)
++{
++ return TQString("(no cost)");
++}
++
++TQString TraceItem::name() const
++{
++ if (part()) {
++ return i18n("%1 from %2")
++ .arg(_dep->name())
++ .arg(part()->name());
++ }
++
++ if (_dep)
++ return _dep->name();
++
++ return i18n("(unknown)");
++}
++
++TQString TraceItem::prettyName() const
++{
++ if (name().isEmpty()) return i18n("(unknown)");
++ return name();
++}
++
++
++TQString TraceItem::fullName() const
++{
++ return TQString("%1 %2")
++ .arg(typeName(type())).arg(prettyName());
++}
++
++TQString TraceItem::toString()
++{
++ return TQString("%1\n [%3]").arg(fullName()).arg(costString(0));
++}
++
++void TraceItem::invalidate()
++{
++ if (_dirty) return;
++ _dirty = true;
++
++ if (_dep)
++ _dep->invalidate();
++}
++
++void TraceItem::update()
++{
++ _dirty = false;
++}
++
++TracePart* TraceItem::part()
++{
++ return _position ? _position->part() : 0;
++}
++
++const TracePart* TraceItem::part() const
++{
++ return _position ? _position->part() : 0;
++}
++
++TraceData* TraceItem::data()
++{
++ return _position ? _position->data() : 0;
++}
++
++const TraceData* TraceItem::data() const
++{
++ return _position ? _position->data() : 0;
++}
++
++
++//---------------------------------------------------
++// TraceCost
++
++TraceCost::TraceCost()
++ : TraceItem()
++{
++ _cachedType = 0; // no virtual value cached
++
++ TraceCost::clear();
++}
++
++TraceCost::~TraceCost()
++{}
++
++
++void TraceCost::clear()
++{
++ // simple set usage count to 0
++ _count = 0;
++
++ TraceItem::clear();
++}
++
++
++
++void TraceCost::set(TraceSubMapping* sm, const char* s)
++{
++ if (!sm) return;
++ if (!s) {
++ if (_count>0) clear();
++ return;
++ }
++
++ while(*s == ' ') s++;
++
++ if (sm->isIdentity()) {
++ int i = 0;
++ while(i<sm->count()) {
++ if (!_cost[i].set(&s)) break;
++ i++;
++ }
++ _count = i;
++ }
++ else {
++ int i = 0, maxIndex = 0, index;
++ while(1) {
++ index = sm->realIndex(i);
++ if (maxIndex<index) maxIndex=index;
++ if (index == TraceCost::InvalidIndex) break;
++ if (!_cost[index].set(&s)) break;
++ i++;
++ }
++ // we have to set all costs of unused indexes till maxIndex to zero
++ for(i=sm->firstUnused(); i<=maxIndex; i=sm->nextUnused(i))
++ _cost[i] = 0;
++ _count = maxIndex;
++ }
++ // a cost change has to be propagated (esp. in subclasses)
++ invalidate();
++}
++
++void TraceCost::set(TraceSubMapping* sm, FixString & s)
++{
++ if (!sm) return;
++
++ s.stripSpaces();
++
++ if (sm->isIdentity()) {
++ int i = 0;
++ while(i<sm->count()) {
++ if (!s.stripUInt64(_cost[i])) break;
++ i++;
++ }
++ _count = i;
++ }
++ else {
++ int i = 0, maxIndex = 0, index;
++ while(1) {
++ index = sm->realIndex(i);
++ if (maxIndex<index) maxIndex=index;
++ if (index == TraceCost::InvalidIndex) break;
++ if (!s.stripUInt64(_cost[index])) break;
++ i++;
++ }
++ // we have to set all costs of unused indexes till maxIndex to zero
++ for(i=sm->firstUnused(); i<=maxIndex; i=sm->nextUnused(i))
++ _cost[i] = 0;
++ _count = maxIndex+1;
++ }
++ invalidate();
++}
++
++
++void TraceCost::addCost(TraceSubMapping* sm, const char* s)
++{
++ if (!sm || !s) return;
++
++ SubCost v;
++
++ if (sm->isIdentity()) {
++ int i = 0;
++ while(i<sm->count()) {
++ if (!v.set(&s)) break;
++ if (i<_count)
++ _cost[i] += v;
++ else
++ _cost[i] = v;
++ i++;
++ }
++ if (i > _count) _count = i;
++ }
++ else {
++ int i = 0, maxIndex = 0, index;
++ while(1) {
++ if (!v.set(&s)) break;
++ index = sm->realIndex(i);
++ if (maxIndex<index) maxIndex=index;
++ if (index == TraceCost::InvalidIndex) break;
++ if (index<_count)
++ _cost[index] += v;
++ else
++ _cost[index] = v;
++ i++;
++ }
++ if (maxIndex >= _count) {
++ /* we have to set all costs of unused indexes in the interval
++ * [_count;maxIndex] to zero */
++ for(i=sm->nextUnused(_count-1); i<=maxIndex; i=sm->nextUnused(i))
++ _cost[i] = 0;
++ _count = maxIndex+1;
++ }
++ }
++
++ // a cost change has to be propagated (esp. in subclasses)
++ invalidate();
++
++#if TRACE_DEBUG
++ _dirty = false; // don't recurse !
++ qDebug("%s\n now %s", fullName().ascii(),
++ TraceCost::costString(0).ascii());
++ _dirty = true; // because of invalidate()
++#endif
++}
++
++void TraceCost::addCost(TraceSubMapping* sm, FixString & s)
++{
++ if (!sm) return;
++
++ s.stripSpaces();
++
++ SubCost v;
++
++ if (sm->isIdentity()) {
++ int i = 0;
++ while(i<sm->count()) {
++ if (!s.stripUInt64(v)) break;
++ if (i<_count)
++ _cost[i] += v;
++ else
++ _cost[i] = v;
++ i++;
++ }
++ if (i > _count) _count = i;
++ }
++ else {
++ int i = 0, maxIndex = 0, index;
++ while(1) {
++ if (!s.stripUInt64(v)) break;
++ index = sm->realIndex(i);
++ if (maxIndex<index) maxIndex=index;
++ if (index == TraceCost::InvalidIndex) break;
++ if (index<_count)
++ _cost[index] += v;
++ else
++ _cost[index] = v;
++ i++;
++ }
++ if (maxIndex >= _count) {
++ /* we have to set all costs of unused indexes in the interval
++ * [_count;maxIndex] to zero */
++ for(i=sm->nextUnused(_count-1); i<=maxIndex; i=sm->nextUnused(i))
++ _cost[i] = 0;
++ _count = maxIndex+1;
++ }
++ }
++
++ invalidate();
++
++#if TRACE_DEBUG
++ _dirty = false; // don't recurse !
++ qDebug("%s\n now %s", fullName().ascii(),
++ TraceCost::costString(0).ascii());
++ _dirty = true; // because of invalidate()
++#endif
++}
++
++
++// update each subcost to be maximum of old and given costs
++void TraceCost::maxCost(TraceSubMapping* sm, FixString & s)
++{
++ if (!sm) return;
++
++ s.stripSpaces();
++
++ SubCost v;
++
++ if (sm->isIdentity()) {
++ int i = 0;
++ while(i<sm->count()) {
++ if (!s.stripUInt64(v)) break;
++ if (i<_count) {
++ if (v>_cost[i]) _cost[i] = v;
++ }
++ else
++ _cost[i] = v;
++ i++;
++ }
++ if (i > _count) _count = i;
++ }
++ else {
++ int i = 0, maxIndex = 0, index;
++ while(1) {
++ if (!s.stripUInt64(v)) break;
++ index = sm->realIndex(i);
++ if (maxIndex<index) maxIndex=index;
++ if (index == TraceCost::InvalidIndex) break;
++ if (index<_count) {
++ if (v>_cost[index]) _cost[index] = v;
++ }
++ else
++ _cost[index] = v;
++ i++;
++ }
++ if (maxIndex >= _count) {
++ /* we have to set all costs of unused indexes in the interval
++ * [_count;maxIndex] to zero */
++ for(i=sm->nextUnused(_count-1); i<=maxIndex; i=sm->nextUnused(i))
++ _cost[i] = 0;
++ _count = maxIndex+1;
++ }
++ }
++
++ invalidate();
++
++#if TRACE_DEBUG
++ _dirty = false; // don't recurse !
++ qDebug("%s\n now %s", fullName().ascii(),
++ TraceCost::costString(0).ascii());
++ _dirty = true; // because of invalidate()
++#endif
++}
++
++
++void TraceCost::addCost(TraceCost* item)
++{
++ int i;
++
++ if (!item) return;
++
++ // we have to update the other item if needed
++ // because we access the item costs directly
++ if (item->_dirty) item->update();
++
++ if (item->_count < _count) {
++ for (i = 0; i<item->_count; i++)
++ _cost[i] += item->_cost[i];
++ }
++ else {
++ for (i = 0; i<_count; i++)
++ _cost[i] += item->_cost[i];
++ for (; i<item->_count; i++)
++ _cost[i] = item->_cost[i];
++ _count = item->_count;
++ }
++
++ // a cost change has to be propagated (esp. in subclasses)
++ invalidate();
++
++#if TRACE_DEBUG
++ _dirty = false; // don't recurse !
++ qDebug("%s added cost item\n %s\n now %s",
++ fullName().ascii(), item->fullName().ascii(),
++ TraceCost::costString(0).ascii());
++ _dirty = true; // because of invalidate()
++#endif
++}
++
++void TraceCost::maxCost(TraceCost* item)
++{
++ int i;
++
++ if (!item) return;
++
++ // we have to update the other item if needed
++ // because we access the item costs directly
++ if (item->_dirty) item->update();
++
++ if (item->_count < _count) {
++ for (i = 0; i<item->_count; i++)
++ if (_cost[i] < item->_cost[i]) _cost[i] = item->_cost[i];
++ }
++ else {
++ for (i = 0; i<_count; i++)
++ if (_cost[i] < item->_cost[i]) _cost[i] = item->_cost[i];
++ for (; i<item->_count; i++)
++ _cost[i] = item->_cost[i];
++ _count = item->_count;
++ }
++
++ // a cost change has to be propagated (esp. in subclasses)
++ invalidate();
++
++#if TRACE_DEBUG
++ _dirty = false; // don't recurse !
++ qDebug("%s added cost item\n %s\n now %s",
++ fullName().ascii(), item->fullName().ascii(),
++ TraceCost::costString(0).ascii());
++ _dirty = true; // because of invalidate()
++#endif
++}
++
++void TraceCost::addCost(int type, SubCost value)
++{
++ if (type<0 || type>=MaxRealIndex) return;
++ if (type<_count)
++ _cost[type] += value;
++ else {
++ for(int i=_count;i<type;i++)
++ _cost[i] = 0;
++ _cost[type] = value;
++ _count = type+1;
++ }
++
++ // a cost change has to be propagated (esp. in subclasses)
++ invalidate();
++}
++
++void TraceCost::maxCost(int type, SubCost value)
++{
++ if (type<0 || type>=MaxRealIndex) return;
++ if (type<_count) {
++ if (value>_cost[type]) _cost[type] = value;
++ }
++ else {
++ for(int i=_count;i<type;i++)
++ _cost[i] = 0;
++ _cost[type] = value;
++ _count = type+1;
++ }
++
++ // a cost change has to be propagated (esp. in subclasses)
++ invalidate();
++}
++
++
++TraceCost TraceCost::diff(TraceCost* item)
++{
++ TraceCost res;
++
++ // we have to update the other item if needed
++ // because we access the item costs directly
++ if (item->_dirty) item->update();
++
++ int maxCount = (item->_count > _count) ? item->_count : _count;
++
++ res._count = maxCount;
++ for (int i=0; i<maxCount;i++)
++ res._cost[i] = item->subCost(i) - subCost(i);
++
++ return res;
++}
++
++TQString TraceCost::costString(TraceCostMapping* m)
++{
++ TQString res;
++
++ if (_dirty) update();
++
++ int maxIndex = m ? m->realCount() : TraceCost::MaxRealIndex;
++ for (int i = 0; i<maxIndex; i++) {
++ if (!res.isEmpty()) res += ", ";
++ if (m) res += m->type(i)->name() + " ";
++
++ res += subCost(i).pretty();
++ }
++ return res;
++}
++
++
++void TraceCost::invalidate()
++{
++ if (_dirty) return;
++ _dirty = true;
++ _cachedType = 0; // cached value is invalid, too
++
++ if (_dep)
++ _dep->invalidate();
++}
++
++void TraceCost::update()
++{
++ _dirty = false;
++}
++
++// this is only for real types
++SubCost TraceCost::subCost(int idx)
++{
++ if (idx<0) return 0;
++
++ /* update if needed as cost could be calculated dynamically in subclasses
++ * this can change _count !! */
++ if (_dirty) update();
++ if (idx>=_count) return 0;
++
++ return _cost[idx];
++}
++
++SubCost TraceCost::subCost(TraceCostType* t)
++{
++ if (!t) return 0;
++ if (_cachedType != t) {
++ _cachedType = t;
++ _cachedCost = t->subCost(this);
++ }
++ return _cachedCost;
++}
++
++TQString TraceCost::prettySubCost(TraceCostType* t)
++{
++ return subCost(t).pretty();
++}
++
++
++
++//---------------------------------------------------
++// TraceJumpCost
++
++TraceJumpCost::TraceJumpCost()
++ :TraceItem()
++{
++ TraceJumpCost::clear();
++}
++
++TraceJumpCost::~TraceJumpCost()
++{}
++
++SubCost TraceJumpCost::executedCount()
++{
++ if (_dirty) update();
++
++ return _executedCount;
++}
++
++SubCost TraceJumpCost::followedCount()
++{
++ if (_dirty) update();
++
++ return _followedCount;
++}
++
++TQString TraceJumpCost::costString(TraceCostMapping*)
++{
++ if (_dirty) update();
++
++ return TQString("%1/%2")
++ .arg(_followedCount.pretty())
++ .arg(_executedCount.pretty());
++}
++
++void TraceJumpCost::clear()
++{
++ _followedCount = 0;
++ _executedCount = 0;
++}
++
++void TraceJumpCost::addCost(TraceJumpCost* item)
++{
++ if (item->_dirty) item->update();
++
++ _followedCount += item->followedCount();
++ _executedCount += item->executedCount();
++}
++
++
++//---------------------------------------------------
++// TraceCostType
++
++TQPtrList<TraceCostType>* TraceCostType::_knownTypes = 0;
++
++TraceCostType::TraceCostType(TQString name, TQString longName, TQString formula)
++{
++ _name = name;
++ _longName = longName;
++ _formula = formula;
++ _mapping = 0;
++ _realIndex = TraceCost::InvalidIndex;
++ _parsed = false;
++ _inParsing = false;
++
++ for (int i=0; i<TraceCost::MaxRealIndex;i++)
++ _coefficient[i] = 0;
++}
++
++void TraceCostType::setFormula(TQString formula)
++{
++ _formula = formula;
++ _realIndex = TraceCost::InvalidIndex;
++ _parsed = false;
++}
++
++void TraceCostType::setMapping(TraceCostMapping* m)
++{
++ _parsed = false;
++ _mapping = m;
++}
++
++// setting the index to TraceCost::MaxRealIndex makes it a
++// real type with unspecified index
++void TraceCostType::setRealIndex(int i)
++{
++ if (i<0 || i>TraceCost::MaxRealIndex)
++ i=TraceCost::InvalidIndex;
++
++ _realIndex = i;
++ _formula = TQString();
++}
++
++// checks for existing types and sets coefficients
++bool TraceCostType::parseFormula()
++{
++ if (_parsed) return true;
++ if (_inParsing) {
++ qDebug("TraceCostType::parseFormula: Recursion detected.");
++ return false;
++ }
++
++ if (!_mapping) {
++ qDebug("TraceCostType::parseFormula: No mapping set!");
++ return false;
++ }
++
++ _inParsing = true;
++
++ for (int i=0; i<TraceCost::MaxRealIndex;i++)
++ _coefficient[i] = 0;
++
++ TQRegExp rx( "((?:\\+|\\-)?)\\s*(\\d*)\\s*\\*?\\s*(\\w+)" );
++
++ int factor, pos;
++ TQString costName;
++ TraceCostType* costType;
++
++ pos = 0;
++ while (1) {
++ pos = rx.search(_formula, pos);
++ if (pos<0) break;
++ pos += rx.matchedLength();
++ if (rx.cap(0).isEmpty()) break;
++
++ //qDebug("parseFormula: matched '%s','%s','%s'",
++ // rx.cap(1).ascii(), rx.cap(2).ascii(), rx.cap(3).ascii());
++
++ costName = rx.cap(3);
++ costType = _mapping->type(costName);
++ if (!costType) {
++ // qDebug("Cost type '%s': In formula cost '%s' unknown.",
++ // _name.ascii(), costName.ascii());
++
++ _inParsing = false;
++ return false;
++ }
++
++ factor = (rx.cap(2).isEmpty()) ? 1 : rx.cap(2).toInt();
++ if (rx.cap(1) == "-") factor = -factor;
++
++ if (costType->isReal())
++ _coefficient[costType->realIndex()] += factor;
++ else {
++ costType->parseFormula();
++ for (int i=0; i<TraceCost::MaxRealIndex;i++)
++ _coefficient[i] += factor * costType->_coefficient[i];
++ }
++ }
++
++ _inParsing = false;
++ _parsed = true;
++
++ return true;
++}
++
++TQString TraceCostType::parsedFormula()
++{
++ TQString res;
++
++ if (!parseFormula()) return res;
++
++ for (int i=0; i<TraceCost::MaxRealIndex;i++) {
++ int c = _coefficient[i];
++ if (c == 0) continue;
++
++ if (!res.isEmpty()) {
++ res += " ";
++ if (c>0) res += "+ ";
++ }
++ if (c<0) { res += "- "; c = -c; }
++ res += TQString::number(c);
++
++ TraceCostType* t = _mapping->type(i);
++ if (!t) continue;
++
++ if (!t->name().isEmpty())
++ res += TQString(" * %1").arg(t->name());
++ }
++
++ return res;
++}
++
++SubCost TraceCostType::subCost(TraceCost* c)
++{
++ if (_realIndex != TraceCost::InvalidIndex)
++ return c->subCost(_realIndex);
++
++ if (!_parsed) {
++ if (!parseFormula()) return 0;
++ }
++ SubCost res = 0;
++
++ int rc = _mapping->realCount();
++ for (int i = 0;i<rc;i++)
++ if (_coefficient[i] != 0)
++ res += _coefficient[i] * c->subCost(i);
++
++ return res;
++}
++
++int TraceCostType::histCost(TraceCost* c, double total, double* hist)
++{
++ if (total == 0.0) return 0;
++
++ if (!_parsed) {
++ if (!parseFormula()) return 0;
++ }
++
++ int rc = _mapping->realCount();
++ for (int i = 0;i<rc;i++) {
++ if (_coefficient[i] != 0)
++ hist[i] = _coefficient[i] * c->subCost(i) / total;
++ else
++ hist[i] = 0.0;
++ }
++
++ return rc;
++}
++
++
++
++
++TraceCostType* TraceCostType::knownRealType(TQString n)
++{
++ if (!_knownTypes) return 0;
++
++ TraceCostType* t;
++ for (t=_knownTypes->first();t;t=_knownTypes->next())
++ if (t->isReal() && (t->name() == n)) {
++ TraceCostType* type = new TraceCostType(*t);
++ return type;
++ }
++
++ return 0;
++}
++
++TraceCostType* TraceCostType::knownVirtualType(TQString n)
++{
++ if (!_knownTypes) return 0;
++
++ TraceCostType* t;
++ for (t=_knownTypes->first();t;t=_knownTypes->next())
++ if (!t->isReal() && (t->name() == n)) {
++ TraceCostType* type = new TraceCostType(*t);
++ return type;
++ }
++
++ return 0;
++}
++
++// we take ownership
++void TraceCostType::add(TraceCostType* t)
++{
++ if (!t) return;
++
++ t->setMapping(0);
++
++ if (!_knownTypes)
++ _knownTypes = new TQPtrList<TraceCostType>;
++
++ /* Already known? */
++ TraceCostType* kt;
++ for (kt=_knownTypes->first();kt;kt=_knownTypes->next())
++ if (kt->name() == t->name()) break;
++
++ if (kt) {
++ // Overwrite old type
++ if (!t->longName().isEmpty() &&
++ (t->longName() != t->name())) kt->setLongName(t->longName());
++ if (!t->formula().isEmpty()) kt->setFormula(t->formula());
++
++ delete t;
++ }
++ else {
++ if (t->longName().isEmpty()) t->setLongName(t->name());
++ _knownTypes->append(t);
++ }
++}
++
++
++int TraceCostType::knownTypeCount()
++{
++ if (!_knownTypes) return 0;
++
++ return _knownTypes->count();
++}
++
++bool TraceCostType::remove(TQString n)
++{
++ if (!_knownTypes) return false;
++
++ TraceCostType* t;
++ for (t=_knownTypes->first();t;t=_knownTypes->next())
++ if (!t->isReal() && (t->name() == n)) {
++ _knownTypes->removeRef(t);
++ delete t;
++ return true;
++ }
++
++ return false;
++}
++
++TraceCostType* TraceCostType::knownType(int i)
++{
++ if (!_knownTypes) return 0;
++ if (i<0 || i>=(int)_knownTypes->count()) return 0;
++
++ return _knownTypes->at(i);
++}
++
++TQColor TraceCostType::color()
++{
++ if (!_mapping) return TQColor();
++ return _mapping->realColors()[_realIndex];
++}
++
++
++//---------------------------------------------------
++// TraceCostMapping
++
++TraceCostMapping::TraceCostMapping()
++{
++ _realCount = 0;
++ _virtualCount = 0;
++ for (int i=0;i<TraceCost::MaxRealIndex;i++) _real[i] = 0;
++ for (int i=0;i<TraceCost::MaxRealIndex;i++) _virtual[i] = 0;
++}
++
++TraceCostMapping::~TraceCostMapping()
++{
++ for (int i=0;i<TraceCost::MaxRealIndex;i++)
++ if (_real[i]) delete _real[i];
++
++ for (int i=0;i<TraceCost::MaxRealIndex;i++)
++ if (_virtual[i]) delete _virtual[i];
++}
++
++TraceSubMapping* TraceCostMapping::subMapping(TQString types, bool create)
++{
++ // first check if there's enough space in the mapping
++ int newCount = 0;
++ int pos = 0, pos2, len = types.length();
++
++ while (1) {
++ // skip space
++ while((pos<len) && types[pos].isSpace()) pos++;
++
++ pos2 = pos;
++ while((pos2<len) && !types[pos2].isSpace()) pos2++;
++ if (pos2 == pos) break;
++
++ if (realIndex(types.mid(pos,pos2-pos)) == TraceCost::InvalidIndex)
++ newCount++;
++
++ pos = pos2;
++ }
++
++ if (!create && (newCount>0)) return 0;
++
++ if (newCount+_realCount > TraceCost::MaxRealIndex) {
++ kdDebug() << "TraceCostMapping::subMapping: No space for "
++ << newCount << " sub costs." << endl;
++ return 0;
++ }
++
++ TraceSubMapping* sm = new TraceSubMapping(this);
++
++ pos = 0;
++ while (1) {
++ // skip space
++ while((pos<len) && types[pos].isSpace()) pos++;
++
++ pos2 = pos;
++ while((pos2<len) && !types[pos2].isSpace()) pos2++;
++ if (pos2 == pos) break;
++
++ sm->append(addReal(types.mid(pos,pos2-pos)));
++
++ pos = pos2;
++ }
++
++ return sm;
++}
++
++
++int TraceCostMapping::addReal(TQString t)
++{
++ int index = realIndex(t);
++ if (index>=0) return index;
++
++ TraceCostType* ct = TraceCostType::knownRealType(t);
++ if (!ct) ct = new TraceCostType(t, t);
++
++ // make it real
++ ct->setRealIndex();
++
++ return add(ct);
++}
++
++// add a cost type to a mapping
++// this transfers ownership of the type!
++int TraceCostMapping::add(TraceCostType* ct)
++{
++ if (!ct) return TraceCost::InvalidIndex;
++
++ ct->setMapping(this);
++
++ if (ct->isReal()) {
++ if (_realCount >= TraceCost::MaxRealIndex) {
++ qDebug("WARNING: Maximum for real cost types reached (on adding '%s')",
++ ct->name().ascii());
++ return TraceCost::InvalidIndex;
++ }
++ _real[_realCount] = ct;
++ ct->setRealIndex(_realCount);
++ _realColor[_realCount] = Configuration::costTypeColor(ct);
++
++ _realCount++;
++ return _realCount-1;
++ }
++
++ if (_virtualCount >= TraceCost::MaxRealIndex) {
++ qDebug("WARNING: Maximum for virtual cost types reached (on adding '%s')",
++ ct->name().ascii());
++ return TraceCost::InvalidIndex;
++ }
++ _virtual[_virtualCount] = ct;
++ _virtualCount++;
++ return _virtualCount-1;
++}
++
++// we delete the type: t is invalid when returning true!
++bool TraceCostMapping::remove(TraceCostType* t)
++{
++ if (!t) return false;
++ if (t->mapping() != this) return false;
++
++ // don't delete real types
++ if (t->isReal()) return false;
++
++ int i;
++ for(i=0;i<_virtualCount;i++)
++ if (_virtual[i] == t) break;
++
++ // not found?
++ if (i == _virtualCount) return false;
++
++ // delete known type with same name
++ TraceCostType::remove(t->name());
++
++ // delete this type
++ _virtual[i] = 0;
++ delete t;
++ if (i+1 == _virtualCount) {
++ // we can reuse the last index
++ _virtualCount--;
++ }
++ return true;
++}
++
++
++TraceCostType* TraceCostMapping::realType(int t)
++{
++ if (t<0 || t>=_realCount) return 0;
++ return _real[t];
++}
++
++TraceCostType* TraceCostMapping::virtualType(int t)
++{
++ if (t<0 || t>=_virtualCount) return 0;
++ return _virtual[t];
++}
++
++
++TraceCostType* TraceCostMapping::type(int t)
++{
++ if (t<0) return 0;
++ if (t<_realCount) return _real[t];
++
++ t -= TraceCost::MaxRealIndex;
++ if (t<0) return 0;
++ if (t<_virtualCount) return _virtual[t];
++
++ return 0;
++}
++
++TraceCostType* TraceCostMapping::type(TQString name)
++{
++ for (int i=0;i<_realCount;i++)
++ if (_real[i] && (_real[i]->name() == name))
++ return _real[i];
++
++ for (int i=0;i<_virtualCount;i++)
++ if (_virtual[i] && (_virtual[i]->name() == name))
++ return _virtual[i];
++
++ return 0;
++}
++
++TraceCostType* TraceCostMapping::typeForLong(TQString name)
++{
++ for (int i=0;i<_realCount;i++)
++ if (_real[i] && (_real[i]->longName() == name))
++ return _real[i];
++
++ for (int i=0;i<_virtualCount;i++)
++ if (_virtual[i] && (_virtual[i]->longName() == name))
++ return _virtual[i];
++
++ return 0;
++}
++
++
++int TraceCostMapping::realIndex(TQString name)
++{
++ for (int i=0;i<_realCount;i++)
++ if (_real[i] && (_real[i]->name() == name))
++ return i;
++
++ return TraceCost::InvalidIndex;
++}
++
++int TraceCostMapping::index(TQString name)
++{
++ for (int i=0;i<_realCount;i++)
++ if (_real[i] && (_real[i]->name() == name))
++ return i;
++
++ for (int i=0;i<_virtualCount;i++)
++ if (_virtual[i] && (_virtual[i]->name() == name))
++ return TraceCost::MaxRealIndex + 1 + i;
++
++ return TraceCost::InvalidIndex;
++}
++
++int TraceCostMapping::addKnownVirtualTypes()
++{
++ int addCount = 0;
++ int addDiff, i;
++ int knownCount = TraceCostType::knownTypeCount();
++
++ while (1) {
++ addDiff = 0;
++ for (i=0; i<knownCount; i++) {
++ TraceCostType* t = TraceCostType::knownType(i);
++ if (t->isReal()) continue;
++ if (index(t->name()) != TraceCost::InvalidIndex) continue;
++ t->setMapping(this);
++ if (t->parseFormula()) {
++ addDiff++;
++ add(new TraceCostType(t->name(), t->longName(), t->formula()));
++ }
++ t->setMapping(0);
++ }
++ if (addDiff == 0) break;
++ addCount += addDiff;
++ }
++ return addCount;
++}
++
++
++//---------------------------------------------------
++// TraceSubMapping
++
++TraceSubMapping::TraceSubMapping(TraceCostMapping* mapping)
++{
++ _mapping = mapping;
++ clear();
++}
++
++void TraceSubMapping::clear()
++{
++ _count = 0;
++ _isIdentity = true;
++ _firstUnused = 0;
++ for(int i=0;i<TraceCost::MaxRealIndex;i++) {
++ _realIndex[i] = TraceCost::InvalidIndex;
++ _nextUnused[i] = i+1;
++ }
++}
++
++bool TraceSubMapping::append(TQString type, bool create)
++{
++ if (!_mapping) return false;
++ int index = create ? _mapping->addReal(type) : _mapping->realIndex(type);
++
++ return append(index);
++}
++
++bool TraceSubMapping::append(int type)
++{
++ if (!_mapping) return false;
++ if ((type<0) || (type >= _mapping->realCount())) return false;
++
++ if ( _count >= TraceCost::MaxRealIndex) return false;
++
++ _realIndex[_count] = type;
++
++ if (_isIdentity && (_count != type)) _isIdentity = false;
++ if (type == _firstUnused)
++ _firstUnused = _nextUnused[type];
++ for(int i=0;i<type;i++)
++ if (_nextUnused[i] == type)
++ _nextUnused[i]=_nextUnused[type];
++
++ _count++;
++ return true;
++}
++
++
++//---------------------------------------------------
++// TraceCallCost
++
++TraceCallCost::TraceCallCost()
++{
++ _callCount = 0;
++}
++
++TraceCallCost::~TraceCallCost()
++{}
++
++
++TQString TraceCallCost::costString(TraceCostMapping* m)
++{
++ return TQString("%1, Calls %2")
++ .arg(TraceCost::costString(m))
++ .arg(_callCount.pretty());
++}
++
++TQString TraceCallCost::prettyCallCount()
++{
++ return _callCount.pretty();
++}
++
++void TraceCallCost::clear()
++{
++ _callCount = 0;
++ TraceCost::clear();
++}
++
++SubCost TraceCallCost::callCount()
++{
++ if (_dirty) update();
++
++ return _callCount;
++}
++
++void TraceCallCost::addCallCount(SubCost c)
++{
++ _callCount += c;
++
++ invalidate();
++}
++
++
++//---------------------------------------------------
++// TraceInclusiveCost
++
++TraceInclusiveCost::TraceInclusiveCost()
++{}
++
++TraceInclusiveCost::~TraceInclusiveCost()
++{}
++
++TQString TraceInclusiveCost::costString(TraceCostMapping* m)
++{
++ return TQString("%1, Inclusive %2")
++ .arg(TraceCost::costString(m))
++ .arg(_inclusive.costString(m));
++}
++
++void TraceInclusiveCost::clear()
++{
++ _inclusive.clear();
++ TraceCost::clear();
++}
++
++TraceCost* TraceInclusiveCost::inclusive()
++{
++ if (_dirty) update();
++
++ return &_inclusive;
++}
++
++void TraceInclusiveCost::addInclusive(TraceCost* c)
++{
++ _inclusive.addCost(c);
++
++ invalidate();
++}
++
++
++//---------------------------------------------------
++// TraceListCost
++
++TraceListCost::TraceListCost()
++{
++ _lastDep = 0;
++}
++
++TraceListCost::~TraceListCost()
++{}
++
++void TraceListCost::addDep(TraceCost* dep)
++{
++#if TRACE_ASSERTIONS
++ if (_deps.findRef(dep)>=0) {
++ qDebug("addDep: %s already in list!",
++ dep->fullName().ascii());
++ return;
++ }
++#endif
++
++ _deps.append(dep);
++ _lastDep = dep;
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(), dep->fullName().ascii(),
++ _deps.count());
++#endif
++}
++
++TraceCost* TraceListCost::findDepFromPart(TracePart* part)
++{
++ if (_lastDep && _lastDep->part() == part)
++ return _lastDep;
++
++ TraceCost* dep;
++ for (dep = _deps.first(); dep; dep = _deps.next())
++ if (dep->part() == part) {
++ _lastDep = dep;
++ return dep;
++ }
++ return 0;
++}
++
++
++void TraceListCost::update()
++{
++ if (!_dirty) return;
++
++#if TRACE_DEBUG
++ qDebug("update %s (count %d)",
++ fullName().ascii(), _deps.count());
++#endif
++
++ clear();
++ TraceCost* item;
++ for (item = _deps.first(); item; item = _deps.next()) {
++ if (onlyActiveParts())
++ if (!item->part() || !item->part()->isActive()) continue;
++
++ addCost(item);
++ }
++
++ _dirty = false;
++
++#if TRACE_DEBUG
++ qDebug(" > %s", costString(0).ascii());
++#endif
++}
++
++
++
++//---------------------------------------------------
++// TraceJumpListCost
++
++TraceJumpListCost::TraceJumpListCost()
++{
++ _lastDep = 0;
++}
++
++TraceJumpListCost::~TraceJumpListCost()
++{}
++
++void TraceJumpListCost::addDep(TraceJumpCost* dep)
++{
++#if TRACE_ASSERTIONS
++ if (_deps.findRef(dep)>=0) {
++ qDebug("addDep: %s already in list!",
++ dep->fullName().ascii());
++ return;
++ }
++#endif
++
++ _deps.append(dep);
++ _lastDep = dep;
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(), dep->fullName().ascii(),
++ _deps.count());
++#endif
++}
++
++TraceJumpCost* TraceJumpListCost::findDepFromPart(TracePart* part)
++{
++ if (_lastDep && _lastDep->part() == part)
++ return _lastDep;
++
++ TraceJumpCost* dep;
++ for (dep = _deps.first(); dep; dep = _deps.next())
++ if (dep->part() == part) {
++ _lastDep = dep;
++ return dep;
++ }
++ return 0;
++}
++
++
++void TraceJumpListCost::update()
++{
++ if (!_dirty) return;
++
++#if TRACE_DEBUG
++ qDebug("update %s (count %d)",
++ fullName().ascii(), _deps.count());
++#endif
++
++ clear();
++ TraceJumpCost* item;
++ for (item = _deps.first(); item; item = _deps.next()) {
++ if (onlyActiveParts())
++ if (!item->part() || !item->part()->isActive()) continue;
++
++ addCost(item);
++ }
++
++ _dirty = false;
++
++#if TRACE_DEBUG
++ qDebug(" > %s", costString(0).ascii());
++#endif
++}
++
++
++
++//---------------------------------------------------
++// TraceCallListCost
++
++TraceCallListCost::TraceCallListCost()
++{
++ _lastDep = 0;
++}
++
++TraceCallListCost::~TraceCallListCost()
++{}
++
++void TraceCallListCost::addDep(TraceCallCost* dep)
++{
++#if TRACE_ASSERTIONS
++ if (_deps.findRef(dep)>=0) {
++ qDebug("addDep: %s already in list!",
++ dep->fullName().ascii());
++ return;
++ }
++#endif
++
++ _deps.append(dep);
++ _lastDep = dep;
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(), dep->fullName().ascii(),
++ _deps.count());
++#endif
++}
++
++TraceCallCost* TraceCallListCost::findDepFromPart(TracePart* part)
++{
++ if (_lastDep && _lastDep->part() == part)
++ return _lastDep;
++
++ TraceCallCost* dep;
++ for (dep = _deps.first(); dep; dep = _deps.next())
++ if (dep->part() == part) {
++ _lastDep = dep;
++ return dep;
++ }
++ return 0;
++}
++
++
++void TraceCallListCost::update()
++{
++ if (!_dirty) return;
++
++#if TRACE_DEBUG
++ qDebug("update %s (count %d)",
++ fullName().ascii(), _deps.count());
++#endif
++
++ /* Without dependent cost items, assume fixed costs,
++ * i.e. don't change cost */
++ if (_deps.count()>0) {
++ clear();
++ TraceCallCost* item;
++ for (item = _deps.first(); item; item = _deps.next()) {
++ if (onlyActiveParts())
++ if (!item->part() || !item->part()->isActive()) continue;
++
++ addCost(item);
++ addCallCount(item->callCount());
++ }
++ }
++
++ _dirty = false;
++
++#if TRACE_DEBUG
++ qDebug(" > %s", costString(0).ascii());
++#endif
++}
++
++
++//---------------------------------------------------
++// TraceInclusiveListCost
++
++TraceInclusiveListCost::TraceInclusiveListCost()
++{
++ _lastDep = 0;
++}
++
++TraceInclusiveListCost::~TraceInclusiveListCost()
++{}
++
++
++void TraceInclusiveListCost::addDep(TraceInclusiveCost* dep)
++{
++#if TRACE_ASSERTIONS
++ if (_deps.findRef(dep)>=0) {
++ qDebug("addDep: %s already in list!",
++ dep->fullName().ascii());
++ return;
++ }
++#endif
++
++ _deps.append(dep);
++ _lastDep = dep;
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(), dep->fullName().ascii(),
++ _deps.count());
++#endif
++}
++
++TraceInclusiveCost* TraceInclusiveListCost::findDepFromPart(TracePart* part)
++{
++ if (_lastDep && _lastDep->part() == part)
++ return _lastDep;
++
++ TraceInclusiveCost* dep;
++ for (dep = _deps.first(); dep; dep = _deps.next())
++ if (dep->part() == part) {
++ _lastDep = dep;
++ return dep;
++ }
++ return 0;
++}
++
++void TraceInclusiveListCost::update()
++{
++ if (!_dirty) return;
++
++#if TRACE_DEBUG
++ qDebug("update %s (count %d)",
++ fullName().ascii(), _deps.count());
++#endif
++
++ clear();
++ TraceInclusiveCost* item;
++ for (item = _deps.first(); item; item = _deps.next()) {
++ if (onlyActiveParts())
++ if (!item->part() || !item->part()->isActive()) continue;
++
++ addCost(item);
++ addInclusive(item->inclusive());
++ }
++
++ _dirty = false;
++
++#if TRACE_DEBUG
++ qDebug(" > %s", costString(0).ascii());
++#endif
++}
++
++
++
++//---------------------------------------------------
++// TracePartInstrJump
++
++TracePartInstrJump::TracePartInstrJump(TraceInstrJump* instrJump,
++ TracePartInstrJump* next)
++{
++ _dep = instrJump;
++ _next = next;
++}
++
++TracePartInstrJump::~TracePartInstrJump()
++{}
++
++
++//---------------------------------------------------
++// TracePartInstrCall
++
++TracePartInstrCall::TracePartInstrCall(TraceInstrCall* instrCall)
++{
++ _dep = instrCall;
++}
++
++TracePartInstrCall::~TracePartInstrCall()
++{}
++
++
++
++//---------------------------------------------------
++// TracePartInstr
++
++TracePartInstr::TracePartInstr(TraceInstr* instr)
++{
++ _dep = instr;
++}
++
++TracePartInstr::~TracePartInstr()
++{}
++
++
++
++//---------------------------------------------------
++// TracePartLineJump
++
++TracePartLineJump::TracePartLineJump(TraceLineJump* lineJump)
++{
++ _dep = lineJump;
++}
++
++TracePartLineJump::~TracePartLineJump()
++{}
++
++
++//---------------------------------------------------
++// TracePartLineCall
++
++TracePartLineCall::TracePartLineCall(TraceLineCall* lineCall)
++{
++ _dep = lineCall;
++}
++
++TracePartLineCall::~TracePartLineCall()
++{}
++
++
++//---------------------------------------------------
++// TracePartLine
++
++TracePartLine::TracePartLine(TraceLine* line)
++{
++ _dep = line;
++}
++
++TracePartLine::~TracePartLine()
++{}
++
++
++
++
++//---------------------------------------------------
++// TracePartCall
++
++TracePartCall::TracePartCall(TraceCall* call)
++{
++ _dep = call;
++
++ _firstFixCallCost = 0;
++}
++
++TracePartCall::~TracePartCall()
++{}
++
++bool TracePartCall::isRecursion()
++{
++ return call()->isRecursion();
++}
++
++void TracePartCall::update()
++{
++#if !USE_FIXCOST
++ TraceCallListCost::update();
++#else
++
++ if (!_dirty) return;
++
++#if TRACE_DEBUG
++ qDebug("update %s", fullName().ascii());
++#endif
++
++ /* Without dependent cost items, assume fixed costs,
++ * i.e. don't change cost */
++ if (_firstFixCallCost) {
++ clear();
++ FixCallCost* item;
++ for (item = _firstFixCallCost; item; item = item->nextCostOfPartCall())
++ item->addTo(this);
++ }
++
++ _dirty = false;
++
++#if TRACE_DEBUG
++ qDebug(" > %s", costString(0).ascii());
++#endif
++
++#endif // USE_FIXCOST
++}
++
++
++//---------------------------------------------------
++// TracePartFunction
++
++TracePartFunction::TracePartFunction(TraceFunction* function,
++ TracePartObject* partObject,
++ TracePartFile *partFile)
++{
++ _dep = function;
++ _partObject = partObject;
++ _partFile = partFile;
++ _partClass = 0;
++
++ _calledCount = 0;
++ _callingCount = 0;
++ _calledContexts = 0;
++ _callingContexts = 0;
++
++ _firstFixCost = 0;
++ _firstFixJump = 0;
++}
++
++TracePartFunction::~TracePartFunction()
++{}
++
++TQString TracePartFunction::prettyCalledCount()
++{
++ return _calledCount.pretty();
++}
++
++TQString TracePartFunction::prettyCallingCount()
++{
++ return _callingCount.pretty();
++}
++
++TQString TracePartFunction::costString(TraceCostMapping* m)
++{
++ update();
++
++ TQString res = TraceInclusiveCost::costString(m);
++ res += TQString(", called from %1: %2")
++ .arg(_calledContexts).arg(prettyCalledCount());
++ res += TQString(", calling from %1: %2")
++ .arg(_callingContexts).arg(prettyCallingCount());
++
++ return res;
++}
++
++
++void TracePartFunction::addPartInstr(TracePartInstr* ref)
++{
++#if TRACE_ASSERTIONS
++ if (_partInstr.findRef(ref)>=0) {
++ qDebug("TracePartFunction::addPartInstr: %s already in list!",
++ ref->name().ascii());
++ return;
++ }
++#endif
++
++ _partInstr.append(ref);
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(), ref->fullName().ascii(),
++ _partInstr.count());
++#endif
++}
++
++
++void TracePartFunction::addPartLine(TracePartLine* ref)
++{
++#if TRACE_ASSERTIONS
++ if (_partLines.findRef(ref)>=0) {
++ qDebug("TracePartFunction::addPartLine: %s already in list!",
++ ref->name().ascii());
++ return;
++ }
++#endif
++
++ _partLines.append(ref);
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(), ref->fullName().ascii(),
++ _partLines.count());
++#endif
++}
++
++
++void TracePartFunction::addPartCaller(TracePartCall* ref)
++{
++#if TRACE_ASSERTIONS
++ if (_partCallers.findRef(ref)>=0) {
++ qDebug("TracePartFunction::addPartCaller: %s already in list!",
++ ref->name().ascii());
++ return;
++ }
++#endif
++
++ _partCallers.append(ref);
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added Caller\n %s (now %d)",
++ fullName().ascii(), ref->fullName().ascii(),
++ _partCallers.count());
++#endif
++}
++
++
++void TracePartFunction::addPartCalling(TracePartCall* ref)
++{
++#if TRACE_ASSERTIONS
++ if (_partCallings.findRef(ref)>=0) {
++ qDebug("TracePartFunction::addPartCalling: %s already in list!",
++ ref->name().ascii());
++ return;
++ }
++#endif
++
++ _partCallings.append(ref);
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added Calling\n %s (now %d)",
++ fullName().ascii(), ref->fullName().ascii(),
++ _partCallings.count());
++#endif
++}
++
++SubCost TracePartFunction::calledCount()
++{
++ if (_dirty) update();
++
++ return _calledCount;
++}
++
++int TracePartFunction::calledContexts()
++{
++ if (_dirty) update();
++
++ return _calledContexts;
++}
++
++SubCost TracePartFunction::callingCount()
++{
++ if (_dirty) update();
++
++ return _callingCount;
++}
++
++
++int TracePartFunction::callingContexts()
++{
++ if (_dirty) update();
++
++ return _callingContexts;
++}
++
++
++void TracePartFunction::update()
++{
++ if (!_dirty) return;
++
++#if TRACE_DEBUG
++ qDebug("TracePartFunction::update %s (Callers %d, Callings %d, lines %d)",
++ name().ascii(), _partCallers.count(), _partCallings.count(),
++ _partLines.count());
++#endif
++
++ _calledCount = 0;
++ _callingCount = 0;
++ _calledContexts = 0;
++ _callingContexts = 0;
++
++ // calculate additional cost metrics
++ TracePartCall *caller, *calling;
++ for (caller=_partCallers.first();caller;caller=_partCallers.next()) {
++
++ // FIXME
++ if (caller->subCost(0)>0)
++ _calledContexts++;
++
++ SubCost c = caller->callCount();
++ if (c>0) {
++ _calledCount += c;
++ }
++ }
++ for (calling=_partCallings.first();calling;calling=_partCallings.next()) {
++ // FIXME
++ if (calling->subCost(0)>0)
++ _callingContexts++;
++
++ SubCost c = calling->callCount();
++ if (c>0) {
++ _callingCount += c;
++ }
++ }
++
++ // self cost
++#if !USE_FIXCOST
++ if (_partLines.count()>0) {
++ TraceCost::clear();
++
++ TracePartLine* line;
++ for (line = _partLines.first(); line; line = _partLines.next())
++ addCost(line);
++ }
++#else
++ if (_firstFixCost) {
++ TraceCost::clear();
++
++ FixCost* item;
++ for (item = _firstFixCost; item; item = item->nextCostOfPartFunction())
++ item->addTo(this);
++ }
++#endif
++
++
++ /* There are two possibilities to calculate inclusive cost:
++ * 1) sum of call costs to this function
++ * 2) sum of call costs from this function + self cost
++ *
++ * 1) is wrong if a function was called spontaneous, but also by a call.
++ * This eventually can happen with thread/process startup functions,
++ * and signal handlers.
++ *
++ * 2) is wrong with "skipped PLT" and the calltree skin, because
++ * cost of PLT is attributed to called function (?)
++ *
++ * For now, do 1) if there are callers, otherwise 2).
++ * Should this be fixed to take the maximum of 1) and 2) ?
++ */
++ _inclusive.clear();
++ if (_calledCount>0) {
++ // inclusive cost: if possible, use caller sums
++ for (caller=_partCallers.first();caller;caller=_partCallers.next()) {
++ // detect simple recursion (no cycle)
++ if (caller->isRecursion()) continue;
++
++ addInclusive(caller);
++ }
++ }
++ else {
++ // without caller info, use calling sum + line costs
++ for (calling=_partCallings.first();calling;calling=_partCallings.next()) {
++ // detect simple recursion (no cycle)
++ if (calling->isRecursion()) continue;
++
++ addInclusive(calling);
++ }
++ _dirty = false; // don't recurse!
++ addInclusive(this);
++ }
++
++ _dirty = false;
++
++#if TRACE_DEBUG
++ qDebug(" > %s", costString(0).ascii());
++#endif
++}
++
++
++
++//---------------------------------------------------
++// TracePartClass
++
++TracePartClass::TracePartClass(TraceClass* cls)
++{
++ _dep = cls;
++}
++
++TracePartClass::~TracePartClass()
++{}
++
++TQString TracePartClass::prettyName() const
++{
++ return TQString("%1 from %2")
++ .arg( _dep->name().isEmpty() ? TQString("(global)") : _dep->name())
++ .arg(part()->name());
++}
++
++//---------------------------------------------------
++// TracePartFile
++
++TracePartFile::TracePartFile(TraceFile* file)
++{
++ _dep = file;
++}
++
++TracePartFile::~TracePartFile()
++{}
++
++
++//---------------------------------------------------
++// TracePartObject
++
++TracePartObject::TracePartObject(TraceObject* object)
++{
++ _dep = object;
++}
++
++TracePartObject::~TracePartObject()
++{}
++
++
++
++
++//---------------------------------------------------
++// TraceInstrJump
++
++TraceInstrJump::TraceInstrJump(TraceInstr* instrFrom, TraceInstr* instrTo,
++ bool isCondJump)
++{
++ _first = 0;
++
++ _instrFrom = instrFrom;
++ _instrTo = instrTo;
++ _isCondJump = isCondJump;
++}
++
++TraceInstrJump::~TraceInstrJump()
++{
++ // we are the owner of the TracePartInstrJump's generated in our factory
++ TracePartInstrJump* item = _first, *next;
++ while(item) {
++ next = item->next();
++ delete item;
++ item = next;
++ }
++}
++
++TracePartInstrJump* TraceInstrJump::partInstrJump(TracePart* part)
++{
++ static TracePartInstrJump* item = 0;
++
++ // shortcut
++ if (item && (item->instrJump()==this) && (item->part() == part)) return item;
++
++ for(item = _first; item; item = item->next())
++ if (item->part() == part) break;
++
++ if (!item) {
++ item = new TracePartInstrJump(this, _first);
++ item->setPosition(part);
++ _first = item;
++ }
++ return item;
++}
++
++void TraceInstrJump::update()
++{
++ if (!_dirty) return;
++
++ clear();
++ TracePartInstrJump* item;
++ for (item = _first; item; item = item->next()) {
++ if (!item->part() || !item->part()->isActive()) continue;
++
++ addCost(item);
++ }
++ _dirty = false;
++
++#if TRACE_DEBUG
++ qDebug("updated %s", fullName().ascii());
++#endif
++
++#if TRACE_DEBUG
++ qDebug(" > %s", costString(0).ascii());
++#endif
++}
++
++TQString TraceInstrJump::name() const
++{
++ return TQString("jump at 0x%1 to 0x%2")
++ .arg(_instrFrom->addr().toString())
++ .arg(_instrTo->addr().toString());
++}
++
++
++//---------------------------------------------------
++// TraceInstrJumpList
++
++
++int TraceInstrJumpList::compareItems ( Item item1, Item item2 )
++{
++ TraceInstrJump* ij1 = (TraceInstrJump*) item1;
++ TraceInstrJump* ij2 = (TraceInstrJump*) item2;
++
++ Addr addr1Low = ij1->instrFrom()->addr();
++ Addr addr2Low = ij2->instrFrom()->addr();
++ Addr addr1High = ij1->instrTo()->addr();
++ Addr addr2High = ij2->instrTo()->addr();
++ Addr t;
++
++ if (addr1Low > addr1High) {
++ t = addr1Low;
++ addr1Low = addr1High;
++ addr1High = t;
++ }
++
++ if (addr2Low > addr2High) {
++ t = addr2Low;
++ addr2Low = addr2High;
++ addr2High = t;
++ }
++
++ if (_sortLow) {
++ // we sort according to smallest instruction address
++ if (addr1Low != addr2Low) return (addr1Low > addr2Low) ? 1:-1;
++ // jump ends come before jump starts
++ if (addr1Low == ij1->instrTo()->addr()) return -1;
++ if (addr2Low == ij2->instrTo()->addr()) return 1;
++ return (addr1High > addr2High) ? 1:-1;
++ }
++
++ // we sort according to highest instruction address
++ if (addr1High != addr2High) return (addr1High > addr2High) ? 1:-1;
++ // jump ends come before jump starts
++ if (addr1High == ij1->instrTo()->addr()) return -1;
++ if (addr2High == ij2->instrTo()->addr()) return 1;
++ return (addr1Low > addr2Low) ? 1:-1;
++}
++
++
++//---------------------------------------------------
++// TraceLineJump
++
++TraceLineJump::TraceLineJump(TraceLine* lineFrom, TraceLine* lineTo,
++ bool isCondJump)
++{
++ // we are the owner of TracePartLineJump's generated in our factory
++ _deps.setAutoDelete(true);
++
++ _lineFrom = lineFrom;
++ _lineTo = lineTo;
++ _isCondJump = isCondJump;
++}
++
++TraceLineJump::~TraceLineJump()
++{}
++
++
++TracePartLineJump* TraceLineJump::partLineJump(TracePart* part)
++{
++ TracePartLineJump* item = (TracePartLineJump*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartLineJump(this);
++ item->setPosition(part);
++ addDep(item);
++ }
++ return item;
++}
++
++
++TQString TraceLineJump::name() const
++{
++ return TQString("jump at %1 to %2")
++ .arg(_lineFrom->prettyName())
++ .arg(_lineTo->prettyName());
++}
++
++
++//---------------------------------------------------
++// TraceLineJumpList
++
++
++int TraceLineJumpList::compareItems ( Item item1, Item item2 )
++{
++ TraceLineJump* lj1 = (TraceLineJump*) item1;
++ TraceLineJump* lj2 = (TraceLineJump*) item2;
++
++ uint line1Low = lj1->lineFrom()->lineno();
++ uint line2Low = lj2->lineFrom()->lineno();
++ uint line1High = lj1->lineTo()->lineno();
++ uint line2High = lj2->lineTo()->lineno();
++ uint t;
++
++ if (line1Low > line1High) {
++ t = line1Low; line1Low = line1High; line1High = t;
++ }
++ if (line2Low > line2High) {
++ t = line2Low; line2Low = line2High; line2High = t;
++ }
++
++ if (_sortLow) {
++ // we sort according to smallest line number
++ if (line1Low != line2Low) return line1Low - line2Low;
++ // jump ends come before jump starts
++ if (line1Low == lj1->lineTo()->lineno()) return -1;
++ if (line2Low == lj2->lineTo()->lineno()) return 1;
++ return line1High - line2High;
++ }
++
++ // we sort according to highest line number
++ if (line1High != line2High) return line1High - line2High;
++ // jump ends come before jump starts
++ if (line1High == lj1->lineTo()->lineno()) return -1;
++ if (line2High == lj2->lineTo()->lineno()) return 1;
++ return line1Low - line2Low;
++}
++
++
++//---------------------------------------------------
++// TraceInstrCall
++
++TraceInstrCall::TraceInstrCall(TraceCall* call, TraceInstr* instr)
++{
++ // we are the owner of TracePartInstrCall's generated in our factory
++ _deps.setAutoDelete(true);
++
++ _call = call;
++ _instr = instr;
++}
++
++TraceInstrCall::~TraceInstrCall()
++{}
++
++
++TracePartInstrCall* TraceInstrCall::partInstrCall(TracePart* part,
++ TracePartCall*)
++{
++ TracePartInstrCall* item = (TracePartInstrCall*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartInstrCall(this);
++ item->setPosition(part);
++ addDep(item);
++ // instruction calls are not registered in function calls
++ // as together with line calls calls are duplicated
++ //partCall->addDep(item);
++ }
++ return item;
++}
++
++
++TQString TraceInstrCall::name() const
++{
++ return TQString("%1 at %2").arg(_call->name()).arg(_instr->name());
++}
++
++
++//---------------------------------------------------
++// TraceLineCall
++
++TraceLineCall::TraceLineCall(TraceCall* call, TraceLine* line)
++{
++ // we are the owner of TracePartLineCall's generated in our factory
++ _deps.setAutoDelete(true);
++
++ _call = call;
++ _line = line;
++}
++
++TraceLineCall::~TraceLineCall()
++{}
++
++
++TracePartLineCall* TraceLineCall::partLineCall(TracePart* part,
++ TracePartCall* partCall)
++{
++ TracePartLineCall* item = (TracePartLineCall*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartLineCall(this);
++ item->setPosition(part);
++ addDep(item);
++ partCall->addDep(item);
++ }
++ return item;
++}
++
++
++TQString TraceLineCall::name() const
++{
++ return TQString("%1 at %2").arg(_call->name()).arg(_line->name());
++}
++
++
++//---------------------------------------------------
++// TraceCall
++
++TraceCall::TraceCall(TraceFunction* caller, TraceFunction* called)
++{
++ // we are the owner of all items generated in our factory
++ _deps.setAutoDelete(true);
++ _lineCalls.setAutoDelete(true);
++
++ _caller = caller;
++ _called = called;
++}
++
++
++TraceCall::~TraceCall()
++{}
++
++TracePartCall* TraceCall::partCall(TracePart* part,
++ TracePartFunction* partCaller,
++ TracePartFunction* partCalling)
++{
++ TracePartCall* item = (TracePartCall*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartCall(this);
++ item->setPosition(part);
++ addDep(item);
++ partCaller->addPartCalling(item);
++ partCalling->addPartCaller(item);
++ }
++ return item;
++}
++
++TraceInstrCall* TraceCall::instrCall(TraceInstr* i)
++{
++ TraceInstrCall* icall;
++ for (icall=_instrCalls.first();icall;icall=_instrCalls.next())
++ if (icall->instr() == i)
++ break;
++
++ if (!icall) {
++ icall = new TraceInstrCall(this, i);
++
++ _instrCalls.append(icall);
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("Created %s [TraceCall::instrCall]", icall->fullName().ascii());
++#endif
++ i->addInstrCall(icall);
++ }
++ return icall;
++}
++
++
++TraceLineCall* TraceCall::lineCall(TraceLine* l)
++{
++ TraceLineCall* lcall;
++ for (lcall=_lineCalls.first();lcall;lcall=_lineCalls.next())
++ if (lcall->line() == l)
++ break;
++
++ if (!lcall) {
++ lcall = new TraceLineCall(this, l);
++
++ _lineCalls.append(lcall);
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("Created %s [TraceCall::lineCall]", lcall->fullName().ascii());
++#endif
++ l->addLineCall(lcall);
++ }
++ return lcall;
++}
++
++
++void TraceCall::invalidateDynamicCost()
++{
++ TraceLineCall* lc;
++ for (lc=_lineCalls.first();lc;lc=_lineCalls.next())
++ lc->invalidate();
++
++ TraceInstrCall* ic;
++ for (ic=_instrCalls.first();ic;ic=_instrCalls.next())
++ ic->invalidate();
++
++ invalidate();
++}
++
++
++TQString TraceCall::name() const
++{
++ return TQString("%1 => %2")
++ .arg(_caller->name())
++ .arg(_called->name());
++}
++
++int TraceCall::inCycle()
++{
++ if (!_caller || !_called) return 0;
++ if (!_caller->cycle()) return 0;
++ if (_caller == _caller->cycle()) return 0;
++ if (_caller->cycle() != _called->cycle()) return 0;
++
++ return _caller->cycle()->cycleNo();
++}
++
++void TraceCall::update()
++{
++ if (!_dirty) return;
++
++ // special handling for cycles
++ if (_caller && _caller->cycle() && _caller==_caller->cycle()) {
++
++ // we have no part calls: use inclusive cost of called function
++ clear();
++ if (_called)
++ addCost(_called->inclusive());
++ _dirty = false;
++ return;
++ }
++
++ TraceCallListCost::update();
++}
++
++TraceFunction* TraceCall::caller(bool /*skipCycle*/) const
++{
++ return _caller;
++}
++
++TraceFunction* TraceCall::called(bool skipCycle) const
++{
++ if (!skipCycle && _called) {
++ // if this is a call to a cycle member from outside of the cycle,
++ // fake it to be a call to the whole cycle
++ if (_called->cycle() && _caller &&
++ (_caller->cycle() != _called->cycle()))
++ return _called->cycle();
++ }
++
++ return _called;
++}
++
++TQString TraceCall::callerName(bool skipCycle) const
++{
++ if (!_caller) return i18n("(no caller)");
++
++ if (!skipCycle) {
++ // if this call goes into a cycle, add the entry function
++ TraceFunctionCycle* c = _called->cycle();
++ if (c && _caller && (_caller->cycle() != c)) {
++ TQString via = _called->prettyName();
++ return i18n("%1 via %2").arg(_caller->prettyName()).arg(via);
++ }
++ }
++
++ return _caller->prettyName();
++}
++
++TQString TraceCall::calledName(bool skipCycle) const
++{
++ if (!_called) return i18n("(no callee)");
++
++ if (!skipCycle) {
++ // if this call goes into a cycle, add the entry function
++ TraceFunctionCycle* c = _called->cycle();
++ if (c && _caller && (_caller->cycle() != c)) {
++ // HACK to get rid of cycle postfix...
++ _called->setCycle(0);
++ TQString via = _called->prettyName();
++ _called->setCycle(c);
++ return i18n("%1 via %2").arg(c->name()).arg(via);
++ }
++ }
++ return _called->prettyName();
++}
++
++
++//---------------------------------------------------
++// TraceInstr
++
++TraceInstr::TraceInstr()
++{
++ // we are the owner of TracePartInstr's generated in our factory
++ _deps.setAutoDelete(true);
++ _instrJumps.setAutoDelete(true);
++
++ _addr = 0;
++ _line = 0;
++ _function = 0;
++}
++
++TraceInstr::~TraceInstr()
++{}
++
++bool TraceInstr::hasCost(TraceCostType* ct)
++{
++ bool res = subCost(ct) > 0;
++ if (!res) {
++ TraceInstrCall* ic;
++ for(ic=_instrCalls.first();ic;ic=_instrCalls.next())
++ if (ic->subCost(ct) > 0) break;
++ res = (ic != 0);
++ if (!res) {
++ TraceInstrJump* ij;
++ for(ij=_instrJumps.first();ij;ij=_instrJumps.next())
++ if (ij->executedCount() > 0) break;
++ res = (ij != 0);
++ }
++ }
++
++ return res;
++}
++
++TracePartInstr* TraceInstr::partInstr(TracePart* part,
++ TracePartFunction* partFunction)
++{
++ TracePartInstr* item = (TracePartInstr*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartInstr(this);
++ item->setPosition(part);
++ addDep(item);
++ //part->addDep(item);
++ partFunction->addPartInstr(item);
++ }
++ return item;
++}
++
++TraceInstrJump* TraceInstr::instrJump(TraceInstr* to, bool isJmpCond)
++{
++ TraceInstrJump* jump;
++ for (jump=_instrJumps.first();jump;jump=_instrJumps.next())
++ if (jump->instrTo() == to)
++ break;
++
++ if (!jump) {
++ jump = new TraceInstrJump(this, to, isJmpCond);
++
++ _instrJumps.append(jump);
++ }
++ return jump;
++}
++
++
++
++void TraceInstr::addInstrCall(TraceInstrCall* instrCall)
++{
++#if TRACE_ASSERTIONS
++ if (_instrCalls.findRef(instrCall)>=0) return;
++
++ if (instrCall->instr() != this) {
++ qDebug("Can't add instruction call to another instruction!");
++ return;
++ }
++#endif
++
++ _instrCalls.append(instrCall);
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(),
++ instrCall->fullName().ascii(), _instrCalls.count());
++#endif
++}
++
++
++TQString TraceInstr::name() const
++{
++ return TQString("0x%1").arg(_addr.toString());
++}
++
++TQString TraceInstr::prettyName() const
++{
++ return TQString("0x%1").arg(_addr.toString());
++}
++
++
++//---------------------------------------------------
++// TraceLine
++
++TraceLine::TraceLine()
++{
++ // we are the owner of TracePartLine's generated in our factory
++ _deps.setAutoDelete(true);
++ _lineJumps.setAutoDelete(true);
++
++ _lineno = 0;
++ _sourceFile = 0;
++}
++
++TraceLine::~TraceLine()
++{}
++
++bool TraceLine::hasCost(TraceCostType* ct)
++{
++ bool res = subCost(ct) > 0;
++ if (!res) {
++ TraceLineCall* lc;
++ for(lc=_lineCalls.first();lc;lc=_lineCalls.next())
++ if (lc->subCost(ct) > 0) break;
++ res = (lc != 0);
++ if (!res) {
++ TraceLineJump* lj;
++ for(lj=_lineJumps.first();lj;lj=_lineJumps.next())
++ if (lj->executedCount() > 0) break;
++ res = (lj != 0);
++ }
++ }
++
++ return res;
++}
++
++TracePartLine* TraceLine::partLine(TracePart* part,
++ TracePartFunction* partFunction)
++{
++ TracePartLine* item = (TracePartLine*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartLine(this);
++ item->setPosition(part);
++ addDep(item);
++#if !USE_FIXCOST
++ part->addDep(item);
++#endif
++ partFunction->addPartLine(item);
++ }
++ return item;
++}
++
++TraceLineJump* TraceLine::lineJump(TraceLine* to, bool isJmpCond)
++{
++ TraceLineJump* jump;
++ for (jump=_lineJumps.first();jump;jump=_lineJumps.next())
++ if (jump->lineTo() == to)
++ break;
++
++ if (!jump) {
++ jump = new TraceLineJump(this, to, isJmpCond);
++
++ _lineJumps.append(jump);
++ }
++ return jump;
++}
++
++
++void TraceLine::addLineCall(TraceLineCall* lineCall)
++{
++#if TRACE_ASSERTIONS
++ if (_lineCalls.findRef(lineCall)>=0) return;
++
++ if (lineCall->line() != this) {
++ qDebug("Can't add line call to another line!");
++ return;
++ }
++#endif
++
++ TraceFunction* caller = lineCall->call()->caller();
++ TraceFunction* function = _sourceFile->function();
++ if (caller != function) {
++ // We regard 2 functions as the same if they have
++ // same class, name, object
++ if ((caller->cls() != function->cls()) ||
++ (caller->name() != function->name()) ||
++ (caller->object() != function->object())) {
++
++ qDebug("ERROR: Adding line call, line %d\n of %s to\n %s ?!",
++ lineCall->line()->lineno(),
++ caller->info().ascii(), function->info().ascii());
++ }
++ }
++
++ _lineCalls.append(lineCall);
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(),
++ lineCall->fullName().ascii(), _lineCalls.count());
++#endif
++}
++
++
++TQString TraceLine::name() const
++{
++ TQString fileShortName = _sourceFile->file()->shortName();
++ if (fileShortName.isEmpty())
++ return i18n("(unknown)");
++
++ return TQString("%1:%2")
++ .arg(fileShortName).arg(_lineno);
++}
++
++TQString TraceLine::prettyName() const
++{
++ return TQString("%1 [%2]")
++ .arg(name()).arg(_sourceFile->function()->prettyName());
++}
++
++//---------------------------------------------------
++// TraceCostItem
++
++TraceCostItem::TraceCostItem()
++{
++}
++
++TraceCostItem::~TraceCostItem()
++{}
++
++
++//---------------------------------------------------
++// TraceFunctionSource
++
++TraceFunctionSource::TraceFunctionSource(TraceFunction* function,
++ TraceFile* file)
++{
++ _file = file;
++ _function = function;
++
++ // the function is dependent from our cost sum
++ _dep = _function;
++
++ _lineMap = 0;
++ _lineMapFilled = false;
++ _line0 = 0;
++}
++
++TraceFunctionSource::~TraceFunctionSource()
++{
++ if (_lineMap) delete _lineMap;
++ if (_line0) delete _line0;
++}
++
++TQString TraceFunctionSource::name() const
++{
++ return TQString("%1 for %2").arg(_file->name()).arg(_function->name());
++}
++
++uint TraceFunctionSource::firstLineno()
++{
++ // lazy generate the map if not done up to now
++ TraceLineMap* map = lineMap();
++ // ignore line 0 here
++ if (!map || map->count() == 0) return 0;
++ TraceLineMap::Iterator it = map->begin();
++ return (*it).lineno();
++}
++
++uint TraceFunctionSource::lastLineno()
++{
++ // lazy generate the map if not done up to now
++ TraceLineMap* map = lineMap();
++ // ignore line 0 here
++ if (!map || map->count() == 0) return 0;
++ TraceLineMap::Iterator it = map->end();
++ --it;
++ return (*it).lineno();
++}
++
++/* factory */
++TraceLine* TraceFunctionSource::line(uint lineno, bool createNew)
++{
++ if (lineno == 0) {
++ if (!_line0) {
++ if (!createNew) return 0;
++ _line0 = new TraceLine;
++ _line0->setSourceFile(this);
++ _line0->setLineno(0);
++ }
++ return _line0;
++ }
++
++ if (!createNew) {
++ if (!_lineMap) return 0;
++ TraceLineMap::Iterator it = _lineMap->find(lineno);
++ if (it == _lineMap->end()) return 0;
++ return &(it.data());
++ }
++
++ if (!_lineMap) _lineMap = new TraceLineMap;
++
++ TraceLine& l = (*_lineMap)[lineno];
++ if (!l.isValid()) {
++ l.setSourceFile(this);
++ l.setLineno(lineno);
++
++#if TRACE_DEBUG
++ qDebug("Created %s [TraceFunctionSource::line]",
++ l.fullName().ascii());
++#endif
++ }
++ return &l;
++}
++
++void TraceFunctionSource::update()
++{
++ if (!_dirty) return;
++
++ clear();
++
++ // no need to create lineMap if not already created
++ if (_lineMap) {
++ TraceLineMap::Iterator lit;
++ for ( lit = _lineMap->begin();
++ lit != _lineMap->end(); ++lit )
++ addCost( &(*lit) );
++ }
++
++ _dirty = false;
++}
++
++void TraceFunctionSource::invalidateDynamicCost()
++{
++ // no need to create lineMap if not already created
++ if (_lineMap) {
++ TraceLineMap::Iterator lit;
++ for ( lit = _lineMap->begin();
++ lit != _lineMap->end(); ++lit )
++ (*lit).invalidate();
++ }
++
++ invalidate();
++}
++
++TraceLineMap* TraceFunctionSource::lineMap()
++{
++#if USE_FIXCOST
++
++ if (_lineMapFilled) return _lineMap;
++ _lineMapFilled = true;
++ if (!_lineMap)
++ _lineMap = new TraceLineMap;
++
++ TraceLine* l = 0;
++ TracePartLine* pl = 0;
++ TraceLineCall* lc = 0;
++ TracePartLineCall* plc = 0;
++
++ /* go over all part objects for this function, and
++ * - build TraceLines (the line map) using FixCost objects
++ * - build TraceJumpLines using FixJump objects
++ */
++ TraceInclusiveCostList pfList = _function->deps();
++ TracePartFunction* pf = (TracePartFunction*) pfList.first();
++ for(; pf; pf = (TracePartFunction*) pfList.next()) {
++
++ if (0) qDebug("PartFunction %s:%d",
++ pf->function()->name().ascii(), pf->part()->partNumber());
++
++ FixCost* fc = pf->firstFixCost();
++ for(; fc; fc = fc->nextCostOfPartFunction()) {
++ if (fc->line() == 0) continue;
++ if (fc->functionSource() != this) continue;
++
++ if (!l || l->lineno() != fc->line()) {
++ l = &(*_lineMap)[fc->line()];
++ if (!l->isValid()) {
++ l->setSourceFile(this);
++ l->setLineno(fc->line());
++ }
++ pl = 0;
++ }
++ if (!pl || pl->part() != fc->part())
++ pl = l->partLine(fc->part(), pf);
++ fc->addTo(pl);
++ }
++
++ TraceLine* to = 0;
++ TraceLineJump* lj;
++ TracePartLineJump* plj;
++ FixJump* fj = pf->firstFixJump();
++ for(; fj; fj = fj->nextJumpOfPartFunction()) {
++ if (fj->line() == 0) continue;
++ if (fj->source() != this) continue;
++ if (!fj->targetSource()) {
++ // be robust against buggy loaders
++ continue;
++ }
++
++ // don't display jumps to same or following line
++ if ((fj->line() == fj->targetLine()) ||
++ (fj->line()+1 == fj->targetLine())) continue;
++
++ if (!l || l->lineno() != fj->line()) {
++ l = &(*_lineMap)[fj->line()];
++ if (!l->isValid()) {
++ l->setSourceFile(this);
++ l->setLineno(fj->line());
++ }
++ }
++
++ to = fj->targetSource()->line(fj->targetLine(), true);
++
++ lj = l->lineJump(to, fj->isCondJump());
++ plj = lj->partLineJump(fj->part());
++
++ fj->addTo(plj);
++ }
++
++
++ TracePartCallList pcList = pf->partCallings();
++ TracePartCall* pc = pcList.first();
++ for(; pc; pc = pcList.next()) {
++
++ if (0) qDebug("PartCall %s:%d",
++ pc->call()->name().ascii(),
++ pf->part()->partNumber());
++
++ FixCallCost* fcc = pc->firstFixCallCost();
++ for(; fcc; fcc = fcc->nextCostOfPartCall()) {
++ if (fcc->line() == 0) continue;
++ if (fcc->functionSource() != this) continue;
++
++ if (!l || l->lineno() != fcc->line()) {
++ l = &(*_lineMap)[fcc->line()];
++ if (!l->isValid()) {
++ l->setSourceFile(this);
++ l->setLineno(fcc->line());
++ }
++ }
++ if (!lc || lc->call() != pc->call() || lc->line() != l) {
++ lc = pc->call()->lineCall(l);
++ plc = 0;
++ }
++ if (!plc || plc->part() != fcc->part())
++ plc = lc->partLineCall(fcc->part(), pc);
++
++ fcc->addTo(plc);
++ if (0) qDebug("Add FixCallCost %s:%d/0x%s, CallCount %s",
++ fcc->functionSource()->file()->shortName().ascii(),
++ fcc->line(), fcc->addr().toString().ascii(),
++ fcc->callCount().pretty().ascii());
++ }
++ }
++ }
++
++#endif
++
++ return _lineMap;
++}
++
++
++
++//---------------------------------------------------
++// TraceAssoziation
++
++TraceAssoziation::TraceAssoziation()
++{
++ _function = 0;
++ _valid = false;
++}
++
++TraceAssoziation::~TraceAssoziation()
++{
++ // don't delete from TraceFunction
++ if (_function) _function->removeAssoziation(this);
++}
++
++bool TraceAssoziation::isAssoziated()
++{
++ if (!_function) return false;
++
++ return _function->assoziation(rtti())==this;
++}
++
++bool TraceAssoziation::setFunction(TraceFunction* f)
++{
++ if (_function == f)
++ return isAssoziated();
++
++ if (_function) {
++ // don't delete ourself
++ _function->removeAssoziation(this);
++ }
++
++ _function = f;
++ if (f && f->assoziation(rtti()) == 0) {
++ f->addAssoziation(this);
++ return true;
++ }
++ return false;
++}
++
++void TraceAssoziation::clear(TraceData* d, int rtti)
++{
++ TraceFunctionMap::Iterator it;
++ for ( it = d->functionMap().begin();
++ it != d->functionMap().end(); ++it )
++ (*it).removeAssoziation(rtti);
++}
++
++void TraceAssoziation::invalidate(TraceData* d, int rtti)
++{
++ TraceFunctionMap::Iterator it;
++ for ( it = d->functionMap().begin();
++ it != d->functionMap().end(); ++it )
++ (*it).invalidateAssoziation(rtti);
++}
++
++
++//---------------------------------------------------
++// TraceFunction
++
++TraceFunction::TraceFunction()
++{
++ _object = 0;
++ _file = 0;
++ _cls = 0;
++ _cycle = 0;
++
++ // we are the owner of items generated in our factory
++ _deps.setAutoDelete(true);
++ _callings.setAutoDelete(true);
++ _sourceFiles.setAutoDelete(true);
++
++ _calledCount = 0;
++ _callingCount = 0;
++ _calledContexts = 0;
++ _callingContexts = 0;
++
++ _instrMap = 0;
++ _instrMapFilled = false;
++}
++
++
++TraceFunction::~TraceFunction()
++{
++ _assoziations.setAutoDelete(true);
++ _assoziations.clear();
++
++ if (_instrMap) delete _instrMap;
++}
++
++// no unique check is done!
++void TraceFunction::addAssoziation(TraceAssoziation* a)
++{
++ if (!a) return;
++ _assoziations.append(a);
++}
++
++void TraceFunction::removeAssoziation(TraceAssoziation* a)
++{
++ _assoziations.removeRef(a);
++}
++
++void TraceFunction::removeAssoziation(int rtti, bool reallyDelete)
++{
++ if (rtti==0) {
++ if (reallyDelete)
++ _assoziations.setAutoDelete(true);
++ _assoziations.clear();
++ _assoziations.setAutoDelete(false);
++ return;
++ }
++
++ TraceAssoziation* a;
++ for (a=_assoziations.first();a;a=_assoziations.next())
++ if (a->rtti() == rtti) {
++ if (reallyDelete) delete a;
++ _assoziations.remove();
++ return;
++ }
++}
++
++void TraceFunction::invalidateAssoziation(int rtti)
++{
++ TraceAssoziation* a;
++ for (a=_assoziations.first();a;a=_assoziations.next())
++ if ((rtti==0) || (a->rtti() == rtti))
++ a->invalidate();
++}
++
++TraceAssoziation* TraceFunction::assoziation(int rtti)
++{
++ TraceAssoziation* a;
++ for (a=_assoziations.first();a;a=_assoziations.next())
++ if (a->rtti() == rtti)
++ return a;
++ return 0;
++}
++
++
++// helper for prettyName
++bool TraceFunction::isUniquePrefix(TQString prefix) const
++{
++ TraceFunctionMap::ConstIterator it, it2;
++ it = it2 = _myMapIterator;
++ if (it != data()->functionBeginIterator()) {
++ it2--;
++ if ((*it2).name().startsWith(prefix)) return false;
++ }
++ if (it != data()->functionEndIterator()) {
++ it++;
++ if ((*it).name().startsWith(prefix)) return false;
++ }
++ return true;
++}
++
++
++TQString TraceFunction::prettyName() const
++{
++ TQString res = _name;
++
++ if (_name.isEmpty())
++ return i18n("(unknown)");
++
++ int p = _name.find('(');
++ if (p>0) {
++ // handle C++ "operator()" correct
++ if ((_name[p+1] == ')') && (_name[p+2] == '(')) p+=2;
++
++ // we have a C++ symbol with argument types:
++ // check for unique function name (inclusive '(' !)
++ if (isUniquePrefix(_name.left(p+1)))
++ res = _name.left(p);
++ }
++
++ // cycle members
++ if (_cycle) {
++ if (_cycle != this)
++ res = TQString("%1 <cycle %2>").arg(res).arg(_cycle->cycleNo());
++ else
++ res = TQString("<cycle %2>").arg(_cycle->cycleNo());
++ }
++
++
++ return res;
++}
++
++/*
++ * Returns location string: ELF object and source file(s).
++ */
++TQString TraceFunction::location(int maxFiles) const
++{
++ TQString loc;
++
++ // add object file with address range
++ if (_object) {
++ loc = _object->shortName();
++
++#if 0
++ uint from = firstAddress();
++ uint to = lastAddress();
++ if (from != 0 && to != 0) {
++ if (from == to)
++ loc += TQString(" (0x%1)").arg(to, 0, 16);
++ else
++ loc += TQString(" (0x%1-0x%2)").arg(from, 0, 16).arg(to, 0, 16);
++ }
++#endif
++ }
++
++ // add all source files
++ int filesAdded = 0;
++ TraceFunctionSourceList list = _sourceFiles;
++ TraceFunctionSource* sourceFile = list.first();
++ for (;sourceFile;sourceFile=list.next()) {
++ if (!sourceFile->file() ||
++ (sourceFile->file()->name().isEmpty()) )
++ continue;
++
++ if (!loc.isEmpty())
++ loc += (filesAdded>0) ? ", " : ": ";
++ filesAdded++;
++
++ if ((maxFiles>0) && (filesAdded>maxFiles)) {
++ loc += "...";
++ break;
++ }
++ loc += sourceFile->file()->shortName();
++
++#if 0
++ from = sourceFile->firstLineno();
++ to = sourceFile->lastLineno();
++ if (from != 0 && to != 0) {
++ if (from == to)
++ loc += TQString(" (%1)").arg(to);
++ else
++ loc += TQString(" (%1-%2)").arg(from).arg(to);
++ }
++#endif
++ }
++
++ return loc;
++}
++
++// pretty version is allowed to mangle the string...
++TQString TraceFunction::prettyLocation(int maxFiles) const
++{
++ TQString l = location(maxFiles);
++ if (l.isEmpty()) return i18n("(unknown)");
++
++ return l;
++}
++
++void TraceFunction::addPrettyLocation(TQString& s, int maxFiles) const
++{
++ TQString l = location(maxFiles);
++ if (l.isEmpty()) return;
++
++ s += TQString(" (%1)").arg(l);
++}
++
++TQString TraceFunction::prettyNameWithLocation(int maxFiles) const
++{
++ TQString l = location(maxFiles);
++ if (l.isEmpty()) return prettyName();
++
++ return TQString("%1 (%2)").arg(prettyName()).arg(l);
++}
++
++TQString TraceFunction::info() const
++{
++ TQString l = location();
++ if (l.isEmpty())
++ return TQString("Function %1").arg(name());
++
++ return TQString("Function %1 (location %2)")
++ .arg(name()).arg(l);
++}
++
++
++Addr TraceFunction::firstAddress() const
++{
++ // ignore address 0 here
++ if (!_instrMap || _instrMap->count() == 0) return 0;
++ TraceInstrMap::ConstIterator it = _instrMap->begin();
++ return (*it).addr();
++}
++
++Addr TraceFunction::lastAddress() const
++{
++ // ignore address 0 here
++ if (!_instrMap || _instrMap->count() == 0) return 0;
++ TraceInstrMap::ConstIterator it = _instrMap->end();
++ --it;
++ return (*it).addr();
++}
++
++/* factory */
++TraceInstr* TraceFunction::instr(Addr addr, bool createNew)
++{
++ // address 0 not allowed
++ if (addr == Addr(0)) return 0;
++
++ if (!createNew) {
++ if (!_instrMap) return 0;
++ TraceInstrMap::Iterator it = _instrMap->find(addr);
++ if (it == _instrMap->end())
++ return 0;
++ return &(it.data());
++ }
++
++ if (!_instrMap) _instrMap = new TraceInstrMap;
++
++ TraceInstr& i = (*_instrMap)[addr];
++ if (!i.isValid()) {
++ i.setAddr(addr);
++ i.setFunction(this);
++
++#if TRACE_DEBUG
++ qDebug("Created %s [TraceFunction::instr]",
++ i.fullName().ascii());
++#endif
++ }
++ return &i;
++}
++
++void TraceFunction::addCaller(TraceCall* caller)
++{
++#if TRACE_ASSERTIONS
++ if (caller->called() != this) {
++ qDebug("Can't add call to another line!\n");
++ return;
++ }
++
++ if (_callers.findRef(caller)>=0) return;
++#endif
++
++ _callers.append(caller);
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added Caller\n %s (now %d)",
++ fullName().ascii(), caller->fullName().ascii(), _callers.count());
++#endif
++}
++
++
++
++TraceCall* TraceFunction::calling(TraceFunction* called)
++{
++ TraceCallMap::Iterator it = _callingMap.find(called);
++ TraceCall* calling = (it == _callingMap.end()) ? 0 : it.data();
++
++ if (!calling) {
++ calling = new TraceCall(this, called);
++
++ _callingMap.insert(called, calling);
++ _callings.append(calling);
++
++ // we have to invalidate ourself so invalidations from item propagate up
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("Created %s [TraceFunction::calling]", calling->fullName().ascii());
++#endif
++ called->addCaller(calling);
++ }
++ return calling;
++}
++
++TraceFunctionSource* TraceFunction::sourceFile(TraceFile* file,
++ bool createNew)
++{
++ if (!file) file = _file;
++
++ TraceFunctionSource* sourceFile = _sourceFiles.first();
++ for (;sourceFile;sourceFile=_sourceFiles.next())
++ if (sourceFile->file() == file) break;
++
++ if (!sourceFile && createNew) {
++ sourceFile = new TraceFunctionSource(this, file);
++
++ _sourceFiles.append(sourceFile);
++
++ // we have to invalidate ourself so invalidations from item propagate up
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("Created SourceFile %s [TraceFunction::line]",
++ file->name().ascii());
++#endif
++ file->addSourceFile(sourceFile);
++ }
++ return sourceFile;
++}
++
++TraceLine* TraceFunction::line(TraceFile* file, uint lineno,
++ bool createNew)
++{
++ Q_ASSERT(file!=0);
++
++ TraceFunctionSource* sf = sourceFile(file, createNew);
++ if (!sf)
++ return 0;
++ else
++ return sf->line(lineno, createNew);
++}
++
++
++TracePartFunction* TraceFunction::partFunction(TracePart* part,
++ TracePartFile* partFile,
++ TracePartObject* partObject)
++{
++ TracePartFunction* item = (TracePartFunction*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartFunction(this, partObject, partFile);
++ item->setPosition(part);
++ addDep(item);
++#if USE_FIXCOST
++ part->addDep(item);
++#endif
++
++ if (_cls) {
++ TracePartClass* partClass = _cls->partClass(part);
++ partClass->addPartFunction(item);
++ item->setPartClass(partClass);
++ }
++
++ partFile->addPartFunction(item);
++ if (partObject)
++ partObject->addPartFunction(item);
++ }
++ else if (item->partObject()==0 && partObject) {
++ item->setPartObject(partObject);
++ partObject->addPartFunction(item);
++ }
++
++ return item;
++}
++
++
++SubCost TraceFunction::calledCount()
++{
++ if (_dirty) update();
++
++ return _calledCount;
++}
++
++int TraceFunction::calledContexts()
++{
++ if (_dirty) update();
++
++ return _calledContexts;
++}
++
++SubCost TraceFunction::callingCount()
++{
++ if (_dirty) update();
++
++ return _callingCount;
++}
++
++int TraceFunction::callingContexts()
++{
++ if (_dirty) update();
++
++ return _callingContexts;
++}
++
++TQString TraceFunction::prettyCalledCount()
++{
++ return _calledCount.pretty();
++}
++
++TQString TraceFunction::prettyCallingCount()
++{
++ return _callingCount.pretty();
++}
++
++
++TraceCallList TraceFunction::callers(bool skipCycle) const
++{
++ if (skipCycle) return _callers;
++
++ // fake the callers for cycle members
++ if (_cycle && (_cycle != this)) {
++ TraceCallList l;
++ TraceCall* c;
++
++ // inner-cycle-callers
++ TraceCallList list=_callers;
++ for (c=list.first();c;c=list.next())
++ if (c->caller()->cycle() == _cycle)
++ l.append(c);
++
++ // call from cycle itself
++ for (c=_cycle->_callings.first();c;c=_cycle->_callings.next())
++ if (c->called() == this) {
++ l.append(c);
++ return l;
++ }
++ }
++
++ return _callers;
++}
++
++const TraceCallList& TraceFunction::callings(bool /* skipCycle */) const
++{
++ return _callings;
++}
++
++void TraceFunction::invalidateDynamicCost()
++{
++ TraceCall* c;
++ for (c=_callings.first();c;c=_callings.next())
++ c->invalidateDynamicCost();
++
++ TraceFunctionSource* sf;
++ for (sf=_sourceFiles.first();sf;sf=_sourceFiles.next())
++ sf->invalidateDynamicCost();
++
++ if (_instrMap) {
++ TraceInstrMap::Iterator iit;
++ for ( iit = _instrMap->begin();
++ iit != _instrMap->end(); ++iit )
++ (*iit).invalidate();
++ }
++
++ invalidate();
++}
++
++void TraceFunction::update()
++{
++ if (!_dirty) return;
++
++#if TRACE_DEBUG
++ qDebug("Update %s (Callers %d, sourceFiles %d, instrs %d)",
++ _name.ascii(), _callers.count(),
++ _sourceFiles.count(), _instrMap ? _instrMap->count():0);
++#endif
++
++ _calledCount = 0;
++ _callingCount = 0;
++ _calledContexts = 0;
++ _callingContexts = 0;
++ clear();
++
++ // context count is NOT the sum of part contexts
++ TraceCall *caller, *calling;
++ for (caller=_callers.first();caller;caller=_callers.next()) {
++ // FIXME
++ if (caller->subCost(0)>0)
++ _calledContexts++;
++ _calledCount += caller->callCount();
++ }
++
++ for (calling=_callings.first();calling;calling=_callings.next()) {
++ // FIXME
++ if (calling->subCost(0)>0) _callingContexts++;
++ _callingCount += calling->callCount();
++ }
++
++ if (data()->inFunctionCycleUpdate() || !_cycle) {
++ // usual case (no cycle member)
++ TraceInclusiveCost* item;
++ for (item=_deps.first();item;item=_deps.next()) {
++ if (!item->part() || !item->part()->isActive()) continue;
++
++ addCost(item);
++ addInclusive(item->inclusive());
++ }
++ }
++ else {
++ // this is a cycle or cycle member
++ for (calling=_callings.first();calling;calling=_callings.next()) {
++
++ // ignore inner-cycle member calls for inclusive cost
++ if ((_cycle != this) &&
++ (calling->inCycle()>0)) continue;
++
++ addInclusive(calling);
++ }
++
++ // self cost
++ if (type() == FunctionCycle) {
++ // cycle: self cost is sum of cycle member self costs, but
++ // doesn't add to inclusive cost
++ TraceFunctionList mList = ((TraceFunctionCycle*)this)->members();
++ TraceFunction* m;
++ for (m=mList.first();m;m=mList.next())
++ addCost(m);
++ }
++ else {
++ // cycle member
++ TraceInclusiveCost* item;
++ for (item=_deps.first();item;item=_deps.next()) {
++ if (!item->part() || !item->part()->isActive()) continue;
++
++ addCost(item);
++ }
++ _dirty = false; // don't recurse
++ addInclusive(this);
++ }
++ }
++ _dirty = false;
++
++#if TRACE_DEBUG
++ qDebug("> %s", costString(0).ascii());
++#endif
++}
++
++bool TraceFunction::isCycle()
++{
++ return _cycle == this;
++}
++
++bool TraceFunction::isCycleMember()
++{
++ return _cycle && (_cycle != this);
++}
++
++void TraceFunction::cycleReset()
++{
++ _cycle = 0;
++ _cycleStackDown = 0;
++ _cycleLow = 0;
++}
++
++// this doesn't mark functions calling themself !
++void TraceFunction::cycleDFS(int d, int& pNo, TraceFunction** pTop)
++{
++ if (_cycleLow != 0) return;
++
++ if (0)
++ qDebug("%s D%02d > %s (%d)",
++ TQString().fill(' ', d).ascii(), d, prettyName().ascii(), pNo+1);
++
++
++
++ // initialize with prefix order
++ pNo++;
++ int prefixNo = pNo;
++ _cycleLow = prefixNo;
++
++ // put myself on stack
++ _cycleStackDown = *pTop;
++ *pTop = this;
++
++ /* cycle cut heuristic:
++ * skip calls for cycle detection if they make less than _cycleCut
++ * percent of the cost of the function.
++ * FIXME: Which cost type to use for this heuristic ?!
++ */
++
++ SubCost base = 0;
++ if (_callers.count()>0) {
++ TraceCallList l = _callers;
++ TraceCall *caller;
++
++ for (caller=l.first();caller;caller=l.next())
++ if (caller->subCost(0) > base)
++ base = caller->subCost(0);
++ }
++ else base = inclusive()->subCost(0);
++
++ SubCost cutLimit = SubCost(base * Configuration::cycleCut());
++
++ if (0)
++ qDebug("%s Cum. %s, Max Caller %s, cut limit %s",
++ TQString().fill(' ', d).ascii(),
++ inclusive()->subCost(0).pretty().ascii(),
++ base.pretty().ascii(),
++ cutLimit.pretty().ascii());
++
++ TraceCall *calling;
++ TraceCallList l = _callings;
++ for (calling=l.first();calling;calling=l.next()) {
++ TraceFunction* called = calling->called();
++
++ // cycle cut heuristic
++ if (calling->subCost(0) < cutLimit) {
++ if (0) qDebug("%s Cut call to %s (cum. %s)",
++ TQString().fill(' ', d).ascii(),
++ called->prettyName().ascii(),
++ calling->subCost(0).pretty().ascii());
++
++ continue;
++ }
++
++ if (called->_cycleLow==0) {
++ // not visited yet
++ called->cycleDFS(d+1, pNo, pTop);
++ if (called->_cycleLow < _cycleLow)
++ _cycleLow = called->_cycleLow;
++ }
++ else if (called->_cycleStackDown) {
++ // backlink to same SCC (still in stack)
++ if (called->_cycleLow < _cycleLow)
++ _cycleLow = called->_cycleLow;
++
++ if (0)
++ qDebug("%s D%02d - %s (%d)",
++ TQString().fill(' ', d+1).ascii(), d+1,
++ called->prettyName().ascii(), called->_cycleLow);
++ }
++ else {
++ if (0)
++ qDebug("%s D%02d - %s (%d) [Not on stack]",
++ TQString().fill(' ', d+1).ascii(), d+1,
++ called->prettyName().ascii(), called->_cycleLow);
++ }
++ }
++
++ if (prefixNo == _cycleLow) {
++ // this is the base of a SCC.
++
++ if (*pTop == this) {
++ *pTop = _cycleStackDown;
++ _cycleStackDown = 0;
++ }
++ else {
++ // a SCC with >1 members
++
++ TraceFunctionCycle* cycle = data()->functionCycle(this);
++ if (0) qDebug("BASE CYC %d %s",
++ cycle->cycleNo(), prettyName().ascii());
++ while(*pTop) {
++ TraceFunction* top = *pTop;
++ cycle->add(top);
++
++ // remove from stack
++ *pTop = top->_cycleStackDown;
++ top->_cycleStackDown = 0;
++
++ if (0) qDebug("CYC %s", top->prettyName().ascii());
++ if (top == this) break;
++ }
++ }
++ }
++ if (0)
++ qDebug("%s D%02d < %s (%d)",
++ TQString().fill(' ', d).ascii(), d,
++ prettyName().ascii(), _cycleLow);
++}
++
++
++TraceInstrMap* TraceFunction::instrMap()
++{
++#if USE_FIXCOST
++
++ if (_instrMapFilled) return _instrMap;
++ _instrMapFilled = true;
++ if (!_instrMap)
++ _instrMap = new TraceInstrMap;
++
++ TraceLine* l = 0;
++ TraceInstr* i = 0;
++ TracePartInstr* pi = 0;
++ TraceInstrCall* ic = 0;
++ TracePartInstrCall* pic = 0;
++
++ TraceInclusiveCostList pfList = deps();
++ TracePartFunction* pf = (TracePartFunction*) pfList.first();
++ for(; pf; pf = (TracePartFunction*) pfList.next()) {
++
++ if (0) qDebug("PartFunction %s:%d",
++ pf->function()->name().ascii(), pf->part()->partNumber());
++
++ FixCost* fc = pf->firstFixCost();
++ for(; fc; fc = fc->nextCostOfPartFunction()) {
++ if (fc->addr() == 0) continue;
++
++ if (!l || (l->lineno() != fc->line()) ||
++ (l->functionSource() != fc->functionSource()))
++ l = fc->functionSource()->line(fc->line(),true);
++
++ if (!i || i->addr() != fc->addr()) {
++ i = &(*_instrMap)[fc->addr()];
++ if (!i->isValid()) {
++ i->setFunction(this);
++ i->setAddr(fc->addr());
++ i->setLine(l);
++ }
++ pi = 0;
++ }
++ if (!pi || pi->part() != fc->part())
++ pi = i->partInstr(fc->part(), pf);
++ fc->addTo(pi);
++ }
++
++ TraceInstr* to = 0;
++ TraceInstrJump* ij;
++ TracePartInstrJump* pij;
++ FixJump* fj = pf->firstFixJump();
++ for(; fj; fj = fj->nextJumpOfPartFunction()) {
++ if (fj->addr() == 0) continue;
++
++ if (!l || (l->lineno() != fj->line()) ||
++ (l->functionSource() != fj->source()))
++ l = fj->source()->line(fj->line(),true);
++
++ if (!i || i->addr() != fj->addr()) {
++ i = &(*_instrMap)[fj->addr()];
++ if (!i->isValid()) {
++ i->setFunction(this);
++ i->setAddr(fj->addr());
++ i->setLine(l);
++ }
++ }
++
++ to = fj->targetFunction()->instr(fj->targetAddr(), true);
++
++ ij = i->instrJump(to, fj->isCondJump());
++ pij = ij->partInstrJump(fj->part());
++
++ fj->addTo(pij);
++ }
++
++ TracePartCallList pcList = pf->partCallings();
++ TracePartCall* pc = pcList.first();
++ for(; pc; pc = pcList.next()) {
++
++ if (0) qDebug("PartCall %s:%d",
++ pc->call()->name().ascii(),
++ pf->part()->partNumber());
++
++ FixCallCost* fcc = pc->firstFixCallCost();
++ for(; fcc; fcc = fcc->nextCostOfPartCall()) {
++ if (fcc->addr() == 0) continue;
++
++ if (!l || (l->lineno() != fcc->line()) ||
++ (l->functionSource() != fcc->functionSource()))
++ l = fcc->functionSource()->line(fcc->line(),true);
++
++ if (!i || i->addr() != fcc->addr()) {
++ i = &(*_instrMap)[fcc->addr()];
++ if (!i->isValid()) {
++ i->setFunction(this);
++ i->setAddr(fcc->addr());
++ i->setLine(l);
++ }
++ }
++ if (!ic || ic->call() != pc->call() || ic->instr() != i) {
++ ic = pc->call()->instrCall(i);
++ pic = 0;
++ }
++ if (!pic || pic->part() != fcc->part())
++ pic = ic->partInstrCall(fcc->part(), pc);
++
++ fcc->addTo(pic);
++ if (0) qDebug("Add FixCallCost %s:%d/0x%s, CallCount %s",
++ fcc->functionSource()->file()->shortName().ascii(),
++ fcc->line(), fcc->addr().toString().ascii(),
++ fcc->callCount().pretty().ascii());
++ }
++ }
++ }
++
++#endif
++
++ return _instrMap;
++}
++
++
++
++//---------------------------------------------------
++// TraceFunctionCycle
++
++TraceFunctionCycle::TraceFunctionCycle(TraceFunction* f, int n)
++{
++ _base = f;
++ _cycleNo = n;
++ _cycle = this;
++
++ setPosition(f->data());
++ setName(TQString("<cycle %1>").arg(n));
++
++ // reset to attributes of base function
++ setFile(_base->file());
++ setClass(_base->cls());
++ setObject(_base->object());
++}
++
++void TraceFunctionCycle::init()
++{
++ _members.clear();
++ _memberSet.clear();
++ _callers.clear();
++ // this deletes all TraceCall's to members
++ _callings.clear();
++
++ invalidate();
++}
++
++void TraceFunctionCycle::add(TraceFunction* f)
++{
++ _members.append(f);
++ _memberSet.insert(f,1);
++}
++
++void TraceFunctionCycle::setup()
++{
++ if (_members.count()==0) return;
++
++ TraceFunction* f;
++ for (f=_members.first();f;f=_members.next()) {
++
++ // the cycle takes all outside callers from its members
++ TraceCall *call;
++ TraceCallList l = f->callers();
++ for (call=l.first();call;call=l.next()) {
++ if ( _memberSet.contains(call->caller()) ) continue;
++ _callers.append(call);
++ }
++
++ // the cycle has a call to each member
++ call = new TraceCall(this, f);
++ call->invalidate();
++ _callings.append(call);
++
++ // now do some faking...
++ f->setCycle(this);
++ }
++ invalidate();
++}
++
++
++//---------------------------------------------------
++// TraceClass
++
++TraceClass::TraceClass()
++{
++ // we are the owner of items generated in our factory
++ _deps.setAutoDelete(true);
++}
++
++TraceClass::~TraceClass()
++{}
++
++TQString TraceClass::prettyName() const
++{
++ if (_name.isEmpty())
++ return TQString("(global)");
++ return _name;
++}
++
++TracePartClass* TraceClass::partClass(TracePart* part)
++{
++ TracePartClass* item = (TracePartClass*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartClass(this);
++ item->setPosition(part);
++ addDep(item);
++ }
++ return item;
++}
++
++void TraceClass::addFunction(TraceFunction* function)
++{
++#if TRACE_ASSERTIONS
++ if (function->cls() != this) {
++ qDebug("Can't add function to a class not enclosing this function\n");
++ return;
++ }
++
++ if (_functions.findRef(function)>=0) return;
++#endif
++
++ _functions.append(function);
++
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(),
++ function->fullName().ascii(), _functions.count());
++#endif
++}
++
++
++
++//---------------------------------------------------
++// TraceFile
++
++TraceFile::TraceFile()
++{
++ // we are the owner of items generated in our factory
++ _deps.setAutoDelete(true);
++}
++
++TraceFile::~TraceFile()
++{}
++
++TracePartFile* TraceFile::partFile(TracePart* part)
++{
++ TracePartFile* item = (TracePartFile*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartFile(this);
++ item->setPosition(part);
++ addDep(item);
++ }
++ return item;
++}
++
++void TraceFile::addFunction(TraceFunction* function)
++{
++#if TRACE_ASSERTIONS
++ if (function->file() != this) {
++ qDebug("Can't add function to a file not enclosing this function\n");
++ return;
++ }
++
++ if (_functions.findRef(function)>=0) return;
++#endif
++
++ _functions.append(function);
++
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(),
++ function->fullName().ascii(), _functions.count());
++#endif
++}
++
++
++void TraceFile::addSourceFile(TraceFunctionSource* sourceFile)
++{
++#if TRACE_ASSERTIONS
++ if (sourceFile->file() != this) {
++ qDebug("Can't add sourceFile to a file not having lines for it\n");
++ return;
++ }
++#endif
++
++ _sourceFiles.append(sourceFile);
++ // not truely needed, as we don't use the sourceFiles for cost update
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s \n added SourceFile %s (now %d)",
++ fullName().ascii(), sourceFile->fullName().ascii(),
++ _sourceFiles.count());
++#endif
++}
++
++
++
++void TraceFile::setDirectory(const TQString& dir)
++{
++ if (dir.endsWith("/"))
++ _dir = dir.left(dir.length()-1);
++ else
++ _dir = dir;
++}
++
++TQString TraceFile::directory()
++{
++ if (!_dir.isEmpty()) return _dir;
++
++ int lastIndex = 0, index;
++ while ( (index=_name.find("/", lastIndex)) >=0)
++ lastIndex = index+1;
++
++ if (lastIndex==0) return TQString();
++
++ // without ending "/"
++ return _name.left(lastIndex-1);
++}
++
++
++TQString TraceFile::shortName() const
++{
++ int lastIndex = 0, index;
++ while ( (index=_name.find("/", lastIndex)) >=0)
++ lastIndex = index+1;
++
++ return _name.mid(lastIndex);
++}
++
++TQString TraceFile::prettyName() const
++{
++ TQString sn = shortName();
++
++ if (sn.isEmpty())
++ return i18n("(unknown)");
++
++ return sn;
++}
++
++TQString TraceFile::prettyLongName() const
++{
++ if (_name.isEmpty())
++ return i18n("(unknown)");
++ return _name;
++}
++
++
++//---------------------------------------------------
++// TraceObject
++
++TraceObject::TraceObject()
++{
++ // we are the owner of items generated in our factory
++ _deps.setAutoDelete(true);
++}
++
++TraceObject::~TraceObject()
++{}
++
++TracePartObject* TraceObject::partObject(TracePart* part)
++{
++ TracePartObject* item = (TracePartObject*) findDepFromPart(part);
++ if (!item) {
++ item = new TracePartObject(this);
++ item->setPosition(part);
++ addDep(item);
++ }
++ return item;
++}
++
++void TraceObject::addFunction(TraceFunction* function)
++{
++#if TRACE_ASSERTIONS
++ if (function->object() != this) {
++ qDebug("Can't add function to an object not enclosing this function\n");
++ return;
++ }
++
++ if (_functions.findRef(function)>=0) return;
++#endif
++
++ _functions.append(function);
++
++ invalidate();
++
++#if TRACE_DEBUG
++ qDebug("%s added\n %s (now %d)",
++ fullName().ascii(),
++ function->fullName().ascii(), _functions.count());
++#endif
++}
++
++// strip path
++void TraceObject::setName(const TQString& name)
++{
++ _name = name;
++
++ int lastIndex = 0, index;
++ while ( (index=_name.find("/", lastIndex)) >=0)
++ lastIndex = index+1;
++
++ _shortName = _name.mid(lastIndex);
++}
++
++TQString TraceObject::prettyName() const
++{
++ if (_shortName.isEmpty())
++ return i18n("(unknown)");
++
++ return _shortName;
++}
++
++//---------------------------------------------------
++// TracePart
++
++TracePart::TracePart(TraceData* data, TQFile* file)
++{
++ setPosition(data);
++
++ _dep = data;
++ _file = file;
++ if (_file)
++ _name = _file->name();
++ _active = true;
++
++ _number = 0;
++ _tid = 0;
++ _pid = 0;
++
++ _fixSubMapping = 0;
++}
++
++TracePart::~TracePart()
++{
++ delete _file;
++
++ delete _fixSubMapping;
++}
++
++void TracePart::setPartNumber(int n)
++{
++ if (data()->maxPartNumber() <n) data()->setMaxPartNumber(n);
++ _number = n;
++}
++
++void TracePart::setThreadID(int tid)
++{
++ if (data()->maxThreadID() <tid) data()->setMaxThreadID(tid);
++ _tid = tid;
++}
++
++void TracePart::setProcessID(int pid)
++{
++ _pid = pid;
++}
++
++
++
++// strip path
++TQString TracePart::shortName() const
++{
++ int lastIndex = 0, index;
++ while ( (index=_name.find("/", lastIndex)) >=0)
++ lastIndex = index+1;
++
++ return _name.mid(lastIndex);
++}
++
++TQString TracePart::prettyName() const
++{
++ TQString name = TQString("%1.%2").arg(_pid).arg(_number);
++ if (data()->maxThreadID()>1)
++ name += TQString("-%3").arg(_tid);
++ return name;
++}
++
++bool TracePart::activate(bool active)
++{
++ if (_active == active) return false;
++ _active = active;
++
++ // to be done by the client of this function
++ // data()->invalidateDynamicCost();
++ // So better use the TraceData functions...
++
++ return true;
++}
++
++
++
++//---------------------------------------------------
++// TracePartList
++
++int TracePartList::compareItems ( Item item1, Item item2 )
++{
++ TracePart* p1 = (TracePart*) item1;
++ TracePart* p2 = (TracePart*) item2;
++ int mTID = p1->data()->maxThreadID()+1;
++ int mNum = p1->data()->maxPartNumber()+1;
++
++ return
++ (p1->processID() - p2->processID()) * mTID * mNum +
++ (p1->partNumber() - p2->partNumber()) * mTID +
++ (p1->threadID() - p2->threadID());
++}
++
++TQString TracePartList::names() const
++{
++ TQString res;
++ TracePart* p;
++ TracePartList l = *this;
++ for (p=l.first();p;p=l.next()) {
++ if (!res.isEmpty()) res += ", ";
++ res += p->shortName();
++ }
++
++ return res;
++}
++
++
++
++//---------------------------------------------------
++// TraceData
++
++
++// create vectors with reasonable default sizes, but not wasting memory
++TraceData::TraceData(TopLevel* top)
++{
++ _topLevel = top;
++ init();
++}
++
++TraceData::TraceData(const TQString& base)
++{
++ _topLevel = 0;
++ init();
++ load(base);
++}
++
++void TraceData::init()
++{
++ _parts.setAutoDelete(true);
++
++ _functionCycleCount = 0;
++ _inFunctionCycleUpdate = false;
++
++ _maxThreadID = 0;
++ _maxPartNumber = 0;
++ _fixPool = 0;
++ _dynPool = 0;
++}
++
++TraceData::~TraceData()
++{
++ if (_fixPool) delete _fixPool;
++ if (_dynPool) delete _dynPool;
++}
++
++TQString TraceData::shortTraceName() const
++{
++ int lastIndex = 0, index;
++ while ( (index=_traceName.find("/", lastIndex)) >=0)
++ lastIndex = index+1;
++
++ return _traceName.mid(lastIndex);
++}
++
++FixPool* TraceData::fixPool()
++{
++ if (!_fixPool)
++ _fixPool = new FixPool();
++
++ return _fixPool;
++}
++
++DynPool* TraceData::dynPool()
++{
++ if (!_dynPool)
++ _dynPool = new DynPool();
++
++ return _dynPool;
++}
++
++
++/**
++ * Two cases:
++ *
++ * - <base> is a directory: Load first profile data file available
++ * - <base> is a file name without part/thread suffixes
++ */
++void TraceData::load(const TQString& base)
++{
++ bool baseExisting = true;
++
++ _traceName = base;
++ TQFileInfo finfo(base);
++ TQString file = finfo.fileName();
++ TQDir dir = finfo.dir();
++
++ if (!finfo.exists()) {
++ baseExisting = false;
++ }
++ else if (finfo.isDir()) {
++ // search for first profile data file in directory
++ dir = TQDir(base);
++
++ TQStringList prefixList;
++ prefixList << "callgrind.out" << "cachegrind.out";
++ for ( TQStringList::Iterator it = prefixList.begin();
++ it != prefixList.end(); ++it ) {
++ file = *it;
++
++ // search for ".pid"
++ TQStringList strList = dir.entryList(file+".*", TQDir::Files);
++ if (strList.count()>0) {
++ int l = file.length();
++ file = strList.first();
++ l++;
++ while(file[l] >= '0' && file[l] <= '9') l++;
++ file = file.left(l);
++ break;
++ }
++ }
++
++ _traceName = dir.path() + "/" + file;
++ }
++
++ TQStringList strList;
++ strList += dir.entryList(file+".*", TQDir::Files);
++ strList += dir.entryList(file+"-*", TQDir::Files);
++
++ baseExisting = TQFile::exists(_traceName);
++ if (baseExisting)
++ strList << file;
++
++ if (strList.count() == 0) {
++ _traceName = base + "/" + file + " " + i18n("(not found)");
++ return;
++ }
++
++
++ // try to guess pid from file name
++ unsigned int pos = file.length();
++ unsigned int pid = 0, f=1;
++ pos--;
++ while(pos>0) {
++ if (file[pos] < '0' || file[pos] > '9') break;
++ pid += f * (file[pos].latin1() - '0');
++ pos--;
++ f *= 10;
++ }
++
++ TQStringList::Iterator it;
++ unsigned int maxNumber = 0;
++ for (it = strList.begin(); it != strList.end(); ++it ) {
++ TracePart* p = addPart( dir.path(), *it );
++
++ if (!p) {
++ kdDebug() << "Error loading " << *it << endl;
++ continue;
++ }
++
++ const TQString& str = *it;
++ unsigned int pos = file.length();
++
++ // try to guess part number from file name
++ unsigned int n = 0;
++ if ((str.length() > pos) && (str[pos] == '.')) {
++ pos++;
++ while(str.length()>pos) {
++ if ((int)str.at(pos) < '0' || (int)str.at(pos) > '9') break;
++ n = 10*n + (str[pos++] - '0');
++ }
++ }
++
++ // try to guess thread number from file name
++ unsigned int t = 0;
++ if ((str.length() > pos) && (str[pos] == '-')) {
++ pos++;
++ while(str.length()>pos) {
++ if ((int)str.at(pos) < '0' || (int)str.at(pos) > '9') break;
++ t = 10*t + (str[pos++] - '0');
++ }
++ }
++
++ //qDebug("File %s: Part %d, Thread %d", (*it).ascii(), n, t);
++
++ if (p->partNumber()>0) n = p->partNumber();
++ if (n>maxNumber) maxNumber = n;
++ if (n==0) n = maxNumber+1;
++ p->setPartNumber(n);
++
++ if (p->threadID()==0) p->setThreadID(t);
++ if (p->processID()==0) p->setProcessID(pid);
++
++ _parts.append(p);
++ }
++ _parts.sort();
++
++ invalidateDynamicCost();
++ updateFunctionCycles();
++
++ // clear loading messages from status bar
++ if (_topLevel) _topLevel->showStatus(TQString(), 0);
++}
++
++TracePart* TraceData::addPart(const TQString& dir, const TQString& name)
++{
++ TQString filename = TQString("%1/%2").arg(dir).arg(name);
++#if TRACE_DEBUG
++ qDebug("TraceData::addPart('%s')", filename.ascii());
++#endif
++
++ TQFile* file = new TQFile(filename);
++
++ Loader* l = Loader::matchingLoader(file);
++ if (!l) return 0;
++
++ if (_topLevel)
++ _topLevel->connect(l, TQT_SIGNAL(updateStatus(TQString, int)),
++ TQT_SLOT(showStatus(TQString, int)));
++
++ TracePart* part = new TracePart(this, file);
++
++ if (! l->loadTrace(part)) {
++ delete part;
++ part = 0;
++ }
++
++ if (_topLevel) l->disconnect(_topLevel);
++
++ return part;
++}
++
++bool TraceData::activateParts(const TracePartList& l)
++{
++ bool changed = false;
++
++ TracePart* part;
++ for (part=_parts.first();part;part=_parts.next())
++ if (part->activate(l.containsRef(part)>0))
++ changed = true;
++
++ if (changed) {
++ // because active parts have changed, throw away calculated
++ // costs...
++ invalidateDynamicCost();
++ updateFunctionCycles();
++ }
++
++ return changed;
++}
++
++
++bool TraceData::activateParts(TracePartList l, bool active)
++{
++ bool changed = false;
++
++ TracePart* part;
++ for (part=l.first();part;part=l.next())
++ if (_parts.findRef(part)>=0)
++ if (part->activate(active))
++ changed = true;
++
++ if (changed) {
++ invalidateDynamicCost();
++ updateFunctionCycles();
++ }
++
++ return changed;
++}
++
++bool TraceData::activatePart(TracePart* p, bool active)
++{
++ return p->activate(active);
++}
++
++bool TraceData::activateAll(bool active)
++{
++ return activateParts(_parts, active);
++}
++
++
++TracePart* TraceData::part(TQString& name)
++{
++ TracePart* part;
++ for (part=_parts.first();part;part=_parts.next())
++ if (part->name() == name)
++ return part;
++ return 0;
++}
++
++TQString TraceData::activePartRange()
++{
++ TQString res;
++ int r1=-1, r2=-1, count=1;
++ TracePart* part;
++ for (part=_parts.first();part;part=_parts.next(), count++)
++ if (part->isActive()) {
++ if (r1<0) { r1 = r2 = count; }
++ else if (r2 == count-1) { r2 = count; }
++ else {
++ if (!res.isEmpty()) res += ";";
++ if (r1==r2) res += TQString::number(r1);
++ else res += TQString("%1-%2").arg(r1).arg(r2);
++ r1 = r2 = count;
++ }
++ }
++ if (r1>=0) {
++ if (!res.isEmpty()) res += ";";
++ if (r1==r2) res += TQString::number(r1);
++ else res += TQString("%1-%2").arg(r1).arg(r2);
++ }
++
++ return res;
++}
++
++void TraceData::invalidateDynamicCost()
++{
++ // invalidate all dynamic costs
++
++ TraceObjectMap::Iterator oit;
++ for ( oit = _objectMap.begin();
++ oit != _objectMap.end(); ++oit )
++ (*oit).invalidate();
++
++ TraceClassMap::Iterator cit;
++ for ( cit = _classMap.begin();
++ cit != _classMap.end(); ++cit )
++ (*cit).invalidate();
++
++ TraceFileMap::Iterator fit;
++ for ( fit = _fileMap.begin();
++ fit != _fileMap.end(); ++fit )
++ (*fit).invalidate();
++
++ TraceFunctionMap::Iterator it;
++ for ( it = _functionMap.begin();
++ it != _functionMap.end(); ++it ) {
++ (*it).invalidateDynamicCost();
++ }
++
++ invalidate();
++
++}
++
++
++TraceObject* TraceData::object(const TQString& name)
++{
++ TraceObject& o = _objectMap[name];
++ if (!o.data()) {
++ // was created
++ o.setPosition(this);
++ o.setName(name);
++
++#if TRACE_DEBUG
++ qDebug("Created %s [TraceData::object]",
++ o.fullName().ascii());
++#endif
++ }
++ return &o;
++}
++
++
++TraceFile* TraceData::file(const TQString& name)
++{
++ TraceFile& f = _fileMap[name];
++ if (!f.data()) {
++ // was created
++ f.setPosition(this);
++ f.setName(name);
++
++#if TRACE_DEBUG
++ qDebug("Created %s [TraceData::file]",
++ f.fullName().ascii());
++#endif
++ }
++ return &f;
++}
++
++
++// usually only called by function()
++TraceClass* TraceData::cls(const TQString& fnName, TQString& shortName)
++{
++ int lastIndex = 0, index, pIndex;
++
++ // we ignore any "::" after a '(' or a space
++ pIndex=fnName.find("(", 0);
++
++#if 0
++ int sIndex=fnName.find(" ", 0);
++ if (sIndex>=0)
++ if ((pIndex == -1) || (sIndex < pIndex))
++ pIndex = sIndex;
++#endif
++
++ while ((index=fnName.find("::", lastIndex)) >=0) {
++ if (pIndex>=0 && pIndex<index) break;
++ lastIndex = index+2;
++ }
++
++ TQString clsName = (lastIndex < 3) ? TQString() :
++ fnName.left(lastIndex-2);
++ shortName = fnName.mid(lastIndex);
++
++ TraceClass& c = _classMap[clsName];
++ if (!c.data()) {
++ // was created
++ c.setPosition(this);
++ c.setName(clsName);
++
++#if TRACE_DEBUG
++ qDebug("Created %s [TraceData::cls]",
++ c.fullName().ascii());
++#endif
++ }
++ return &c;
++}
++
++
++// name is inclusive class/namespace prefix
++TraceFunction* TraceData::function(const TQString& name,
++ TraceFile* file, TraceObject* object)
++{
++ // strip class name
++ TQString shortName;
++ TraceClass* c = cls(name, shortName);
++
++ if (!file || !object || !c) {
++ qDebug("ERROR - no file/object/class for %s ?!", name.ascii());
++ return 0;
++ }
++
++ // Don't use file in key: A function can go over many files
++ // (inlined parts), but still is ONE function.
++ TQString key = name + object->shortName();
++
++ TraceFunctionMap::Iterator it;
++ it = _functionMap.find(key);
++ if (it == _functionMap.end()) {
++ it = _functionMap.insert(key, TraceFunction());
++ TraceFunction& f = it.data();
++
++ f.setPosition(this);
++ f.setName(name);
++ f.setClass(c);
++ f.setObject(object);
++ f.setFile(file);
++ f.setMapIterator(it);
++
++#if TRACE_DEBUG
++ qDebug("Created %s [TraceData::function]\n for %s, %s, %s",
++ f.fullName().ascii(),
++ c->fullName().ascii(), file->fullName().ascii(),
++ object ? object->fullName().ascii() : "(unknown object)");
++#endif
++
++ c->addFunction(&f);
++ object->addFunction(&f);
++ file->addFunction(&f);
++ }
++
++ return &(it.data());
++}
++
++TraceFunctionMap::Iterator TraceData::functionIterator(TraceFunction* f)
++{
++
++ // IMPORTANT: build as SAME key as used in function() above !!
++ TQString key;
++
++ if (f->cls()) key = f->cls()->name() + "::";
++ key += f->name();
++ key += f->object()->shortName();
++
++ return _functionMap.find(key);
++}
++
++TraceFunctionMap::ConstIterator TraceData::functionBeginIterator() const
++{
++ return _functionMap.begin();
++}
++
++TraceFunctionMap::ConstIterator TraceData::functionEndIterator() const
++{
++ return _functionMap.end();
++}
++
++
++void TraceData::resetSourceDirs()
++{
++ TraceFileMap::Iterator fit;
++ for ( fit = _fileMap.begin();
++ fit != _fileMap.end(); ++fit )
++ (*fit).resetDirectory();
++}
++
++void TraceData::update()
++{
++ if (!_dirty) return;
++
++ clear();
++ _totals.clear();
++
++ TracePart* part;
++ for (part=_parts.first();part;part=_parts.next()) {
++ _totals.addCost(part->totals());
++ if (part->isActive())
++ addCost(part->totals());
++ }
++
++ _dirty = false;
++}
++
++TraceCost* TraceData::search(TraceItem::CostType t, TQString name,
++ TraceCostType* ct, TraceCost* parent)
++{
++ TraceCost* result = 0;
++ TraceItem::CostType pt = parent ? parent->type() : NoCostType;
++ SubCost sc, scTop = 0;
++
++ switch(t) {
++ case Function:
++ {
++ TraceFunction *f;
++ TraceFunctionMap::Iterator it;
++ for ( it = _functionMap.begin();
++ it != _functionMap.end(); ++it ) {
++ f = &(*it);
++
++ if (f->name() != name) continue;
++
++ if ((pt == Class) && (parent != f->cls())) continue;
++ if ((pt == File) && (parent != f->file())) continue;
++ if ((pt == Object) && (parent != f->object())) continue;
++
++ if (ct) {
++ sc = f->inclusive()->subCost(ct);
++ if (sc <= scTop) continue;
++ scTop = sc;
++ }
++
++ result = f;
++ }
++ }
++ break;
++
++ case File:
++ {
++ TraceFile *f;
++ TraceFileMap::Iterator it;
++ for ( it = _fileMap.begin();
++ it != _fileMap.end(); ++it ) {
++ f = &(*it);
++ if (f->name() != name) continue;
++ if (ct) {
++ sc = f->subCost(ct);
++ if (sc <= scTop) continue;
++ scTop = sc;
++ }
++ result = f;
++ }
++ }
++ break;
++
++ case Class:
++ {
++ TraceClass *c;
++ TraceClassMap::Iterator it;
++ for ( it = _classMap.begin();
++ it != _classMap.end(); ++it ) {
++ c = &(*it);
++ if (c->name() != name) continue;
++ if (ct) {
++ sc = c->subCost(ct);
++ if (sc <= scTop) continue;
++ scTop = sc;
++ }
++ result = c;
++ }
++ }
++ break;
++
++ case Object:
++ {
++ TraceObject *o;
++ TraceObjectMap::Iterator it;
++ for ( it = _objectMap.begin();
++ it != _objectMap.end(); ++it ) {
++ o = &(*it);
++ if (o->name() != name) continue;
++ if (ct) {
++ sc = o->subCost(ct);
++ if (sc <= scTop) continue;
++ scTop = sc;
++ }
++ result = o;
++ }
++ }
++ break;
++
++ case Instr:
++ if (pt == Function) {
++ TraceInstrMap* instrMap = ((TraceFunction*)parent)->instrMap();
++ if (!instrMap) break;
++
++ TraceInstr *instr;
++ TraceInstrMap::Iterator it;
++ for ( it = instrMap->begin();
++ it != instrMap->end(); ++it ) {
++ instr = &(*it);
++ if (instr->name() != name) continue;
++ result = instr;
++ }
++ }
++ break;
++
++ case Line:
++ {
++ TraceFunctionSourceList sList;
++ if (pt == Function)
++ sList = ((TraceFunction*)parent)->sourceFiles();
++ else if (pt == FunctionSource)
++ sList.append((TraceFunctionSource*) parent);
++ else break;
++
++ TraceLineMap* lineMap;
++ TraceLine* line;
++ TraceLineMap::Iterator it;
++ TraceFunctionSource* fs;
++ for(fs = sList.first(); fs; fs = sList.next()) {
++ lineMap = fs->lineMap();
++ if (!lineMap) continue;
++
++ for ( it = lineMap->begin();
++ it != lineMap->end(); ++it ) {
++ line = &(*it);
++ if (line->name() != name) continue;
++ result = line;
++ }
++ }
++ }
++ break;
++
++ default:
++ break;
++ }
++
++ return result;
++}
++
++
++TraceFunctionCycle* TraceData::functionCycle(TraceFunction* f)
++{
++ TraceFunctionCycle* cycle;
++ for (cycle=_functionCycles.first();cycle;cycle=_functionCycles.next())
++ if (cycle->base() == f) return cycle;
++
++ _functionCycleCount++;
++ cycle = new TraceFunctionCycle(f, _functionCycleCount);
++
++ _functionCycles.append(cycle);
++ return cycle;
++}
++
++
++void TraceData::updateFunctionCycles()
++{
++ //qDebug("Updating cycles...");
++
++ // init cycle info
++ TraceFunctionCycle* cycle;
++ for (cycle=_functionCycles.first();cycle;cycle=_functionCycles.next())
++ cycle->init();
++
++ TraceFunctionMap::Iterator it;
++ for ( it = _functionMap.begin(); it != _functionMap.end(); ++it )
++ (*it).cycleReset();
++
++ if (!Configuration::showCycles()) return;
++
++ _inFunctionCycleUpdate = true;
++
++
++#if 0
++ int fCount = _functionMap.size(), fNo = 0, progress=0, p;
++ TQString msg = i18n("Recalculating Function Cycles...");
++ if (_topLevel) _topLevel->showStatus(msg,0);
++#endif
++
++ // DFS and collapse strong connected components (Tarjan)
++ int pNo = 0;
++ TraceFunction* stackTop;
++ for ( it = _functionMap.begin(); it != _functionMap.end(); ++it ) {
++
++#if 0
++ if (_topLevel) {
++ fNo++;
++ p = 100*fNo/fCount;
++ if (p> progress) {
++ progress = p;
++ _topLevel->showStatus(msg, p);
++ }
++ }
++#endif
++
++ stackTop = 0;
++ (*it).cycleDFS(1, pNo, &stackTop);
++ }
++
++ // postprocess cycles
++ for (cycle=_functionCycles.first();cycle;cycle=_functionCycles.next())
++ cycle->setup();
++
++ _inFunctionCycleUpdate = false;
++ // we have to invalidate costs because cycles are now taken into account
++ invalidateDynamicCost();
++
++#if 0
++ if (0) if (_topLevel) _topLevel->showStatus(TQString(),0);
++#endif
++}
++
++void TraceData::updateObjectCycles()
++{
++}
++
++
++void TraceData::updateClassCycles()
++{
++}
++
++
++void TraceData::updateFileCycles()
++{
++}
++
++
+diff --git a/kdecachegrind/kdecachegrind/tracedata.h b/kdecachegrind/kdecachegrind/tracedata.h
+new file mode 100644
+index 0000000..8fab2b6
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/tracedata.h
+@@ -0,0 +1,1967 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Classes holding profiling data for
++ * multiple tracefiles for one command.
++ * See class TraceData first.
++ */
++
++#ifndef TRACEDATA_H
++#define TRACEDATA_H
++
++#include <tqstring.h>
++#include <tqstringlist.h>
++#include <tqptrlist.h>
++#include <tqmap.h>
++#include <tqptrvector.h>
++#include <tqcolor.h>
++
++#include "subcost.h"
++#include "utils.h"
++
++class TQFile;
++
++/**
++ * All cost items are classes prefixed with "Trace".
++ * "TraceCost" holds basic cost metrics for the simplest, smallest
++ * trace entity: These are events counted for an instruction at
++ * a specific memory address of the traced program.
++ * All other cost items are derived from TraceCost, and add needed
++ * cost metrics, e.g. for a call the number of calls that happened.
++ *
++ * Abstract, i.e. never instantiated cost items are
++ * - TraceCost: Basic cost metrics (instr/read/write access + cache events)
++ * - TraceCallCost: Additional call count cost metric.
++ * - TraceInclusiveCost: Additional TraceCost aggregated.
++ * - TraceListCost: Adds dependency to a list of TraceCost's
++ * - TraceCallListCost: same for list of TraceCallCost's
++ * - TraceInclusiveListCost: same for list of TraceInclusiveCost's
++ * - TraceCostItem: Base for cost items for "interesting" costs:
++ * TraceFunction, TraceClass, TraceFile, TraceObject
++ *
++ * The smallest Cachegrind output is trace data indexed by a source
++ * line number, a TracePartLine. Another one is a call from one
++ * source line of a function to another function, a TracePartLineCall.
++ * All other cost items derive the value by summation of cost metrics
++ * from TraceLineItem and TracePartLineCall costs; their cost is
++ * calculated lazy on demand and cached afterwards.
++ *
++ * For cost items, which are sums over all trace files read in, the
++ * summed cost metrics change when e.g. a new trace file is read.
++ * Thus, their cached costs are invalidated, and again recalculated
++ * only on demand. In the following list, theses cost items are called
++ * "dynamic", the other "fixed" (but neverless calculated lazy).
++ *
++ * Cost Item Type Summation of ...
++ *
++ * TracePartLineCall fixed Read from trace file
++ * TracePartLine fixed Read from trace file
++ * TracePartCall fixed TracePartLineCall's
++ * TraceLineCall dynamic TracePartLineCall's
++ * TraceCall dynamic TraceLineCall's
++ * TraceLine dynamic TracePartLine's and TraceLineCall's
++ * TracePartFunction fixed TracePartLine's / TracePartCall's
++ * TraceFunction dynamic TraceLine's / TraceCall's (called from)
++ * TracePartClass fixed TracePartFunction's
++ * TraceClass dynamic TraceFunction's
++ * TracePartFile fixed TracePartFunction's
++ * TraceFile dynamic TraceFunction's
++ * TracePartObject fixed TracePartFunction's
++ * TraceObject dynamic TraceFunction's
++ * TracePart fixed TracePartLine's
++ * TraceData dynamic TracePart's
++ *
++ * As there exists only one TraceData object for a traced program, its the
++ * owner of some "high level" cost items. The following shows the owner
++ * relationship of the cost item classes, together with references.
++ *
++ * Cost Item Owner (& back ref) Other References to
++ *
++ * TracePartLineCall TraceLineCall
++ * TracePartCall TraceCall TracePartLineCall's
++ * TracePartLine TraceLine TracePartLineCall's
++ * TracePartFunction TraceFunction
++ * TracePartClass TraceClass TracePart
++ * TracePartFile TraceFile TracePart
++ * TracePartObject TraceObject TracePart
++ * TraceLineCall TraceCall TracePartLineCall's
++ * TraceCall TraceFunction TracePartCall's
++ * TraceLine TraceData TraceLineCall's
++ * TraceFunction TraceData TraceCall's (calling)
++ * TraceClass TraceData
++ * TraceFile TraceData
++ * TraceObject TraceData
++ * TracePart TraceData
++ * TraceData Main Application
++ *
++ * Convention:
++ * - The owner has a factory method for owned objects,
++ * and calls addXXX() to install references in other objects
++ * - The owner is first arg in a constructor.
++ */
++
++
++class FixString;
++class FixCost;
++class FixCallCost;
++class FixJump;
++class FixPool;
++class DynPool;
++class TopLevel;
++
++class TraceCost;
++class TraceCostType;
++class TraceCostMapping;
++class TraceSubMapping;
++class TraceJumpCost;
++class TraceCallCost;
++class TraceInclusiveCost;
++
++class TracePartInstr;
++class TracePartInstrCall;
++class TracePartLine;
++class TracePartLineCall;
++class TracePartCall;
++class TracePartLineRegion;
++class TracePartFunction;
++class TracePartClass;
++class TracePartObject;
++class TracePartFile;
++
++class TraceInstr;
++class TraceInstrJump;
++class TraceInstrCall;
++class TraceLine;
++class TraceLineJump;
++class TraceLineCall;
++class TraceCall;
++class TraceLineRegion;
++class TraceFunctionSource;
++class TraceFunction;
++class TraceFunctionCycle;
++class TraceClass;
++class TraceObject;
++class TraceFile;
++class TracePart;
++class TraceData;
++
++typedef TQPtrList<TraceCost> TraceCostList;
++typedef TQPtrList<TraceJumpCost> TraceJumpCostList;
++typedef TQPtrList<TraceCallCost> TraceCallCostList;
++typedef TQPtrList<TraceInclusiveCost> TraceInclusiveCostList;
++
++typedef TQPtrList<TracePartCall> TracePartCallList;
++typedef TQPtrList<TracePartInstr> TracePartInstrList;
++typedef TQPtrList<TracePartLine> TracePartLineList;
++typedef TQPtrList<TracePartLineRegion> TracePartLineRegionList;
++typedef TQPtrList<TracePartFunction> TracePartFunctionList;
++typedef TQPtrList<TracePartInstrCall> TracePartInstrCallList;
++typedef TQPtrList<TracePartLineCall> TracePartLineCallList;
++
++
++typedef TQPtrList<TraceInstr> TraceInstrList;
++typedef TQPtrList<TraceLine> TraceLineList;
++typedef TQPtrList<TraceInstrCall> TraceInstrCallList;
++typedef TQPtrList<TraceLineCall> TraceLineCallList;
++typedef TQPtrList<TraceCall> TraceCallList;
++typedef TQPtrList<TraceFile> TraceFileList;
++typedef TQPtrList<TraceLineRegion> TraceLineRegionList;
++typedef TQPtrList<TraceFunctionSource> TraceFunctionSourceList;
++typedef TQPtrList<TraceFunction> TraceFunctionList;
++typedef TQPtrList<TraceFunctionCycle> TraceFunctionCycleList;
++typedef TQMap<TQString, TraceObject> TraceObjectMap;
++typedef TQMap<TQString, TraceClass> TraceClassMap;
++typedef TQMap<TQString, TraceFile> TraceFileMap;
++typedef TQMap<TQString, TraceFunction> TraceFunctionMap;
++typedef TQMap<uint, TraceLine> TraceLineMap;
++
++
++/**
++ * Addresses are 64bit values like costs to be able
++ * to always load profile data produced on 64bit
++ * architectures.
++ */
++class Addr
++{
++ public:
++ Addr() { _v=0; }
++ Addr(uint64 v) { _v = v; }
++
++ // Interpretes char data at s as hex (without "0x" prefix)
++ // and return number of interpreted chars.
++ int set(const char *s);
++ bool set(FixString& s);
++ TQString toString() const;
++ // similar to toString(), but adds a space every 4 digits
++ TQString pretty() const;
++
++ // returns true if this address is in [a-distance;a+distance]
++ bool isInRange(Addr a, int distance);
++
++ bool operator==(const Addr& a) const { return (_v == a._v); }
++ bool operator!=(const Addr& a) const { return (_v != a._v); }
++ bool operator>(const Addr& a) const { return _v > a._v; }
++ bool operator>=(const Addr& a) const { return _v >= a._v; }
++ bool operator<(const Addr& a) const { return _v < a._v; }
++ bool operator<=(const Addr& a) const { return _v <= a._v; }
++
++ Addr operator+(int d) const { return Addr(_v + d); }
++ Addr operator-(int d) const { return Addr(_v - d); }
++
++ private:
++ uint64 _v;
++};
++
++typedef TQMap<Addr, TraceInstr> TraceInstrMap;
++
++
++/**
++ * Base class for cost items.
++ */
++class TraceItem
++{
++public:
++
++ // RTTI for trace item classes, using type() method
++ enum CostType { Item, Cost,
++ PartInstr, Instr,
++ PartLine, Line,
++ PartInstrJump, InstrJump,
++ PartLineJump, LineJump,
++ PartInstrCall, InstrCall,
++ PartLineCall, LineCall,
++ PartCall, Call,
++ PartLineRegion, LineRegion,
++ PartFunction, FunctionSource, Function, FunctionCycle,
++ PartClass, Class, ClassCycle,
++ PartFile, File, FileCycle,
++ PartObject, Object, ObjectCycle,
++ Part, Data,
++ MaxCostType, NoCostType };
++
++ TraceItem();
++ virtual ~TraceItem();
++
++ virtual CostType type() const { return Item; }
++
++ // conversion of item type to locale independent string (e.g. for config)
++ static TQString typeName(CostType);
++ static CostType costType(TQString);
++ // the versions below should be used for user visible strings, as
++ // these use localisation settings
++ static TQString i18nTypeName(CostType);
++ static CostType i18nCostType(TQString);
++ // clean up some static data
++ static void cleanup();
++
++ /**
++ * Returns dynamic name info (without type)
++ */
++ virtual TQString name() const;
++
++ /**
++ * Same as name, but sometimes nicer for humans :-)
++ */
++ virtual TQString prettyName() const;
++
++ /**
++ * Returns text of all cost metrics
++ */
++ virtual TQString costString(TraceCostMapping*);
++
++ /**
++ * Returns type name + dynamic name
++ */
++ TQString fullName() const;
++
++ /**
++ * Returns full name + cost text
++ */
++ TQString toString();
++
++ /**
++ * Set all cost counters to zero
++ */
++ virtual void clear();
++
++ /** Invalidate the cost attributes.
++ * An invalidated object needs to be recalculated when a cost
++ * attribute is requested (e.g. by subCost()).
++ * Has to be overwritten by subclasses when the cost influences costs of
++ * other cost items. If only one item depends on the cost of this item,
++ * it can by set with setDependant() without a need for overwriting.
++ */
++ virtual void invalidate();
++
++ /**
++ * Sets a dependant to be invalidated when this cost is invalidated.
++ * Call this function directly after the constructor.
++ */
++ void setDependant(TraceItem* d) { _dep = d; }
++
++ TraceItem* dependant() { return _dep; }
++
++ /**
++ * If this item is from a single profile data file, position
++ * points to a TracePart, otherwise to a TraceData object.
++ */
++ void setPosition(TraceItem* p) { _position = p; }
++
++ // getters for specific positions, to be overwritten
++ virtual TracePart* part();
++ virtual const TracePart* part() const;
++ virtual TraceData* data();
++ virtual const TraceData* data() const;
++
++ protected:
++ /** Updates cost attributes.
++ * This has to be called by subclasses that access cost attributes
++ * directly
++ */
++ virtual void update();
++
++ bool _dirty;
++
++ TraceItem* _position;
++ TraceItem* _dep;
++
++ private:
++ static TQString *_typeName, *_i18nTypeName;
++};
++
++
++
++/**
++ * An array of basic cost metrics for a trace item.
++ *
++ * The semantic of specific indexes is stored in the
++ * TraceCostMapping of the TraceData object holding this TraceCost.
++ */
++class TraceCost: public TraceItem
++{
++public:
++ /**
++ * The maximal number of subcosts a TraceCost can have.
++ */
++ static const int MaxRealIndex;
++#define MaxRealIndexValue 13
++ static const int InvalidIndex;
++
++
++ TraceCost();
++ virtual ~TraceCost();
++
++ virtual CostType type() const { return Cost; }
++ virtual TQString costString(TraceCostMapping*);
++
++ virtual void clear();
++
++ // set the cost according to a submapping and a list of ASCII numbers
++ void set(TraceSubMapping*, const char*);
++ void set(TraceSubMapping*, FixString&);
++ // add a cost according to a submapping and a list of ASCII numbers
++ void addCost(TraceSubMapping*, const char*);
++ void addCost(TraceSubMapping*, FixString&);
++ // add the cost of another item
++ void addCost(TraceCost* item);
++ void addCost(int index, SubCost value);
++
++ // maximal cost
++ void maxCost(TraceSubMapping*, FixString&);
++ void maxCost(TraceCost* item);
++ void maxCost(int index, SubCost value);
++ TraceCost diff(TraceCost* item);
++
++ virtual void invalidate();
++
++ /** Returns a sub cost. This automatically triggers
++ * a call to update() if needed.
++ */
++ SubCost subCost(TraceCostType*);
++
++ /**
++ * Same as above, but only for real types
++ */
++ SubCost subCost(int);
++
++ /** Returns a cost attribute converted to a string
++ * (with space after every 3 digits)
++ */
++ TQString prettySubCost(TraceCostType*);
++
++ protected:
++ virtual void update();
++
++ SubCost _cost[MaxRealIndexValue];
++ int _count; // only _count first indexes of _cost are used
++
++ // cache last virtual subcost for faster access
++ SubCost _cachedCost;
++ TraceCostType* _cachedType;
++};
++
++
++
++/**
++ * A cost type, e.g. "L1 Read Miss", short "l1rm".
++ *
++ * We distinguish "real" cost types, where the values come
++ * from the trace file, and "virtual" cost types, which
++ * are calculated from the real ones.
++ *
++ * For a virtual cost type, set a formula to calculate it:
++ * e.g. for "Read Misses" : "l1rm + l2rm".
++ * To allow for parsing, you must specify a TraceCostMapping
++ * with according cost types (e.g. "l1rm" and "l2rm" for above formula).
++ *
++ * The cost type with empty name is the "const" cost type.
++ */
++class TraceCostType
++{
++public:
++
++ /**
++ * <name> is a short (non-localized) identifier for the cost type,
++ * e.g. "l1rm".
++ * <longName> is a long localized string, e.g. "L1 Read Miss"
++ * <formula> uses short names to reference other types
++ */
++ TraceCostType(TQString name,
++ TQString longName = TQString(),
++ TQString formula = TQString());
++
++ void setName(TQString n) { _name = n; }
++ void setLongName(TQString n) { _longName = n; }
++ void setMapping(TraceCostMapping* m);
++ void setFormula(TQString);
++ // default arg is for specifying a real type, but index unknown
++ void setRealIndex(int r = TraceCost::MaxRealIndex);
++
++ const TQString& name() { return _name; }
++ const TQString& longName() { return _longName; }
++ const TQString& formula() { return _formula; }
++ TraceCostMapping* mapping() { return _mapping; }
++ int realIndex() { return _realIndex; }
++ bool isReal() { return _formula.isEmpty(); }
++ TQColor color();
++
++ /*
++ * returns true if all cost type names can be resolved in formula
++ */
++ bool parseFormula();
++ TQString parsedFormula();
++
++ SubCost subCost(TraceCost*);
++
++ /*
++ * For virtual costs, returns a histogram for use with
++ * partitionPixmap().
++ * Returns maximal real index.
++ */
++ int histCost(TraceCost* c, double total, double* hist);
++
++ // application wide known types, referenced by short name
++ // next 2 functions return a new type object instance
++ static TraceCostType* knownRealType(TQString);
++ static TraceCostType* knownVirtualType(TQString);
++ static void add(TraceCostType*);
++ static bool remove(TQString);
++ static int knownTypeCount();
++ static TraceCostType* knownType(int);
++
++private:
++
++ TQString _name, _longName, _formula;
++ TraceCostMapping* _mapping;
++ bool _parsed, _inParsing;
++ // index MaxRealIndex is for constant addition
++ int _coefficient[MaxRealIndexValue];
++ int _realIndex;
++
++ static TQPtrList<TraceCostType>* _knownTypes;
++};
++
++
++/**
++ * A class for managing a set of cost types.
++ *
++ * Each cost type has an index:
++ * - Real costs are in range [0 .. TraceCost:MaxRealIndex[
++ * - Virtual costs are in range [MaxRealIndex, ...]
++ */
++class TraceCostMapping
++{
++public:
++ TraceCostMapping();
++ ~TraceCostMapping();
++
++ /**
++ * Defines a sub mapping with a list of real types
++ * If <create> is false, checks if this is a existing sub mapping.
++ */
++ TraceSubMapping* subMapping(TQString types, bool create = true);
++
++ // "knows" about some real types
++ int addReal(TQString);
++ int add(TraceCostType*);
++ bool remove(TraceCostType*);
++ int realCount() { return _realCount; }
++ int virtualCount() { return _virtualCount; }
++ int minVirtualIndex() { return TraceCost::MaxRealIndex; }
++ TraceCostType* type(int);
++ TraceCostType* realType(int);
++ TraceCostType* virtualType(int);
++ TraceCostType* type(TQString);
++ TraceCostType* typeForLong(TQString);
++ int realIndex(TQString);
++ int index(TQString);
++ TQColor* realColors() { return _realColor; }
++
++ /**
++ * Adds all known virtual types that can be parsed
++ */
++ int addKnownVirtualTypes();
++
++private:
++ // we support only a fixed number of real and virtual types
++ TraceCostType* _real[MaxRealIndexValue];
++ TQColor _realColor[MaxRealIndexValue];
++ TraceCostType* _virtual[MaxRealIndexValue];
++ int _realCount, _virtualCount;
++};
++
++/**
++ * A submapping of a TraceCostMapping
++ *
++ * This is a fixed ordered list of indexes for real cost types
++ * in a mapping.
++ *
++ * You can define a mapping by requesting submappings. Undefined cost
++ * types will get a new real type index.
++ * TraceCostMapping m;
++ * sm1 = m.subMapping("Event1 Cost1 Cost2"); // returns submap [0,1,2]
++ * sm2 = m.subMapping("Event2 Cost3 Event1"); // returns submap [3,4,0]
++ * Real types of m will be:
++ * (0:Event1, 1:Cost1, 2:Cost2, 3:Event2, 4:Cost3)
++ */
++class TraceSubMapping
++{
++public:
++ TraceSubMapping(TraceCostMapping*);
++
++ bool append(TQString, bool create=true);
++ bool append(int);
++ void clear();
++
++ /**
++ * Get number of used indexes
++ */
++ int count() { return _count; }
++
++ /**
++ * Is this submapping the identity( i.e. realIndex(i)=i ) ?
++ * This often allows for optimizations.
++ */
++ bool isIdentity() { return _isIdentity; }
++ int realIndex(int i)
++ { return (i<0 || i>=_count) ? TraceCost::InvalidIndex : _realIndex[i]; }
++
++ /*
++ * Allows an iteration over the sorted list of all real indexes not used in
++ * this submapping, up to topIndex (use TraceCost::MaxRealIndex for all).
++ * Usage: for(i = firstUnused(); i < topIndex; i = nextUnused(i)) { LOOP }
++ */
++ int firstUnused() { return _firstUnused; }
++ int nextUnused(int i) {
++ if (i<0 || i>=TraceCost::MaxRealIndex) return TraceCost::InvalidIndex;
++ return _nextUnused[i]; }
++
++private:
++ TraceCostMapping* _mapping;
++ int _count, _firstUnused;
++ bool _isIdentity;
++ int _realIndex[MaxRealIndexValue];
++ int _nextUnused[MaxRealIndexValue];
++};
++
++
++/**
++ * Cost of a (conditional) jump.
++ */
++class TraceJumpCost: public TraceItem
++{
++ public:
++ TraceJumpCost();
++ virtual ~TraceJumpCost();
++
++ // reimplementations for cost addition
++ virtual TQString costString(TraceCostMapping* m);
++ virtual void clear();
++
++ void addCost(TraceJumpCost*);
++
++ // additional cost metrics
++ SubCost followedCount();
++ SubCost executedCount();
++ void addFollowedCount(SubCost c) { _followedCount += c; }
++ void addExecutedCount(SubCost c) { _executedCount += c; }
++
++ protected:
++ SubCost _executedCount, _followedCount;
++};
++
++
++
++/**
++ * Cost item with additional call count metric.
++ */
++class TraceCallCost: public TraceCost
++{
++ public:
++ TraceCallCost();
++ virtual ~TraceCallCost();
++
++ // reimplementations for cost addition
++ virtual TQString costString(TraceCostMapping* m);
++ virtual void clear();
++
++ // additional cost metric
++ SubCost callCount();
++ TQString prettyCallCount();
++ void addCallCount(SubCost c);
++
++ protected:
++ SubCost _callCount;
++};
++
++
++/**
++ * Cost item with additional inclusive metric
++ */
++class TraceInclusiveCost: public TraceCost
++{
++ public:
++ TraceInclusiveCost();
++ virtual ~TraceInclusiveCost();
++
++ // reimplementations for cost addition
++ virtual TQString costString(TraceCostMapping* m);
++ virtual void clear();
++
++ // additional cost metric
++ TraceCost* inclusive();
++ void addInclusive(TraceCost*);
++
++ protected:
++ TraceCost _inclusive;
++};
++
++
++/**
++ * Cost Item
++ * dependend on a list of cost items.
++ */
++class TraceListCost: public TraceCost
++{
++ public:
++ TraceListCost();
++ virtual ~TraceListCost();
++
++ // reimplementation for dependency list
++ virtual void update();
++
++ TraceCostList& deps() { return _deps; }
++ void addDep(TraceCost*);
++ TraceCost* findDepFromPart(TracePart*);
++
++ protected:
++ // overwrite in subclass to change update behaviour
++ virtual bool onlyActiveParts() { return false; }
++
++ TraceCostList _deps;
++
++ private:
++ // very temporary: cached
++ TraceCost* _lastDep;
++};
++
++
++/**
++ * Jump Cost Item
++ * dependend on a list of Jump cost items.
++ */
++class TraceJumpListCost: public TraceJumpCost
++{
++ public:
++ TraceJumpListCost();
++ virtual ~TraceJumpListCost();
++
++ // reimplementation for dependency list
++ virtual void update();
++
++ TraceJumpCostList deps() { return _deps; }
++ void addDep(TraceJumpCost*);
++ TraceJumpCost* findDepFromPart(TracePart*);
++
++ protected:
++ // overwrite in subclass to change update behaviour
++ virtual bool onlyActiveParts() { return false; }
++
++ TraceJumpCostList _deps;
++
++ private:
++ // very temporary: cached
++ TraceJumpCost* _lastDep;
++};
++
++
++
++
++/**
++ * Call Cost Item
++ * dependend on a list of Call cost items.
++ */
++class TraceCallListCost: public TraceCallCost
++{
++ public:
++ TraceCallListCost();
++ virtual ~TraceCallListCost();
++
++ // reimplementation for dependency list
++ virtual void update();
++
++ TraceCallCostList deps() { return _deps; }
++ void addDep(TraceCallCost*);
++ TraceCallCost* findDepFromPart(TracePart*);
++
++ protected:
++ // overwrite in subclass to change update behaviour
++ virtual bool onlyActiveParts() { return false; }
++
++ TraceCallCostList _deps;
++
++ private:
++ // very temporary: cached
++ TraceCallCost* _lastDep;
++};
++
++
++/**
++ * Inclusive Cost Item dependend on a list of inclusive cost items.
++ */
++class TraceInclusiveListCost: public TraceInclusiveCost
++{
++ public:
++ TraceInclusiveListCost();
++ virtual ~TraceInclusiveListCost();
++
++ // reimplementation for dependency
++ virtual void update();
++
++ TraceInclusiveCostList deps() { return _deps; }
++ void addDep(TraceInclusiveCost*);
++ TraceInclusiveCost* findDepFromPart(TracePart*);
++
++ protected:
++ // overwrite in subclass to change update behaviour
++ virtual bool onlyActiveParts() { return false; }
++
++ TraceInclusiveCostList _deps;
++
++ private:
++ // very temporary: cached
++ TraceInclusiveCost* _lastDep;
++};
++
++
++
++
++
++/*-----------------------------------------------------------------
++ * Classes for cost items of one trace file, i.e. a "trace part"
++ *-----------------------------------------------------------------
++ */
++
++/**
++ * Cost of jump at a instruction code address from a trace file.
++ */
++class TracePartInstrJump: public TraceJumpCost
++{
++ public:
++ TracePartInstrJump(TraceInstrJump*, TracePartInstrJump*);
++ virtual ~TracePartInstrJump();
++
++ virtual CostType type() const { return PartInstrJump; }
++ // fix cost item
++ virtual void update() {}
++ TraceInstrJump* instrJump() const { return (TraceInstrJump*) _dep; }
++ TracePartInstrJump* next() const { return _next; }
++
++ private:
++ // chaining all parts for InstrJump
++ TracePartInstrJump* _next;
++};
++
++
++/**
++ * Cost of a call at a instruction code address from a trace file.
++ * Cost is always up to date, no lazy update needed.
++ */
++class TracePartInstrCall: public TraceCallCost
++{
++public:
++ TracePartInstrCall(TraceInstrCall*);
++ virtual ~TracePartInstrCall();
++
++ virtual CostType type() const { return PartInstrCall; }
++ // fix cost item
++ virtual void update() {}
++ TraceInstrCall* instrCall() const { return (TraceInstrCall*) _dep; }
++};
++
++
++/**
++ * Cost of a code instruction address from a trace file.
++ * Cost is always up to date, no lazy update needed.
++ */
++class TracePartInstr: public TraceCost
++{
++public:
++ TracePartInstr(TraceInstr*);
++ virtual ~TracePartInstr();
++
++ virtual CostType type() const { return PartInstr; }
++ // fix cost item
++ virtual void update() {}
++
++ TraceInstr* instr() const { return (TraceInstr*)_dep; }
++};
++
++
++/**
++ * Cost of jump at a source line from a trace file.
++ */
++class TracePartLineJump: public TraceJumpCost
++{
++ public:
++ TracePartLineJump(TraceLineJump*);
++ virtual ~TracePartLineJump();
++
++ virtual CostType type() const { return PartLineJump; }
++ // fix cost item
++ virtual void update() {}
++ TraceLineJump* lineJump() const { return (TraceLineJump*) _dep; }
++};
++
++
++/**
++ * Cost of a call at a line from a trace file.
++ * Cost is always up to date, no lazy update needed.
++ */
++class TracePartLineCall: public TraceCallCost
++{
++public:
++ TracePartLineCall(TraceLineCall*);
++ virtual ~TracePartLineCall();
++
++ virtual CostType type() const { return PartLineCall; }
++ // fix cost item
++ virtual void update() {}
++ TraceLineCall* lineCall() const { return (TraceLineCall*) _dep; }
++};
++
++
++
++/**
++ * Cost of a line from a trace file.
++ * Cost is always up to date, no lazy update needed.
++ */
++class TracePartLine: public TraceCost
++{
++public:
++ TracePartLine(TraceLine*);
++ virtual ~TracePartLine();
++
++ virtual CostType type() const { return PartLine; }
++ // fix cost item
++ virtual void update() {}
++
++ TraceLine* line() const { return (TraceLine*)_dep; }
++};
++
++
++/**
++ * Cost of a source region.
++ */
++class TracePartLineRegion: public TraceInclusiveCost
++{
++public:
++ TracePartLineRegion(TraceLineRegion*);
++ virtual ~TracePartLineRegion();
++
++ virtual CostType type() const { return PartLineRegion; }
++ virtual void update();
++
++ TraceLineRegion* region() const { return (TraceLineRegion*)_dep; }
++};
++
++
++/**
++ * Cost of a call at a function to another function,
++ * from a single trace file.
++ */
++class TracePartCall: public TraceCallListCost
++{
++public:
++ TracePartCall(TraceCall* call);
++ virtual ~TracePartCall();
++
++ virtual CostType type() const { return PartCall; }
++ // calls a function itself?
++ bool isRecursion();
++
++ // reimplementation for dependency list
++ virtual void update();
++
++ TraceCall* call() const { return (TraceCall*)_dep; }
++
++ FixCallCost* setFirstFixCallCost(FixCallCost* fc)
++ { FixCallCost* t = _firstFixCallCost; _firstFixCallCost = fc; return t; }
++ FixCallCost* firstFixCallCost() const { return _firstFixCallCost; }
++
++private:
++ FixCallCost* _firstFixCallCost;
++};
++
++
++/**
++ * Cost of a function,
++ * from a single trace file.
++ */
++class TracePartFunction: public TraceInclusiveCost
++{
++public:
++ TracePartFunction(TraceFunction*,
++ TracePartObject*, TracePartFile*);
++ virtual ~TracePartFunction();
++
++ virtual CostType type() const { return PartFunction; }
++ virtual void update();
++ virtual TQString costString(TraceCostMapping* m);
++
++ void addPartInstr(TracePartInstr*);
++ void addPartLine(TracePartLine*);
++ void addPartCaller(TracePartCall*);
++ void addPartCalling(TracePartCall*);
++
++ TraceFunction* function() { return (TraceFunction*) _dep; }
++ TracePartObject* partObject() { return _partObject; }
++ TracePartClass* partClass() { return _partClass; }
++ TracePartFile* partFile() { return _partFile; }
++ const TracePartCallList& partCallers() { return _partCallers; }
++ const TracePartCallList& partCallings() { return _partCallings; }
++ void setPartObject(TracePartObject* o) { _partObject = o; }
++ void setPartClass(TracePartClass* c) { _partClass = c; }
++ void setPartFile(TracePartFile* f) { _partFile = f; }
++
++ /* for linked list of FixXXX objects */
++ FixCost* setFirstFixCost(FixCost* fc)
++ { FixCost* t = _firstFixCost; _firstFixCost = fc; return t; }
++ FixCost* firstFixCost() const { return _firstFixCost; }
++ FixJump* setFirstFixJump(FixJump* fj)
++ { FixJump* t = _firstFixJump; _firstFixJump = fj; return t; }
++ FixJump* firstFixJump() const { return _firstFixJump; }
++
++ // additional cost metrics
++ SubCost calledCount();
++ SubCost callingCount();
++ TQString prettyCalledCount();
++ TQString prettyCallingCount();
++ int calledContexts();
++ int callingContexts();
++
++private:
++ TracePartObject* _partObject;
++ TracePartClass* _partClass;
++ TracePartFile* _partFile;
++
++ TracePartCallList _partCallings;
++ TracePartCallList _partCallers;
++ TracePartInstrList _partInstr;
++ TracePartLineList _partLines;
++
++ // cached
++ SubCost _calledCount, _callingCount;
++ int _calledContexts, _callingContexts;
++
++ FixCost* _firstFixCost;
++ FixJump* _firstFixJump;
++};
++
++
++/**
++ * Cost of a class,
++ * from a single trace file.
++ */
++class TracePartClass: public TraceInclusiveListCost
++{
++public:
++ TracePartClass(TraceClass*);
++ virtual ~TracePartClass();
++
++ virtual CostType type() const { return PartClass; }
++ TQString prettyName() const;
++
++ TraceClass* cls() { return (TraceClass*)_dep; }
++ void addPartFunction(TracePartFunction* f) { addDep(f); }
++};
++
++
++/**
++ * Cost of a source file,
++ * from a single trace file.
++ */
++class TracePartFile: public TraceInclusiveListCost
++{
++public:
++ TracePartFile(TraceFile*);
++ virtual ~TracePartFile();
++
++ virtual CostType type() const { return PartFile; }
++ TraceFile* file() { return (TraceFile*)_dep; }
++ void addPartFunction(TracePartFunction* f) { addDep(f); }
++};
++
++
++/**
++ * Cost of a object,
++ * from a single trace file.
++ */
++class TracePartObject: public TraceInclusiveListCost
++{
++public:
++ TracePartObject(TraceObject*);
++ virtual ~TracePartObject();
++
++ virtual CostType type() const { return PartObject; }
++ TraceObject* object() const { return (TraceObject*)_dep; }
++ void addPartFunction(TracePartFunction* f) { addDep(f); }
++};
++
++
++
++/**
++ * A Trace Part: All data read from a trace file, containing all costs
++ * that happened in a specified time interval of the executed command.
++ */
++class TracePart: public TraceListCost
++{
++public:
++ TracePart(TraceData*, TQFile* file);
++ virtual ~TracePart();
++
++ virtual CostType type() const { return Part; }
++ virtual TracePart* part() { return this; }
++ virtual const TracePart* part() const { return this; }
++
++ TQString shortName() const;
++ TQString prettyName() const;
++ TQFile* file() const { return _file; }
++ TQString name() const { return _name; }
++ TQString description() const { return _descr; }
++ TQString trigger() const { return _trigger; }
++ TQString timeframe() const { return _timeframe; }
++ TQString version() const { return _version; }
++ int partNumber() { return _number; }
++ int threadID() { return _tid; }
++ int processID() { return _pid; }
++ void setDescription(const TQString& d) { _descr = d; }
++ void setTrigger(const TQString& t) { _trigger = t; }
++ void setTimeframe(const TQString& t) { _timeframe = t; }
++ void setVersion(const TQString& v) { _version = v; }
++ void setPartNumber(int n);
++ void setThreadID(int t);
++ void setProcessID(int p);
++ TraceCost* totals() { return &_totals; }
++ /* we get owner of the submapping */
++ void setFixSubMapping(TraceSubMapping* sm) { _fixSubMapping = sm; }
++ TraceSubMapping* fixSubMapping() { return _fixSubMapping; }
++
++ // returns true if something changed
++ bool activate(bool);
++ bool isActive() { return _active; }
++
++private:
++ TQFile* _file;
++ TQString _name;
++ TQString _descr;
++ TQString _trigger;
++ TQString _timeframe;
++ TQString _version;
++
++ int _number, _tid, _pid;
++
++ bool _active;
++
++ // the totals line
++ TraceCost _totals;
++
++ // submapping for all fix costs of this part
++ TraceSubMapping* _fixSubMapping;
++};
++
++
++class TracePartList: public TQPtrList<TracePart>
++{
++ public:
++ TQString names() const;
++ protected:
++ int compareItems ( Item item1, Item item2 );
++};
++
++
++/*-----------------------------------------------------------------
++ * Classes for cost items summed up from multiple trace parts
++ *-----------------------------------------------------------------
++ */
++
++
++/**
++ * A jump from an instruction to another inside of a function
++ */
++class TraceInstrJump: public TraceJumpCost
++{
++public:
++ TraceInstrJump(TraceInstr* instrFrom, TraceInstr* instrTo,
++ bool isCondJump);
++ virtual ~TraceInstrJump();
++
++ virtual CostType type() const { return InstrJump; }
++ virtual TQString name() const;
++
++ virtual void update();
++
++ TraceInstr* instrFrom() const { return _instrFrom; }
++ TraceInstr* instrTo() const { return _instrTo; }
++ bool isCondJump() const { return _isCondJump; }
++
++ // part factory
++ TracePartInstrJump* partInstrJump(TracePart*);
++
++ private:
++ TraceInstr *_instrFrom, *_instrTo;
++ bool _isCondJump;
++ // list of parts for this InstrJump
++ TracePartInstrJump* _first;
++};
++
++class TraceInstrJumpList: public TQPtrList<TraceInstrJump>
++{
++ public:
++ TraceInstrJumpList() { _sortLow = true; }
++ void setSortLow(bool s) { _sortLow = s; }
++
++ protected:
++ int compareItems ( Item item1, Item item2 );
++
++ private:
++ bool _sortLow;
++};
++
++
++/**
++ * A jump from one line to another inside of a function.
++ */
++class TraceLineJump: public TraceJumpListCost
++{
++ public:
++ TraceLineJump(TraceLine* lineFrom, TraceLine* lineTo,
++ bool isCondJump);
++ virtual ~TraceLineJump();
++
++ virtual CostType type() const { return LineJump; }
++ virtual TQString name() const;
++
++ TraceLine* lineFrom() const { return _lineFrom; }
++ TraceLine* lineTo() const { return _lineTo; }
++ bool isCondJump() { return _isCondJump; }
++
++ // part factory
++ TracePartLineJump* partLineJump(TracePart*);
++
++ protected:
++ bool onlyActiveParts() { return true; }
++
++ private:
++ TraceLine *_lineFrom, *_lineTo;
++ bool _isCondJump;
++};
++
++
++class TraceLineJumpList: public TQPtrList<TraceLineJump>
++{
++ public:
++ TraceLineJumpList() { _sortLow = true; }
++ void setSortLow(bool s) { _sortLow = s; }
++
++ protected:
++ int compareItems ( Item item1, Item item2 );
++
++ private:
++ bool _sortLow;
++};
++
++
++/**
++ * A call from an instruction of one function to another function
++ */
++class TraceInstrCall: public TraceCallListCost
++{
++ public:
++ TraceInstrCall(TraceCall* call, TraceInstr* instr);
++ virtual ~TraceInstrCall();
++
++ virtual CostType type() const { return InstrCall; }
++ virtual TQString name() const;
++
++ TraceInstr* instr() const { return _instr; }
++ TraceCall* call() const { return _call; }
++
++ // part factory
++ TracePartInstrCall* partInstrCall(TracePart*, TracePartCall*);
++
++ protected:
++ bool onlyActiveParts() { return true; }
++
++ private:
++ TraceInstr* _instr;
++ TraceCall* _call;
++};
++
++
++/**
++ * A call from a line of one function to another function.
++ */
++class TraceLineCall: public TraceCallListCost
++{
++ public:
++ TraceLineCall(TraceCall* call, TraceLine* line);
++ virtual ~TraceLineCall();
++
++ virtual CostType type() const { return LineCall; }
++ virtual TQString name() const;
++
++ TraceLine* line() const { return _line; }
++ TraceCall* call() const { return _call; }
++
++ // part factory
++ TracePartLineCall* partLineCall(TracePart*, TracePartCall*);
++
++ protected:
++ bool onlyActiveParts() { return true; }
++
++ private:
++ TraceLine* _line;
++ TraceCall* _call;
++};
++
++
++/**
++ * A call from one to another function.
++ * Consists of a list a TraceLineCalls
++ */
++class TraceCall: public TraceCallListCost
++{
++ public:
++ TraceCall(TraceFunction* caller, TraceFunction* called);
++ virtual ~TraceCall();
++
++ virtual CostType type() const { return Call; }
++ virtual TQString name() const;
++
++ // calls a function itself?
++ bool isRecursion() { return _caller == _called; }
++
++ // return cycle number >0 if call is inside of a cycle
++ int inCycle();
++ // we need some special handling for cycle calls
++ void update();
++
++ void invalidateDynamicCost();
++
++ // factories
++ TracePartCall* partCall(TracePart*,
++ TracePartFunction*, TracePartFunction*);
++ TraceLineCall* lineCall(TraceLine*);
++ TraceInstrCall* instrCall(TraceInstr*);
++
++ TraceFunction* caller(bool skipCycle=false) const;
++ TraceFunction* called(bool skipCycle=false) const;
++ TQString callerName(bool skipCycle=false) const;
++ TQString calledName(bool skipCycle=false) const;
++ const TraceLineCallList& lineCalls() const { return _lineCalls; }
++ const TraceInstrCallList& instrCalls() const { return _instrCalls; }
++
++ FixCallCost* setFirstFixCost(FixCallCost* fc)
++ { FixCallCost* t = _firstFixCost; _firstFixCost = fc; return t; }
++
++ protected:
++ bool onlyActiveParts() { return true; }
++
++ private:
++ TraceInstrCallList _instrCalls;
++ TraceLineCallList _lineCalls;
++ TraceFunction* _caller;
++ TraceFunction* _called;
++
++ FixCallCost* _firstFixCost;
++};
++
++
++/**
++ * A code instruction address of the program.
++ * Consists of a list a TracePartInstr from different trace files
++ * and a list of TraceInstrCalls if there are calls from this address.
++ */
++class TraceInstr: public TraceListCost
++{
++ public:
++ TraceInstr();
++ virtual ~TraceInstr();
++
++ virtual CostType type() const { return Instr; }
++ virtual TQString name() const;
++ TQString prettyName() const;
++
++ bool isValid() { return _addr != Addr(0); }
++
++ // factories
++ TracePartInstr* partInstr(TracePart* part,
++ TracePartFunction* partFunction);
++ TraceInstrJump* instrJump(TraceInstr* to, bool isCondJump);
++
++ void addInstrCall(TraceInstrCall*);
++
++ Addr addr() const { return _addr; }
++ TraceFunction* function() const { return _function; }
++ TraceLine* line() const { return _line; }
++ const TraceInstrJumpList& instrJumps() const { return _instrJumps; }
++ const TraceInstrCallList& instrCalls() const { return _instrCalls; }
++ bool hasCost(TraceCostType*);
++
++ // only to be called after default constructor
++ void setAddr(const Addr addr) { _addr = addr; }
++ void setFunction(TraceFunction* f) { _function = f; }
++ void setLine(TraceLine* l) { _line = l; }
++
++ protected:
++ bool onlyActiveParts() { return true; }
++
++ private:
++ Addr _addr;
++ TraceFunction* _function;
++ TraceLine* _line;
++
++ TraceInstrJumpList _instrJumps;
++ TraceInstrCallList _instrCalls;
++};
++
++
++/**
++ * A source line of the program.
++ * Consists of a list a TracePartLines from different trace files
++ * and a list of TraceLineCalls if there are calls from this line.
++ */
++class TraceLine: public TraceListCost
++{
++public:
++ TraceLine();
++ virtual ~TraceLine();
++
++ virtual CostType type() const { return Line; }
++ virtual TQString name() const;
++ TQString prettyName() const;
++
++ // factories
++ TracePartLine* partLine(TracePart* part,
++ TracePartFunction* partFunction);
++ TraceLineJump* lineJump(TraceLine* to, bool isCondJump);
++
++ void addLineCall(TraceLineCall*);
++
++
++ bool isValid() { return _sourceFile != 0; }
++ bool hasCost(TraceCostType*);
++ TraceFunctionSource* functionSource() const { return _sourceFile; }
++ uint lineno() const { return _lineno; }
++ const TraceLineCallList& lineCalls() const { return _lineCalls; }
++ const TraceLineJumpList& lineJumps() const { return _lineJumps; }
++
++ // only to be called after default constructor
++ void setSourceFile(TraceFunctionSource* sf) { _sourceFile = sf; }
++ void setLineno(uint lineno) { _lineno = lineno; }
++
++ protected:
++ bool onlyActiveParts() { return true; }
++
++ private:
++ TraceFunctionSource* _sourceFile;
++ uint _lineno;
++
++ TraceLineJumpList _lineJumps;
++ TraceLineCallList _lineCalls;
++};
++
++
++/*
++ * Base class for all costs which
++ * represent "interesting" items or group of items
++ * with settable name and inclusive cost
++ */
++class TraceCostItem: public TraceInclusiveListCost
++{
++ public:
++ TraceCostItem();
++ virtual ~TraceCostItem();
++
++ virtual TQString name() const { return _name; }
++ virtual void setName(const TQString& name) { _name = name; }
++
++ protected:
++ bool onlyActiveParts() { return true; }
++
++ protected:
++ TQString _name;
++};
++
++
++/**
++ * Cost of a source region.
++ */
++class TraceLineRegion: public TraceInclusiveListCost
++{
++public:
++ TraceLineRegion(uint from, uint to, TQString name);
++ virtual ~TraceLineRegion();
++
++ virtual CostType type() const { return LineRegion; }
++ virtual void update();
++
++ uint from() const { return _from; }
++ uint to() const { return _to; }
++ TQString name() const { return _name; }
++
++ // factories
++ TracePartLine* partLineRegion(TracePart* part,
++ TracePartFunction* partFunction);
++ private:
++ uint _from, _to;
++ TQString _name;
++};
++
++
++/**
++ * A container helper class for TraceFunction for source lines
++ * where a function is implemented in.
++ * With inlining, lines of the same function can come from
++ * different source files.
++ * An instance of this class holds all lines of one source file
++ * for a function in a map
++ */
++class TraceFunctionSource: public TraceCost
++{
++public:
++ TraceFunctionSource(TraceFunction*, TraceFile*);
++ virtual ~TraceFunctionSource();
++
++ virtual CostType type() const { return FunctionSource; }
++ virtual TQString name() const;
++
++ // reimplementation for dependency map
++ virtual void update();
++
++ TraceFile* file() const { return _file; }
++ TraceFunction* function() const { return _function; }
++ uint firstLineno();
++ uint lastLineno();
++ TraceLineMap* lineMap();
++
++ void invalidateDynamicCost();
++
++ /* factories */
++ TraceLine* line(uint lineno, bool createNew = true);
++ TraceLineRegion* region(uint from, uint to, TQString name,
++ bool createNew = true);
++
++ private:
++ TraceFile* _file;
++ TraceFunction* _function;
++ TraceLineMap* _lineMap;
++ TraceLine* _line0;
++ TraceLineRegionList* _regions;
++
++ bool _lineMapFilled;
++};
++
++
++/**
++ * For temporary assoziation of objects with TraceFunctions.
++ * Used in coverage analysis and TreeMap drawing.
++ */
++class TraceAssoziation
++{
++ public:
++ /**
++ * Creates an invalid assoziation.
++ */
++ TraceAssoziation();
++ virtual ~TraceAssoziation();
++
++ // for runtime detection
++ virtual int rtti() { return 0; }
++
++ /**
++ * Could we set the function assoziation to ourself?
++ * This only can return false if this is a unique assoziation.
++ */
++ bool isAssoziated();
++
++ /**
++ * reset function to assoziate this object to.
++ * returns true if assoziation could be established
++ */
++ bool setFunction(TraceFunction*);
++ TraceFunction* function() { return _function; }
++
++ void invalidate() { _valid = false; }
++ bool isValid() { return _valid; }
++
++ /**
++ * Delete all assoziations in TraceFunctions of data with
++ * rtti runtime info. rtti = 0: delete ALL assoziations.
++ */
++ static void clear(TraceData* data, int rtti);
++
++ /**
++ * Invalidate all assoziations in TraceFunctions of data with
++ * rtti runtime info. rtti = 0: Invalidate ALL assoziations.
++ */
++ static void invalidate(TraceData* data, int rtti);
++
++ protected:
++ TraceFunction* _function;
++ bool _valid;
++};
++
++typedef TQPtrList<TraceAssoziation> TraceAssoziationList;
++typedef TQMap<TraceFunction*, TraceCall*> TraceCallMap;
++
++/**
++ * A traced function
++ *
++ * References to functions are stored in
++ * (1) a function map in TraceData (by value)
++ * (2) a TraceClass
++ */
++class TraceFunction: public TraceCostItem
++{
++ public:
++ TraceFunction();
++ TraceFunction(TraceData* data, const TQString& name,
++ TraceClass* cls, TraceFile* file, TraceObject* object);
++ virtual ~TraceFunction();
++
++ virtual CostType type() const { return Function; }
++ virtual void update();
++
++ // this invalidate all subcosts of function depending on
++ // active status of parts
++ void invalidateDynamicCost();
++
++ void addCaller(TraceCall*);
++
++ // factories
++ TraceCall* calling(TraceFunction* called);
++ TraceLine* line(TraceFile*, uint lineno, bool createNew = true);
++ TraceInstr* instr(Addr addr, bool createNew = true);
++ TracePartFunction* partFunction(TracePart*,
++ TracePartFile*, TracePartObject*);
++
++ /**
++ * Returns empty string if location is fully unknown.
++ * Use prettyLocation for single user-visible string.
++ * A function can have a lot of code from different sources (inlined);
++ * maxItems limits this list. Default is full list
++ */
++ TQString location(int maxFiles = 0) const;
++
++ TQString prettyName() const;
++ TQString prettyLocation(int maxFiles = 0) const;
++ TQString prettyNameWithLocation(int maxFiles = 1) const;
++ void addPrettyLocation(TQString&, int maxFiles = 1) const;
++ // type + name + location
++ TQString info() const;
++
++ TraceClass* cls() const { return _cls; }
++ TraceFile* file() const { return _file; }
++ TraceObject* object() const { return _object; }
++ // get the source file with lines from function declaration (not inlined)
++ TraceFunctionSource* sourceFile(TraceFile* file = 0,
++ bool createNew = false);
++ const TraceFunctionSourceList& sourceFiles() const
++ { return _sourceFiles; }
++ TraceCallList callers(bool skipCycle=false) const;
++ const TraceCallList& callings(bool skipCycle=false) const;
++
++ Addr firstAddress() const;
++ Addr lastAddress() const;
++ TraceInstrMap* instrMap();
++
++ // cost metrics
++ SubCost calledCount();
++ SubCost callingCount();
++ TQString prettyCalledCount();
++ TQString prettyCallingCount();
++ int calledContexts();
++ int callingContexts();
++
++ // only to be called after default constructor
++ void setFile(TraceFile* file) { _file = file; }
++ void setObject(TraceObject* object) { _object = object; }
++ void setClass(TraceClass* cls) { _cls = cls; }
++ void setMapIterator(TraceFunctionMap::Iterator it) { _myMapIterator = it; }
++
++ // see TraceFunctionAssoziation
++ void addAssoziation(TraceAssoziation* a);
++ void removeAssoziation(TraceAssoziation* a);
++ void removeAssoziation(int rtti, bool reallyDelete = true);
++ void invalidateAssoziation(int rtti);
++ TraceAssoziation* assoziation(int rtti);
++
++ // cycles
++ void setCycle(TraceFunctionCycle* c) { _cycle = c; }
++ TraceFunctionCycle* cycle() { return _cycle; }
++ bool isCycle();
++ bool isCycleMember();
++ void cycleReset();
++ void cycleDFS(int d, int& pNo, TraceFunction** pTop);
++
++ protected:
++ TraceCallList _callers; // list of calls we are called from
++ TraceCallList _callings; // list of calls we are calling (we are owner)
++ TraceCallMap _callingMap; // contains the same as _callings in a map
++ TraceFunctionCycle* _cycle;
++
++ private:
++ bool isUniquePrefix(TQString) const;
++ TraceFunctionMap::Iterator _myMapIterator;
++
++ TraceClass* _cls;
++ TraceObject* _object;
++ TraceFile* _file;
++
++ TraceFunctionSourceList _sourceFiles; // we are owner
++ TraceInstrMap* _instrMap; // we are owner
++ bool _instrMapFilled;
++
++ // see TraceAssoziation
++ TraceAssoziationList _assoziations;
++
++ // for cycle detection
++ int _cycleLow;
++ TraceFunction* _cycleStackDown;
++
++ // cached
++ SubCost _calledCount, _callingCount;
++ int _calledContexts, _callingContexts;
++};
++
++typedef TQMap<TraceFunction*,int> TraceFunctionSet;
++
++/**
++ * A cycle of recursive calling functions.
++ *
++ * This is itself shown as a function
++ */
++class TraceFunctionCycle: public TraceFunction
++{
++ public:
++ TraceFunctionCycle(TraceFunction*, int n);
++
++ virtual CostType type() const { return FunctionCycle; }
++
++ // this removes all members from this cycle
++ void init();
++ void add(TraceFunction*);
++ // this sets up the cycle once members are added
++ void setup();
++
++ TraceFunction* base() const { return _base; }
++ int cycleNo() const { return _cycleNo; }
++ const TraceFunctionList& members() const { return _members; }
++
++ private:
++ TraceFunction* _base;
++ int _cycleNo;
++
++ TraceFunctionList _members;
++ TraceFunctionSet _memberSet;
++};
++
++
++/**
++ * A C++ Class / Namespace
++ *
++ * If a function symbol has a prefix ending in "::",
++ * the prefix is supposed to be a class/namespace specifier.
++ * Without such a prefix, we put a symbol in the "(global)" namespace.
++ */
++class TraceClass: public TraceCostItem
++{
++ public:
++ TraceClass();
++ virtual ~TraceClass();
++
++ virtual CostType type() const { return Class; }
++ virtual TQString prettyName() const;
++
++ void addFunction(TraceFunction*);
++ const TraceFunctionList& functions() const { return _functions; }
++
++ // part factory
++ TracePartClass* partClass(TracePart*);
++
++ private:
++ TraceFunctionList _functions;
++};
++
++
++
++/**
++ * A source file containing function definitions
++ */
++class TraceFile: public TraceCostItem
++{
++ public:
++ TraceFile();
++ virtual ~TraceFile();
++
++ virtual CostType type() const { return File; }
++ void setDirectory(const TQString& dir);
++ void resetDirectory() { _dir = TQString(); }
++ TQString directory();
++
++ void addFunction(TraceFunction*);
++ void addSourceFile(TraceFunctionSource*);
++
++ // without path
++ TQString shortName() const;
++ TQString prettyName() const;
++ TQString prettyLongName() const;
++ const TraceFunctionList& functions() const { return _functions; }
++ const TraceFunctionSourceList& sourceFiles() const
++ { return _sourceFiles; }
++
++ // part factory
++ TracePartFile* partFile(TracePart*);
++
++ private:
++ TraceFunctionList _functions;
++ TraceFunctionSourceList _sourceFiles;
++ TQString _dir;
++};
++
++
++/**
++ * A object containing a text segment (shared lib/executable)
++ * with defined functions
++ */
++class TraceObject: public TraceCostItem
++{
++ public:
++ TraceObject();
++ virtual ~TraceObject();
++
++ virtual CostType type() const { return Object; }
++
++ void addFunction(TraceFunction*);
++
++ virtual void setName(const TQString& name);
++ TQString shortName() const { return _shortName; }
++ TQString prettyName() const;
++ const TraceFunctionList& functions() const { return _functions; }
++
++ // part factory
++ TracePartObject* partObject(TracePart*);
++
++ private:
++ TraceFunctionList _functions;
++ TQString _shortName;
++};
++
++
++
++/**
++ * This class holds profiling data of multiple tracefiles
++ * generated with cachegrind on one command.
++ *
++ */
++class TraceData: public TraceCost
++{
++ public:
++ TraceData(TopLevel* top = 0);
++ TraceData(const TQString& base);
++ virtual ~TraceData();
++
++ virtual CostType type() const { return Data; }
++ virtual TraceData* data() { return this; }
++ virtual const TraceData* data() const { return this; }
++
++ /**
++ * Loads a trace file.
++ *
++ * This adjusts the TraceCostMapping according to given cost types
++ */
++ void load(const TQString&);
++
++ /** returns true if something changed. These do NOT
++ * invalidate the dynamic costs on a activation change,
++ * i.e. all cost items dependend on active parts.
++ * This has to be done by the caller when true is returned by
++ * calling invalidateDynamicCost().
++ */
++ bool activateParts(const TracePartList&);
++ bool activateParts(TracePartList, bool active);
++ bool activatePart(TracePart*, bool active);
++ bool activateAll(bool active=true);
++
++ TracePartList parts() const { return _parts; }
++ TracePart* part(TQString& name);
++
++ // with path
++ TQString traceName() const { return _traceName; }
++
++ // without path
++ TQString shortTraceName() const;
++ TQString activePartRange();
++
++ TraceCostMapping* mapping() { return &_mapping; }
++
++ // memory pools
++ FixPool* fixPool();
++ DynPool* dynPool();
++
++ // factories for object/file/class/function/line instances
++ TraceObject* object(const TQString& name);
++ TraceFile* file(const TQString& name);
++ TraceClass* cls(const TQString& fnName, TQString& shortName);
++ // function creation involves class creation if needed
++ TraceFunction* function(const TQString& name, TraceFile*, TraceObject*);
++ // factory for function cycles
++ TraceFunctionCycle* functionCycle(TraceFunction*);
++
++ /**
++ * Search for item with given name and highest subcost of given cost type.
++ *
++ * For some items, they will only be found if the parent cost is given:
++ * Instr, Line, Call => need parent of type Function
++ * For Function, a parent of type Obj/File/Class can be given, but
++ * isn't needed.
++ */
++ TraceCost* search(TraceItem::CostType, TQString,
++ TraceCostType* ct = 0, TraceCost* parent = 0);
++
++ // for pretty function names without signature if unique...
++ TraceFunctionMap::Iterator functionIterator(TraceFunction*);
++ TraceFunctionMap::ConstIterator functionBeginIterator() const;
++ TraceFunctionMap::ConstIterator functionEndIterator() const;
++
++ TraceObjectMap& objectMap() { return _objectMap; }
++ TraceFileMap& fileMap() { return _fileMap; }
++ TraceClassMap& classMap() { return _classMap; }
++ TraceFunctionMap& functionMap() { return _functionMap; }
++
++ const TraceFunctionCycleList& functionCycles() { return _functionCycles; }
++
++ TraceCost* callMax() { return &_callMax; }
++
++ void setCommand(const TQString& command) { _command = command; }
++ TQString command() const { return _command; }
++ TraceCost* totals() { return &_totals; }
++ void setMaxThreadID(int tid) { _maxThreadID = tid; }
++ int maxThreadID() const { return _maxThreadID; }
++ void setMaxPartNumber(int n) { _maxPartNumber = n; }
++ int maxPartNumber() const { return _maxPartNumber; }
++
++ // reset all manually set directories for source files
++ void resetSourceDirs();
++
++ virtual void update();
++
++ // invalidates all cost items dependant on active state of parts
++ void invalidateDynamicCost();
++
++ // cycle detection
++ void updateFunctionCycles();
++ void updateObjectCycles();
++ void updateClassCycles();
++ void updateFileCycles();
++ bool inFunctionCycleUpdate() { return _inFunctionCycleUpdate; }
++
++ private:
++ void init();
++ // add trace part: events from one trace file
++ TracePart* addPart(const TQString& dir, const TQString& file);
++
++ // for progress bar callbacks
++ TopLevel* _topLevel;
++
++ TracePartList _parts;
++
++ // The mapping for all costs
++ TraceCostMapping _mapping;
++
++ FixPool* _fixPool;
++ DynPool* _dynPool;
++
++ // always the trace totals (not dependent on active parts)
++ TraceCost _totals;
++ int _maxThreadID;
++ int _maxPartNumber;
++
++ TraceObjectMap _objectMap;
++ TraceClassMap _classMap;
++ TraceFileMap _fileMap;
++ TraceFunctionMap _functionMap;
++ TQString _command;
++ TQString _traceName;
++
++ // Max of all costs of calls: This allows to see if the incl. cost can
++ // be hidden for a cost type, as it's always the same as self cost
++ TraceCost _callMax;
++
++ // cycles
++ TraceFunctionCycleList _functionCycles;
++ int _functionCycleCount;
++ bool _inFunctionCycleUpdate;
++};
++
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/traceitemview.cpp b/kdecachegrind/kdecachegrind/traceitemview.cpp
+new file mode 100644
+index 0000000..d11f02b
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/traceitemview.cpp
+@@ -0,0 +1,443 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Trace Item View
++ */
++
++#include <tqwidget.h>
++#include <kconfig.h>
++#include <klocale.h>
++#include <kdebug.h>
++
++#include "traceitemview.h"
++#include "toplevel.h"
++
++#define TRACE_UPDATES 0
++
++TraceItemView::TraceItemView(TraceItemView* parentView, TopLevel* top)
++{
++ _parentView = parentView;
++ _topLevel = top ? top : parentView->topLevel();
++
++ _data = _newData = 0;
++ // _partList and _newPartList is empty
++ _activeItem = _newActiveItem = 0;
++ _selectedItem = _newSelectedItem = 0;
++ _costType = _newCostType = 0;
++ _costType2 = _newCostType2 = 0;
++ _groupType = _newGroupType = TraceItem::NoCostType;
++
++ _status = nothingChanged;
++ _inUpdate = false;
++ _pos = Hidden;
++}
++
++TQString TraceItemView::whatsThis() const
++{
++ return i18n("No description available");
++}
++
++void TraceItemView::select(TraceItem* i)
++{
++ _newSelectedItem = i;
++}
++
++KConfigGroup* TraceItemView::configGroup(KConfig* c,
++ TQString group, TQString post)
++{
++ TQStringList gList = c->groupList();
++ if (gList.contains((group+post).ascii()) ) group += post;
++ return new KConfigGroup(c, group);
++}
++
++void TraceItemView::writeConfigEntry(KConfigBase* c, const char* pKey,
++ TQString value, const char* def, bool bNLS)
++{
++ if (!c) return;
++ if ((value.isEmpty() && ((def == 0) || (*def == 0))) ||
++ (value == TQString(def)))
++ c->deleteEntry(pKey);
++ else
++ c->writeEntry(pKey, value, true, false, bNLS);
++}
++
++void TraceItemView::writeConfigEntry(KConfigBase* c, const char* pKey,
++ int value, int def)
++{
++ if (!c) return;
++ if (value == def)
++ c->deleteEntry(pKey);
++ else
++ c->writeEntry(pKey, value);
++}
++
++void TraceItemView::writeConfigEntry(KConfigBase* c, const char* pKey,
++ double value, double def)
++{
++ if (!c) return;
++ if (value == def)
++ c->deleteEntry(pKey);
++ else
++ c->writeEntry(pKey, value);
++}
++
++void TraceItemView::writeConfigEntry(KConfigBase* c, const char* pKey,
++ bool value, bool def)
++{
++ if (!c) return;
++ if (value == def)
++ c->deleteEntry(pKey);
++ else
++ c->writeEntry(pKey, value);
++}
++
++void TraceItemView::readViewConfig(KConfig*, TQString, TQString, bool)
++{}
++
++#if 1
++void TraceItemView::saveViewConfig(KConfig*, TQString, TQString, bool)
++{}
++#else
++void TraceItemView::saveViewConfig(KConfig* c,
++ TQString prefix, TQString postfix, bool)
++{
++ // write a dummy config entry to see missing virtual functions
++ KConfigGroup g(c, (prefix+postfix).ascii());
++ g.writeEntry("SaveNotImplemented", true);
++}
++#endif
++
++bool TraceItemView::activate(TraceItem* i)
++{
++ i = canShow(i);
++ _newActiveItem = i;
++
++ return (i != 0);
++}
++
++TraceFunction* TraceItemView::activeFunction()
++{
++ TraceItem::CostType t = _activeItem->type();
++ switch(t) {
++ case TraceItem::Function:
++ case TraceItem::FunctionCycle:
++ return (TraceFunction*) _activeItem;
++ default:
++ break;
++ }
++ return 0;
++}
++
++bool TraceItemView::set(int changeType, TraceData* d,
++ TraceCostType* t1, TraceCostType* t2,
++ TraceItem::CostType g, const TracePartList& l,
++ TraceItem* a, TraceItem* s)
++{
++ _status |= changeType;
++ _newData = d;
++ _newGroupType = g;
++ _newCostType = t1;
++ _newCostType2 = t2;
++ _newPartList = l;
++ _newSelectedItem = s;
++ _newActiveItem = canShow(a);
++ if (!_newActiveItem) {
++ _newSelectedItem = 0;
++ return false;
++ }
++
++ return true;
++}
++
++
++bool TraceItemView::isViewVisible()
++{
++ TQWidget* w = widget();
++ if (w)
++ return w->isVisible();
++ return false;
++}
++
++void TraceItemView::setData(TraceData* d)
++{
++ _newData = d;
++
++ // invalidate all pointers to old data
++ _activeItem = _newActiveItem = 0;
++ _selectedItem = _newSelectedItem = 0;
++ _costType = _newCostType = 0;
++ _costType2 = _newCostType2 = 0;
++ _groupType = _newGroupType = TraceItem::NoCostType;
++ _partList.clear();
++ _newPartList.clear();
++
++ // updateView will change this to dataChanged
++ _status = nothingChanged;
++}
++
++void TraceItemView::updateView(bool force)
++{
++ if (!force && !isViewVisible()) return;
++
++ if (_newData != _data) {
++ _status |= dataChanged;
++ _data = _newData;
++ }
++ else {
++ _status &= ~dataChanged;
++
++ // if there's no data change and data is 0, no update needed
++ if (!_data) return;
++ }
++
++ if (!(_newPartList == _partList)) {
++ _status |= partsChanged;
++ _partList = _newPartList;
++ }
++ else
++ _status &= ~partsChanged;
++
++ if (_newActiveItem != _activeItem) {
++
++ // when setting a new active item, there's no selection
++ _selectedItem = 0;
++
++ _status |= activeItemChanged;
++ _activeItem = _newActiveItem;
++ }
++ else
++ _status &= ~activeItemChanged;
++
++ if (_newCostType != _costType) {
++ _status |= costTypeChanged;
++ _costType = _newCostType;
++ }
++ else
++ _status &= ~costTypeChanged;
++
++ if (_newCostType2 != _costType2) {
++ _status |= costType2Changed;
++ _costType2 = _newCostType2;
++ }
++ else
++ _status &= ~costType2Changed;
++
++ if (_newGroupType != _groupType) {
++ _status |= groupTypeChanged;
++ _groupType = _newGroupType;
++ }
++ else
++ _status &= ~groupTypeChanged;
++
++
++ if (_newSelectedItem != _selectedItem) {
++ _status |= selectedItemChanged;
++ _selectedItem = _newSelectedItem;
++ }
++ else
++ _status &= ~selectedItemChanged;
++
++
++ if (!force && (_status == nothingChanged)) return;
++
++#if TRACE_UPDATES
++ kdDebug() << (widget() ? widget()->name() : "TraceItemView")
++ << "::doUpdate ( "
++ << ((_status & dataChanged) ? "data ":"")
++ << ((_status & configChanged) ? "config ":"")
++ << ")" << endl;
++
++ if (_status & partsChanged)
++ kdDebug() << " Part List "
++ << _partList.names()
++ << endl;
++
++ if (_status & costTypeChanged)
++ kdDebug() << " Cost type "
++ << (_costType ? _costType->name().ascii() : "?")
++ << endl;
++
++ if (_status & costType2Changed)
++ kdDebug() << " Cost type 2 "
++ << (_costType2 ? _costType2->name().ascii() : "?")
++ << endl;
++
++ if (_status & groupTypeChanged)
++ kdDebug() << " Group type "
++ << TraceItem::typeName(_groupType)
++ << endl;
++
++ if (_status & activeItemChanged)
++ kdDebug() << " Active: "
++ << (_activeItem ? _activeItem->fullName().ascii() : "?")
++ << endl;
++
++ if (_status & selectedItemChanged)
++ kdDebug() << " Selected: "
++ << (_selectedItem ? _selectedItem->fullName().ascii() : "?")
++ << endl;
++#endif
++
++ int st = _status;
++ _status = nothingChanged;
++ doUpdate(st);
++ return;
++
++ if (_inUpdate) return;
++ _inUpdate = true;
++ doUpdate(_status);
++ _inUpdate = false;
++}
++
++
++void TraceItemView::selected(TraceItemView* /*sender*/, TraceItem* i)
++{
++#if TRACE_UPDATES
++ kdDebug() << (widget() ? widget()->name() : "TraceItemView")
++ << "::selected "
++ << (i ? i->name().ascii(): "(nil)")
++ << ", sender "
++ << sender->widget()->name() << endl;
++#endif
++
++ if (_parentView) _parentView->selected(this, i);
++}
++
++void TraceItemView::selected(TraceItemView* /*sender*/, const TracePartList& l)
++{
++#if TRACE_UPDATES
++ kdDebug() << (widget() ? widget()->name() : "TraceItemView")
++ << "::selected "
++ << l.names()
++ << ", sender "
++ << sender->widget()->name() << endl;
++#endif
++
++ if (_parentView)
++ _parentView->selected(this, l);
++ else
++ if (_topLevel) _topLevel->activePartsChangedSlot(l);
++}
++
++void TraceItemView::activated(TraceItemView* /*sender*/, TraceItem* i)
++{
++#if TRACE_UPDATES
++ kdDebug() << (widget() ? widget()->name() : "TraceItemView")
++ << "::activated "
++ << (i ? i->name().ascii(): "(nil)")
++ << ", sender "
++ << sender->widget()->name() << endl;
++#endif
++
++ if (_parentView)
++ _parentView->activated(this, i);
++ else
++ if (_topLevel) _topLevel->setTraceItemDelayed(i);
++}
++
++void TraceItemView::selectedCostType(TraceItemView*, TraceCostType* t)
++{
++ if (_parentView)
++ _parentView->selectedCostType(this, t);
++ else
++ if (_topLevel) _topLevel->setCostTypeDelayed(t);
++}
++
++void TraceItemView::selectedCostType2(TraceItemView*, TraceCostType* t)
++{
++ if (_parentView)
++ _parentView->selectedCostType2(this, t);
++ else
++ if (_topLevel) _topLevel->setCostType2Delayed(t);
++}
++
++void TraceItemView::activated(TraceItemView*, Direction d)
++{
++ if (_parentView)
++ _parentView->activated(this, d);
++ else
++ if (_topLevel) _topLevel->setDirectionDelayed(d);
++}
++
++void TraceItemView::doUpdate(int)
++{
++}
++
++void TraceItemView::selected(TraceItem* i)
++{
++ if (_parentView)
++ _parentView->selected(this, i);
++
++}
++
++void TraceItemView::selected(const TracePartList& l)
++{
++ if (_parentView)
++ _parentView->selected(this, l);
++ else
++ if (_topLevel) _topLevel->activePartsChangedSlot(l);
++}
++
++void TraceItemView::activated(TraceItem* i)
++{
++#if TRACE_UPDATES
++ kdDebug() << (widget() ? widget()->name() : "TraceItemView")
++ << "::activated "
++ << (i ? i->name().ascii(): "(nil)") << endl;
++#endif
++
++ if (_parentView)
++ _parentView->activated(this, i);
++ else
++ if (_topLevel) _topLevel->setTraceItemDelayed(i);
++}
++
++void TraceItemView::selectedCostType(TraceCostType* t)
++{
++ if (_parentView)
++ _parentView->selectedCostType(this, t);
++ else
++ if (_topLevel) _topLevel->setCostTypeDelayed(t);
++}
++
++void TraceItemView::selectedCostType2(TraceCostType* t)
++{
++ if (_parentView)
++ _parentView->selectedCostType2(this, t);
++ else
++ if (_topLevel) _topLevel->setCostType2Delayed(t);
++}
++
++void TraceItemView::activated(Direction d)
++{
++ if (_parentView)
++ _parentView->activated(this, d);
++ else
++ if (_topLevel) _topLevel->setDirectionDelayed(d);
++}
++
++void TraceItemView::addCostMenu(TQPopupMenu* p, bool withCost2)
++{
++ if (_topLevel) _topLevel->addCostMenu(p, withCost2);
++}
++
++void TraceItemView::addGoMenu(TQPopupMenu* p)
++{
++ if (_topLevel) _topLevel->addGoMenu(p);
++}
+diff --git a/kdecachegrind/kdecachegrind/traceitemview.h b/kdecachegrind/kdecachegrind/traceitemview.h
+new file mode 100644
+index 0000000..f83aa89
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/traceitemview.h
+@@ -0,0 +1,206 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Trace Item View
++ */
++
++#ifndef TRACEITEMVIEW_H
++#define TRACEITEMVIEW_H
++
++#include "tracedata.h"
++
++class TQWidget;
++class TQPopupMenu;
++
++class KConfig;
++class KConfigGroup;
++class KConfigBase;
++
++class TopLevel;
++
++/**
++ * Abstract Base Class for KCachegrind Views
++ *
++ * This class delivers the shared functionality of all KCachegrind
++ * Views for one TraceItem (like Function, Object...), the "active"
++ * item. Additional view attributes are current primary cost type,
++ * an optional secondary cost type, group type,
++ * and possibly a selected costitem in this view.
++ * Note that there is a difference in changing the selected item of
++ * a view (this usually changes selection in other views, too), and
++ * activating that item.
++ */
++class TraceItemView
++{
++public:
++
++ /**
++ * Change type for update functions
++ * - <dataChanged> is used if e.g. cycles are recalculated
++ */
++ enum { nothingChanged = 0,
++ costTypeChanged = 1,
++ costType2Changed = 2,
++ groupTypeChanged = 4,
++ partsChanged = 8,
++ activeItemChanged = 16,
++ selectedItemChanged = 32,
++ dataChanged = 64,
++ configChanged = 128 };
++
++ enum Direction { None, Back, Forward, Up };
++
++ // a TraceItemView can have a position in a parent container
++ enum Position { Hidden, Top, Right, Left, Bottom };
++
++ TraceItemView(TraceItemView* parentView, TopLevel* top = 0);
++ virtual ~TraceItemView() {}
++
++ virtual TQString whatsThis() const;
++
++ static KConfigGroup* configGroup(KConfig*, TQString prefix, TQString postfix);
++ static void writeConfigEntry(KConfigBase*, const char* pKey, TQString value,
++ const char* def, bool bNLS = false);
++ static void writeConfigEntry(KConfigBase*, const char* pKey,
++ int value, int def);
++ static void writeConfigEntry(KConfigBase*, const char* pKey,
++ bool value, bool def);
++ static void writeConfigEntry(KConfigBase*, const char* pKey,
++ double value, double def);
++ virtual void readViewConfig(KConfig*, TQString prefix, TQString postfix,
++ bool withOptions);
++ virtual void saveViewConfig(KConfig*, TQString prefix, TQString postfix,
++ bool withOptions);
++
++ // Immediate remove all references to old data, and set the new.
++ // This resets the visualization state.
++ // A GUI update has to be triggered with updateView().
++ // Overwrite in container views to also set new data for all members.
++ virtual void setData(TraceData* d);
++
++ // change from parent, call updateView() to update lazily (only if visible)
++ void setCostType(TraceCostType* t) { _newCostType = t; }
++ void setCostType2(TraceCostType* t) { _newCostType2 = t; }
++ void set(TraceItem::CostType g) { _newGroupType = g; }
++ void set(const TracePartList& l) { _newPartList = l; }
++ // returns false if nothing can be shown for this trace item
++ bool activate(TraceItem* i);
++ void select(TraceItem* i);
++ void notifyChange(int changeType) { _status |= changeType; }
++ // all in one
++ bool set(int, TraceData*, TraceCostType*, TraceCostType*,
++ TraceItem::CostType, const TracePartList&,
++ TraceItem*, TraceItem*);
++
++ // general update request, call if view is/gets visible
++ void updateView(bool force = false);
++
++ /**
++ * Notification from child views.
++ * Default implementation notifies parent
++ */
++ virtual void selected(TraceItemView* sender, TraceItem*);
++ virtual void selected(TraceItemView* sender, const TracePartList&);
++ virtual void activated(TraceItemView* sender, Direction);
++ virtual void selectedCostType(TraceItemView* sender, TraceCostType*);
++ virtual void selectedCostType2(TraceItemView* sender, TraceCostType*);
++ virtual void activated(TraceItemView* sender, TraceItem*);
++
++ // getters...
++ // always get the newest values
++ TraceData* data() const { return _newData; }
++ TraceItem* activeItem() const { return _newActiveItem; }
++ TraceItem* selectedItem() const { return _newSelectedItem; }
++ TraceCostType* costType() const { return _newCostType; }
++ TraceCostType* costType2() const { return _newCostType2; }
++ TraceItem::CostType groupType() const { return _newGroupType; }
++ const TracePartList& partList() const { return _newPartList; }
++
++ TraceFunction* activeFunction();
++ int status() const { return _status; }
++
++ // pointer to top level window to e.g. show status messages
++ void setTopLevel(TopLevel* t) { _topLevel = t; }
++ TopLevel* topLevel() const { return _topLevel; }
++
++ void setPosition(Position p) { _pos = p; }
++ Position position() const { return _pos; }
++
++ void setTitle(TQString t) { _title = t; }
++ TQString title() const { return _title; }
++
++ // We depend on derived class to be a widget.
++ // Force overiding by making this abstract.
++ virtual TQWidget* widget() = 0;
++
++ /**
++ * This function is called when a new item should become active.
++ * Reimplement this in subclasses.
++ *
++ * Returns the real item to become active. You can call select() here.
++ * Return 0 if nothing can be shown.
++ * Use the methods like data() instead of _data here, as
++ * _data possibly will give old/wrong information.
++ */
++ virtual TraceItem* canShow(TraceItem* i) { return i; }
++
++ /* convenience functions for often used context menu items */
++ void addCostMenu(TQPopupMenu*,bool withCost2 = true);
++ void addGoMenu(TQPopupMenu*);
++
++protected:
++ // helpers to call selected()/activated() of parentView
++ void selected(TraceItem*);
++ void selected(const TracePartList&);
++ void activated(TraceItem*);
++ void selectedCostType(TraceCostType*);
++ void selectedCostType2(TraceCostType*);
++ void activated(Direction);
++
++ /* Is this view visible?
++ * if not, doUpdate() won't be called by updateView()
++ */
++ virtual bool isViewVisible();
++
++ // update handler (to be reimplemented)
++ virtual void doUpdate(int changeType);
++
++ TraceItemView* _parentView;
++ TopLevel* _topLevel;
++
++ TraceData* _data;
++ TracePartList _partList;
++ TraceItem *_activeItem, *_selectedItem;
++ TraceCostType *_costType, *_costType2;
++ TraceItem::CostType _groupType;
++
++private:
++ TraceData* _newData;
++ TracePartList _newPartList;
++ TraceItem *_newActiveItem, *_newSelectedItem;
++ TraceCostType *_newCostType, *_newCostType2;
++ TraceItem::CostType _newGroupType;
++
++ TQString _title;
++ int _status;
++ bool _inUpdate;
++ Position _pos;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/treemap.cpp b/kdecachegrind/kdecachegrind/treemap.cpp
+new file mode 100644
+index 0000000..0d4b8dc
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/treemap.cpp
+@@ -0,0 +1,3214 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * A Widget for visualizing hierarchical metrics as areas.
++ * The API is similar to TQListView.
++ */
++
++#include <math.h>
++
++#include <tqpainter.h>
++#include <tqtooltip.h>
++#include <tqregexp.h>
++#include <tqstyle.h>
++#include <tqpopupmenu.h>
++
++#include <klocale.h>
++#include <kconfig.h>
++#include <kdebug.h>
++
++#include "treemap.h"
++
++
++// set this to 1 to enable debug output
++#define DEBUG_DRAWING 0
++#define MAX_FIELD 12
++
++
++//
++// StoredDrawParams
++//
++StoredDrawParams::StoredDrawParams()
++{
++ _selected = false;
++ _current = false;
++ _shaded = true;
++ _rotated = false;
++
++ _backColor = TQt::white;
++
++ // field array has size 0
++}
++
++StoredDrawParams::StoredDrawParams(TQColor c,
++ bool selected, bool current)
++{
++ _backColor = c;
++
++ _selected = selected;
++ _current = current;
++ _shaded = true;
++ _rotated = false;
++ _drawFrame = true;
++
++ // field array has size 0
++}
++
++TQString StoredDrawParams::text(int f) const
++{
++ if ((f<0) || (f >= (int)_field.size()))
++ return TQString();
++
++ return _field[f].text;
++}
++
++TQPixmap StoredDrawParams::pixmap(int f) const
++{
++ if ((f<0) || (f >= (int)_field.size()))
++ return TQPixmap();
++
++ return _field[f].pix;
++}
++
++DrawParams::Position StoredDrawParams::position(int f) const
++{
++ if ((f<0) || (f >= (int)_field.size()))
++ return Default;
++
++ return _field[f].pos;
++}
++
++int StoredDrawParams::maxLines(int f) const
++{
++ if ((f<0) || (f >= (int)_field.size()))
++ return 0;
++
++ return _field[f].maxLines;
++}
++
++const TQFont& StoredDrawParams::font() const
++{
++ static TQFont* f = 0;
++ if (!f) f = new TQFont(TQApplication::font());
++
++ return *f;
++}
++
++void StoredDrawParams::ensureField(int f)
++{
++ static Field* def = 0;
++ if (!def) {
++ def = new Field();
++ def->pos = Default;
++ def->maxLines = 0;
++ }
++
++ if (f<0 || f>=MAX_FIELD) return;
++
++ if ((int)_field.size() < f+1) _field.resize(f+1, *def);
++}
++
++
++void StoredDrawParams::setField(int f, const TQString& t, TQPixmap pm,
++ Position p, int maxLines)
++{
++ if (f<0 || f>=MAX_FIELD) return;
++ ensureField(f);
++
++ _field[f].text = t;
++ _field[f].pix = pm;
++ _field[f].pos = p;
++ _field[f].maxLines = maxLines;
++}
++
++void StoredDrawParams::setText(int f, const TQString& t)
++{
++ if (f<0 || f>=MAX_FIELD) return;
++ ensureField(f);
++
++ _field[f].text = t;
++}
++
++void StoredDrawParams::setPixmap(int f, const TQPixmap& pm)
++{
++ if (f<0 || f>=MAX_FIELD) return;
++ ensureField(f);
++
++ _field[f].pix = pm;
++}
++
++void StoredDrawParams::setPosition(int f, Position p)
++{
++ if (f<0 || f>=MAX_FIELD) return;
++ ensureField(f);
++
++ _field[f].pos = p;
++}
++
++void StoredDrawParams::setMaxLines(int f, int m)
++{
++ if (f<0 || f>=MAX_FIELD) return;
++ ensureField(f);
++
++ _field[f].maxLines = m;
++}
++
++
++
++//
++// RectDrawing
++//
++
++RectDrawing::RectDrawing(TQRect r)
++{
++ _fm = 0;
++ _dp = 0;
++ setRect(r);
++}
++
++
++RectDrawing::~RectDrawing()
++{
++ delete _fm;
++ delete _dp;
++}
++
++DrawParams* RectDrawing::drawParams()
++{
++ if (!_dp)
++ _dp = new StoredDrawParams();
++
++ return _dp;
++}
++
++
++void RectDrawing::setDrawParams(DrawParams* dp)
++{
++ if (_dp) delete _dp;
++ _dp = dp;
++}
++
++void RectDrawing::setRect(TQRect r)
++{
++ _rect = r;
++
++ _usedTopLeft = 0;
++ _usedTopCenter = 0;
++ _usedTopRight = 0;
++ _usedBottomLeft = 0;
++ _usedBottomCenter = 0;
++ _usedBottomRight = 0;
++
++ _fontHeight = 0;
++}
++
++TQRect RectDrawing::remainingRect(DrawParams* dp)
++{
++ if (!dp) dp = drawParams();
++
++ if ((_usedTopLeft >0) ||
++ (_usedTopCenter >0) ||
++ (_usedTopRight >0)) {
++ if (dp->rotated())
++ _rect.setLeft(_rect.left() + _fontHeight);
++ else
++ _rect.setTop(_rect.top() + _fontHeight);
++ }
++
++ if ((_usedBottomLeft >0) ||
++ (_usedBottomCenter >0) ||
++ (_usedBottomRight >0)) {
++ if (dp->rotated())
++ _rect.setRight(_rect.right() - _fontHeight);
++ else
++ _rect.setBottom(_rect.bottom() - _fontHeight);
++ }
++ return _rect;
++}
++
++
++void RectDrawing::drawBack(TQPainter* p, DrawParams* dp)
++{
++ if (!dp) dp = drawParams();
++ if (_rect.width()<=0 || _rect.height()<=0) return;
++
++ TQRect r = _rect;
++ TQColor normal = dp->backColor();
++ if (dp->selected()) normal = normal.light();
++ bool isCurrent = dp->current();
++
++ if (dp->drawFrame() || isCurrent) {
++ // 3D raised/sunken frame effect...
++ TQColor high = normal.light();
++ TQColor low = normal.dark();
++ p->setPen( isCurrent ? low:high);
++ p->drawLine(r.left(), r.top(), r.right(), r.top());
++ p->drawLine(r.left(), r.top(), r.left(), r.bottom());
++ p->setPen( isCurrent ? high:low);
++ p->drawLine(r.right(), r.top(), r.right(), r.bottom());
++ p->drawLine(r.left(), r.bottom(), r.right(), r.bottom());
++ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2);
++ }
++ if (r.width()<=0 || r.height()<=0) return;
++
++ if (dp->shaded()) {
++ // some shading
++ bool goDark = tqGray(normal.rgb())>128;
++ int rBase, gBase, bBase;
++ normal.rgb(&rBase, &gBase, &bBase);
++ p->setBrush(TQBrush::NoBrush);
++
++ // shade parameters:
++ int d = 7;
++ float factor = 0.1, forth=0.7, back1 =0.9, toBack2 = .7, back2 = 0.97;
++
++ // coefficient corrections because of rectangle size
++ int s = r.width();
++ if (s > r.height()) s = r.height();
++ if (s<100) {
++ forth -= .3 * (100-s)/100;
++ back1 -= .2 * (100-s)/100;
++ back2 -= .02 * (100-s)/100;
++ }
++
++
++ // maximal color difference
++ int rDiff = goDark ? -rBase/d : (255-rBase)/d;
++ int gDiff = goDark ? -gBase/d : (255-gBase)/d;
++ int bDiff = goDark ? -bBase/d : (255-bBase)/d;
++
++ TQColor shadeColor;
++ while (factor<.95) {
++ shadeColor.setRgb((int)(rBase+factor*rDiff+.5),
++ (int)(gBase+factor*gDiff+.5),
++ (int)(bBase+factor*bDiff+.5));
++ p->setPen(shadeColor);
++ p->drawRect(r);
++ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2);
++ if (r.width()<=0 || r.height()<=0) return;
++ factor = 1.0 - ((1.0 - factor) * forth);
++ }
++
++ // and back (1st half)
++ while (factor>toBack2) {
++ shadeColor.setRgb((int)(rBase+factor*rDiff+.5),
++ (int)(gBase+factor*gDiff+.5),
++ (int)(bBase+factor*bDiff+.5));
++ p->setPen(shadeColor);
++ p->drawRect(r);
++ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2);
++ if (r.width()<=0 || r.height()<=0) return;
++ factor = 1.0 - ((1.0 - factor) / back1);
++ }
++
++ // and back (2nd half)
++ while ( factor>.01) {
++ shadeColor.setRgb((int)(rBase+factor*rDiff+.5),
++ (int)(gBase+factor*gDiff+.5),
++ (int)(bBase+factor*bDiff+.5));
++ p->setPen(shadeColor);
++ p->drawRect(r);
++ r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2);
++ if (r.width()<=0 || r.height()<=0) return;
++
++ factor = factor * back2;
++ }
++ }
++
++ // fill inside
++ p->setPen(TQPen::NoPen);
++ p->setBrush(normal);
++ p->drawRect(r);
++}
++
++
++bool RectDrawing::drawField(TQPainter* p, int f, DrawParams* dp)
++{
++ if (!dp) dp = drawParams();
++
++ if (!_fm) {
++ _fm = new TQFontMetrics(dp->font());
++ _fontHeight = _fm->height();
++ }
++
++ TQRect r = _rect;
++
++ if (0) kdDebug(90100) << "DrawField: Rect " << r.x() << "/" << r.y()
++ << " - " << r.width() << "x" << r.height() << endl;
++
++ int h = _fontHeight;
++ bool rotate = dp->rotated();
++ int width = (rotate ? r.height() : r.width()) -4;
++ int height = (rotate ? r.width() : r.height());
++ int lines = height / h;
++
++ // stop if we have no space available
++ if (lines<1) return false;
++
++ // calculate free space in first line (<unused>)
++ int pos = dp->position(f);
++ if (pos == DrawParams::Default) {
++ switch(f%4) {
++ case 0: pos = DrawParams::TopLeft; break;
++ case 1: pos = DrawParams::TopRight; break;
++ case 2: pos = DrawParams::BottomRight; break;
++ case 3: pos = DrawParams::BottomLeft; break;
++ }
++ }
++
++ int unused = 0;
++ bool isBottom = false;
++ bool isCenter = false;
++ bool isRight = false;
++ int* used = 0;
++ switch(pos) {
++ case DrawParams::TopLeft:
++ used = &_usedTopLeft;
++ if (_usedTopLeft == 0) {
++ if (_usedTopCenter)
++ unused = (width - _usedTopCenter)/2;
++ else
++ unused = width - _usedTopRight;
++ }
++ break;
++
++ case DrawParams::TopCenter:
++ isCenter = true;
++ used = &_usedTopCenter;
++ if (_usedTopCenter == 0) {
++ if (_usedTopLeft > _usedTopRight)
++ unused = width - 2 * _usedTopLeft;
++ else
++ unused = width - 2 * _usedTopRight;
++ }
++ break;
++
++ case DrawParams::TopRight:
++ isRight = true;
++ used = &_usedTopRight;
++ if (_usedTopRight == 0) {
++ if (_usedTopCenter)
++ unused = (width - _usedTopCenter)/2;
++ else
++ unused = width - _usedTopLeft;
++ }
++ break;
++
++ case DrawParams::BottomLeft:
++ isBottom = true;
++ used = &_usedBottomLeft;
++ if (_usedBottomLeft == 0) {
++ if (_usedBottomCenter)
++ unused = (width - _usedBottomCenter)/2;
++ else
++ unused = width - _usedBottomRight;
++ }
++ break;
++
++ case DrawParams::BottomCenter:
++ isCenter = true;
++ isBottom = true;
++ used = &_usedBottomCenter;
++ if (_usedBottomCenter == 0) {
++ if (_usedBottomLeft > _usedBottomRight)
++ unused = width - 2 * _usedBottomLeft;
++ else
++ unused = width - 2 * _usedBottomRight;
++ }
++ break;
++
++ case DrawParams::BottomRight:
++ isRight = true;
++ isBottom = true;
++ used = &_usedBottomRight;
++ if (_usedBottomRight == 0) {
++ if (_usedBottomCenter)
++ unused = (width - _usedBottomCenter)/2;
++ else
++ unused = width - _usedBottomLeft;
++ }
++ break;
++ }
++
++ if (isBottom) {
++ if ((_usedTopLeft >0) ||
++ (_usedTopCenter >0) ||
++ (_usedTopRight >0))
++ lines--;
++ }
++ else if (!isBottom) {
++ if ((_usedBottomLeft >0) ||
++ (_usedBottomCenter >0) ||
++ (_usedBottomRight >0))
++ lines--;
++ }
++ if (lines<1) return false;
++
++
++ int y = isBottom ? height - h : 0;
++
++ if (unused < 0) unused = 0;
++ if (unused == 0) {
++ // no space available in last line at this position
++ y = isBottom ? (y-h) : (y+h);
++ lines--;
++
++ if (lines<1) return false;
++
++ // new line: reset used space
++ if (isBottom)
++ _usedBottomLeft = _usedBottomCenter = _usedBottomRight = 0;
++ else
++ _usedTopLeft = _usedTopCenter = _usedTopRight = 0;
++
++ unused = width;
++ }
++
++ // stop as soon as possible when there's no space for "..."
++ static int dotW = 0;
++ if (!dotW) dotW = _fm->width("...");
++ if (width < dotW) return false;
++
++ // get text and pixmap now, only if we need to, because it is possible
++ // that they are calculated on demand (and this can take some time)
++ TQString name = dp->text(f);
++ if (name.isEmpty()) return 0;
++ TQPixmap pix = dp->pixmap(f);
++
++ // check if pixmap can be drawn
++ int pixW = pix.width();
++ int pixH = pix.height();
++ int pixY = 0;
++ bool pixDrawn = true;
++ if (pixW>0) {
++ pixW += 2; // X distance from pix
++ if ((width < pixW + dotW) || (height < pixH)) {
++ // don't draw
++ pixW = 0;
++ }
++ else
++ pixDrawn = false;
++ }
++
++ // width of text and pixmap to be drawn
++ int w = pixW + _fm->width(name);
++
++ if (0) kdDebug(90100) << " For '" << name << "': Unused " << unused
++ << ", StrW " << w << ", Width " << width << endl;
++
++ // if we have limited space at 1st line:
++ // use it only if whole name does fit in last line...
++ if ((unused < width) && (w > unused)) {
++ y = isBottom ? (y-h) : (y+h);
++ lines--;
++
++ if (lines<1) return false;
++
++ // new line: reset used space
++ if (isBottom)
++ _usedBottomLeft = _usedBottomCenter = _usedBottomRight = 0;
++ else
++ _usedTopLeft = _usedTopCenter = _usedTopRight = 0;
++ }
++
++ p->save();
++ p->setPen( (tqGray(dp->backColor().rgb())>100) ? TQt::black : TQt::white);
++ p->setFont(dp->font());
++ if (rotate) {
++ //p->translate(r.x()+2, r.y()+r.height());
++ p->translate(r.x(), r.y()+r.height()-2);
++ p->rotate(270);
++ }
++ else
++ p->translate(r.x()+2, r.y());
++
++
++ // adjust available lines according to maxLines
++ int max = dp->maxLines(f);
++ if ((max > 0) && (lines>max)) lines = max;
++
++ /* loop over name parts to break up string depending on available width.
++ * every char category change is supposed a possible break,
++ * with the exception Uppercase=>Lowercase.
++ * It's good enough for numbers, Symbols...
++ *
++ * If the text is to be written at the bottom, we start with the
++ * end of the string (so everything is reverted)
++ */
++ TQString remaining;
++ int origLines = lines;
++ while (lines>0) {
++
++ if (w>width && lines>1) {
++ int lastBreakPos = name.length(), lastWidth = w;
++ int len = name.length();
++ TQChar::Category caOld, ca;
++
++ if (!isBottom) {
++ // start with comparing categories of last 2 chars
++ caOld = name[len-1].category();
++ while (len>2) {
++ len--;
++ ca = name[len-1].category();
++ if (ca != caOld) {
++ // "Aa" has no break between...
++ if (ca == TQChar::Letter_Uppercase &&
++ caOld == TQChar::Letter_Lowercase) {
++ caOld = ca;
++ continue;
++ }
++ caOld = ca;
++ lastBreakPos = len;
++ w = pixW + _fm->width(name, len);
++ lastWidth = w;
++ if (w <= width) break;
++ }
++ }
++ w = lastWidth;
++ remaining = name.mid(lastBreakPos);
++ // remove space on break point
++ if (name[lastBreakPos-1].category() == TQChar::Separator_Space)
++ name = name.left(lastBreakPos-1);
++ else
++ name = name.left(lastBreakPos);
++ }
++ else { // bottom
++ int l = len;
++ caOld = name[l-len].category();
++ while (len>2) {
++ len--;
++ ca = name[l-len].category();
++
++ if (ca != caOld) {
++ // "Aa" has no break between...
++ if (caOld == TQChar::Letter_Uppercase &&
++ ca == TQChar::Letter_Lowercase) {
++ caOld = ca;
++ continue;
++ }
++ caOld = ca;
++ lastBreakPos = len;
++ w = pixW + _fm->width(name.right(len));
++ lastWidth = w;
++ if (w <= width) break;
++ }
++ }
++ w = lastWidth;
++ remaining = name.left(l-lastBreakPos);
++ // remove space on break point
++ if (name[l-lastBreakPos].category() == TQChar::Separator_Space)
++ name = name.right(lastBreakPos-1);
++ else
++ name = name.right(lastBreakPos);
++ }
++ }
++ else
++ remaining = TQString();
++
++ /* truncate and add ... if needed */
++ if (w>width) {
++ int len = name.length();
++ w += dotW;
++ while (len>2 && (w > width)) {
++ len--;
++ w = pixW + _fm->width(name, len) + dotW;
++ }
++ // stop drawing: we cannot draw 2 chars + "..."
++ if (w>width) break;
++
++ name = name.left(len) + "...";
++ }
++
++ int x = 0;
++ if (isCenter)
++ x = (width - w)/2;
++ else if (isRight)
++ x = width - w;
++
++ if (!pixDrawn) {
++ pixY = y+(h-pixH)/2; // default: center vertically
++ if (pixH > h) pixY = isBottom ? y-(pixH-h) : y;
++
++ p->drawPixmap( x, pixY, pix);
++
++ // for distance to next text
++ pixY = isBottom ? (pixY - h - 2) : (pixY + pixH + 2);
++ pixDrawn = true;
++ }
++
++
++ if (0) kdDebug(90100) << " Drawing '" << name << "' at "
++ << x+pixW << "/" << y << endl;
++
++ p->drawText( x+pixW, y,
++ width - pixW, h,
++ TQt::AlignLeft, name);
++ y = isBottom ? (y-h) : (y+h);
++ lines--;
++
++ if (remaining.isEmpty()) break;
++ name = remaining;
++ w = pixW + _fm->width(name);
++ }
++
++ // make sure the pix stays visible
++ if (pixDrawn && (pixY>0)) {
++ if (isBottom && (pixY<y)) y = pixY;
++ if (!isBottom && (pixY>y)) y = pixY;
++ }
++
++ if (origLines > lines) {
++ // if only 1 line written, don't reset _used* vars
++ if (lines - origLines >1) {
++ if (isBottom)
++ _usedBottomLeft = _usedBottomCenter = _usedBottomRight = 0;
++ else
++ _usedTopLeft = _usedTopCenter = _usedTopRight = 0;
++ }
++
++ // take back one line
++ y = isBottom ? (y+h) : (y-h);
++ if (used) *used = w;
++ }
++
++ // update free space
++ if (!isBottom) {
++ if (rotate)
++ _rect.setRect(r.x()+y, r.y(), r.width()-y, r.height());
++ else
++ _rect.setRect(r.x(), r.y()+y, r.width(), r.height()-y);
++ }
++ else {
++ if (rotate)
++ _rect.setRect(r.x(), r.y(), y+h, r.height());
++ else
++ _rect.setRect(r.x(), r.y(), r.width(), y+h);
++ }
++
++ p->restore();
++
++ return true;
++}
++
++
++
++
++
++
++//
++// TreeMapItemList
++//
++
++int TreeMapItemList::compareItems ( Item item1, Item item2 )
++{
++ bool ascending;
++ int result;
++
++ TreeMapItem* parent = ((TreeMapItem*)item1)->parent();
++ // shouldn't happen
++ if (!parent) return 0;
++
++ int textNo = parent->sorting(&ascending);
++
++ if (textNo < 0) {
++ double diff = ((TreeMapItem*)item1)->value() -
++ ((TreeMapItem*)item2)->value();
++ result = (diff < -.9) ? -1 : (diff > .9) ? 1 : 0;
++ }
++ else
++ result = (((TreeMapItem*)item1)->text(textNo) <
++ ((TreeMapItem*)item2)->text(textNo)) ? -1 : 1;
++
++ return ascending ? result : -result;
++}
++
++
++TreeMapItem* TreeMapItemList::commonParent()
++{
++ TreeMapItem* parent, *item;
++ parent = first();
++ if (parent)
++ while( (item = next()) != 0)
++ parent = parent->commonParent(item);
++
++ return parent;
++}
++
++
++// TreeMapItem
++
++TreeMapItem::TreeMapItem(TreeMapItem* parent, double value)
++{
++ _value = value;
++ _parent = parent;
++
++ _sum = 0;
++ _children = 0;
++ _widget = 0;
++ _index = -1;
++ _depth = -1; // not set
++ _unused_self = 0;
++ _freeRects = 0;
++
++ if (_parent) {
++ // take sorting from parent
++ _sortTextNo = _parent->sorting(&_sortAscending);
++ _parent->addItem(this);
++ }
++ else {
++ _sortAscending = false;
++ _sortTextNo = -1; // default: no sorting
++ }
++}
++
++
++TreeMapItem::TreeMapItem(TreeMapItem* parent, double value,
++ TQString text1, TQString text2,
++ TQString text3, TQString text4)
++{
++ _value = value;
++ _parent = parent;
++
++ // this resizes the text vector only if needed
++ if (!text4.isEmpty()) setText(3, text4);
++ if (!text3.isEmpty()) setText(2, text3);
++ if (!text2.isEmpty()) setText(1, text2);
++ setText(0, text1);
++
++ _sum = 0;
++ _children = 0;
++ _widget = 0;
++ _index = -1;
++ _depth = -1; // not set
++ _unused_self = 0;
++ _freeRects = 0;
++
++ if (_parent) _parent->addItem(this);
++}
++
++TreeMapItem::~TreeMapItem()
++{
++ if (_children) delete _children;
++ if (_freeRects) delete _freeRects;
++
++ // finally, notify widget about deletion
++ if (_widget) _widget->deletingItem(this);
++}
++
++void TreeMapItem::setParent(TreeMapItem* p)
++{
++ _parent = p;
++ if (p) _widget = p->_widget;
++}
++
++bool TreeMapItem::isChildOf(TreeMapItem* item)
++{
++ if (!item) return false;
++
++ TreeMapItem* i = this;
++ while (i) {
++ if (item == i) return true;
++ i = i->_parent;
++ }
++ return false;
++}
++
++TreeMapItem* TreeMapItem::commonParent(TreeMapItem* item)
++{
++ while (item && !isChildOf(item)) {
++ item = item->parent();
++ }
++ return item;
++}
++
++void TreeMapItem::redraw()
++{
++ if (_widget)
++ _widget->redraw(this);
++}
++
++void TreeMapItem::clear()
++{
++ if (_children) {
++ // delete selected items below this item from selection
++ if (_widget) _widget->clearSelection(this);
++
++ delete _children;
++ _children = 0;
++ }
++}
++
++
++// invalidates current children and forces redraw
++// this is only usefull when children are created on demand in items()
++void TreeMapItem::refresh()
++{
++ clear();
++ redraw();
++}
++
++
++TQStringList TreeMapItem::path(int textNo) const
++{
++ TQStringList list(text(textNo));
++
++ TreeMapItem* i = _parent;
++ while (i) {
++ TQString text = i->text(textNo);
++ if (!text.isEmpty())
++ list.prepend(i->text(textNo));
++ i = i->_parent;
++ }
++ return list;
++}
++
++int TreeMapItem::depth() const
++{
++ if (_depth>0) return _depth;
++
++ if (_parent)
++ return _parent->depth() + 1;
++ return 1;
++}
++
++
++bool TreeMapItem::initialized()
++{
++ if (!_children) {
++ _children = new TreeMapItemList;
++ _children->setAutoDelete(true);
++ return false;
++ }
++ return true;
++}
++
++void TreeMapItem::addItem(TreeMapItem* i)
++{
++ if (!i) return;
++
++ if (!_children) {
++ _children = new TreeMapItemList;
++ _children->setAutoDelete(true);
++ }
++ i->setParent(this);
++
++ if (sorting(0) == -1)
++ _children->append(i); // preserve insertion order
++ else
++ _children->inSort(i);
++}
++
++
++// default implementations of virtual functions
++
++double TreeMapItem::value() const
++{
++ return _value;
++}
++
++double TreeMapItem::sum() const
++{
++ return _sum;
++}
++
++DrawParams::Position TreeMapItem::position(int f) const
++{
++ Position p = StoredDrawParams::position(f);
++ if (_widget && (p == Default))
++ p = _widget->fieldPosition(f);
++
++ return p;
++}
++
++// use widget font
++const TQFont& TreeMapItem::font() const
++{
++ return _widget->currentFont();
++}
++
++
++bool TreeMapItem::isMarked(int) const
++{
++ return false;
++}
++
++
++int TreeMapItem::borderWidth() const
++{
++ if (_widget)
++ return _widget->borderWidth();
++
++ return 2;
++}
++
++int TreeMapItem::sorting(bool* ascending) const
++{
++ if (ascending) *ascending = _sortAscending;
++ return _sortTextNo;
++}
++
++// do *not* set sorting recursively
++void TreeMapItem::setSorting(int textNo, bool ascending)
++{
++ if (_sortTextNo == textNo) {
++ if(_sortAscending == ascending) return;
++ if (textNo == -1) {
++ // when no sorting is done, order change doesn't do anything
++ _sortAscending = ascending;
++ return;
++ }
++ }
++ _sortAscending = ascending;
++ _sortTextNo = textNo;
++
++ if (_children && _sortTextNo != -1) _children->sort();
++}
++
++void TreeMapItem::resort(bool recursive)
++{
++ if (!_children) return;
++
++ if (_sortTextNo != -1) _children->sort();
++
++ if (recursive)
++ for (TreeMapItem* i=_children->first(); i; i=_children->next())
++ i->resort(recursive);
++}
++
++
++TreeMapItem::SplitMode TreeMapItem::splitMode() const
++{
++ if (_widget)
++ return _widget->splitMode();
++
++ return Best;
++}
++
++int TreeMapItem::rtti() const
++{
++ return 0;
++}
++
++TreeMapItemList* TreeMapItem::children()
++{
++ if (!_children) {
++ _children = new TreeMapItemList;
++ _children->setAutoDelete(true);
++ }
++ return _children;
++}
++
++void TreeMapItem::clearItemRect()
++{
++ _rect = TQRect();
++ clearFreeRects();
++}
++
++void TreeMapItem::clearFreeRects()
++{
++ if (_freeRects) _freeRects->clear();
++}
++
++void TreeMapItem::addFreeRect(const TQRect& r)
++{
++ // don't add invalid rects
++ if ((r.width() < 1) || (r.height() < 1)) return;
++
++ if (!_freeRects) {
++ _freeRects = new TQPtrList<TQRect>;
++ _freeRects->setAutoDelete(true);
++ }
++
++ if (0) kdDebug(90100) << "addFree(" << path(0).join("/") << ", "
++ << r.x() << "/" << r.y() << "-"
++ << r.width() << "x" << r.height() << ")" << endl;
++
++ TQRect* last = _freeRects->last();
++ if (!last) {
++ _freeRects->append(new TQRect(r));
++ return;
++ }
++
++ // join rect with last rect if possible
++ // this saves memory and doesn't make the tooltip flicker
++
++ bool replaced = false;
++ if ((last->left() == r.left()) && (last->width() == r.width())) {
++ if ((last->bottom()+1 == r.top()) || (r.bottom()+1 == last->top())) {
++ *last |= r;
++ replaced = true;
++ }
++ }
++ else if ((last->top() == r.top()) && (last->height() == r.height())) {
++ if ((last->right()+1 == r.left()) || (r.right()+1 == last->left())) {
++ *last |= r;
++ replaced = true;
++ }
++ }
++
++ if (!replaced) {
++ _freeRects->append(new TQRect(r));
++ return;
++ }
++
++ if (0) kdDebug(90100) << " united with last to ("
++ << last->x() << "/" << last->y() << "-"
++ << last->width() << "x" << last->height() << ")" << endl;
++}
++
++
++// Tooltips for TreeMapWidget
++
++class TreeMapTip: public TQToolTip
++{
++public:
++ TreeMapTip( TQWidget* p ):TQToolTip(p) {}
++
++protected:
++ void maybeTip( const TQPoint & );
++};
++
++void TreeMapTip::maybeTip( const TQPoint& pos )
++{
++ if ( !parentWidget()->inherits( "TreeMapWidget" ) )
++ return;
++
++ TreeMapWidget* p = (TreeMapWidget*)parentWidget();
++ TreeMapItem* i;
++ i = p->item(pos.x(), pos.y());
++ TQPtrList<TQRect>* rList = i ? i->freeRects() : 0;
++ if (rList) {
++ TQRect* r;
++ for(r=rList->first();r;r=rList->next())
++ if (r->contains(pos))
++ tip(*r, p->tipString(i));
++ }
++}
++
++
++
++// TreeMapWidget
++
++TreeMapWidget::TreeMapWidget(TreeMapItem* base,
++ TQWidget* parent, const char* name)
++ : TQWidget(parent, name)
++{
++ _base = base;
++ _base->setWidget(this);
++
++ _font = font();
++ _fontHeight = fontMetrics().height();
++
++
++ // default behaviour
++ _selectionMode = Single;
++ _splitMode = TreeMapItem::AlwaysBest;
++ _visibleWidth = 2;
++ _reuseSpace = false;
++ _skipIncorrectBorder = false;
++ _drawSeparators = false;
++ _allowRotation = true;
++ _borderWidth = 2;
++ _shading = true; // beautiful is default!
++ _maxSelectDepth = -1; // unlimited
++ _maxDrawingDepth = -1; // unlimited
++ _minimalArea = -1; // unlimited
++ _markNo = 0;
++
++ for(int i=0;i<4;i++) {
++ _drawFrame[i] = true;
++ _transparent[i] = false;
++ }
++
++ // _stopAtText will be unset on resizing (per default)
++ // _textVisible will be true on resizing (per default)
++ // _forceText will be false on resizing (per default)
++
++ // start state: _selection is an empty list
++ _current = 0;
++ _oldCurrent = 0;
++ _pressed = 0;
++ _lastOver = 0;
++ _needsRefresh = _base;
++
++ setBackgroundMode(TQt::NoBackground);
++ setFocusPolicy(TQ_StrongFocus);
++ _tip = new TreeMapTip(this);
++}
++
++TreeMapWidget::~TreeMapWidget()
++{
++ delete _base;
++ delete _tip;
++}
++
++const TQFont& TreeMapWidget::currentFont() const
++{
++ return _font;
++}
++
++void TreeMapWidget::setSplitMode(TreeMapItem::SplitMode m)
++{
++ if (_splitMode == m) return;
++
++ _splitMode = m;
++ redraw();
++}
++
++TreeMapItem::SplitMode TreeMapWidget::splitMode() const
++{
++ return _splitMode;
++}
++
++bool TreeMapWidget::setSplitMode(TQString mode)
++{
++ if (mode == "Bisection") setSplitMode(TreeMapItem::Bisection);
++ else if (mode == "Columns") setSplitMode(TreeMapItem::Columns);
++ else if (mode == "Rows") setSplitMode(TreeMapItem::Rows);
++ else if (mode == "AlwaysBest") setSplitMode(TreeMapItem::AlwaysBest);
++ else if (mode == "Best") setSplitMode(TreeMapItem::Best);
++ else if (mode == "HAlternate") setSplitMode(TreeMapItem::HAlternate);
++ else if (mode == "VAlternate") setSplitMode(TreeMapItem::VAlternate);
++ else if (mode == "Horizontal") setSplitMode(TreeMapItem::Horizontal);
++ else if (mode == "Vertical") setSplitMode(TreeMapItem::Vertical);
++ else return false;
++
++ return true;
++}
++
++TQString TreeMapWidget::splitModeString() const
++{
++ TQString mode;
++ switch(splitMode()) {
++ case TreeMapItem::Bisection: mode = "Bisection"; break;
++ case TreeMapItem::Columns: mode = "Columns"; break;
++ case TreeMapItem::Rows: mode = "Rows"; break;
++ case TreeMapItem::AlwaysBest: mode = "AlwaysBest"; break;
++ case TreeMapItem::Best: mode = "Best"; break;
++ case TreeMapItem::HAlternate: mode = "HAlternate"; break;
++ case TreeMapItem::VAlternate: mode = "VAlternate"; break;
++ case TreeMapItem::Horizontal: mode = "Horizontal"; break;
++ case TreeMapItem::Vertical: mode = "Vertical"; break;
++ default: mode = "Unknown"; break;
++ }
++ return mode;
++}
++
++
++void TreeMapWidget::setShadingEnabled(bool s)
++{
++ if (_shading == s) return;
++
++ _shading = s;
++ redraw();
++}
++
++void TreeMapWidget::drawFrame(int d, bool b)
++{
++ if ((d<0) || (d>=4) || (_drawFrame[d]==b)) return;
++
++ _drawFrame[d] = b;
++ redraw();
++}
++
++void TreeMapWidget::setTransparent(int d, bool b)
++{
++ if ((d<0) || (d>=4) || (_transparent[d]==b)) return;
++
++ _transparent[d] = b;
++ redraw();
++}
++
++void TreeMapWidget::setAllowRotation(bool enable)
++{
++ if (_allowRotation == enable) return;
++
++ _allowRotation = enable;
++ redraw();
++}
++
++void TreeMapWidget::setVisibleWidth(int width, bool reuseSpace)
++{
++ if (_visibleWidth == width && _reuseSpace == reuseSpace) return;
++
++ _visibleWidth = width;
++ _reuseSpace = reuseSpace;
++ redraw();
++}
++
++void TreeMapWidget::setSkipIncorrectBorder(bool enable)
++{
++ if (_skipIncorrectBorder == enable) return;
++
++ _skipIncorrectBorder = enable;
++ redraw();
++}
++
++void TreeMapWidget::setBorderWidth(int w)
++{
++ if (_borderWidth == w) return;
++
++ _borderWidth = w;
++ redraw();
++}
++
++void TreeMapWidget::setMaxDrawingDepth(int d)
++{
++ if (_maxDrawingDepth == d) return;
++
++ _maxDrawingDepth = d;
++ redraw();
++}
++
++TQString TreeMapWidget::defaultFieldType(int f) const
++{
++ return i18n("Text %1").arg(f+1);
++}
++
++TQString TreeMapWidget::defaultFieldStop(int) const
++{
++ return TQString();
++}
++
++bool TreeMapWidget::defaultFieldVisible(int f) const
++{
++ return (f<2);
++}
++
++bool TreeMapWidget::defaultFieldForced(int) const
++{
++ return false;
++}
++
++DrawParams::Position TreeMapWidget::defaultFieldPosition(int f) const
++{
++ switch(f%4) {
++ case 0: return DrawParams::TopLeft;
++ case 1: return DrawParams::TopRight;
++ case 2: return DrawParams::BottomRight;
++ case 3: return DrawParams::BottomLeft;
++ default:break;
++ }
++ return DrawParams::TopLeft;
++}
++
++bool TreeMapWidget::resizeAttr(int size)
++{
++ if (size<0 || size>=MAX_FIELD) return false;
++
++ if (size>(int)_attr.size()) {
++ struct FieldAttr a;
++ int oldSize = _attr.size();
++ _attr.resize(size, a);
++ while (oldSize<size) {
++ _attr[oldSize].type = defaultFieldType(oldSize);
++ _attr[oldSize].stop = defaultFieldStop(oldSize);
++ _attr[oldSize].visible = defaultFieldVisible(oldSize);
++ _attr[oldSize].forced = defaultFieldForced(oldSize);
++ _attr[oldSize].pos = defaultFieldPosition(oldSize);
++ oldSize++;
++ }
++ }
++ return true;
++}
++
++void TreeMapWidget::setFieldType(int f, TQString type)
++{
++ if (((int)_attr.size() < f+1) &&
++ (type == defaultFieldType(f))) return;
++ if (resizeAttr(f+1)) _attr[f].type = type;
++
++ // no need to redraw: the type string is not visible in the TreeMap
++}
++
++TQString TreeMapWidget::fieldType(int f) const
++{
++ if (f<0 || (int)_attr.size()<f+1) return defaultFieldType(f);
++ return _attr[f].type;
++}
++
++void TreeMapWidget::setFieldStop(int f, TQString stop)
++{
++ if (((int)_attr.size() < f+1) &&
++ (stop == defaultFieldStop(f))) return;
++ if (resizeAttr(f+1)) {
++ _attr[f].stop = stop;
++ redraw();
++ }
++}
++
++TQString TreeMapWidget::fieldStop(int f) const
++{
++ if (f<0 || (int)_attr.size()<f+1) return defaultFieldStop(f);
++ return _attr[f].stop;
++}
++
++void TreeMapWidget::setFieldVisible(int f, bool enable)
++{
++ if (((int)_attr.size() < f+1) &&
++ (enable == defaultFieldVisible(f))) return;
++
++ if (resizeAttr(f+1)) {
++ _attr[f].visible = enable;
++ redraw();
++ }
++}
++
++bool TreeMapWidget::fieldVisible(int f) const
++{
++ if (f<0 || (int)_attr.size()<f+1)
++ return defaultFieldVisible(f);
++
++ return _attr[f].visible;
++}
++
++void TreeMapWidget::setFieldForced(int f, bool enable)
++{
++ if (((int)_attr.size() < f+1) &&
++ (enable == defaultFieldForced(f))) return;
++
++ if (resizeAttr(f+1)) {
++ _attr[f].forced = enable;
++ if (_attr[f].visible) redraw();
++ }
++}
++
++bool TreeMapWidget::fieldForced(int f) const
++{
++ if (f<0 || (int)_attr.size()<f+1)
++ return defaultFieldForced(f);
++
++ return _attr[f].forced;
++}
++
++void TreeMapWidget::setFieldPosition(int f, TreeMapItem::Position pos)
++{
++ if (((int)_attr.size() < f+1) &&
++ (pos == defaultFieldPosition(f))) return;
++
++ if (resizeAttr(f+1)) {
++ _attr[f].pos = pos;
++ if (_attr[f].visible) redraw();
++ }
++}
++
++DrawParams::Position TreeMapWidget::fieldPosition(int f) const
++{
++ if (f<0 || (int)_attr.size()<f+1)
++ return defaultFieldPosition(f);
++
++ return _attr[f].pos;
++}
++
++void TreeMapWidget::setFieldPosition(int f, TQString pos)
++{
++ if (pos == "TopLeft")
++ setFieldPosition(f, DrawParams::TopLeft);
++ else if (pos == "TopCenter")
++ setFieldPosition(f, DrawParams::TopCenter);
++ else if (pos == "TopRight")
++ setFieldPosition(f, DrawParams::TopRight);
++ else if (pos == "BottomLeft")
++ setFieldPosition(f, DrawParams::BottomLeft);
++ else if (pos == "BottomCenter")
++ setFieldPosition(f, DrawParams::BottomCenter);
++ else if (pos == "BottomRight")
++ setFieldPosition(f, DrawParams::BottomRight);
++ else if (pos == "Default")
++ setFieldPosition(f, DrawParams::Default);
++}
++
++TQString TreeMapWidget::fieldPositionString(int f) const
++{
++ TreeMapItem::Position pos = fieldPosition(f);
++ if (pos == DrawParams::TopLeft) return TQString("TopLeft");
++ if (pos == DrawParams::TopCenter) return TQString("TopCenter");
++ if (pos == DrawParams::TopRight) return TQString("TopRight");
++ if (pos == DrawParams::BottomLeft) return TQString("BottomLeft");
++ if (pos == DrawParams::BottomCenter) return TQString("BottomCenter");
++ if (pos == DrawParams::BottomRight) return TQString("BottomRight");
++ if (pos == DrawParams::Default) return TQString("Default");
++ return TQString("unknown");
++}
++
++void TreeMapWidget::setMinimalArea(int area)
++{
++ if (_minimalArea == area) return;
++
++ _minimalArea = area;
++ redraw();
++}
++
++
++void TreeMapWidget::deletingItem(TreeMapItem* i)
++{
++ // remove any references to the item to be deleted
++ while(_selection.findRef(i) > -1)
++ _selection.remove();
++
++ while(_tmpSelection.findRef(i) > -1)
++ _tmpSelection.remove();
++
++ if (_current == i) _current = 0;
++ if (_oldCurrent == i) _oldCurrent = 0;
++ if (_pressed == i) _pressed = 0;
++ if (_lastOver == i) _lastOver = 0;
++
++ // don't redraw a deleted item
++ if (_needsRefresh == i) {
++ // we can savely redraw the parent, as deleting order is
++ // from child to parent; i.e. i->parent() is existing.
++ _needsRefresh = i->parent();
++ }
++}
++
++
++TQString TreeMapWidget::tipString(TreeMapItem* i) const
++{
++ TQString tip, itemTip;
++
++ while (i) {
++ if (!i->text(0).isEmpty()) {
++ itemTip = i->text(0);
++ if (!i->text(1).isEmpty())
++ itemTip += " (" + i->text(1) + ")";
++
++ if (!tip.isEmpty())
++ tip += "\n";
++
++ tip += itemTip;
++ }
++ i = i->parent();
++ }
++ return tip;
++}
++
++TreeMapItem* TreeMapWidget::item(int x, int y) const
++{
++ TreeMapItem* p = _base;
++ TreeMapItem* i;
++
++ if (!TQT_TQRECT_OBJECT(rect()).contains(x, y)) return 0;
++ if (DEBUG_DRAWING) kdDebug(90100) << "item(" << x << "," << y << "):" << endl;
++
++ while (1) {
++ TreeMapItemList* list = p->children();
++ if (!list)
++ i = 0;
++ else {
++ int idx=0;
++ for (i=list->first();i;i=list->next(),idx++) {
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " Checking " << i->path(0).join("/") << " ("
++ << i->itemRect().x() << "/" << i->itemRect().y()
++ << "-" << i->itemRect().width()
++ << "x" << i->itemRect().height() << ")" << endl;
++
++ if (i->itemRect().contains(x, y)) {
++
++ if (DEBUG_DRAWING) kdDebug(90100) << " .. Got. Index " << idx << endl;
++
++ p->setIndex(idx);
++ break;
++ }
++ }
++ }
++
++ if (!i) {
++ static TreeMapItem* last = 0;
++ if (p != last) {
++ last = p;
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << "item(" << x << "," << y << "): Got "
++ << p->path(0).join("/") << " (Size "
++ << p->itemRect().width() << "x" << p->itemRect().height()
++ << ", Val " << p->value() << ")" << endl;
++ }
++
++ return p;
++ }
++ p = i;
++ }
++ return 0;
++}
++
++TreeMapItem* TreeMapWidget::possibleSelection(TreeMapItem* i) const
++{
++ if (i) {
++ if (_maxSelectDepth>=0) {
++ int depth = i->depth();
++ while(i && depth > _maxSelectDepth) {
++ i = i->parent();
++ depth--;
++ }
++ }
++ }
++ return i;
++}
++
++TreeMapItem* TreeMapWidget::visibleItem(TreeMapItem* i) const
++{
++ if (i) {
++ /* Must have a visible area */
++ while(i && ((i->itemRect().width() <1) ||
++ (i->itemRect().height() <1))) {
++ TreeMapItem* p = i->parent();
++ if (!p) break;
++ int idx = p->children()->findRef(i);
++ idx--;
++ if (idx<0)
++ i = p;
++ else
++ i = p->children()->at(idx);
++ }
++ }
++ return i;
++}
++
++void TreeMapWidget::setSelected(TreeMapItem* item, bool selected)
++{
++ item = possibleSelection(item);
++ setCurrent(item);
++
++ TreeMapItem* changed = setTmpSelected(item, selected);
++ if (!changed) return;
++
++ _selection = _tmpSelection;
++ if (_selectionMode == Single)
++ emit selectionChanged(item);
++ emit selectionChanged();
++ redraw(changed);
++
++ if (0) kdDebug(90100) << (selected ? "S":"Des") << "elected Item "
++ << (item ? item->path(0).join("") : TQString("(null)"))
++ << " (depth " << (item ? item->depth() : -1)
++ << ")" << endl;
++}
++
++void TreeMapWidget::setMarked(int markNo, bool redrawWidget)
++{
++ // if there's no marking, return
++ if ((_markNo == 0) && (markNo == 0)) return;
++
++ _markNo = markNo;
++ if (!clearSelection() && redrawWidget) redraw();
++}
++
++/* Returns all items which appear only in one of the given lists */
++TreeMapItemList TreeMapWidget::diff(TreeMapItemList& l1,
++ TreeMapItemList& l2)
++{
++ TreeMapItemList l;
++ TreeMapItemListIterator it1(l1), it2(l2);
++
++ TreeMapItem* item;
++ while ( (item = it1.current()) != 0 ) {
++ ++it1;
++ if (l2.containsRef(item) > 0) continue;
++ l.append(item);
++ }
++ while ( (item = it2.current()) != 0 ) {
++ ++it2;
++ if (l1.containsRef(item) > 0) continue;
++ l.append(item);
++ }
++
++ return l;
++}
++
++/* Only modifies _tmpSelection.
++ * Returns 0 when no change happened, otherwise the TreeMapItem that has
++ * to be redrawn for all changes.
++ */
++TreeMapItem* TreeMapWidget::setTmpSelected(TreeMapItem* item, bool selected)
++{
++ if (!item) return 0;
++ if (_selectionMode == NoSelection) return 0;
++
++ TreeMapItemList old = _tmpSelection;
++
++ if (_selectionMode == Single) {
++ _tmpSelection.clear();
++ if (selected) _tmpSelection.append(item);
++ }
++ else {
++ if (selected) {
++ TreeMapItem* i=_tmpSelection.first();
++ while (i) {
++ if (i->isChildOf(item) || item->isChildOf(i)) {
++ _tmpSelection.remove();
++ i = _tmpSelection.current();
++ }
++ else
++ i = _tmpSelection.next();
++ }
++ _tmpSelection.append(item);
++ }
++ else
++ _tmpSelection.removeRef(item);
++ }
++
++ return diff(old, _tmpSelection).commonParent();
++}
++
++
++bool TreeMapWidget::clearSelection(TreeMapItem* parent)
++{
++ TreeMapItemList old = _selection;
++
++ TreeMapItem* i=_selection.first();
++ while (i) {
++ if (i->isChildOf(parent)) {
++ _selection.remove();
++ i = _selection.current();
++ }
++ else
++ i = _selection.next();
++ }
++
++ TreeMapItem* changed = diff(old, _selection).commonParent();
++ if (changed) {
++ changed->redraw();
++ emit selectionChanged();
++ }
++ return (changed != 0);
++}
++
++bool TreeMapWidget::isSelected(TreeMapItem* i) const
++{
++ return _selection.containsRef(i)>0;
++}
++
++bool TreeMapWidget::isTmpSelected(TreeMapItem* i)
++{
++ return _tmpSelection.containsRef(i)>0;
++}
++
++
++void TreeMapWidget::setCurrent(TreeMapItem* i, bool kbd)
++{
++ TreeMapItem* old = _current;
++ _current = i;
++
++ if (_markNo >0) {
++ // remove mark
++ _markNo = 0;
++
++ if (1) kdDebug(90100) << "setCurrent(" << i->path(0).join("/")
++ << ") - mark removed" << endl;
++
++ // always complete redraw needed to remove mark
++ redraw();
++
++ if (old == _current) return;
++ }
++ else {
++ if (old == _current) return;
++
++ if (old) old->redraw();
++ if (i) i->redraw();
++ }
++
++ //kdDebug(90100) << "Current Item " << (i ? i->path().ascii() : "(null)") << endl;
++
++ emit currentChanged(i, kbd);
++}
++
++void TreeMapWidget::setRangeSelection(TreeMapItem* i1,
++ TreeMapItem* i2, bool selected)
++{
++ i1 = possibleSelection(i1);
++ i2 = possibleSelection(i2);
++ setCurrent(i2);
++
++ TreeMapItem* changed = setTmpRangeSelection(i1, i2, selected);
++ if (!changed) return;
++
++ _selection = _tmpSelection;
++ if (_selectionMode == Single)
++ emit selectionChanged(i2);
++ emit selectionChanged();
++ redraw(changed);
++}
++
++TreeMapItem* TreeMapWidget::setTmpRangeSelection(TreeMapItem* i1,
++ TreeMapItem* i2,
++ bool selected)
++{
++ if ((i1 == 0) && (i2 == 0)) return 0;
++ if ((i1 == 0) || i1->isChildOf(i2)) return setTmpSelected(i2, selected);
++ if ((i2 == 0) || i2->isChildOf(i1)) return setTmpSelected(i1, selected);
++
++ TreeMapItem* changed = setTmpSelected(i1, selected);
++ TreeMapItem* changed2 = setTmpSelected(i2, selected);
++ if (changed2) changed = changed2->commonParent(changed);
++
++ TreeMapItem* commonParent = i1;
++ while (commonParent && !i2->isChildOf(commonParent)) {
++ i1 = commonParent;
++ commonParent = commonParent->parent();
++ }
++ if (!commonParent) return changed;
++ while (i2 && i2->parent() != commonParent)
++ i2 = i2->parent();
++ if (!i2) return changed;
++
++ TreeMapItemList* list = commonParent->children();
++ if (!list) return changed;
++
++ TreeMapItem* i = list->first();
++ bool between = false;
++ while (i) {
++ if (between) {
++ if (i==i1 || i==i2) break;
++ changed2 = setTmpSelected(i, selected);
++ if (changed2) changed = changed2->commonParent(changed);
++ }
++ else if (i==i1 || i==i2)
++ between = true;
++ i = list->next();
++ }
++
++ return changed;
++}
++
++void TreeMapWidget::contextMenuEvent( TQContextMenuEvent* e )
++{
++ //kdDebug(90100) << "TreeMapWidget::contextMenuEvent" << endl;
++
++ if ( receivers( TQT_SIGNAL(contextMenuRequested(TreeMapItem*, const TQPoint &)) ) )
++ e->accept();
++
++ if ( e->reason() == TQContextMenuEvent::Keyboard ) {
++ TQRect r = (_current) ? _current->itemRect() : _base->itemRect();
++ TQPoint p = TQPoint(r.left() + r.width()/2, r.top() + r.height()/2);
++ emit contextMenuRequested(_current, p);
++ }
++ else {
++ TreeMapItem* i = item(e->x(), e->y());
++ emit contextMenuRequested(i, e->pos());
++ }
++}
++
++
++void TreeMapWidget::mousePressEvent( TQMouseEvent* e )
++{
++ //kdDebug(90100) << "TreeMapWidget::mousePressEvent" << endl;
++
++ _oldCurrent = _current;
++
++ TreeMapItem* i = item(e->x(), e->y());
++
++ _pressed = i;
++
++ _inShiftDrag = e->state() & ShiftButton;
++ _inControlDrag = e->state() & ControlButton;
++ _lastOver = _pressed;
++
++ TreeMapItem* changed = 0;
++ TreeMapItem* item = possibleSelection(_pressed);
++
++ switch(_selectionMode) {
++ case Single:
++ changed = setTmpSelected(item, true);
++ break;
++ case Multi:
++ changed = setTmpSelected(item, !isTmpSelected(item));
++ break;
++ case Extended:
++ if (_inControlDrag)
++ changed = setTmpSelected(item, !isTmpSelected(item));
++ else if (_inShiftDrag) {
++ TreeMapItem* sCurrent = possibleSelection(_current);
++ changed = setTmpRangeSelection(sCurrent, item,
++ !isTmpSelected(item));
++ }
++ else {
++ _selectionMode = Single;
++ changed = setTmpSelected(item, true);
++ _selectionMode = Extended;
++ }
++ break;
++ default:
++ break;
++ }
++
++ // item under mouse always selected on right button press
++ if (e->button() == Qt::RightButton) {
++ TreeMapItem* changed2 = setTmpSelected(item, true);
++ if (changed2) changed = changed2->commonParent(changed);
++ }
++
++ setCurrent(_pressed);
++
++ if (changed)
++ redraw(changed);
++
++ if (e->button() == Qt::RightButton) {
++
++ // emit selection change
++ if (! (_tmpSelection == _selection)) {
++ _selection = _tmpSelection;
++ if (_selectionMode == Single)
++ emit selectionChanged(_lastOver);
++ emit selectionChanged();
++ }
++ _pressed = 0;
++ _lastOver = 0;
++ emit rightButtonPressed(i, e->pos());
++ }
++}
++
++void TreeMapWidget::mouseMoveEvent( TQMouseEvent* e )
++{
++ //kdDebug(90100) << "TreeMapWidget::mouseMoveEvent" << endl;
++
++ if (!_pressed) return;
++ TreeMapItem* over = item(e->x(), e->y());
++ if (_lastOver == over) return;
++
++ setCurrent(over);
++ if (over == 0) {
++ _lastOver = 0;
++ return;
++ }
++
++ TreeMapItem* changed = 0;
++ TreeMapItem* item = possibleSelection(over);
++
++ switch(_selectionMode) {
++ case Single:
++ changed = setTmpSelected(item, true);
++ break;
++ case Multi:
++ changed = setTmpSelected(item, !isTmpSelected(item));
++ break;
++ case Extended:
++ if (_inControlDrag)
++ changed = setTmpSelected(item, !isTmpSelected(item));
++ else {
++ TreeMapItem* sLast = possibleSelection(_lastOver);
++ changed = setTmpRangeSelection(sLast, item, true);
++ }
++ break;
++
++ default:
++ break;
++ }
++
++ _lastOver = over;
++
++ if (changed)
++ redraw(changed);
++}
++
++void TreeMapWidget::mouseReleaseEvent( TQMouseEvent* )
++{
++ //kdDebug(90100) << "TreeMapWidget::mouseReleaseEvent" << endl;
++
++ if (!_pressed) return;
++
++ if (!_lastOver) {
++ // take back
++ setCurrent(_oldCurrent);
++ TreeMapItem* changed = diff(_tmpSelection, _selection).commonParent();
++ _tmpSelection = _selection;
++ if (changed)
++ redraw(changed);
++ }
++ else {
++ if (! (_tmpSelection == _selection)) {
++ _selection = _tmpSelection;
++ if (_selectionMode == Single)
++ emit selectionChanged(_lastOver);
++ emit selectionChanged();
++ }
++ if (!_inControlDrag && !_inShiftDrag && (_pressed == _lastOver))
++ emit clicked(_lastOver);
++ }
++
++ _pressed = 0;
++ _lastOver = 0;
++}
++
++
++void TreeMapWidget::mouseDoubleClickEvent( TQMouseEvent* e )
++{
++ TreeMapItem* over = item(e->x(), e->y());
++
++ emit doubleClicked(over);
++}
++
++
++/* returns -1 if nothing visible found */
++int nextVisible(TreeMapItem* i)
++{
++ TreeMapItem* p = i->parent();
++ if (!p || p->itemRect().isEmpty()) return -1;
++
++ int idx = p->children()->findRef(i);
++ if (idx<0) return -1;
++
++ while (idx < (int)p->children()->count()-1) {
++ idx++;
++ TQRect r = p->children()->at(idx)->itemRect();
++ if (r.width()>1 && r.height()>1)
++ return idx;
++ }
++ return -1;
++}
++
++/* returns -1 if nothing visible found */
++int prevVisible(TreeMapItem* i)
++{
++ TreeMapItem* p = i->parent();
++ if (!p || p->itemRect().isEmpty()) return -1;
++
++ int idx = p->children()->findRef(i);
++ if (idx<0) return -1;
++
++ while (idx > 0) {
++ idx--;
++ TQRect r = p->children()->at(idx)->itemRect();
++ if (r.width()>1 && r.height()>1)
++ return idx;
++ }
++ return -1;
++}
++
++
++
++
++void TreeMapWidget::keyPressEvent( TQKeyEvent* e )
++{
++ if (e->key() == Key_Escape && _pressed) {
++
++ // take back
++ if (_oldCurrent != _lastOver)
++ setCurrent(_oldCurrent);
++ if (! (_tmpSelection == _selection)) {
++ TreeMapItem* changed = diff(_tmpSelection, _selection).commonParent();
++ _tmpSelection = _selection;
++ if (changed)
++ redraw(changed);
++ }
++ _pressed = 0;
++ _lastOver = 0;
++ }
++
++ if ((e->key() == Key_Space) ||
++ (e->key() == Key_Return)) {
++
++ switch(_selectionMode) {
++ case NoSelection:
++ break;
++ case Single:
++ setSelected(_current, true);
++ break;
++ case Multi:
++ setSelected(_current, !isSelected(_current));
++ break;
++ case Extended:
++ if ((e->state() & ControlButton) || (e->state() & ShiftButton))
++ setSelected(_current, !isSelected(_current));
++ else {
++ _selectionMode = Single;
++ setSelected(_current, true);
++ _selectionMode = Extended;
++ }
++ }
++
++ if (_current && (e->key() == Key_Return))
++ emit returnPressed(_current);
++
++ return;
++ }
++
++ if (!_current) {
++ if (e->key() == Key_Down) {
++ setCurrent(_base, true);
++ }
++ return;
++ }
++
++ TreeMapItem* old = _current, *newItem;
++ TreeMapItem* p = _current->parent();
++
++ bool goBack;
++ if (_current->sorting(&goBack) == -1) {
++ // noSorting
++ goBack = false;
++ }
++
++
++ if ((e->key() == Key_Backspace) ||
++ (e->key() == Key_Up)) {
++ newItem = visibleItem(p);
++ setCurrent(newItem, true);
++ }
++ else if (e->key() == Key_Left) {
++ int newIdx = goBack ? nextVisible(_current) : prevVisible(_current);
++ if (p && newIdx>=0) {
++ p->setIndex(newIdx);
++ setCurrent(p->children()->at(newIdx), true);
++ }
++ }
++ else if (e->key() == Key_Right) {
++ int newIdx = goBack ? prevVisible(_current) : nextVisible(_current);
++ if (p && newIdx>=0) {
++ p->setIndex(newIdx);
++ setCurrent(p->children()->at(newIdx), true);
++ }
++ }
++ else if (e->key() == Key_Down) {
++ if (_current->children() && _current->children()->count()>0) {
++ int newIdx = _current->index();
++ if (newIdx<0)
++ newIdx = goBack ? (_current->children()->count()-1) : 0;
++ if (newIdx>=(int)_current->children()->count())
++ newIdx = _current->children()->count()-1;
++ newItem = visibleItem(_current->children()->at(newIdx));
++ setCurrent(newItem, true);
++ }
++ }
++
++ if (old == _current) return;
++ if (! (e->state() & ControlButton)) return;
++ if (! (e->state() & ShiftButton)) return;
++
++ switch(_selectionMode) {
++ case NoSelection:
++ break;
++ case Single:
++ setSelected(_current, true);
++ break;
++ case Multi:
++ setSelected(_current, !isSelected(_current));
++ break;
++ case Extended:
++ if (e->state() & ControlButton)
++ setSelected(_current, !isSelected(_current));
++ else
++ setSelected(_current, isSelected(old));
++ }
++}
++
++void TreeMapWidget::fontChange( const TQFont& )
++{
++ redraw();
++}
++
++
++void TreeMapWidget::resizeEvent( TQResizeEvent * )
++{
++ // this automatically redraws (as size is changed)
++ drawTreeMap();
++}
++
++void TreeMapWidget::paintEvent( TQPaintEvent * )
++{
++ drawTreeMap();
++}
++
++void TreeMapWidget::showEvent( TQShowEvent * )
++{
++ // refresh only if needed
++ drawTreeMap();
++}
++
++// Updates screen from shadow buffer,
++// but redraws before if needed
++void TreeMapWidget::drawTreeMap()
++{
++ // no need to draw if hidden
++ if (!isVisible()) return;
++
++ if (_pixmap.size() != size())
++ _needsRefresh = _base;
++
++ if (_needsRefresh) {
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << "Redrawing " << _needsRefresh->path(0).join("/") << endl;
++
++ if (_needsRefresh == _base) {
++ // redraw whole widget
++ _pixmap = TQPixmap(size());
++ _pixmap.fill(backgroundColor());
++ }
++ TQPainter p(&_pixmap);
++ if (_needsRefresh == _base) {
++ p.setPen(black);
++ p.drawRect(TQRect(2, 2, TQWidget::width()-4, TQWidget::height()-4));
++ _base->setItemRect(TQRect(3, 3, TQWidget::width()-6, TQWidget::height()-6));
++ }
++ else {
++ // only subitem
++ if (!_needsRefresh->itemRect().isValid()) return;
++ }
++
++ // reset cached font object; it could have been changed
++ _font = font();
++ _fontHeight = fontMetrics().height();
++
++ drawItems(&p, _needsRefresh);
++ _needsRefresh = 0;
++ }
++
++ bitBlt( TQT_TQPAINTDEVICE(this), 0, 0, TQT_TQPAINTDEVICE(&_pixmap), 0, 0,
++ TQWidget::width(), TQWidget::height(), CopyROP, true);
++
++ if (hasFocus()) {
++ TQPainter p(this);
++ style().tqdrawPrimitive( TQStyle::PE_FocusRect, &p,
++ TQRect(0, 0, TQWidget::width(), TQWidget::height()),
++ colorGroup() );
++ }
++}
++
++
++
++void TreeMapWidget::redraw(TreeMapItem* i)
++{
++ if (!i) return;
++
++ if (!_needsRefresh)
++ _needsRefresh = i;
++ else {
++ if (!i->isChildOf(_needsRefresh))
++ _needsRefresh = _needsRefresh->commonParent(i);
++ }
++
++ if (isVisible()) {
++ // delayed drawing if we have multiple redraw requests
++ update();
++ }
++}
++
++void TreeMapWidget::drawItem(TQPainter* p,
++ TreeMapItem* item)
++{
++ bool isSelected = false;
++ TreeMapItem* i;
++
++ if (_markNo>0) {
++ for(i = item;i;i=i->parent())
++ if (i->isMarked(_markNo)) break;
++
++ isSelected = (i!=0);
++ }
++ else {
++ for (i=_tmpSelection.first();i;i=_tmpSelection.next())
++ if (item->isChildOf(i)) break;
++
++ isSelected = (i!=0);
++ }
++
++ bool isCurrent = _current && item->isChildOf(_current);
++ int dd = item->depth();
++ if (isTransparent(dd)) return;
++
++ RectDrawing d(item->itemRect());
++ item->setSelected(isSelected);
++ item->setCurrent(isCurrent);
++ item->setShaded(_shading);
++ item->drawFrame(drawFrame(dd));
++ d.drawBack(p, item);
++}
++
++
++bool TreeMapWidget::horizontal(TreeMapItem* i, const TQRect& r)
++{
++ switch(i->splitMode()) {
++ case TreeMapItem::HAlternate:
++ return (i->depth()%2)==1;
++ case TreeMapItem::VAlternate:
++ return (i->depth()%2)==0;
++ case TreeMapItem::Horizontal:
++ return true;
++ case TreeMapItem::Vertical:
++ return false;
++ default:
++ return r.width() > r.height();
++ }
++ return false;
++}
++
++
++/**
++ * Draw TreeMapItems recursive, starting from item
++ */
++void TreeMapWidget::drawItems(TQPainter* p,
++ TreeMapItem* item)
++{
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << "+drawItems(" << item->path(0).join("/") << ", "
++ << item->itemRect().x() << "/" << item->itemRect().y()
++ << "-" << item->itemRect().width() << "x"
++ << item->itemRect().height() << "), Val " << item->value()
++ << ", Sum " << item->sum() << endl;
++
++ drawItem(p, item);
++ item->clearFreeRects();
++
++ TQRect origRect = item->itemRect();
++ int bw = item->borderWidth();
++ TQRect r = TQRect(origRect.x()+bw, origRect.y()+bw,
++ origRect.width()-2*bw, origRect.height()-2*bw);
++
++ TreeMapItemList* list = item->children();
++ TreeMapItem* i;
++
++ bool stopDrawing = false;
++
++ // only subdivide if there are children
++ if (!list || list->count()==0)
++ stopDrawing = true;
++
++ // only subdivide if there is enough space
++ if (!stopDrawing && (r.width()<=0 || r.height()<=0))
++ stopDrawing = true;
++
++ // stop drawing if maximum depth is reached
++ if (!stopDrawing &&
++ (_maxDrawingDepth>=0 && item->depth()>=_maxDrawingDepth))
++ stopDrawing = true;
++
++ // stop drawing if stopAtText is reached
++ if (!stopDrawing)
++ for (int no=0;no<(int)_attr.size();no++) {
++ TQString stopAt = fieldStop(no);
++ if (!stopAt.isEmpty() && (item->text(no) == stopAt)) {
++ stopDrawing = true;
++ break;
++ }
++ }
++
++ // area size is checked later...
++#if 0
++ // stop drawing if minimal area size is reached
++ if (!stopDrawing &&
++ (_minimalArea > 0) &&
++ (r.width() * r.height() < _minimalArea)) stopDrawing = true;
++#endif
++
++ if (stopDrawing) {
++ if (list) {
++ // invalidate rects
++ for (i=list->first();i;i=list->next())
++ i->clearItemRect();
++ }
++ // tooltip apears on whole item rect
++ item->addFreeRect(item->itemRect());
++
++ // if we have space for text...
++ if ((r.height() < _fontHeight) || (r.width() < _fontHeight)) return;
++
++ RectDrawing d(r);
++ item->setRotated(_allowRotation && (r.height() > r.width()));
++ for (int no=0;no<(int)_attr.size();no++) {
++ if (!fieldVisible(no)) continue;
++ d.drawField(p, no, item);
++ }
++ r = d.remainingRect(item);
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << "-drawItems(" << item->path(0).join("/") << ")" << endl;
++ return;
++ }
++
++ double user_sum, child_sum, self;
++
++ // user supplied sum
++ user_sum = item->sum();
++
++ // own sum
++ child_sum = 0;
++ for (i=list->first();i;i=list->next()) {
++ child_sum += i->value();
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " child: " << i->text(0) << ", value "
++ << i->value() << endl;
++ }
++
++ TQRect orig = r;
++
++ // if we have space for text...
++ if ((r.height() >= _fontHeight) && (r.width() >= _fontHeight)) {
++
++ RectDrawing d(r);
++ item->setRotated(_allowRotation && (r.height() > r.width()));
++ for (int no=0;no<(int)_attr.size();no++) {
++ if (!fieldVisible(no)) continue;
++ if (!fieldForced(no)) continue;
++ d.drawField(p, no, item);
++ }
++ r = d.remainingRect(item);
++ }
++
++ if (orig.x() == r.x()) {
++ // Strings on top
++ item->addFreeRect(TQRect(orig.x(), orig.y(),
++ orig.width(), orig.height()-r.height()));
++ }
++ else {
++ // Strings on the left
++ item->addFreeRect(TQRect(orig.x(), orig.y(),
++ orig.width()-r.width(), orig.height()));
++ }
++
++ if (user_sum == 0) {
++ // user didn't supply any sum
++ user_sum = child_sum;
++ self = 0;
++ }
++ else {
++ self = user_sum - child_sum;
++
++ if (user_sum < child_sum) {
++ //kdDebug(90100) << "TreeMWidget " <<
++ // item->path() << ": User sum " << user_sum << " < Child Items sum " << child_sum << endl;
++
++ // invalid user supplied sum: ignore and use calculate sum
++ user_sum = child_sum;
++ self = 0.0;
++ }
++ else {
++ // Try to put the border waste in self
++ // percent of wasted space on border...
++ float borderArea = origRect.width() * origRect.height();
++ borderArea = (borderArea - r.width()*r.height())/borderArea;
++ unsigned borderValue = (unsigned)(borderArea * user_sum);
++
++ if (borderValue > self) {
++ if (_skipIncorrectBorder) {
++ r = origRect;
++ // should add my self to nested self and set my self =0
++ }
++ else
++ self = 0.0;
++ }
++ else
++ self -= borderValue;
++
++ user_sum = child_sum + self;
++ }
++ }
++
++ bool rotate = (_allowRotation && (r.height() > r.width()));
++ int self_length = (int)( ((rotate) ? r.width() : r.height()) *
++ self / user_sum + .5);
++ if (self_length > 0) {
++ // take space for self cost
++ TQRect sr = r;
++ if (rotate) {
++ sr.setWidth( self_length );
++ r.setRect(r.x()+sr.width(), r.y(), r.width()-sr.width(), r.height());
++ }
++ else {
++ sr.setHeight( self_length );
++ r.setRect(r.x(), r.y()+sr.height(), r.width(), r.height()-sr.height());
++ }
++
++ // set selfRect (not occupied by children) for tooltip
++ item->addFreeRect(sr);
++
++ if (0) kdDebug(90100) << "Item " << item->path(0).join("/") << ": SelfR "
++ << sr.x() << "/" << sr.y() << "-" << sr.width()
++ << "/" << sr.height() << ", self " << self << "/"
++ << user_sum << endl;
++
++ if ((sr.height() >= _fontHeight) && (sr.width() >= _fontHeight)) {
++
++ RectDrawing d(sr);
++ item->setRotated(_allowRotation && (r.height() > r.width()));
++ for (int no=0;no<(int)_attr.size();no++) {
++ if (!fieldVisible(no)) continue;
++ if (fieldForced(no)) continue;
++ d.drawField(p, no, item);
++ }
++ }
++
++ user_sum -= self;
++ }
++
++ bool goBack;
++ if (item->sorting(&goBack) == -1) {
++ // noSorting
++ goBack = false;
++ }
++
++ TreeMapItemListIterator it(*list);
++ if (goBack) it.toLast();
++
++ if (item->splitMode() == TreeMapItem::Columns) {
++ int len = list->count();
++ bool drawDetails = true;
++
++ while (len>0 && user_sum>0) {
++ TreeMapItemListIterator first = it;
++ double valSum = 0;
++ int lenLeft = len;
++ int columns = (int)(sqrt((double)len * r.width()/r.height())+.5);
++ if (columns==0) columns = 1; //should never be needed
++
++ while (lenLeft>0 && ((double)valSum*(len-lenLeft) <
++ (double)len*user_sum/columns/columns)) {
++ valSum += it.current()->value();
++ if (goBack) --it; else ++it;
++ lenLeft--;
++ }
++
++ // we always split horizontally
++ int nextPos = (int)((double)r.width() * valSum / user_sum);
++ TQRect firstRect = TQRect(r.x(), r.y(), nextPos, r.height());
++
++ if (nextPos < _visibleWidth) {
++ if (item->sorting(0) == -1) {
++ // fill current rect with hash pattern
++ drawFill(item, p, firstRect);
++ }
++ else {
++ // fill rest with hash pattern
++ drawFill(item, p, r, first, len, goBack);
++ break;
++ }
++ }
++ else {
++ drawDetails = drawItemArray(p, item, firstRect,
++ valSum, first, len-lenLeft, goBack);
++ }
++ r.setRect(r.x()+nextPos, r.y(), r.width()-nextPos, r.height());
++ user_sum -= valSum;
++ len = lenLeft;
++
++ if (!drawDetails) {
++ if (item->sorting(0) == -1)
++ drawDetails = true;
++ else {
++ drawFill(item, p, r, it, len, goBack);
++ break;
++ }
++ }
++ }
++ }
++ else if (item->splitMode() == TreeMapItem::Rows) {
++ int len = list->count();
++ bool drawDetails = true;
++
++ while (len>0 && user_sum>0) {
++ TreeMapItemListIterator first = it;
++ double valSum = 0;
++ int lenLeft = len;
++ int rows = (int)(sqrt((double)len * r.height()/r.width())+.5);
++ if (rows==0) rows = 1; //should never be needed
++
++ while (lenLeft>0 && ((double)valSum*(len-lenLeft) <
++ (double)len*user_sum/rows/rows)) {
++ valSum += it.current()->value();
++ if (goBack) --it; else ++it;
++ lenLeft--;
++ }
++
++ // we always split horizontally
++ int nextPos = (int)((double)r.height() * valSum / user_sum);
++ TQRect firstRect = TQRect(r.x(), r.y(), r.width(), nextPos);
++
++ if (nextPos < _visibleWidth) {
++ if (item->sorting(0) == -1) {
++ drawFill(item, p, firstRect);
++ }
++ else {
++ drawFill(item, p, r, first, len, goBack);
++ break;
++ }
++ }
++ else {
++ drawDetails = drawItemArray(p, item, firstRect,
++ valSum, first, len-lenLeft, goBack);
++ }
++ r.setRect(r.x(), r.y()+nextPos, r.width(), r.height()-nextPos);
++ user_sum -= valSum;
++ len = lenLeft;
++
++ if (!drawDetails) {
++ if (item->sorting(0) == -1)
++ drawDetails = true;
++ else {
++ drawFill(item, p, r, it, len, goBack);
++ break;
++ }
++ }
++ }
++ }
++ else
++ drawItemArray(p, item, r, user_sum, it, list->count(), goBack);
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << "-drawItems(" << item->path(0).join("/") << ")" << endl;
++}
++
++// fills area with a pattern if to small to draw children
++void TreeMapWidget::drawFill(TreeMapItem* i, TQPainter* p, TQRect& r)
++{
++ p->setBrush(TQt::Dense4Pattern);
++ p->setPen(TQt::NoPen);
++ p->drawRect(r);
++ i->addFreeRect(r);
++}
++
++// fills area with a pattern if to small to draw children
++void TreeMapWidget::drawFill(TreeMapItem* i, TQPainter* p, TQRect& r,
++ TreeMapItemListIterator it, int len, bool goBack)
++{
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " +drawFill(" << r.x() << "/" << r.y()
++ << "-" << r.width() << "x" << r.height()
++ << ", len " << len << ")" << endl;
++
++ p->setBrush(TQt::Dense4Pattern);
++ p->setPen(TQt::NoPen);
++ p->drawRect(r);
++ i->addFreeRect(r);
++
++ // reset rects
++ while (len>0 && it.current()) {
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " Reset Rect " << (*it)->path(0).join("/") << endl;
++
++ (*it)->clearItemRect();
++ if (goBack) --it; else ++it;
++ len--;
++ }
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " -drawFill(" << r.x() << "/" << r.y()
++ << "-" << r.width() << "x" << r.height()
++ << ", len " << len << ")" << endl;
++}
++
++// returns false if rect gets to small
++bool TreeMapWidget::drawItemArray(TQPainter* p, TreeMapItem* item,
++ TQRect& r, double user_sum,
++ TreeMapItemListIterator it, int len,
++ bool goBack)
++{
++ if (user_sum == 0) return false;
++
++ static bool b2t = true;
++
++ // stop recursive bisection for small rectangles
++ if (((r.height() < _visibleWidth) &&
++ (r.width() < _visibleWidth)) ||
++ ((_minimalArea > 0) &&
++ (r.width() * r.height() < _minimalArea))) {
++
++ drawFill(item, p, r, it, len, goBack);
++ return false;
++ }
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " +drawItemArray(" << item->path(0).join("/")
++ << ", " << r.x() << "/" << r.y() << "-" << r.width()
++ << "x" << r.height() << ")" << endl;
++
++ if (len>2 && (item->splitMode() == TreeMapItem::Bisection)) {
++
++ TreeMapItemListIterator first = it;
++ double valSum = 0;
++ int lenLeft = len;
++ //while (lenLeft>0 && valSum<user_sum/2) {
++ while (lenLeft>len/2) {
++ valSum += it.current()->value();
++ if (goBack) --it; else ++it;
++ lenLeft--;
++ }
++
++ // draw first half...
++ bool drawOn;
++
++ if (r.width() > r.height()) {
++ int halfPos = (int)((double)r.width() * valSum / user_sum);
++ TQRect firstRect = TQRect(r.x(), r.y(), halfPos, r.height());
++ drawOn = drawItemArray(p, item, firstRect,
++ valSum, first, len-lenLeft, goBack);
++ r.setRect(r.x()+halfPos, r.y(), r.width()-halfPos, r.height());
++ }
++ else {
++ int halfPos = (int)((double)r.height() * valSum / user_sum);
++ TQRect firstRect = TQRect(r.x(), r.y(), r.width(), halfPos);
++ drawOn = drawItemArray(p, item, firstRect,
++ valSum, first, len-lenLeft, goBack);
++ r.setRect(r.x(), r.y()+halfPos, r.width(), r.height()-halfPos);
++ }
++
++ // if no sorting, don't stop drawing
++ if (item->sorting(0) == -1) drawOn = true;
++
++ // second half
++ if (drawOn)
++ drawOn = drawItemArray(p, item, r, user_sum - valSum,
++ it, lenLeft, goBack);
++ else {
++ drawFill(item, p, r, it, len, goBack);
++ }
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " -drawItemArray(" << item->path(0).join("/")
++ << ")" << endl;
++
++ return drawOn;
++ }
++
++ bool hor = horizontal(item,r);
++
++ TreeMapItem* i;
++ while (len>0) {
++ i = it.current();
++ if (user_sum <= 0) {
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << "drawItemArray: Reset " << i->path(0).join("/") << endl;
++
++ i->clearItemRect();
++ if (goBack) --it; else ++it;
++ len--;
++ continue;
++ }
++
++ // stop drawing for small rectangles
++ if (((r.height() < _visibleWidth) &&
++ (r.width() < _visibleWidth)) ||
++ ((_minimalArea > 0) &&
++ (r.width() * r.height() < _minimalArea))) {
++
++ drawFill(item, p, r, it, len, goBack);
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " -drawItemArray(" << item->path(0).join("/")
++ << "): Stop" << endl;
++ return false;
++ }
++
++ if (i->splitMode() == TreeMapItem::AlwaysBest)
++ hor = r.width() > r.height();
++
++ int lastPos = hor ? r.width() : r.height();
++ double val = i->value();
++ int nextPos = (user_sum <= 0.0) ? 0: (int)(lastPos * val / user_sum +.5);
++ if (nextPos>lastPos) nextPos = lastPos;
++
++ if ((item->sorting(0) != -1) && (nextPos < _visibleWidth)) {
++ drawFill(item, p, r, it, len, goBack);
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " -drawItemArray(" << item->path(0).join("/")
++ << "): Stop" << endl;
++ return false;
++ }
++
++ TQRect currRect = r;
++
++ if (hor)
++ currRect.setWidth(nextPos);
++ else {
++ if (b2t)
++ currRect.setRect(r.x(), r.bottom()-nextPos+1, r.width(), nextPos);
++ else
++ currRect.setHeight(nextPos);
++ }
++
++ // don't draw very small rectangles:
++ if (nextPos >= _visibleWidth) {
++ i->setItemRect(currRect);
++ drawItems(p, i);
++ }
++ else {
++ i->clearItemRect();
++ drawFill(item, p, currRect);
++ }
++
++ // draw Separator
++ if (_drawSeparators && (nextPos<lastPos)) {
++ p->setPen(black);
++ if (hor) {
++ if (r.top()<=r.bottom())
++ p->drawLine(r.x() + nextPos, r.top(), r.x() + nextPos, r.bottom());
++ }
++ else {
++ if (r.left()<=r.right())
++ p->drawLine(r.left(), r.y() + nextPos, r.right(), r.y() + nextPos);
++ }
++ nextPos++;
++ }
++
++ if (hor)
++ r.setRect(r.x() + nextPos, r.y(), lastPos-nextPos, r.height());
++ else {
++ if (b2t)
++ r.setRect(r.x(), r.y(), r.width(), lastPos-nextPos);
++ else
++ r.setRect(r.x(), r.y() + nextPos, r.width(), lastPos-nextPos);
++ }
++
++ user_sum -= val;
++ if (goBack) --it; else ++it;
++ len--;
++ }
++
++ if (DEBUG_DRAWING)
++ kdDebug(90100) << " -drawItemArray(" << item->path(0).join("/")
++ << "): Continue" << endl;
++
++ return true;
++}
++
++
++/*----------------------------------------------------------------
++ * Popup menus for option setting
++ */
++
++void TreeMapWidget::splitActivated(int id)
++{
++ if (id == _splitID) setSplitMode(TreeMapItem::Bisection);
++ else if (id == _splitID+1) setSplitMode(TreeMapItem::Columns);
++ else if (id == _splitID+2) setSplitMode(TreeMapItem::Rows);
++ else if (id == _splitID+3) setSplitMode(TreeMapItem::AlwaysBest);
++ else if (id == _splitID+4) setSplitMode(TreeMapItem::Best);
++ else if (id == _splitID+5) setSplitMode(TreeMapItem::VAlternate);
++ else if (id == _splitID+6) setSplitMode(TreeMapItem::HAlternate);
++ else if (id == _splitID+7) setSplitMode(TreeMapItem::Horizontal);
++ else if (id == _splitID+8) setSplitMode(TreeMapItem::Vertical);
++}
++
++
++void TreeMapWidget::addSplitDirectionItems(TQPopupMenu* popup, int id)
++{
++ _splitID = id;
++ popup->setCheckable(true);
++
++ connect(popup, TQT_SIGNAL(activated(int)),
++ this, TQT_SLOT(splitActivated(int)));
++
++ popup->insertItem(i18n("Recursive Bisection"), id);
++ popup->insertItem(i18n("Columns"), id+1);
++ popup->insertItem(i18n("Rows"), id+2);
++ popup->insertItem(i18n("Always Best"), id+3);
++ popup->insertItem(i18n("Best"), id+4);
++ popup->insertItem(i18n("Alternate (V)"), id+5);
++ popup->insertItem(i18n("Alternate (H)"), id+6);
++ popup->insertItem(i18n("Horizontal"), id+7);
++ popup->insertItem(i18n("Vertical"), id+8);
++
++ switch(splitMode()) {
++ case TreeMapItem::Bisection: popup->setItemChecked(id,true); break;
++ case TreeMapItem::Columns: popup->setItemChecked(id+1,true); break;
++ case TreeMapItem::Rows: popup->setItemChecked(id+2,true); break;
++ case TreeMapItem::AlwaysBest: popup->setItemChecked(id+3,true); break;
++ case TreeMapItem::Best: popup->setItemChecked(id+4,true); break;
++ case TreeMapItem::VAlternate: popup->setItemChecked(id+5,true); break;
++ case TreeMapItem::HAlternate: popup->setItemChecked(id+6,true); break;
++ case TreeMapItem::Horizontal: popup->setItemChecked(id+7,true); break;
++ case TreeMapItem::Vertical: popup->setItemChecked(id+8,true); break;
++ default: break;
++ }
++}
++
++void TreeMapWidget::visualizationActivated(int id)
++{
++ if (id == _visID+2) setSkipIncorrectBorder(!skipIncorrectBorder());
++ else if (id == _visID+3) setBorderWidth(0);
++ else if (id == _visID+4) setBorderWidth(1);
++ else if (id == _visID+5) setBorderWidth(2);
++ else if (id == _visID+6) setBorderWidth(3);
++ else if (id == _visID+10) setAllowRotation(!allowRotation());
++ else if (id == _visID+11) setShadingEnabled(!isShadingEnabled());
++ else if (id<_visID+19 || id>_visID+100) return;
++
++ id -= 20+_visID;
++ int f = id/10;
++ if ((id%10) == 1) setFieldVisible(f, !fieldVisible(f));
++ else if ((id%10) == 2) setFieldForced(f, !fieldForced(f));
++ else if ((id%10) == 3) setFieldPosition(f, DrawParams::TopLeft);
++ else if ((id%10) == 4) setFieldPosition(f, DrawParams::TopCenter);
++ else if ((id%10) == 5) setFieldPosition(f, DrawParams::TopRight);
++ else if ((id%10) == 6) setFieldPosition(f, DrawParams::BottomLeft);
++ else if ((id%10) == 7) setFieldPosition(f, DrawParams::BottomCenter);
++ else if ((id%10) == 8) setFieldPosition(f, DrawParams::BottomRight);
++}
++
++void TreeMapWidget::addVisualizationItems(TQPopupMenu* popup, int id)
++{
++ _visID = id;
++
++ popup->setCheckable(true);
++
++ TQPopupMenu* bpopup = new TQPopupMenu();
++ bpopup->setCheckable(true);
++
++ connect(popup, TQT_SIGNAL(activated(int)),
++ this, TQT_SLOT(visualizationActivated(int)));
++ connect(bpopup, TQT_SIGNAL(activated(int)),
++ this, TQT_SLOT(visualizationActivated(int)));
++
++ TQPopupMenu* spopup = new TQPopupMenu();
++ addSplitDirectionItems(spopup, id+100);
++ popup->insertItem(i18n("Nesting"), spopup, id);
++
++ popup->insertItem(i18n("Border"), bpopup, id+1);
++ bpopup->insertItem(i18n("Correct Borders Only"), id+2);
++ bpopup->insertSeparator();
++ bpopup->insertItem(i18n("Width %1").arg(0), id+3);
++ bpopup->insertItem(i18n("Width %1").arg(1), id+4);
++ bpopup->insertItem(i18n("Width %1").arg(2), id+5);
++ bpopup->insertItem(i18n("Width %1").arg(3), id+6);
++ bpopup->setItemChecked(id+2, skipIncorrectBorder());
++ bpopup->setItemChecked(id+3, borderWidth()==0);
++ bpopup->setItemChecked(id+4, borderWidth()==1);
++ bpopup->setItemChecked(id+5, borderWidth()==2);
++ bpopup->setItemChecked(id+6, borderWidth()==3);
++
++ popup->insertItem(i18n("Allow Rotation"), id+10);
++ popup->setItemChecked(id+10,allowRotation());
++ popup->insertItem(i18n("Shading"), id+11);
++ popup->setItemChecked(id+11,isShadingEnabled());
++
++ if (_attr.size() ==0) return;
++
++ popup->insertSeparator();
++ int f;
++ TQPopupMenu* tpopup;
++ id += 20;
++ for (f=0;f<(int)_attr.size();f++, id+=10) {
++ tpopup = new TQPopupMenu();
++ tpopup->setCheckable(true);
++ popup->insertItem(_attr[f].type, tpopup, id);
++ tpopup->insertItem(i18n("Visible"), id+1);
++ tpopup->insertItem(i18n("Take Space From Children"), id+2);
++ tpopup->insertSeparator();
++ tpopup->insertItem(i18n("Top Left"), id+3);
++ tpopup->insertItem(i18n("Top Center"), id+4);
++ tpopup->insertItem(i18n("Top Right"), id+5);
++ tpopup->insertItem(i18n("Bottom Left"), id+6);
++ tpopup->insertItem(i18n("Bottom Center"), id+7);
++ tpopup->insertItem(i18n("Bottom Right"), id+8);
++
++ tpopup->setItemChecked(id+1,_attr[f].visible);
++ tpopup->setItemEnabled(id+2,_attr[f].visible);
++ tpopup->setItemEnabled(id+3,_attr[f].visible);
++ tpopup->setItemEnabled(id+4,_attr[f].visible);
++ tpopup->setItemEnabled(id+5,_attr[f].visible);
++ tpopup->setItemEnabled(id+6,_attr[f].visible);
++ tpopup->setItemEnabled(id+7,_attr[f].visible);
++ tpopup->setItemEnabled(id+8,_attr[f].visible);
++ tpopup->setItemChecked(id+2,_attr[f].forced);
++ tpopup->setItemChecked(id+3,_attr[f].pos == DrawParams::TopLeft);
++ tpopup->setItemChecked(id+4,_attr[f].pos == DrawParams::TopCenter);
++ tpopup->setItemChecked(id+5,_attr[f].pos == DrawParams::TopRight);
++ tpopup->setItemChecked(id+6,_attr[f].pos == DrawParams::BottomLeft);
++ tpopup->setItemChecked(id+7,_attr[f].pos == DrawParams::BottomCenter);
++ tpopup->setItemChecked(id+8,_attr[f].pos == DrawParams::BottomRight);
++
++ connect(tpopup, TQT_SIGNAL(activated(int)),
++ this, TQT_SLOT(visualizationActivated(int)));
++ }
++}
++
++void TreeMapWidget::selectionActivated(int id)
++{
++ TreeMapItem* i = _menuItem;
++ id -= _selectionID;
++ while (id>0 && i) {
++ i=i->parent();
++ id--;
++ }
++ if (i)
++ setSelected(i, true);
++}
++
++void TreeMapWidget::addSelectionItems(TQPopupMenu* popup,
++ int id, TreeMapItem* i)
++{
++ if (!i) return;
++
++ _selectionID = id;
++ _menuItem = i;
++
++ connect(popup, TQT_SIGNAL(activated(int)),
++ this, TQT_SLOT(selectionActivated(int)));
++
++ while (i) {
++ TQString name = i->text(0);
++ if (name.isEmpty()) break;
++ popup->insertItem(i->text(0), id++);
++ i = i->parent();
++ }
++}
++
++void TreeMapWidget::fieldStopActivated(int id)
++{
++ if (id == _fieldStopID) setFieldStop(0, TQString());
++ else {
++ TreeMapItem* i = _menuItem;
++ id -= _fieldStopID+1;
++ while (id>0 && i) {
++ i=i->parent();
++ id--;
++ }
++ if (i)
++ setFieldStop(0, i->text(0));
++ }
++}
++
++void TreeMapWidget::addFieldStopItems(TQPopupMenu* popup,
++ int id, TreeMapItem* i)
++{
++ _fieldStopID = id;
++
++ connect(popup, TQT_SIGNAL(activated(int)),
++ this, TQT_SLOT(fieldStopActivated(int)));
++
++ popup->insertItem(i18n("No %1 Limit").arg(fieldType(0)), id);
++ popup->setItemChecked(id, fieldStop(0).isEmpty());
++ _menuItem = i;
++ bool foundFieldStop = false;
++ if (i) {
++ popup->insertSeparator();
++
++ while (i) {
++ id++;
++ TQString name = i->text(0);
++ if (name.isEmpty()) break;
++ popup->insertItem(i->text(0), id);
++ if (fieldStop(0) == i->text(0)) {
++ popup->setItemChecked(id, true);
++ foundFieldStop = true;
++ }
++ i = i->parent();
++ }
++ }
++
++ if (!foundFieldStop && !fieldStop(0).isEmpty()) {
++ popup->insertSeparator();
++ popup->insertItem(fieldStop(0), id+1);
++ popup->setItemChecked(id+1, true);
++ }
++}
++
++void TreeMapWidget::areaStopActivated(int id)
++{
++ if (id == _areaStopID) setMinimalArea(-1);
++ else if (id == _areaStopID+1) {
++ int area = _menuItem ? (_menuItem->width() * _menuItem->height()) : -1;
++ setMinimalArea(area);
++ }
++ else if (id == _areaStopID+2) setMinimalArea(100);
++ else if (id == _areaStopID+3) setMinimalArea(400);
++ else if (id == _areaStopID+4) setMinimalArea(1000);
++ else if (id == _areaStopID+5) setMinimalArea(minimalArea()*2);
++ else if (id == _areaStopID+6) setMinimalArea(minimalArea()/2);
++}
++
++void TreeMapWidget::addAreaStopItems(TQPopupMenu* popup,
++ int id, TreeMapItem* i)
++{
++ _areaStopID = id;
++ _menuItem = i;
++
++ connect(popup, TQT_SIGNAL(activated(int)),
++ this, TQT_SLOT(areaStopActivated(int)));
++
++ bool foundArea = false;
++
++ popup->insertItem(i18n("No Area Limit"), id);
++ popup->setItemChecked(id, minimalArea() == -1);
++
++ if (i) {
++ int area = i->width() * i->height();
++ popup->insertSeparator();
++ popup->insertItem(i18n("Area of '%1' (%2)")
++ .arg(i->text(0)).arg(area), id+1);
++ if (area == minimalArea()) {
++ popup->setItemChecked(id+1, true);
++ foundArea = true;
++ }
++ }
++
++ popup->insertSeparator();
++ int area = 100, count;
++ for (count=0;count<3;count++) {
++ popup->insertItem(i18n("1 Pixel", "%n Pixels", area), id+2+count);
++ if (area == minimalArea()) {
++ popup->setItemChecked(id+2+count, true);
++ foundArea = true;
++ }
++ area = (area==100) ? 400 : (area==400) ? 1000 : 4000;
++ }
++
++ if (minimalArea()>0) {
++ popup->insertSeparator();
++ if (!foundArea) {
++ popup->insertItem(i18n("1 Pixel", "%n Pixels", minimalArea()), id+10);
++ popup->setItemChecked(id+10, true);
++ }
++
++ popup->insertItem(i18n("Double Area Limit (to %1)")
++ .arg(minimalArea()*2), id+5);
++ popup->insertItem(i18n("Halve Area Limit (to %1)")
++ .arg(minimalArea()/2), id+6);
++ }
++}
++
++
++void TreeMapWidget::depthStopActivated(int id)
++{
++ if (id == _depthStopID) setMaxDrawingDepth(-1);
++ else if (id == _depthStopID+1) {
++ int d = _menuItem ? _menuItem->depth() : -1;
++ setMaxDrawingDepth(d);
++ }
++ else if (id == _depthStopID+2) setMaxDrawingDepth(maxDrawingDepth()-1);
++ else if (id == _depthStopID+3) setMaxDrawingDepth(maxDrawingDepth()+1);
++}
++
++void TreeMapWidget::addDepthStopItems(TQPopupMenu* popup,
++ int id, TreeMapItem* i)
++{
++ _depthStopID = id;
++ _menuItem = i;
++
++ connect(popup, TQT_SIGNAL(activated(int)),
++ this, TQT_SLOT(depthStopActivated(int)));
++
++ bool foundDepth = false;
++
++ popup->insertItem(i18n("No Depth Limit"), id);
++ popup->setItemChecked(id, maxDrawingDepth() == -1);
++
++ if (i) {
++ int d = i->depth();
++ popup->insertSeparator();
++ popup->insertItem(i18n("Depth of '%1' (%2)")
++ .arg(i->text(0)).arg(d), id+1);
++ if (d == maxDrawingDepth()) {
++ popup->setItemChecked(id+1, true);
++ foundDepth = true;
++ }
++ }
++
++ if (maxDrawingDepth()>1) {
++ popup->insertSeparator();
++ if (!foundDepth) {
++ popup->insertItem(i18n("Depth %1").arg(maxDrawingDepth()), id+10);
++ popup->setItemChecked(id+10, true);
++ }
++
++ popup->insertItem(i18n("Decrement (to %1)")
++ .arg(maxDrawingDepth()-1), id+2);
++ popup->insertItem(i18n("Increment (to %1)")
++ .arg(maxDrawingDepth()+1), id+3);
++ }
++}
++
++
++
++/*----------------------------------------------------------------
++ * Option saving/restoring
++ */
++
++void TreeMapWidget::saveOptions(KConfigGroup* config, TQString prefix)
++{
++ config->writeEntry(prefix+"Nesting", splitModeString());
++ config->writeEntry(prefix+"AllowRotation", allowRotation());
++ config->writeEntry(prefix+"ShadingEnabled", isShadingEnabled());
++ config->writeEntry(prefix+"OnlyCorrectBorder", skipIncorrectBorder());
++ config->writeEntry(prefix+"BorderWidth", borderWidth());
++ config->writeEntry(prefix+"MaxDepth", maxDrawingDepth());
++ config->writeEntry(prefix+"MinimalArea", minimalArea());
++
++ int f, fCount = _attr.size();
++ config->writeEntry(prefix+"FieldCount", fCount);
++ for (f=0;f<fCount;f++) {
++ config->writeEntry(TQString(prefix+"FieldVisible%1").arg(f),
++ _attr[f].visible);
++ config->writeEntry(TQString(prefix+"FieldForced%1").arg(f),
++ _attr[f].forced);
++ config->writeEntry(TQString(prefix+"FieldStop%1").arg(f),
++ _attr[f].stop);
++ config->writeEntry(TQString(prefix+"FieldPosition%1").arg(f),
++ fieldPositionString(f));
++ }
++}
++
++
++void TreeMapWidget::restoreOptions(KConfigGroup* config, TQString prefix)
++{
++ bool enabled;
++ int num;
++ TQString str;
++
++ str = config->readEntry(prefix+"Nesting");
++ if (!str.isEmpty()) setSplitMode(str);
++
++ if (config->hasKey(prefix+"AllowRotation")) {
++ enabled = config->readBoolEntry(prefix+"AllowRotation", true);
++ setAllowRotation(enabled);
++ }
++
++ if (config->hasKey(prefix+"ShadingEnabled")) {
++ enabled = config->readBoolEntry(prefix+"ShadingEnabled", true);
++ setShadingEnabled(enabled);
++ }
++
++ if (config->hasKey(prefix+"OnlyCorrectBorder")) {
++ enabled = config->readBoolEntry(prefix+"OnlyCorrectBorder", false);
++ setSkipIncorrectBorder(enabled);
++ }
++
++ num = config->readNumEntry(prefix+"BorderWidth", -2);
++ if (num!=-2) setBorderWidth(num);
++
++ num = config->readNumEntry(prefix+"MaxDepth", -2);
++ if (num!=-2) setMaxDrawingDepth(num);
++
++ num = config->readNumEntry(prefix+"MinimalArea", -2);
++ if (num!=-2) setMinimalArea(num);
++
++ num = config->readNumEntry(prefix+"FieldCount", -2);
++ if (num<=0 || num>MAX_FIELD) return;
++
++ int f;
++ for (f=0;f<num;f++) {
++ str = TQString(prefix+"FieldVisible%1").arg(f);
++ if (config->hasKey(str))
++ setFieldVisible(f, config->readBoolEntry(str));
++
++ str = TQString(prefix+"FieldForced%1").arg(f);
++ if (config->hasKey(str))
++ setFieldForced(f, config->readBoolEntry(str));
++
++ str = config->readEntry(TQString(prefix+"FieldStop%1").arg(f));
++ setFieldStop(f, str);
++
++ str = config->readEntry(TQString(prefix+"FieldPosition%1").arg(f));
++ if (!str.isEmpty()) setFieldPosition(f, str);
++ }
++}
++
++#include "treemap.moc"
+diff --git a/kdecachegrind/kdecachegrind/treemap.h b/kdecachegrind/kdecachegrind/treemap.h
+new file mode 100644
+index 0000000..422cd35
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/treemap.h
+@@ -0,0 +1,759 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/**
++ * A Widget for visualizing hierarchical metrics as areas.
++ * The API is similar to TQListView.
++ *
++ * This file defines the following classes:
++ * DrawParams, RectDrawing, TreeMapItem, TreeMapWidget
++ *
++ * DrawParams/RectDrawing allows reusing of TreeMap drawing
++ * functions in other widgets.
++ */
++
++#ifndef TREEMAP_H
++#define TREEMAP_H
++
++#include <tqstring.h>
++#include <tqwidget.h>
++#include <tqpixmap.h>
++#include <tqptrlist.h>
++#include <tqvaluevector.h>
++#include <tqcolor.h>
++#include <tqapplication.h>
++#include <tqstringlist.h>
++
++class TQPopupMenu;
++class TreeMapTip;
++class TreeMapWidget;
++class TreeMapItem;
++class TreeMapItemList;
++class TQString;
++
++class KConfigGroup;
++
++
++/**
++ * Drawing parameters for an object.
++ * A Helper Interface for RectDrawing.
++ */
++class DrawParams
++{
++public:
++ /**
++ * Positions for drawing into a rectangle.
++ *
++ * The specified position assumes no rotation.
++ * If there is more than one text for one position, it is put
++ * nearer to the center of the item.
++ *
++ * Drawing at top positions cuts free space from top,
++ * drawing at bottom positions cuts from bottom.
++ * Default usually gives positions clockwise according to field number.
++ */
++ enum Position { TopLeft, TopCenter, TopRight,
++ BottomLeft, BottomCenter, BottomRight,
++ Default, Unknown};
++
++ // no constructor as this is an abstract class
++ virtual ~DrawParams() {}
++
++ virtual TQString text(int) const = 0;
++ virtual TQPixmap pixmap(int) const = 0;
++ virtual Position position(int) const = 0;
++ // 0: no limit, negative: leave at least -maxLines() free
++ virtual int maxLines(int) const { return 0; }
++ virtual int fieldCount() const { return 0; }
++
++ virtual TQColor backColor() const { return TQt::white; }
++ virtual const TQFont& font() const = 0;
++
++ virtual bool selected() const { return false; }
++ virtual bool current() const { return false; }
++ virtual bool shaded() const { return true; }
++ virtual bool rotated() const { return false; }
++ virtual bool drawFrame() const { return true; }
++};
++
++
++/*
++ * DrawParam with attributes stored
++ */
++class StoredDrawParams: public DrawParams
++{
++public:
++ StoredDrawParams();
++ StoredDrawParams(TQColor c,
++ bool selected = false, bool current = false);
++
++ // getters
++ TQString text(int) const;
++ TQPixmap pixmap(int) const;
++ Position position(int) const;
++ int maxLines(int) const;
++ int fieldCount() const { return _field.size(); }
++
++ TQColor backColor() const { return _backColor; }
++ bool selected() const { return _selected; }
++ bool current() const { return _current; }
++ bool shaded() const { return _shaded; }
++ bool rotated() const { return _rotated; }
++ bool drawFrame() const { return _drawFrame; }
++
++ const TQFont& font() const;
++
++ // attribute setters
++ void setField(int f, const TQString& t, TQPixmap pm = TQPixmap(),
++ Position p = Default, int maxLines = 0);
++ void setText(int f, const TQString&);
++ void setPixmap(int f, const TQPixmap&);
++ void setPosition(int f, Position);
++ void setMaxLines(int f, int);
++ void setBackColor(const TQColor& c) { _backColor = c; }
++ void setSelected(bool b) { _selected = b; }
++ void setCurrent(bool b) { _current = b; }
++ void setShaded(bool b) { _shaded = b; }
++ void setRotated(bool b) { _rotated = b; }
++ void drawFrame(bool b) { _drawFrame = b; }
++
++protected:
++ TQColor _backColor;
++ bool _selected :1;
++ bool _current :1;
++ bool _shaded :1;
++ bool _rotated :1;
++ bool _drawFrame :1;
++
++private:
++ // resize field array if needed to allow to access field <f>
++ void ensureField(int f);
++
++ struct Field {
++ TQString text;
++ TQPixmap pix;
++ Position pos;
++ int maxLines;
++ };
++
++ TQValueVector<Field> _field;
++};
++
++
++/* State for drawing on a rectangle.
++ *
++ * Following drawing functions are provided:
++ * - background drawing with shading and 3D frame
++ * - successive pixmap/text drawing at various positions with wrap-around
++ * optimized for minimal space usage (e.g. if a text is drawn at top right
++ * after text on top left, the same line is used if space allows)
++ *
++ */
++class RectDrawing
++{
++public:
++ RectDrawing(TQRect);
++ ~RectDrawing();
++
++ // The default DrawParams object used.
++ DrawParams* drawParams();
++ // we take control over the given object (i.e. delete at destruction)
++ void setDrawParams(DrawParams*);
++
++ // draw on a given TQPainter, use this class as info provider per default
++ void drawBack(TQPainter*, DrawParams* dp = 0);
++ /* Draw field at position() from pixmap()/text() with maxLines().
++ * Returns true if something was drawn
++ */
++ bool drawField(TQPainter*, int f, DrawParams* dp = 0);
++
++ // resets rectangle for free space
++ void setRect(TQRect);
++
++ // Returns the rectangle area still free of text/pixmaps after
++ // a number of drawText() calls.
++ TQRect remainingRect(DrawParams* dp = 0);
++
++private:
++ int _usedTopLeft, _usedTopCenter, _usedTopRight;
++ int _usedBottomLeft, _usedBottomCenter, _usedBottomRight;
++ TQRect _rect;
++
++ // temporary
++ int _fontHeight;
++ TQFontMetrics* _fm;
++ DrawParams* _dp;
++};
++
++
++class TreeMapItemList: public TQPtrList<TreeMapItem>
++{
++public:
++ TreeMapItem* commonParent();
++protected:
++ int compareItems ( Item item1, Item item2 );
++};
++
++typedef TQPtrListIterator<TreeMapItem> TreeMapItemListIterator;
++
++
++/**
++ * Base class of items in TreeMap.
++ *
++ * This class supports an arbitrary number of text() strings
++ * positioned counterclock-wise starting at TopLeft. Each item
++ * has its own static value(), sum() and sorting(). The
++ * splitMode() and borderWidth() is taken from a TreeMapWidget.
++ *
++ * If you want more flexibility, reimplement TreeMapItem and
++ * override the corresponding methods. For dynamic creation of child
++ * items on demand, reimplement children().
++ */
++class TreeMapItem: public StoredDrawParams
++{
++public:
++
++ /**
++ * Split direction for nested areas:
++ * AlwaysBest: Choose split direction for every subitem according to
++ * longest side of rectangle left for drawing
++ * Best: Choose split direction for all subitems of an area
++ * depending on longest side
++ * HAlternate:Qt::Horizontal at top; alternate direction on depth step
++ * VAlternate:Qt::Vertical at top; alternate direction on depth step
++ * Qt::Horizontal: Always horizontal split direction
++ * Qt::Vertical: Always vertical split direction
++ */
++ enum SplitMode { Bisection, Columns, Rows,
++ AlwaysBest, Best,
++ HAlternate, VAlternate,
++ Horizontal, Vertical };
++
++ TreeMapItem(TreeMapItem* parent = 0, double value = 1.0 );
++ TreeMapItem(TreeMapItem* parent, double value,
++ TQString text1, TQString text2 = TQString(),
++ TQString text3 = TQString(), TQString text4 = TQString());
++ virtual ~TreeMapItem();
++
++ bool isChildOf(TreeMapItem*);
++
++ TreeMapItem* commonParent(TreeMapItem* item);
++
++ // force a redraw of this item
++ void redraw();
++
++ // delete all children
++ void clear();
++
++ // force new child generation & refresh
++ void refresh();
++
++ // call in a reimplemented items() method to check if already called
++ // after a clear(), this will return false
++ bool initialized();
++
++ /**
++ * Adds an item to a parent.
++ * When no sorting is used, the item is appended (drawn at bottom).
++ * This is only needed if the parent was not already specified in the
++ * construction of the item.
++ */
++ void addItem(TreeMapItem*);
++
++ /**
++ * Returns a list of text strings of specified text number,
++ * from root up to this item.
++ */
++ TQStringList path(int) const;
++
++ /**
++ * Depth of this item. This is the distance to root.
++ */
++ int depth() const;
++
++ /**
++ * Parent Item
++ */
++ TreeMapItem* parent() const { return _parent; }
++
++ /**
++ * Temporary rectangle used for drawing this item the last time.
++ * This is internally used to map from a point to an item.
++ */
++ void setItemRect(const TQRect& r) { _rect = r; }
++ void clearItemRect();
++ const TQRect& itemRect() const { return _rect; }
++ int width() const { return _rect.width(); }
++ int height() const { return _rect.height(); }
++
++ /**
++ * Temporary rectangle list of free space of this item.
++ * Used internally to enable tooltip.
++ */
++ void clearFreeRects();
++ TQPtrList<TQRect>* freeRects() const { return _freeRects; }
++ void addFreeRect(const TQRect& r);
++
++ /**
++ * Temporary child item index of the child that was current() recently.
++ */
++ int index() const { return _index; }
++ void setIndex(int i) { _index = i; }
++
++
++ /**
++ * TreeMap widget this item is put in.
++ */
++ TreeMapWidget* widget() const { return _widget; }
++
++ void setParent(TreeMapItem* p);
++ void setWidget(TreeMapWidget* w) { _widget = w; }
++ void setSum(double s) { _sum = s; }
++ void setValue(double s) { _value = s; }
++
++ virtual double sum() const;
++ virtual double value() const;
++ // replace "Default" position with setting from TreeMapWidget
++ virtual Position position(int) const;
++ virtual const TQFont& font() const;
++ virtual bool isMarked(int) const;
++
++ virtual int borderWidth() const;
++
++ /**
++ * Returns the text number after that sorting is done or
++ * -1 for no sorting, -2 for value() sorting (default).
++ * If ascending != 0, a bool value is written at that location
++ * to indicate if sorting should be ascending.
++ */
++ virtual int sorting(bool* ascending) const;
++
++ /**
++ * Set the sorting for child drawing.
++ *
++ * Default is no sorting: <textNo> = -1
++ * For value() sorting, use <textNo> = -2
++ *
++ * For fast sorting, set this to -1 before child insertions and call
++ * again after inserting all children.
++ */
++ void setSorting(int textNo, bool ascending = true);
++
++ /**
++ * Resort according to the already set sorting.
++ *
++ * This has to be done if the sorting base changes (e.g. text or values
++ * change). If this is only true for the children of this item, you can
++ * set the recursive parameter to false.
++ */
++ void resort(bool recursive = true);
++
++ virtual SplitMode splitMode() const;
++ virtual int rtti() const;
++ // not const as this can create children on demand
++ virtual TreeMapItemList* children();
++
++protected:
++ TreeMapItemList* _children;
++ double _sum, _value;
++
++private:
++ TreeMapWidget* _widget;
++ TreeMapItem* _parent;
++
++ int _sortTextNo;
++ bool _sortAscending;
++
++ // temporary layout
++ TQRect _rect;
++ TQPtrList<TQRect>* _freeRects;
++ int _depth;
++
++ // temporary self value (when using level skipping)
++ double _unused_self;
++
++ // index of last active subitem
++ int _index;
++};
++
++
++/**
++ * Class for visualization of a metric of hierarchically
++ * nested items as 2D areas.
++ */
++class TreeMapWidget: public TQWidget
++{
++ Q_OBJECT
++ TQ_OBJECT
++
++public:
++
++ /**
++ * Same as in TQListBox/TQListView
++ */
++ enum SelectionMode { Single, Multi, Extended, NoSelection };
++
++ /* The widget becomes owner of the base item */
++ TreeMapWidget(TreeMapItem* base, TQWidget* parent=0, const char* name=0);
++ ~TreeMapWidget();
++
++ /**
++ * Returns the TreeMapItem filling out the widget space
++ */
++ TreeMapItem* base() const { return _base; }
++
++ /**
++ * Returns a reference to the current widget font.
++ */
++ const TQFont& currentFont() const;
++
++ /**
++ * Returns the area item at position x/y, independent from any
++ * maxSelectDepth setting.
++ */
++ TreeMapItem* item(int x, int y) const;
++
++ /**
++ * Returns the nearest item with a visible area; this
++ * can be the given item itself.
++ */
++ TreeMapItem* visibleItem(TreeMapItem*) const;
++
++ /**
++ * Returns the item possible for selection. this returns the
++ * given item itself or a parent thereof,
++ * depending on setting of maxSelectDepth().
++ */
++ TreeMapItem* possibleSelection(TreeMapItem*) const;
++
++ /**
++ * Selects or unselects an item.
++ * In multiselection mode, the constrain that a selected item
++ * has no selected children or parents stays true.
++ */
++ void setSelected(TreeMapItem*, bool selected = true);
++
++ /**
++ * Switches on the marking <markNo>. Marking 0 switches off marking.
++ * This is mutually exclusive to selection, and is automatically
++ * switched off when selection is changed (also by the user).
++ * Marking is visually the same as selection, and is based on
++ * TreeMapItem::isMarked(<markNo>).
++ * This enables to programmatically show multiple selected items
++ * at once even in single selection mode.
++ */
++ void setMarked(int markNo = 1, bool redraw = true);
++
++ /**
++ * Clear selection of all selected items which are children of
++ * parent. When parent == 0, clears whole selection
++ * Returns true if selection changed.
++ */
++ bool clearSelection(TreeMapItem* parent = 0);
++
++ /**
++ * Selects or unselects items in a range.
++ * This is needed internally for Shift-Click in Extented mode.
++ * Range means for a hierarchical widget:
++ * - select/unselect i1 and i2 according selected
++ * - search common parent of i1 and i2, and select/unselect the
++ * range of direct children between but excluding the child
++ * leading to i1 and the child leading to i2.
++ */
++ void setRangeSelection(TreeMapItem* i1,
++ TreeMapItem* i2, bool selected);
++
++ /**
++ * Sets the current item.
++ * The current item is mainly used for keyboard navigation.
++ */
++ void setCurrent(TreeMapItem*, bool kbd=false);
++
++ /**
++ * Set the maximal depth a selected item can have.
++ * If you try to select a item with higher depth, the ancestor holding
++ * this condition is used.
++ *
++ * See also possibleSelection().
++ */
++ void setMaxSelectDepth(int d) { _maxSelectDepth = d; }
++
++
++ void setSelectionMode(SelectionMode m) { _selectionMode = m; }
++
++ /**
++ * for setting/getting global split direction
++ */
++ void setSplitMode(TreeMapItem::SplitMode m);
++ TreeMapItem::SplitMode splitMode() const;
++ // returns true if string was recognized
++ bool setSplitMode(TQString);
++ TQString splitModeString() const;
++
++
++ /*
++ * Shading of rectangles enabled ?
++ */
++ void setShadingEnabled(bool s);
++ bool isShadingEnabled() const { return _shading; }
++
++ /* Setting for a whole depth level: draw 3D frame (default) or solid */
++ void drawFrame(int d, bool b);
++ bool drawFrame(int d) const { return (d<4)?_drawFrame[d]:true; }
++
++ /* Setting for a whole depth level: draw items (default) or transparent */
++ void setTransparent(int d, bool b);
++ bool isTransparent(int d) const { return (d<4)?_transparent[d]:false; }
++
++ /**
++ * Items usually have a size proportional to their value().
++ * With <width>, you can give the minimum width
++ * of the resulting rectangle to still be drawn.
++ * For space not used because of to small items, you can specify
++ * with <reuseSpace> if the background should shine through or
++ * the space will be used to enlarge the next item to be drawn
++ * at this level.
++ */
++ void setVisibleWidth(int width, bool reuseSpace = false);
++
++ /**
++ * If a children value() is almost the parents sum(),
++ * it can happen that the border to be drawn for visibilty of
++ * nesting relations takes to much space, and the
++ * parent/child size relation can not be mapped to a correct
++ * area size relation.
++ *
++ * Either
++ * (1) Ignore the incorrect drawing, or
++ * (2) Skip drawing of the parent level alltogether.
++ */
++ void setSkipIncorrectBorder(bool enable = true);
++ bool skipIncorrectBorder() const { return _skipIncorrectBorder; }
++
++ /**
++ * Maximal nesting depth
++ */
++ void setMaxDrawingDepth(int d);
++ int maxDrawingDepth() const { return _maxDrawingDepth; }
++
++ /**
++ * Minimal area for rectangles to draw
++ */
++ void setMinimalArea(int area);
++ int minimalArea() const { return _minimalArea; }
++
++ /* defaults for text attributes */
++ TQString defaultFieldType(int) const;
++ TQString defaultFieldStop(int) const;
++ bool defaultFieldVisible(int) const;
++ bool defaultFieldForced(int) const;
++ DrawParams::Position defaultFieldPosition(int) const;
++
++ /**
++ * Set the type name of a field.
++ * This is important for the visualization menu generated
++ * with visualizationMenu()
++ */
++ void setFieldType(int, TQString);
++ TQString fieldType(int) const;
++
++ /**
++ * Stop drawing at item with name
++ */
++ void setFieldStop(int, TQString);
++ TQString fieldStop(int) const;
++
++ /**
++ * Should the text with number textNo be visible?
++ * This is only done if remaining space is enough to allow for
++ * proportional size constrains.
++ */
++ void setFieldVisible(int, bool);
++ bool fieldVisible(int) const;
++
++ /**
++ * Should the drawing of the name into the rectangle be forced?
++ * This enables drawing of the name before drawing subitems, and
++ * thus destroys proportional constrains.
++ */
++ void setFieldForced(int, bool);
++ bool fieldForced(int) const;
++
++ /**
++ * Set the field position in the area. See TreeMapItem::Position
++ */
++ void setFieldPosition(int, DrawParams::Position);
++ DrawParams::Position fieldPosition(int) const;
++ void setFieldPosition(int, TQString);
++ TQString fieldPositionString(int) const;
++
++ /**
++ * Do we allow the texts to be rotated by 90 degrees for better fitting?
++ */
++ void setAllowRotation(bool);
++ bool allowRotation() const { return _allowRotation; }
++
++ void setBorderWidth(int w);
++ int borderWidth() const { return _borderWidth; }
++
++ /**
++ * Save/restore options.
++ */
++ void saveOptions(KConfigGroup*, TQString prefix = TQString());
++ void restoreOptions(KConfigGroup*, TQString prefix = TQString());
++
++ /**
++ * These functions populate given popup menus.
++ * The added items are already connected to handlers.
++ *
++ * The int is the menu id where to start for the items (100 IDs reserved).
++ */
++ void addSplitDirectionItems(TQPopupMenu*, int);
++ void addSelectionItems(TQPopupMenu*, int, TreeMapItem*);
++ void addFieldStopItems(TQPopupMenu*, int, TreeMapItem*);
++ void addAreaStopItems(TQPopupMenu*, int, TreeMapItem*);
++ void addDepthStopItems(TQPopupMenu*, int, TreeMapItem*);
++ void addVisualizationItems(TQPopupMenu*, int);
++
++ TreeMapWidget* widget() { return this; }
++ TreeMapItem* current() const { return _current; }
++ TreeMapItemList selection() const { return _selection; }
++ bool isSelected(TreeMapItem* i) const;
++ int maxSelectDepth() const { return _maxSelectDepth; }
++ SelectionMode selectionMode() const { return _selectionMode; }
++
++ /**
++ * Return tooltip string to show for a item (can be rich text)
++ * Default implementation gives lines with "text0 (text1)" going to root.
++ */
++ virtual TQString tipString(TreeMapItem* i) const;
++
++ /**
++ * Redraws an item with all children.
++ * This takes changed values(), sums(), colors() and text() into account.
++ */
++ void redraw(TreeMapItem*);
++ void redraw() { redraw(_base); }
++
++ /**
++ * Resort all TreeMapItems. See TreeMapItem::resort().
++ */
++ void resort() { _base->resort(true); }
++
++ // internal
++ void drawTreeMap();
++
++ // used internally when items are destroyed
++ void deletingItem(TreeMapItem*);
++
++protected slots:
++ void splitActivated(int);
++ void selectionActivated(int);
++ void fieldStopActivated(int);
++ void areaStopActivated(int);
++ void depthStopActivated(int);
++ void visualizationActivated(int);
++
++signals:
++ void selectionChanged();
++ void selectionChanged(TreeMapItem*);
++
++ /**
++ * This signal is emitted if the current item changes.
++ * If the change is done because of keyboard navigation,
++ * the <kbd> is set to true
++ */
++ void currentChanged(TreeMapItem*, bool keyboard);
++ void clicked(TreeMapItem*);
++ void returnPressed(TreeMapItem*);
++ void doubleClicked(TreeMapItem*);
++ void rightButtonPressed(TreeMapItem*, const TQPoint &);
++ void contextMenuRequested(TreeMapItem*, const TQPoint &);
++
++protected:
++ void mousePressEvent( TQMouseEvent * );
++ void contextMenuEvent( TQContextMenuEvent * );
++ void mouseReleaseEvent( TQMouseEvent * );
++ void mouseMoveEvent( TQMouseEvent * );
++ void mouseDoubleClickEvent( TQMouseEvent * );
++ void keyPressEvent( TQKeyEvent* );
++ void paintEvent( TQPaintEvent * );
++ void resizeEvent( TQResizeEvent * );
++ void showEvent( TQShowEvent * );
++ void fontChange( const TQFont& );
++
++private:
++ TreeMapItemList diff(TreeMapItemList&, TreeMapItemList&);
++ // returns true if selection changed
++ TreeMapItem* setTmpSelected(TreeMapItem*, bool selected = true);
++ TreeMapItem* setTmpRangeSelection(TreeMapItem* i1,
++ TreeMapItem* i2, bool selected);
++ bool isTmpSelected(TreeMapItem* i);
++
++ void drawItem(TQPainter* p, TreeMapItem*);
++ void drawItems(TQPainter* p, TreeMapItem*);
++ bool horizontal(TreeMapItem* i, const TQRect& r);
++ void drawFill(TreeMapItem*,TQPainter* p, TQRect& r);
++ void drawFill(TreeMapItem*,TQPainter* p, TQRect& r,
++ TreeMapItemListIterator it, int len, bool goBack);
++ bool drawItemArray(TQPainter* p, TreeMapItem*, TQRect& r, double,
++ TreeMapItemListIterator it, int len, bool);
++ bool resizeAttr(int);
++
++ TreeMapItem* _base;
++ TreeMapItem *_current, *_pressed, *_lastOver, *_oldCurrent;
++ TreeMapTip* _tip;
++ int _maxSelectDepth, _maxDrawingDepth;
++
++ // attributes for field, per textNo
++ struct FieldAttr {
++ TQString type, stop;
++ bool visible, forced;
++ DrawParams::Position pos;
++ };
++ TQValueVector<FieldAttr> _attr;
++
++ SelectionMode _selectionMode;
++ TreeMapItem::SplitMode _splitMode;
++ int _visibleWidth, _stopArea, _minimalArea, _borderWidth;
++ bool _reuseSpace, _skipIncorrectBorder, _drawSeparators, _shading;
++ bool _allowRotation;
++ bool _transparent[4], _drawFrame[4];
++ TreeMapItem * _needsRefresh;
++ TreeMapItemList _selection;
++ int _markNo;
++
++ // for the context menus: start IDs
++ int _splitID, _selectionID, _visID;
++ int _fieldStopID, _areaStopID, _depthStopID;
++ TreeMapItem* _menuItem;
++
++ // temporary selection while dragging, used for drawing
++ // most of the time, _selection == _tmpSelection
++ TreeMapItemList _tmpSelection;
++ bool _inShiftDrag, _inControlDrag;
++
++ // temporary widget font metrics while drawing
++ TQFont _font;
++ int _fontHeight;
++
++ // back buffer pixmap
++ TQPixmap _pixmap;
++};
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/utils.cpp b/kdecachegrind/kdecachegrind/utils.cpp
+new file mode 100644
+index 0000000..65c7e34
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/utils.cpp
+@@ -0,0 +1,483 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Utility classes for KCachegrind
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifdef HAVE_MMAP
++#include <unistd.h>
++#include <sys/mman.h>
++#endif
++
++#include <tqfile.h>
++#include <errno.h>
++
++#include "utils.h"
++
++
++// class FixString
++
++FixString::FixString(const char* str, int len)
++{
++ _str = str;
++ _len = len;
++}
++
++bool FixString::stripFirst(char& c)
++{
++ if (!_len) {
++ c = 0;
++ return false;
++ }
++
++ c = *_str;
++ _str++;
++ _len--;
++ return true;
++ }
++
++bool FixString::stripPrefix(const char* p)
++{
++ if (_len == 0) return false;
++ if (!p || (*p != *_str)) return false;
++
++ const char* s = _str+1;
++ int l = _len-1;
++ p++;
++ while(*p) {
++ if (l==0) return false;
++ if (*s != *p) return false;
++ p++;
++ s++;
++ l--;
++ }
++ _str = s;
++ _len = l;
++ return true;
++}
++
++
++// this parses hexadecimal (with prefix '0x' too)
++bool FixString::stripUInt(unsigned int& v, bool stripSpaces)
++{
++ if (_len==0) {
++ v = 0;
++ return false;
++ }
++
++ char c = *_str;
++ if (c<'0' || c>'9') {
++ v = 0;
++ return false;
++ }
++
++ v = c-'0';
++ const char* s = _str+1;
++ int l = _len-1;
++ c = *s;
++
++ if ((l>0) && (c == 'x') && (v==0)) {
++ // hexadecimal
++ s++;
++ c = *s;
++ l--;
++
++ while(l>0) {
++ if (c>='0' && c<='9')
++ v = 16*v + (c-'0');
++ else if (c>='a' && c<='f')
++ v = 16*v + 10 + (c-'a');
++ else if (c>='A' && c<='F')
++ v = 16*v + 10 + (c-'A');
++ else
++ break;
++ s++;
++ c = *s;
++ l--;
++ }
++ }
++ else {
++ // decimal
++
++ while(l>0) {
++ if (c<'0' || c>'9') break;
++ v = 10*v + (c-'0');
++ s++;
++ c = *s;
++ l--;
++ }
++ }
++
++ if (stripSpaces)
++ while(l>0) {
++ if (c != ' ') break;
++ s++;
++ c = *s;
++ l--;
++ }
++
++ _str = s;
++ _len = l;
++ return true;
++}
++
++
++void FixString::stripSurroundingSpaces()
++{
++ if (_len==0) return;
++
++ // leading spaces
++ while((_len>0) && (*_str==' ')) {
++ _len--;
++ _str++;
++ }
++
++ // trailing spaces
++ while((_len>0) && (_str[_len-1]==' ')) {
++ _len--;
++ }
++}
++
++void FixString::stripSpaces()
++{
++ while((_len>0) && (*_str==' ')) {
++ _len--;
++ _str++;
++ }
++}
++
++bool FixString::stripName(FixString& s)
++{
++ if (_len==0) return false;
++
++ // first char has to be a letter or "_"
++ if (!TQChar(*_str).isLetter() && (*_str != '_')) return false;
++
++ int newLen = 1;
++ const char* newStr = _str;
++
++ _str++;
++ _len--;
++
++ while(_len>0) {
++ if (!TQChar(*_str).isLetterOrNumber()
++ && (*_str != '_')) break;
++
++ newLen++;
++ _str++;
++ _len--;
++ }
++
++ s.set(newStr, newLen);
++ return true;
++}
++
++FixString FixString::stripUntil(char c)
++{
++ if (_len == 0) return FixString();
++
++ const char* newStr = _str;
++ int newLen = 0;
++
++ while(_len>0) {
++ if (*_str == c) {
++ _str++;
++ _len--;
++ break;
++ }
++
++ _str++;
++ _len--;
++ newLen++;
++ }
++ return FixString(newStr, newLen);
++}
++
++bool FixString::stripUInt64(uint64& v, bool stripSpaces)
++{
++ if (_len==0) {
++ v = 0;
++ return false;
++ }
++
++ char c = *_str;
++ if (c<'0' || c>'9') {
++ v = 0;
++ return false;
++ }
++
++ v = c-'0';
++ const char* s = _str+1;
++ int l = _len-1;
++ c = *s;
++
++ if ((l>0) && (c == 'x') && (v==0)) {
++ // hexadecimal
++ s++;
++ c = *s;
++ l--;
++
++ while(l>0) {
++ if (c>='0' && c<='9')
++ v = 16*v + (c-'0');
++ else if (c>='a' && c<='f')
++ v = 16*v + 10 + (c-'a');
++ else if (c>='A' && c<='F')
++ v = 16*v + 10 + (c-'A');
++ else
++ break;
++ s++;
++ c = *s;
++ l--;
++ }
++ }
++ else {
++ // decimal
++ while(l>0) {
++ if (c<'0' || c>'9') break;
++ v = 10*v + (c-'0');
++ s++;
++ c = *s;
++ l--;
++ }
++ }
++
++ if (stripSpaces)
++ while(l>0) {
++ if (c != ' ') break;
++ s++;
++ c = *s;
++ l--;
++ }
++
++ _str = s;
++ _len = l;
++ return true;
++}
++
++
++bool FixString::stripInt64(int64& v, bool stripSpaces)
++{
++ if (_len==0) {
++ v = 0;
++ return false;
++ }
++
++ char c = *_str;
++ if (c<'0' || c>'9') {
++ v = 0;
++ return false;
++ }
++
++ v = c-'0';
++ const char* s = _str+1;
++ int l = _len-1;
++ c = *s;
++
++ if ((l>0) && (c == 'x') && (v==0)) {
++ // hexadecimal
++ s++;
++ c = *s;
++ l--;
++
++ while(l>0) {
++ if (c>='0' && c<='9')
++ v = 16*v + (c-'0');
++ else if (c>='a' && c<='f')
++ v = 16*v + 10 + (c-'a');
++ else if (c>='A' && c<='F')
++ v = 16*v + 10 + (c-'A');
++ else
++ break;
++ s++;
++ c = *s;
++ l--;
++ }
++ }
++ else {
++ // decimal
++
++ while(l>0) {
++ if (c<'0' || c>'9') break;
++ v = 10*v + (c-'0');
++ s++;
++ c = *s;
++ l--;
++ }
++ }
++
++ if (stripSpaces)
++ while(l>0) {
++ if (c != ' ') break;
++ s++;
++ c = *s;
++ l--;
++ }
++
++ _str = s;
++ _len = l;
++ return true;
++}
++
++
++
++// class FixFile
++
++FixFile::FixFile(TQFile* file)
++{
++ if (!file) {
++ _len = 0;
++ _currentLeft = 0;
++ _openError = true;
++ return;
++ }
++
++ _filename = file->name();
++ if (!file->isOpen() && !file->open( IO_ReadOnly ) ) {
++ qWarning( "%s: %s", (const char*) TQFile::encodeName(_filename),
++ strerror( errno ) );
++ _len = 0;
++ _currentLeft = 0;
++ _openError = true;
++ return;
++ }
++
++ _openError = false;
++ _used_mmap = false;
++
++#ifdef HAVE_MMAP
++ char *addr = 0;
++ size_t len = file->size();
++ if (len>0) addr = (char *) mmap( addr, len,
++ PROT_READ, MAP_PRIVATE,
++ file->handle(), 0 );
++ if (addr && (addr != MAP_FAILED)) {
++ // mmap succeeded
++ _base = addr;
++ _len = len;
++ _used_mmap = true;
++
++ if (0) qDebug("Mapped '%s'", _filename.ascii());
++ } else {
++#endif // HAVE_MMAP
++ // try reading the data into memory instead
++ _data = file->readAll();
++ _base = _data.data();
++ _len = _data.size();
++#ifdef HAVE_MMAP
++ }
++#endif // HAVE_MMAP
++
++ _current = _base;
++ _currentLeft = _len;
++}
++
++FixFile::~FixFile()
++{
++ // if the file was read into _data, it will be deleted automatically
++
++#ifdef HAVE_MMAP
++ if (_used_mmap) {
++ if (0) qDebug("Unmapping '%s'", _filename.ascii());
++ if (munmap(_base, _len) != 0)
++ qWarning( "munmap: %s", strerror( errno ) );
++ }
++#endif // HAVE_MMAP
++}
++
++bool FixFile::nextLine(FixString& str)
++{
++ if (_currentLeft == 0) return false;
++
++ unsigned left = _currentLeft;
++ char* current = _current;
++
++ while(left>0) {
++ if (*current == 0 || *current == '\n') break;
++ current++;
++ left--;
++ }
++
++ if (0) {
++ char tmp[200];
++ int l = _currentLeft-left;
++ if (l>199) l = 199;
++ strncpy(tmp, _current, l);
++ tmp[l] = 0;
++ qDebug("[FixFile::nextLine] At %d, len %d: '%s'",
++ _current - _base, _currentLeft-left, tmp);
++ }
++
++ str.set(_current, _currentLeft-left);
++
++ if (*current == '\n') {
++ current++;
++ left--;
++ }
++ _current = current;
++ _currentLeft = left;
++
++ return true;
++}
++
++bool FixFile::setCurrent(unsigned pos)
++{
++ if (pos > _len) return false;
++
++ _current = _base + pos;
++ _currentLeft = _len - pos;
++ return true;
++}
++
++
++#if 0
++
++// class AppendList
++
++
++AppendList::AppendList()
++{
++ _next = 0;
++ _current = 0;
++ _last = 0;
++
++ _count = 0;
++ _currentIndex = 0;
++ _lastIndex = 0;
++ _autoDelete = false;
++}
++
++
++void AppendList::clear()
++{
++ int count = _count;
++ int i;
++
++ if (count <= firstLen) {
++ if (_autoDelete)
++ for (i=0;i<count;i++)
++ delete _first[i];
++ }
++}
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/utils.h b/kdecachegrind/kdecachegrind/utils.h
+new file mode 100644
+index 0000000..7256f05
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/utils.h
+@@ -0,0 +1,164 @@
++/* This file is part of KCachegrind.
++ Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
++
++ KCachegrind is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public
++ License as published by the Free Software Foundation, version 2.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; see the file COPYING. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++/*
++ * Utility classes for KCachegrind
++ */
++
++#ifndef UTILS_H
++#define UTILS_H
++
++#include <tqstring.h>
++
++class TQFile;
++
++typedef unsigned long long uint64;
++typedef long long int64;
++
++/**
++ * A simple, constant string class
++ *
++ * For use with zero-copy strings from mapped files.
++ */
++class FixString {
++
++ public:
++ // constructor for an invalid string
++ FixString() { _len = 0; _str = 0; }
++
++ /**
++ * FixString never does a deep copy! You have to make sure that
++ * the string starting at the char pointer is valid trough the
++ * lifetime of FixString.
++ */
++ FixString(const char*, int len);
++
++ int len() { return _len; }
++ const char* ascii() { return _str; }
++ bool isEmpty() { return _len == 0; }
++ bool isValid() { return _str != 0; }
++
++ // sets <c> to first character and returns true if length >0
++ bool first(char& c)
++ { if (_len==0) return false; c=_str[0]; return true; }
++
++ void set(const char* s, int l) { _str=s; _len=l; }
++ bool stripFirst(char&);
++ bool stripPrefix(const char*);
++
++ /**
++ * Strip leading and trailing spaces
++ */
++ void stripSurroundingSpaces();
++
++ /**
++ * Strip leading spaces
++ */
++ void stripSpaces();
++
++ /**
++ * Strip name: [A-Za-z_][0-9A_Za-z_]*
++ */
++ bool stripName(FixString&);
++
++ /**
++ * Strip string until char appears or end. Strips char, too.
++ */
++ FixString stripUntil(char);
++
++ bool stripUInt(uint&, bool stripSpaces = true);
++ bool stripUInt64(uint64&, bool stripSpaces = true);
++ bool stripInt64(int64&, bool stripSpaces = true);
++
++ operator TQString() const
++ { return TQString::fromLatin1(_str,_len); }
++
++ private:
++ const char* _str;
++ int _len;
++};
++
++
++/**
++ * A class for fast line by line reading of a read-only ASCII file
++ */
++class FixFile {
++
++ public:
++ FixFile(TQFile*);
++ ~FixFile();
++
++ /**
++ * Read next line into <str>. Returns false on error or EOF.
++ */
++ bool nextLine(FixString& str);
++ bool exists() { return !_openError; }
++ unsigned len() { return _len; }
++ unsigned current() { return _current - _base; }
++ bool setCurrent(unsigned pos);
++ void rewind() { setCurrent(0); }
++
++ private:
++ char *_base, *_current;
++ TQByteArray _data;
++ unsigned _len, _currentLeft;
++ bool _used_mmap, _openError;
++ TQString _filename;
++};
++
++
++/**
++ * A list of pointers, only able to append items.
++ * Optimized for speed, not space.
++ */
++template<class type>
++class AppendList {
++
++ public:
++ AppendList();
++ ~AppendList() { clear(); }
++
++ void setAutoDelete(bool);
++ void clear();
++ void append(const type*);
++
++ unsigned count() const { return _count; }
++ unsigned containsRef(const type*) const;
++
++ type* current();
++ type* first();
++ type* next();
++
++ private:
++ static const int firstLen = 8;
++ static const int maxLen = 256;
++
++ struct AppendListChunk {
++ int size;
++ struct AppendListChunk* next;
++ type* data[1];
++ };
++
++ struct AppendListChunk *_next, *_current, *_last;
++ int _count, _currentIndex, _lastIndex;
++ bool _autoDelete;
++ type* _first[firstLen];
++};
++
++
++#endif
+diff --git a/kdecachegrind/kdecachegrind/x-kcachegrind.desktop b/kdecachegrind/kdecachegrind/x-kcachegrind.desktop
+new file mode 100644
+index 0000000..b9bf93a
+--- /dev/null
++++ b/kdecachegrind/kdecachegrind/x-kcachegrind.desktop
+@@ -0,0 +1,44 @@
++[Desktop Entry]
++Comment=Cachegrind/Callgrind Profile Dump
++Comment[ca]=Resultat del anàlisis de Cachegrind/Callgring
++Comment[cs]=Data profilace Cachegrind/Callgrind
++Comment[cy]=Tomen Proffil Cachegrind/Callgrind
++Comment[da]=Cachegrind/Callgrind profile-dump
++Comment[de]=Cachegrind/Callgrind Profil-Ausgabe
++Comment[el]=Αποτύπωση προφίλ Cachegrind/Callgrind
++Comment[es]=Resultado de análisis de Cachegrind/Callgring
++Comment[et]=Cachegrind/Callgrind profileerimistõmmis
++Comment[eu]=Cachegrind/Callgrind profil iraulketa
++Comment[fa]=تخلیۀ Profile Cachegrind/Callgrind
++Comment[fi]=Cachegrind/Callgrind-profiilivedos
++Comment[fr]=Dépôt de profil Cachegrind / Callgrind
++Comment[gl]=Resultado da análise de Cachegrind/Callgrind
++Comment[hi]=केश-ग्रिंड/काल-ग्रिंड प्रोफ़ाइल डम्प
++Comment[hu]=Cachegrind/Callgrind teljesítményprofil-fájl
++Comment[is]=Niðurstaða afkastakönnunar á Cachegrind/Callgrind
++Comment[it]=Dump del profilo di Cachegrind/Callgrind
++Comment[ja]=Callgrind/Callgrind プロファイルダンプ
++Comment[ka]=Cachegrind/Callgrind პროფილის დამპი
++Comment[kk]=Cachegrind/Callgrind профилінің дампы
++Comment[nds]=Cachegrind/Callgrind-Profilutgaav
++Comment[ne]=Cachegrind/Callgrind प्रोफाइल डम्प
++Comment[nl]=Cachegrind/Callgrind Profieldump
++Comment[nn]=Cachegrind/Callgrind-profildump
++Comment[pl]=Zrzut profilowania Cachegrind/Callgrind
++Comment[pt]=Resultado da Análise do Cachegrind/Callgrind
++Comment[pt_BR]=Depósito de Perfil Cachegrind/Callgrind
++Comment[ru]=Дамп профилирования Cachegrind/Callgrind
++Comment[sk]=Výpis volaní Cachegrind/Callgrind
++Comment[sr]=Cachegrind-ов/Callgrind-ов избачај профила
++Comment[sr@Latn]=Cachegrind-ov/Callgrind-ov izbačaj profila
++Comment[sv]=Profileringsdump från Cachegrind/Callgrind
++Comment[ta]=இடைமாற்றகட்டம்/ அழைப்பு கட்டம் விவரக்குறி திணிப்பு
++Comment[tg]=Дампи профилкунии Cachegrind/Callgrind
++Comment[uk]=Звалювання профілювання Cachegrind/Callgrind
++Comment[zh_CN]=Cachegrind/Callgrind 配置文件转存
++Comment[zh_TW]=Cachegrind/Callgrind 分析資料傾印
++DefaultApp=kdecachegrind
++Icon=kdecachegrind
++Type=MimeType
++MimeType=application/x-kcachegrind
++Patterns=cachegrind.out*;callgrind.out*
+diff --git a/kdecachegrind/tests/cg-badcompression1 b/kdecachegrind/tests/cg-badcompression1
+new file mode 100644
+index 0000000..6076bf9
+--- /dev/null
++++ b/kdecachegrind/tests/cg-badcompression1
+@@ -0,0 +1,17 @@
++# Test with bad callgrind format
++# Expected:
++# :13 - Redefinition of compressed file index 2 (was 'file1.c') to ''
++# :14 - Redefinition of compressed function index 1 (was 'main') to 'main2'
++# :16 - Undefined compressed function index 2
++# :16 - Invalid function, setting to unknown
++
++events: Ir
++
++fl=(2) file1.c
++fn=(1) main
++10 9
++fl=(2 )
++fn=(1) main2
++11 1
++fn=(2)
++12 1
+diff --git a/kdecachegrind/tests/cg-badcostline1 b/kdecachegrind/tests/cg-badcostline1
+new file mode 100644
+index 0000000..224ff67
+--- /dev/null
++++ b/kdecachegrind/tests/cg-badcostline1
+@@ -0,0 +1,11 @@
++# Test with bad callgrind format
++# Expected:
++# :10 - ignored garbage at end of cost line ('30')
++# :11 - ignored garbage at end of cost line ('hello')
++
++events: Ir
++
++fn=main
++10 20 30
++11 hello
++12 10
+diff --git a/kdecachegrind/tests/cg-badposition b/kdecachegrind/tests/cg-badposition
+new file mode 100644
+index 0000000..1be582c
+--- /dev/null
++++ b/kdecachegrind/tests/cg-badposition
+@@ -0,0 +1,15 @@
++# Test with bad callgrind format
++# Expected:
++# :11 - Negative line number -20
++# :12 - Garbage at end of cost line ('a 21')
++# :13 - Negative line number -91
++# :15 - Invalid line 'aa 40'
++
++events: Ir
++
++fn=main
++-20 1
++9a 21
++-100 20
++0x9a 30
++aa 40
+diff --git a/kdecachegrind/version.h.in b/kdecachegrind/version.h.in
+new file mode 100644
+index 0000000..d88081b
+--- /dev/null
++++ b/kdecachegrind/version.h.in
+@@ -0,0 +1 @@
++#define KCACHEGRIND_VERSION "@KCACHEGRIND_VERSION@"
diff --git a/redhat/kdesdk/kdesdk-3.5.13.1-fix_various_cmake_issues.patch b/redhat/kdesdk/kdesdk-3.5.13.1-fix_various_cmake_issues.patch
new file mode 100644
index 000000000..269b9f526
--- /dev/null
+++ b/redhat/kdesdk/kdesdk-3.5.13.1-fix_various_cmake_issues.patch
@@ -0,0 +1,159 @@
+Index: b/cervisia/CMakeLists.txt
+===================================================================
+--- a/cervisia/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100
++++ b/cervisia/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100
+@@ -58,6 +58,24 @@
+ DESTINATION ${KCONF_UPDATE_INSTALL_DIR} )
+
+
++macro( _pod2man )
++ foreach( _pod ${ARGN} )
++ add_custom_command(
++ OUTPUT ${_pod}.1
++ COMMAND pod2man ${CMAKE_CURRENT_SOURCE_DIR}/${_pod}.pod > ${_pod}.1.in
++ COMMAND
++ sed -e 's%_KDEHTMLDIR_%'${HTML_INSTALL_DIR}'%g;'
++ -e 's%_KDECONFDIR_%'${CONFIG_INSTALL_DIR}'%g;'
++ < ${_pod}.1.in > ${_pod}.1
++ DEPENDS ${_pod} )
++ add_custom_target( "${_pod}-man" ALL DEPENDS ${_pod}.1 )
++ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_pod}.1 DESTINATION ${MAN_INSTALL_DIR}/man1 )
++ endforeach( )
++endmacro()
++
++_pod2man( cervisia )
++
++
+ ##### cervisia (static) #########################
+
+ tde_add_library( cervisia STATIC_PIC AUTOMOC
+Index: b/cervisia/cvsservice/CMakeLists.txt
+===================================================================
+--- a/cervisia/cvsservice/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100
++++ b/cervisia/cvsservice/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100
+@@ -41,7 +41,7 @@
+ tde_add_library( cvsservice SHARED AUTOMOC
+ SOURCES
+ cvsservice.stub cvsjob.stub repository.stub
+- VERSION 0.1.0
++ VERSION 0.0.1
+ LINK kdecore-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+ )
+Index: b/kapptemplate/CMakeLists.txt
+===================================================================
+--- a/kapptemplate/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100
++++ b/kapptemplate/CMakeLists.txt 2012-11-05 23:56:28.000000000 +0100
+@@ -23,7 +23,11 @@
+
+ install( PROGRAMS
+ ${CMAKE_CURRENT_BINARY_DIR}/kapptemplate
++ DESTINATION ${BIN_INSTALL_DIR} )
++
++install( PROGRAMS
++ ${CMAKE_CURRENT_SOURCE_DIR}/mkinstalldirs
+ DESTINATION ${DATA_INSTALL_DIR}/kapptemplate/bin )
+
+ install( FILES
+ kapptemplate.common kapptemplate.module
+
+Index: b/kapptemplate/admin/CMakeLists.txt
+===================================================================
+--- a/kapptemplate/admin/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100
++++ b/kapptemplate/admin/CMakeLists.txt 2012-11-06 00:13:16.000000000 +0100
+@@ -9,4 +9,9 @@
+ #
+ #################################################
+
+-tde_install_empty_directory( ${DATA_INSTALL_DIR}/kapptemplate/admin )
++install(
++ DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../admin/
++ DESTINATION ${DATA_INSTALL_DIR}/kapptemplate/admin
++ USE_SOURCE_PERMISSIONS
++ REGEX "Makefile(|\\.in|\\.am)$|.*-orig$" EXCLUDE
++)
+Index: b/kmtrace/CMakeLists.txt
+===================================================================
+--- a/kmtrace/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100
++++ b/kmtrace/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100
+@@ -31,12 +31,16 @@
+ install( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/kminspector
+ DESTINATION ${BIN_INSTALL_DIR} )
+
++install( FILES ktrace.h
++ DESTINATION ${INCLUDE_INSTALL_DIR}
++)
++
+
+ ##### ktrace_s (static) #########################
+
+ tde_add_library( ktrace_s STATIC
+ SOURCES ktrace.c
+- DESTINATION ${LIB_INSTALL_DIR}
++ DESTINATION ${LIB_INSTALL_DIR}/kmtrace
+ )
+
+
+Index: b/kompare/interfaces/CMakeLists.txt
+===================================================================
+--- a/kompare/interfaces/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100
++++ b/kompare/interfaces/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100
+@@ -23,6 +23,7 @@
+
+ tde_add_library( kompareinterface SHARED
+ SOURCES kompareinterface.cpp
++ VERSION 0.0.0
+ LINK ${TQT_LIBRARIES}
+ DESTINATION ${LIB_INSTALL_DIR}
+ )
+Index: b/kunittest/CMakeLists.txt
+===================================================================
+--- a/kunittest/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100
++++ b/kunittest/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100
+@@ -35,6 +35,7 @@
+
+ tde_add_library( kunittestgui SHARED AUTOMOC
+ SOURCES testerwidget.ui runnergui.cpp dcopinterface.skel
++ VERSION 0.0.0
+ LINK kunittest-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+ )
+Index: b/scheck/CMakeLists.txt
+===================================================================
+--- a/scheck/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100
++++ b/scheck/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100
+@@ -30,5 +30,5 @@
+ tde_add_kpart( scheck AUTOMOC
+ SOURCES scheck.cpp
+ LINK kdeui-shared
+- DESTINATION ${PLUGIN_INSTALL_DIR}
++ DESTINATION ${PLUGIN_INSTALL_DIR}/plugins/styles
+ )
+Index: b/scripts/CMakeLists.txt
+===================================================================
+--- a/scripts/CMakeLists.txt 2012-11-05 23:40:05.000000000 +0100
++++ b/scripts/CMakeLists.txt 2012-11-05 23:41:26.000000000 +0100
+@@ -36,7 +36,7 @@
+ COMMAND pod2man ${CMAKE_CURRENT_SOURCE_DIR}/${_pod} > ${_pod}.1
+ DEPENDS ${_pod} )
+ add_custom_target( "${_pod}-man" ALL DEPENDS ${_pod}.1 )
+- install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_pod}.1 DESTINATION ${MAN_INSTALL_DIR} )
++ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_pod}.1 DESTINATION ${MAN_INSTALL_DIR}/man1 )
+ endforeach( )
+ endmacro()
+
+Index: b/kapptemplate/admin/Makefile.am
+===================================================================
+--- a/kapptemplate/admin/Makefile.am 2012-11-06 00:36:24.000000000 +0100
++++ b/kapptemplate/admin/Makefile.am 2012-11-06 00:48:24.000000000 +0100
+@@ -1,8 +1,8 @@
+ install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(kde_datadir)/kapptemplate/admin
+ for file in $(srcdir)/*; do \
+- if [ -f $$file -a $$file != 'Makefile' -a $$file != 'Makefile.in' -a $$file != 'Makefile.am' ]; then \
+- destfile=`basename $$file` \
++ destfile=`basename $$file`; \
++ if [ -f $$file -a $$destfile != 'Makefile' -a $$destfile != 'Makefile.in' -a $$destfile != 'Makefile.am' ]; then \
+ $(INSTALL_DATA) $$file \
+ $(DESTDIR)$(kde_datadir)/kapptemplate/admin/$$destfile; \
+ fi \